mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 16:08:04 +02:00
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 <chad@chad-versace.us>
This commit is contained in:
parent
debf751aea
commit
af9548d335
1 changed files with 51 additions and 51 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue