i915_context.c revision ac2a665fd75249e02838ec63ef4a5b3db093ceb1
1/**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28#include "i915_context.h"
29#include "i915_state.h"
30#include "i915_screen.h"
31#include "i915_batch.h"
32
33#include "draw/draw_context.h"
34#include "pipe/p_defines.h"
35#include "pipe/p_inlines.h"
36#include "util/u_memory.h"
37#include "pipe/p_screen.h"
38
39
40/*
41 * Draw functions
42 */
43
44
45static boolean
46i915_draw_range_elements(struct pipe_context *pipe,
47                         struct pipe_buffer *indexBuffer,
48                         unsigned indexSize,
49                         unsigned min_index,
50                         unsigned max_index,
51                         unsigned prim, unsigned start, unsigned count)
52{
53   struct i915_context *i915 = i915_context(pipe);
54   struct draw_context *draw = i915->draw;
55   unsigned i;
56
57   if (i915->dirty)
58      i915_update_derived(i915);
59
60   /*
61    * Map vertex buffers
62    */
63   for (i = 0; i < i915->num_vertex_buffers; i++) {
64      void *buf = pipe_buffer_map(pipe->screen, i915->vertex_buffer[i].buffer,
65                                  PIPE_BUFFER_USAGE_CPU_READ);
66      draw_set_mapped_vertex_buffer(draw, i, buf);
67   }
68
69   /*
70    * Map index buffer, if present
71    */
72   if (indexBuffer) {
73      void *mapped_indexes = pipe_buffer_map(pipe->screen, indexBuffer,
74                                             PIPE_BUFFER_USAGE_CPU_READ);
75      draw_set_mapped_element_buffer_range(draw, indexSize,
76                                           min_index,
77                                           max_index,
78                                           mapped_indexes);
79   } else {
80      draw_set_mapped_element_buffer(draw, 0, NULL);
81   }
82
83
84   draw_set_mapped_constant_buffer(draw,
85                                   i915->current.constants[PIPE_SHADER_VERTEX],
86                                   (i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
87                                      4 * sizeof(float)));
88
89   /*
90    * Do the drawing
91    */
92   draw_arrays(i915->draw, prim, start, count);
93
94   /*
95    * unmap vertex/index buffers
96    */
97   for (i = 0; i < i915->num_vertex_buffers; i++) {
98      pipe_buffer_unmap(pipe->screen, i915->vertex_buffer[i].buffer);
99      draw_set_mapped_vertex_buffer(draw, i, NULL);
100   }
101
102   if (indexBuffer) {
103      pipe_buffer_unmap(pipe->screen, indexBuffer);
104      draw_set_mapped_element_buffer_range(draw, 0, start, start + count - 1, NULL);
105   }
106
107   return TRUE;
108}
109
110static boolean
111i915_draw_elements(struct pipe_context *pipe,
112                   struct pipe_buffer *indexBuffer,
113                   unsigned indexSize,
114                   unsigned prim, unsigned start, unsigned count)
115{
116   return i915_draw_range_elements(pipe, indexBuffer,
117                                   indexSize,
118                                   0, 0xffffffff,
119                                   prim, start, count);
120}
121
122static boolean
123i915_draw_arrays(struct pipe_context *pipe,
124                 unsigned prim, unsigned start, unsigned count)
125{
126   return i915_draw_elements(pipe, NULL, 0, prim, start, count);
127}
128
129
130/*
131 * Is referenced functions
132 */
133
134
135static unsigned int
136i915_is_texture_referenced(struct pipe_context *pipe,
137                           struct pipe_texture *texture,
138                           unsigned face, unsigned level)
139{
140   /**
141    * FIXME: Return the corrent result. We can't alays return referenced
142    *        since it causes a double flush within the vbo module.
143    */
144#if 0
145   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
146#else
147   return 0;
148#endif
149}
150
151static unsigned int
152i915_is_buffer_referenced(struct pipe_context *pipe,
153                          struct pipe_buffer *buf)
154{
155   /*
156    * Since we never expose hardware buffers to the state tracker
157    * they can never be referenced, so this isn't a lie
158    */
159   return 0;
160}
161
162
163/*
164 * Generic context functions
165 */
166
167
168static void i915_destroy(struct pipe_context *pipe)
169{
170   struct i915_context *i915 = i915_context(pipe);
171   int i;
172
173   draw_destroy(i915->draw);
174
175   if(i915->batch)
176      i915->iws->batchbuffer_destroy(i915->batch);
177
178   /* unbind framebuffer */
179   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
180      pipe_surface_reference(&i915->framebuffer.cbufs[i], NULL);
181   }
182   pipe_surface_reference(&i915->framebuffer.zsbuf, NULL);
183
184   FREE(i915);
185}
186
187struct pipe_context *
188i915_create_context(struct pipe_screen *screen)
189{
190   struct i915_context *i915;
191
192   i915 = CALLOC_STRUCT(i915_context);
193   if (i915 == NULL)
194      return NULL;
195
196   i915->iws = i915_screen(screen)->iws;
197   i915->base.winsys = NULL;
198   i915->base.screen = screen;
199
200   i915->base.destroy = i915_destroy;
201
202   i915->base.clear = i915_clear;
203
204   i915->base.draw_arrays = i915_draw_arrays;
205   i915->base.draw_elements = i915_draw_elements;
206   i915->base.draw_range_elements = i915_draw_range_elements;
207
208   i915->base.is_texture_referenced = i915_is_texture_referenced;
209   i915->base.is_buffer_referenced = i915_is_buffer_referenced;
210
211   /*
212    * Create drawing context and plug our rendering stage into it.
213    */
214   i915->draw = draw_create();
215   assert(i915->draw);
216   if (!debug_get_bool_option("I915_NO_VBUF", FALSE)) {
217      draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915));
218   } else {
219      draw_set_rasterize_stage(i915->draw, i915_draw_render_stage(i915));
220   }
221
222   i915_init_surface_functions(i915);
223   i915_init_state_functions(i915);
224   i915_init_flush_functions(i915);
225
226   draw_install_aaline_stage(i915->draw, &i915->base);
227   draw_install_aapoint_stage(i915->draw, &i915->base);
228
229   i915->dirty = ~0;
230   i915->hardware_dirty = ~0;
231
232   /* Batch stream debugging is a bit hacked up at the moment:
233    */
234   i915->batch = i915->iws->batchbuffer_create(i915->iws);
235
236   return &i915->base;
237}
238