1848b8605Smrg/**************************************************************************
2848b8605Smrg *
3848b8605Smrg * Copyright 2003 VMware, Inc.
4848b8605Smrg * All Rights Reserved.
5848b8605Smrg *
6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7848b8605Smrg * copy of this software and associated documentation files (the
8848b8605Smrg * "Software"), to deal in the Software without restriction, including
9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish,
10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to
11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to
12848b8605Smrg * the following conditions:
13848b8605Smrg *
14848b8605Smrg * The above copyright notice and this permission notice (including the
15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions
16848b8605Smrg * of the Software.
17848b8605Smrg *
18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25848b8605Smrg *
26848b8605Smrg **************************************************************************/
27848b8605Smrg
28848b8605Smrg#include "i915_context.h"
29848b8605Smrg#include "i915_state.h"
30848b8605Smrg#include "i915_screen.h"
31848b8605Smrg#include "i915_surface.h"
32848b8605Smrg#include "i915_query.h"
33848b8605Smrg#include "i915_batch.h"
34848b8605Smrg#include "i915_resource.h"
35848b8605Smrg
36848b8605Smrg#include "draw/draw_context.h"
37848b8605Smrg#include "pipe/p_defines.h"
38848b8605Smrg#include "util/u_inlines.h"
39848b8605Smrg#include "util/u_memory.h"
40b8e80941Smrg#include "util/u_prim.h"
41b8e80941Smrg#include "util/u_upload_mgr.h"
42848b8605Smrg#include "pipe/p_screen.h"
43848b8605Smrg
44848b8605Smrg
45848b8605SmrgDEBUG_GET_ONCE_BOOL_OPTION(i915_no_vbuf, "I915_NO_VBUF", FALSE)
46848b8605Smrg
47848b8605Smrg
48848b8605Smrg/*
49848b8605Smrg * Draw functions
50848b8605Smrg */
51848b8605Smrg
52848b8605Smrg
53848b8605Smrgstatic void
54848b8605Smrgi915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
55848b8605Smrg{
56848b8605Smrg   struct i915_context *i915 = i915_context(pipe);
57848b8605Smrg   struct draw_context *draw = i915->draw;
58848b8605Smrg   const void *mapped_indices = NULL;
59848b8605Smrg   unsigned i;
60848b8605Smrg
61b8e80941Smrg   if (!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
62b8e80941Smrg      return;
63b8e80941Smrg
64848b8605Smrg   /*
65848b8605Smrg    * Ack vs contants here, helps ipers a lot.
66848b8605Smrg    */
67848b8605Smrg   i915->dirty &= ~I915_NEW_VS_CONSTANTS;
68848b8605Smrg
69848b8605Smrg   if (i915->dirty)
70848b8605Smrg      i915_update_derived(i915);
71848b8605Smrg
72848b8605Smrg   /*
73848b8605Smrg    * Map vertex buffers
74848b8605Smrg    */
75848b8605Smrg   for (i = 0; i < i915->nr_vertex_buffers; i++) {
76b8e80941Smrg      const void *buf = i915->vertex_buffers[i].is_user_buffer ?
77b8e80941Smrg                           i915->vertex_buffers[i].buffer.user : NULL;
78b8e80941Smrg      if (!buf) {
79b8e80941Smrg         if (!i915->vertex_buffers[i].buffer.resource)
80b8e80941Smrg            continue;
81b8e80941Smrg         buf = i915_buffer(i915->vertex_buffers[i].buffer.resource)->data;
82b8e80941Smrg      }
83848b8605Smrg      draw_set_mapped_vertex_buffer(draw, i, buf, ~0);
84848b8605Smrg   }
85848b8605Smrg
86848b8605Smrg   /*
87848b8605Smrg    * Map index buffer, if present
88848b8605Smrg    */
89b8e80941Smrg   if (info->index_size) {
90b8e80941Smrg      mapped_indices = info->has_user_indices ? info->index.user : NULL;
91848b8605Smrg      if (!mapped_indices)
92b8e80941Smrg         mapped_indices = i915_buffer(info->index.resource)->data;
93848b8605Smrg      draw_set_indexes(draw,
94b8e80941Smrg                       (ubyte *) mapped_indices,
95b8e80941Smrg                       info->index_size, ~0);
96848b8605Smrg   }
97848b8605Smrg
98848b8605Smrg   if (i915->constants[PIPE_SHADER_VERTEX])
99848b8605Smrg      draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
100848b8605Smrg                                      i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data,
101848b8605Smrg                                      (i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
102848b8605Smrg                                      4 * sizeof(float)));
103848b8605Smrg   else
104848b8605Smrg      draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0);
105848b8605Smrg
106848b8605Smrg   if (i915->num_vertex_sampler_views > 0)
107848b8605Smrg      i915_prepare_vertex_sampling(i915);
108848b8605Smrg
109848b8605Smrg   /*
110848b8605Smrg    * Do the drawing
111848b8605Smrg    */
112848b8605Smrg   draw_vbo(i915->draw, info);
113848b8605Smrg
114848b8605Smrg   /*
115848b8605Smrg    * unmap vertex/index buffers
116848b8605Smrg    */
117848b8605Smrg   for (i = 0; i < i915->nr_vertex_buffers; i++) {
118848b8605Smrg      draw_set_mapped_vertex_buffer(i915->draw, i, NULL, 0);
119848b8605Smrg   }
120848b8605Smrg   if (mapped_indices)
121848b8605Smrg      draw_set_indexes(draw, NULL, 0, 0);
122848b8605Smrg
123848b8605Smrg   if (i915->num_vertex_sampler_views > 0)
124848b8605Smrg      i915_cleanup_vertex_sampling(i915);
125848b8605Smrg
126848b8605Smrg   /*
127848b8605Smrg    * Instead of flushing on every state change, we flush once here
128848b8605Smrg    * when we fire the vbo.
129848b8605Smrg    */
130848b8605Smrg   draw_flush(i915->draw);
131848b8605Smrg}
132848b8605Smrg
133848b8605Smrg
134848b8605Smrg/*
135848b8605Smrg * Generic context functions
136848b8605Smrg */
137848b8605Smrg
138848b8605Smrg
139848b8605Smrgstatic void i915_destroy(struct pipe_context *pipe)
140848b8605Smrg{
141848b8605Smrg   struct i915_context *i915 = i915_context(pipe);
142848b8605Smrg   int i;
143848b8605Smrg
144848b8605Smrg   if (i915->blitter)
145848b8605Smrg      util_blitter_destroy(i915->blitter);
146848b8605Smrg
147848b8605Smrg   draw_destroy(i915->draw);
148848b8605Smrg
149b8e80941Smrg   if (i915->base.stream_uploader)
150b8e80941Smrg      u_upload_destroy(i915->base.stream_uploader);
151b8e80941Smrg
152848b8605Smrg   if(i915->batch)
153848b8605Smrg      i915->iws->batchbuffer_destroy(i915->batch);
154848b8605Smrg
155848b8605Smrg   /* unbind framebuffer */
156848b8605Smrg   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
157848b8605Smrg      pipe_surface_reference(&i915->framebuffer.cbufs[i], NULL);
158848b8605Smrg   }
159848b8605Smrg   pipe_surface_reference(&i915->framebuffer.zsbuf, NULL);
160848b8605Smrg
161848b8605Smrg   /* unbind constant buffers */
162848b8605Smrg   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
163848b8605Smrg      pipe_resource_reference(&i915->constants[i], NULL);
164848b8605Smrg   }
165848b8605Smrg
166848b8605Smrg   FREE(i915);
167848b8605Smrg}
168848b8605Smrg
169848b8605Smrgstruct pipe_context *
170b8e80941Smrgi915_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
171848b8605Smrg{
172848b8605Smrg   struct i915_context *i915;
173848b8605Smrg
174848b8605Smrg   i915 = CALLOC_STRUCT(i915_context);
175b8e80941Smrg   if (!i915)
176848b8605Smrg      return NULL;
177848b8605Smrg
178848b8605Smrg   i915->iws = i915_screen(screen)->iws;
179848b8605Smrg   i915->base.screen = screen;
180848b8605Smrg   i915->base.priv = priv;
181b8e80941Smrg   i915->base.stream_uploader = u_upload_create_default(&i915->base);
182b8e80941Smrg   i915->base.const_uploader = i915->base.stream_uploader;
183848b8605Smrg
184848b8605Smrg   i915->base.destroy = i915_destroy;
185848b8605Smrg
186848b8605Smrg   if (i915_screen(screen)->debug.use_blitter)
187848b8605Smrg      i915->base.clear = i915_clear_blitter;
188848b8605Smrg   else
189848b8605Smrg      i915->base.clear = i915_clear_render;
190848b8605Smrg
191848b8605Smrg   i915->base.draw_vbo = i915_draw_vbo;
192848b8605Smrg
193848b8605Smrg   /* init this before draw */
194b8e80941Smrg   slab_create(&i915->transfer_pool, sizeof(struct pipe_transfer),
195b8e80941Smrg                    16);
196b8e80941Smrg   slab_create(&i915->texture_transfer_pool, sizeof(struct i915_transfer),
197b8e80941Smrg                    16);
198848b8605Smrg
199848b8605Smrg   /* Batch stream debugging is a bit hacked up at the moment:
200848b8605Smrg    */
201848b8605Smrg   i915->batch = i915->iws->batchbuffer_create(i915->iws);
202848b8605Smrg
203848b8605Smrg   /*
204848b8605Smrg    * Create drawing context and plug our rendering stage into it.
205848b8605Smrg    */
206848b8605Smrg   i915->draw = draw_create(&i915->base);
207848b8605Smrg   assert(i915->draw);
208848b8605Smrg   if (!debug_get_option_i915_no_vbuf()) {
209848b8605Smrg      draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915));
210848b8605Smrg   } else {
211848b8605Smrg      draw_set_rasterize_stage(i915->draw, i915_draw_render_stage(i915));
212848b8605Smrg   }
213848b8605Smrg
214848b8605Smrg   i915_init_surface_functions(i915);
215848b8605Smrg   i915_init_state_functions(i915);
216848b8605Smrg   i915_init_flush_functions(i915);
217848b8605Smrg   i915_init_resource_functions(i915);
218848b8605Smrg   i915_init_query_functions(i915);
219848b8605Smrg
220848b8605Smrg   /* Create blitter. */
221848b8605Smrg   i915->blitter = util_blitter_create(&i915->base);
222848b8605Smrg   assert(i915->blitter);
223848b8605Smrg
224848b8605Smrg   /* must be done before installing Draw stages */
225848b8605Smrg   util_blitter_cache_all_shaders(i915->blitter);
226848b8605Smrg
227848b8605Smrg   draw_install_aaline_stage(i915->draw, &i915->base);
228848b8605Smrg   draw_install_aapoint_stage(i915->draw, &i915->base);
229848b8605Smrg   draw_enable_point_sprites(i915->draw, TRUE);
230848b8605Smrg
231848b8605Smrg   i915->dirty = ~0;
232848b8605Smrg   i915->hardware_dirty = ~0;
233848b8605Smrg   i915->immediate_dirty = ~0;
234848b8605Smrg   i915->dynamic_dirty = ~0;
235848b8605Smrg   i915->static_dirty = ~0;
236848b8605Smrg   i915->flush_dirty = 0;
237848b8605Smrg
238848b8605Smrg   return &i915->base;
239848b8605Smrg}
240