From af9548d3358884b408fb4c3cc69028befc5abe1d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 12 Jul 2011 10:20:53 -0700 Subject: [PATCH] i915: Add support for HW rendering with no color draw buffer. This is useful for shadow map generation. Tested with glsl-bug-22603, which rendered the depth textures with fallbacks before. Acked-by: Chad Versace --- src/mesa/drivers/dri/i915/i915_vtbl.c | 102 +++++++++++++------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index bd0664bb79f..495426aa6d8 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -318,7 +318,8 @@ i915_emit_state(struct intel_context *intel) aper_array[aper_count++] = intel->batch.bo; if (dirty & I915_UPLOAD_BUFFERS) { - aper_array[aper_count++] = state->draw_region->buffer; + if (state->draw_region) + aper_array[aper_count++] = state->draw_region->buffer; if (state->depth_region) aper_array[aper_count++] = state->depth_region->buffer; } @@ -388,23 +389,27 @@ i915_emit_state(struct intel_context *intel) if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n"); - count = 14; + count = 17; if (state->Buffer[I915_DESTREG_DRAWRECT0] != MI_NOOP) count++; - if (state->depth_region) - count += 3; BEGIN_BATCH(count); OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]); OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); - OUT_RELOC(state->draw_region->buffer, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); + if (state->draw_region) { + OUT_RELOC(state->draw_region->buffer, + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); + } else { + OUT_BATCH(0); + } + OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]); + OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]); if (state->depth_region) { - OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]); - OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]); OUT_RELOC(state->depth_region->buffer, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); + } else { + OUT_BATCH(0); } OUT_BATCH(state->Buffer[I915_DESTREG_DV0]); @@ -532,6 +537,12 @@ i915_set_buf_info_for_region(uint32_t *state, struct intel_region *region, if (region->tiling == I915_TILING_Y) state[1] |= BUF_3D_TILE_WALK_Y; } + } else { + /* Fill in a default pitch, since 0 is invalid. We'll be + * setting the buffer offset to 0 and not referencing the + * buffer, so the pitch could really be any valid value. + */ + state[1] |= BUF_3D_PITCH(4096); } } @@ -596,6 +607,8 @@ i915_set_draw_region(struct intel_context *intel, LOD_PRECLAMP_OGL | TEX_DEFAULT_COLOR_OGL); if (irb != NULL) { value |= i915_render_target_format_for_mesa_format[irb->Base.Format]; + } else { + value |= DV_PF_8888; } /* This isn't quite safe, thus being hidden behind an option. When changing @@ -670,6 +683,20 @@ i915_set_draw_region(struct intel_context *intel, I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); } +static void +i915_update_color_write_enable(struct i915_context *i915, bool enable) +{ + uint32_t dw = i915->state.Ctx[I915_CTXREG_LIS6]; + if (enable) + dw |= S6_COLOR_WRITE_ENABLE; + else + dw &= ~S6_COLOR_WRITE_ENABLE; + if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS6] = dw; + } +} + /** * Update the hardware state for drawing into a window or framebuffer object. * @@ -683,9 +710,10 @@ i915_set_draw_region(struct intel_context *intel, static void i915_update_draw_buffer(struct intel_context *intel) { + struct i915_context *i915 = (struct i915_context *)intel; struct gl_context *ctx = &intel->ctx; struct gl_framebuffer *fb = ctx->DrawBuffer; - struct intel_region *colorRegions[MAX_DRAW_BUFFERS], *depthRegion = NULL; + struct intel_region *colorRegion = NULL, *depthRegion = NULL; struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL; bool fb_has_hiz = intel_framebuffer_has_hiz(fb); @@ -717,49 +745,19 @@ i915_update_draw_buffer(struct intel_context *intel) /* How many color buffers are we drawing into? * - * If there are zero buffers or the buffer is too big, don't configure any - * regions for hardware drawing. We'll fallback to software below. Not - * having regions set makes some of the software fallback paths faster. + * If there is more than one drawbuffer (GL_FRONT_AND_BACK), or the + * drawbuffers are too big, we have to fallback to software. */ if ((fb->Width > ctx->Const.MaxRenderbufferSize) - || (fb->Height > ctx->Const.MaxRenderbufferSize) - || (fb->_NumColorDrawBuffers == 0)) { - /* writing to 0 */ - colorRegions[0] = NULL; - } - else if (fb->_NumColorDrawBuffers > 1) { - int i; - struct intel_renderbuffer *irb; - - for (i = 0; i < fb->_NumColorDrawBuffers; i++) { - irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]); - colorRegions[i] = irb ? irb->region : NULL; - } - } - else { - /* Get the intel_renderbuffer for the single colorbuffer we're drawing - * into. - */ - if (fb->Name == 0) { - /* drawing to window system buffer */ - if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) - colorRegions[0] = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); - else - colorRegions[0] = intel_get_rb_region(fb, BUFFER_BACK_LEFT); - } - else { - /* drawing to user-created FBO */ - struct intel_renderbuffer *irb; - irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]); - colorRegions[0] = (irb && irb->region) ? irb->region : NULL; - } - } - - if (!colorRegions[0]) { - FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); - } - else { - FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); + || (fb->Height > ctx->Const.MaxRenderbufferSize)) { + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, true); + } else if (fb->_NumColorDrawBuffers > 1) { + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, true); + } else { + struct intel_renderbuffer *irb; + irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]); + colorRegion = irb ? irb->region : NULL; + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, false); } /* Check for depth fallback. */ @@ -801,7 +799,9 @@ i915_update_draw_buffer(struct intel_context *intel) ctx->Driver.Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test); ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); - intel->vtbl.set_draw_region(intel, colorRegions, depthRegion, + i915_update_color_write_enable(i915, colorRegion != NULL); + + intel->vtbl.set_draw_region(intel, &colorRegion, depthRegion, fb->_NumColorDrawBuffers); intel->NewGLState |= _NEW_BUFFERS; -- 2.30.2