130519ffa5099e33ddd0a20640973946d687b339
[profile/ivi/mesa.git] / src / gallium / drivers / i915 / i915_context.c
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 "util/u_inlines.h"
36 #include "util/u_memory.h"
37 #include "pipe/p_screen.h"
38
39
40 /*
41  * Draw functions
42  */
43
44
45 static void
46 i915_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, PIPE_SHADER_VERTEX, 0,
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
108 static void
109 i915_draw_elements(struct pipe_context *pipe,
110                    struct pipe_buffer *indexBuffer,
111                    unsigned indexSize,
112                    unsigned prim, unsigned start, unsigned count)
113 {
114    i915_draw_range_elements(pipe, indexBuffer,
115                             indexSize,
116                             0, 0xffffffff,
117                             prim, start, count);
118 }
119
120 static void
121 i915_draw_arrays(struct pipe_context *pipe,
122                  unsigned prim, unsigned start, unsigned count)
123 {
124    i915_draw_elements(pipe, NULL, 0, prim, start, count);
125 }
126
127
128 /*
129  * Is referenced functions
130  */
131
132
133 static unsigned int
134 i915_is_texture_referenced(struct pipe_context *pipe,
135                            struct pipe_texture *texture,
136                            unsigned face, unsigned level)
137 {
138    /**
139     * FIXME: Return the corrent result. We can't alays return referenced
140     *        since it causes a double flush within the vbo module.
141     */
142 #if 0
143    return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
144 #else
145    return 0;
146 #endif
147 }
148
149 static unsigned int
150 i915_is_buffer_referenced(struct pipe_context *pipe,
151                           struct pipe_buffer *buf)
152 {
153    /*
154     * Since we never expose hardware buffers to the state tracker
155     * they can never be referenced, so this isn't a lie
156     */
157    return 0;
158 }
159
160
161 /*
162  * Generic context functions
163  */
164
165
166 static void i915_destroy(struct pipe_context *pipe)
167 {
168    struct i915_context *i915 = i915_context(pipe);
169    int i;
170
171    draw_destroy(i915->draw);
172    
173    if(i915->batch)
174       i915->iws->batchbuffer_destroy(i915->batch);
175
176    /* unbind framebuffer */
177    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
178       pipe_surface_reference(&i915->framebuffer.cbufs[i], NULL);
179    }
180    pipe_surface_reference(&i915->framebuffer.zsbuf, NULL);
181
182    FREE(i915);
183 }
184
185 struct pipe_context *
186 i915_create_context(struct pipe_screen *screen, void *priv)
187 {
188    struct i915_context *i915;
189
190    i915 = CALLOC_STRUCT(i915_context);
191    if (i915 == NULL)
192       return NULL;
193
194    i915->iws = i915_screen(screen)->iws;
195    i915->base.winsys = NULL;
196    i915->base.screen = screen;
197    i915->base.priv = priv;
198
199    i915->base.destroy = i915_destroy;
200
201    i915->base.clear = i915_clear;
202
203    i915->base.draw_arrays = i915_draw_arrays;
204    i915->base.draw_elements = i915_draw_elements;
205    i915->base.draw_range_elements = i915_draw_range_elements;
206
207    i915->base.is_texture_referenced = i915_is_texture_referenced;
208    i915->base.is_buffer_referenced = i915_is_buffer_referenced;
209
210    /*
211     * Create drawing context and plug our rendering stage into it.
212     */
213    i915->draw = draw_create();
214    assert(i915->draw);
215    if (!debug_get_bool_option("I915_NO_VBUF", FALSE)) {
216       draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915));
217    } else {
218       draw_set_rasterize_stage(i915->draw, i915_draw_render_stage(i915));
219    }
220
221    i915_init_surface_functions(i915);
222    i915_init_state_functions(i915);
223    i915_init_flush_functions(i915);
224    i915_init_texture_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 }