OSDN Git Service

i965: Remove empty brw_set_draw_region.
[android-x86/external-mesa.git] / src / mesa / drivers / dri / i965 / brw_vtbl.c
1 /*
2  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
3  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4  develop this 3D driver.
5  
6  Permission is hereby granted, free of charge, to any person obtaining
7  a 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, sublicense, 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
16  portions of the Software.
17  
18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  
26 **********************************************************************/
27
28 /*
29  * Authors:
30  *   Keith Whitwell <keith@tungstengraphics.com>
31  */
32
33 #include "main/glheader.h"
34 #include "main/mtypes.h"
35 #include "main/imports.h"
36 #include "main/macros.h"
37 #include "main/colormac.h"
38 #include "main/renderbuffer.h"
39 #include "main/framebuffer.h"
40
41 #include "intel_batchbuffer.h" 
42 #include "intel_regions.h" 
43 #include "intel_fbo.h"
44
45 #include "brw_context.h"
46 #include "brw_defines.h"
47 #include "brw_state.h"
48 #include "brw_draw.h"
49 #include "brw_vs.h"
50 #include "brw_wm.h"
51
52 #include "../glsl/ralloc.h"
53
54 static void
55 dri_bo_release(drm_intel_bo **bo)
56 {
57    drm_intel_bo_unreference(*bo);
58    *bo = NULL;
59 }
60
61
62 /**
63  * called from intelDestroyContext()
64  */
65 static void brw_destroy_context( struct intel_context *intel )
66 {
67    struct brw_context *brw = brw_context(&intel->ctx);
68
69    brw_destroy_state(brw);
70    brw_draw_destroy( brw );
71    brw_clear_validated_bos(brw);
72    ralloc_free(brw->wm.compile_data);
73
74    dri_bo_release(&brw->curbe.curbe_bo);
75    dri_bo_release(&brw->vs.const_bo);
76    dri_bo_release(&brw->wm.const_bo);
77
78    free(brw->curbe.last_buf);
79    free(brw->curbe.next_buf);
80 }
81
82 /**
83  * Update the hardware state for drawing into a window or framebuffer object.
84  *
85  * Called by glDrawBuffer, glBindFramebufferEXT, MakeCurrent, and other
86  * places within the driver.
87  *
88  * Basically, this needs to be called any time the current framebuffer
89  * changes, the renderbuffers change, or we need to draw into different
90  * color buffers.
91  */
92 static void
93 brw_update_draw_buffer(struct intel_context *intel)
94 {
95    struct gl_context *ctx = &intel->ctx;
96    struct gl_framebuffer *fb = ctx->DrawBuffer;
97    struct intel_region *colorRegions[MAX_DRAW_BUFFERS], *depthRegion = NULL;
98    struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL;
99    bool fb_has_hiz = intel_framebuffer_has_hiz(fb);
100
101    if (!fb) {
102       /* this can happen during the initial context initialization */
103       return;
104    }
105
106    /*
107     * If intel_context is using separate stencil, but the depth attachment
108     * (gl_framebuffer.Attachment[BUFFER_DEPTH]) has a packed depth/stencil
109     * format, then we must install the real depth buffer at fb->_DepthBuffer
110     * and set fb->_DepthBuffer->Wrapped before calling _mesa_update_framebuffer.
111     * Otherwise, _mesa_update_framebuffer will create and install a swras
112     * depth wrapper instead.
113     *
114     * Ditto for stencil.
115     */
116    irbDepth = intel_get_renderbuffer(fb, BUFFER_DEPTH);
117    if (irbDepth && irbDepth->Base.Format == MESA_FORMAT_X8_Z24) {
118       _mesa_reference_renderbuffer(&fb->_DepthBuffer, &irbDepth->Base);
119       irbDepth->Base.Wrapped = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
120    }
121
122    irbStencil = intel_get_renderbuffer(fb, BUFFER_STENCIL);
123    if (irbStencil && irbStencil->Base.Format == MESA_FORMAT_S8) {
124       _mesa_reference_renderbuffer(&fb->_StencilBuffer, &irbStencil->Base);
125       irbStencil->Base.Wrapped = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
126    }
127
128    /* Do this here, not core Mesa, since this function is called from
129     * many places within the driver.
130     */
131    if (ctx->NewState & _NEW_BUFFERS) {
132       /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */
133       _mesa_update_framebuffer(ctx);
134       /* this updates the DrawBuffer's Width/Height if it's a FBO */
135       _mesa_update_draw_buffer_bounds(ctx);
136    }
137
138    if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
139       /* this may occur when we're called by glBindFrameBuffer() during
140        * the process of someone setting up renderbuffers, etc.
141        */
142       /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/
143       return;
144    }
145
146    /* How many color buffers are we drawing into?
147     *
148     * If there are zero buffers or the buffer is too big, don't configure any
149     * regions for hardware drawing.  We'll fallback to software below.  Not
150     * having regions set makes some of the software fallback paths faster.
151     */
152    if ((fb->Width > ctx->Const.MaxRenderbufferSize)
153        || (fb->Height > ctx->Const.MaxRenderbufferSize)
154        || (fb->_NumColorDrawBuffers == 0)) {
155       /* writing to 0  */
156       colorRegions[0] = NULL;
157    }
158    else if (fb->_NumColorDrawBuffers > 1) {
159        int i;
160        struct intel_renderbuffer *irb;
161
162        for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
163            irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]);
164            colorRegions[i] = irb ? irb->region : NULL;
165        }
166    }
167    else {
168       /* Get the intel_renderbuffer for the single colorbuffer we're drawing
169        * into.
170        */
171       if (fb->Name == 0) {
172          /* drawing to window system buffer */
173          if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT)
174             colorRegions[0] = intel_get_rb_region(fb, BUFFER_FRONT_LEFT);
175          else
176             colorRegions[0] = intel_get_rb_region(fb, BUFFER_BACK_LEFT);
177       }
178       else {
179          /* drawing to user-created FBO */
180          struct intel_renderbuffer *irb;
181          irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
182          colorRegions[0] = (irb && irb->region) ? irb->region : NULL;
183       }
184    }
185
186    /* Check for depth fallback. */
187    if (irbDepth && irbDepth->region) {
188       assert(!fb_has_hiz || irbDepth->Base.Format != MESA_FORMAT_S8_Z24);
189       depthRegion = irbDepth->region;
190    } else if (irbDepth && !irbDepth->region) {
191       depthRegion = NULL;
192    } else { /* !irbDepth */
193       /* No fallback is needed because there is no depth buffer. */
194       depthRegion = NULL;
195    }
196
197    /* Check for stencil fallback. */
198    if (irbStencil && irbStencil->region) {
199       if (!intel->has_separate_stencil)
200          assert(irbStencil->Base.Format == MESA_FORMAT_S8_Z24);
201       if (fb_has_hiz || intel->must_use_separate_stencil)
202          assert(irbStencil->Base.Format == MESA_FORMAT_S8);
203       if (irbStencil->Base.Format == MESA_FORMAT_S8)
204          assert(intel->has_separate_stencil);
205    }
206
207    /* If we have a (packed) stencil buffer attached but no depth buffer,
208     * we still need to set up the shared depth/stencil state so we can use it.
209     */
210    if (depthRegion == NULL && irbStencil && irbStencil->region
211        && irbStencil->Base.Format == MESA_FORMAT_S8_Z24) {
212       depthRegion = irbStencil->region;
213    }
214
215    /*
216     * Update depth and stencil test state
217     */
218    if (ctx->Driver.Enable) {
219       ctx->Driver.Enable(ctx, GL_DEPTH_TEST,
220                          (ctx->Depth.Test && fb->Visual.depthBits > 0));
221       ctx->Driver.Enable(ctx, GL_STENCIL_TEST,
222                          (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0));
223    }
224    else {
225       /* Mesa's Stencil._Enabled field is updated when
226        * _NEW_BUFFERS | _NEW_STENCIL, but i965 code assumes that the value
227        * only changes with _NEW_STENCIL (which seems sensible).  So flag it
228        * here since this is the _NEW_BUFFERS path.
229        */
230       intel->NewGLState |= (_NEW_DEPTH | _NEW_STENCIL);
231    }
232
233    intel->NewGLState |= _NEW_BUFFERS;
234
235    /* update viewport since it depends on window size */
236 #ifdef I915
237    intelCalcViewport(ctx);
238 #else
239    intel->NewGLState |= _NEW_VIEWPORT;
240 #endif
241    /* Set state we know depends on drawable parameters:
242     */
243    if (ctx->Driver.Scissor)
244       ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
245                           ctx->Scissor.Width, ctx->Scissor.Height);
246    intel->NewGLState |= _NEW_SCISSOR;
247
248    if (ctx->Driver.DepthRange)
249       ctx->Driver.DepthRange(ctx,
250                              ctx->Viewport.Near,
251                              ctx->Viewport.Far);
252
253    /* Update culling direction which changes depending on the
254     * orientation of the buffer:
255     */
256    if (ctx->Driver.FrontFace)
257       ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
258    else
259       intel->NewGLState |= _NEW_POLYGON;
260 }
261
262 /**
263  * called from intel_batchbuffer_flush and children before sending a
264  * batchbuffer off.
265  */
266 static void brw_finish_batch(struct intel_context *intel)
267 {
268    struct brw_context *brw = brw_context(&intel->ctx);
269    brw_emit_query_end(brw);
270
271    if (brw->curbe.curbe_bo) {
272       drm_intel_gem_bo_unmap_gtt(brw->curbe.curbe_bo);
273       drm_intel_bo_unreference(brw->curbe.curbe_bo);
274       brw->curbe.curbe_bo = NULL;
275    }
276 }
277
278
279 /**
280  * called from intelFlushBatchLocked
281  */
282 static void brw_new_batch( struct intel_context *intel )
283 {
284    struct brw_context *brw = brw_context(&intel->ctx);
285
286    /* Mark all context state as needing to be re-emitted.
287     * This is probably not as severe as on 915, since almost all of our state
288     * is just in referenced buffers.
289     */
290    brw->state.dirty.brw |= BRW_NEW_CONTEXT | BRW_NEW_BATCH;
291
292    /* Assume that the last command before the start of our batch was a
293     * primitive, for safety.
294     */
295    intel->batch.need_workaround_flush = true;
296
297    brw->vb.nr_current_buffers = 0;
298
299    /* Mark that the current program cache BO has been used by the GPU.
300     * It will be reallocated if we need to put new programs in for the
301     * next batch.
302     */
303    brw->cache.bo_used_by_gpu = true;
304 }
305
306 static void brw_invalidate_state( struct intel_context *intel, GLuint new_state )
307 {
308    /* nothing */
309 }
310
311 /**
312  * \see intel_context.vtbl.is_hiz_depth_format
313  */
314 static bool brw_is_hiz_depth_format(struct intel_context *intel,
315                                     gl_format format)
316 {
317    /* In the future, this will support Z_FLOAT32. */
318    return intel->has_hiz && (format == MESA_FORMAT_X8_Z24);
319 }
320
321
322 void brwInitVtbl( struct brw_context *brw )
323 {
324    brw->intel.vtbl.check_vertex_size = 0;
325    brw->intel.vtbl.emit_state = 0;
326    brw->intel.vtbl.reduced_primitive_state = 0;
327    brw->intel.vtbl.render_start = 0;
328    brw->intel.vtbl.update_texture_state = 0;
329
330    brw->intel.vtbl.invalidate_state = brw_invalidate_state;
331    brw->intel.vtbl.new_batch = brw_new_batch;
332    brw->intel.vtbl.finish_batch = brw_finish_batch;
333    brw->intel.vtbl.destroy = brw_destroy_context;
334    brw->intel.vtbl.update_draw_buffer = brw_update_draw_buffer;
335    brw->intel.vtbl.debug_batch = brw_debug_batch;
336    brw->intel.vtbl.render_target_supported = brw_render_target_supported;
337    brw->intel.vtbl.is_hiz_depth_format = brw_is_hiz_depth_format;
338 }