From: Paul Berry Date: Fri, 13 Jul 2012 14:25:12 +0000 (-0700) Subject: i965: Set width, height, and tiling properly for null render targets. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0aeb87023e64807734aee323e76f81796d525a36;p=mesa.git i965: Set width, height, and tiling properly for null render targets. The HW docs say that the width and height of null render targets need to match the width and height of the corresponding depth and/or stencil buffers, and that they need to be marked as Y-tiled. Although leaving these values at 0 doesn't seem to cause any ill effects, it seems wise to follow the documented requirements. Reviewed-by: Chad Versace --- diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 82e44f9b83a..c2e629ce225 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -961,9 +961,31 @@ const struct brw_tracked_state brw_wm_pull_constants = { static void brw_update_null_renderbuffer_surface(struct brw_context *brw, unsigned int unit) { + /* From the Sandy bridge PRM, Vol4 Part1 p71 (Surface Type: Programming + * Notes): + * + * A null surface will be used in instances where an actual surface is + * not bound. When a write message is generated to a null surface, no + * actual surface is written to. When a read message (including any + * sampling engine message) is generated to a null surface, the result + * is all zeros. Note that a null surface type is allowed to be used + * with all messages, even if it is not specificially indicated as + * supported. All of the remaining fields in surface state are ignored + * for null surfaces, with the following exceptions: + * + * - [DevSNB+]: Width, Height, Depth, and LOD fields must match the + * depth buffer’s corresponding state for all render target surfaces, + * including null. + * + * - Surface Format must be R8G8B8A8_UNORM. + */ struct intel_context *intel = &brw->intel; + struct gl_context *ctx = &intel->ctx; uint32_t *surf; + /* _NEW_BUFFERS */ + const struct gl_framebuffer *fb = ctx->DrawBuffer; + surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 6 * 4, 32, &brw->wm.surf_offset[unit]); @@ -976,8 +998,15 @@ brw_update_null_renderbuffer_surface(struct brw_context *brw, unsigned int unit) 1 << BRW_SURFACE_WRITEDISABLE_A_SHIFT); } surf[1] = 0; - surf[2] = 0; - surf[3] = 0; + surf[2] = ((fb->Width - 1) << BRW_SURFACE_WIDTH_SHIFT | + (fb->Height - 1) << BRW_SURFACE_HEIGHT_SHIFT); + + /* From Sandy bridge PRM, Vol4 Part1 p82 (Tiled Surface: Programming + * Notes): + * + * If Surface Type is SURFTYPE_NULL, this field must be TRUE + */ + surf[3] = BRW_SURFACE_TILED | BRW_SURFACE_TILED_Y; surf[4] = 0; surf[5] = 0; } diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c index 869f9431b9d..25222761e42 100644 --- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c @@ -409,8 +409,28 @@ gen7_create_constant_surface(struct brw_context *brw, static void gen7_update_null_renderbuffer_surface(struct brw_context *brw, unsigned unit) { + /* From the Ivy bridge PRM, Vol4 Part1 p62 (Surface Type: Programming + * Notes): + * + * A null surface is used in instances where an actual surface is not + * bound. When a write message is generated to a null surface, no + * actual surface is written to. When a read message (including any + * sampling engine message) is generated to a null surface, the result + * is all zeros. Note that a null surface type is allowed to be used + * with all messages, even if it is not specificially indicated as + * supported. All of the remaining fields in surface state are ignored + * for null surfaces, with the following exceptions: Width, Height, + * Depth, LOD, and Render Target View Extent fields must match the + * depth buffer’s corresponding state for all render target surfaces, + * including null. + */ + struct intel_context *intel = &brw->intel; + struct gl_context *ctx = &intel->ctx; struct gen7_surface_state *surf; + /* _NEW_BUFFERS */ + const struct gl_framebuffer *fb = ctx->DrawBuffer; + surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, sizeof(*surf), 32, &brw->wm.surf_offset[unit]); memset(surf, 0, sizeof(*surf)); @@ -418,6 +438,15 @@ gen7_update_null_renderbuffer_surface(struct brw_context *brw, unsigned unit) surf->ss0.surface_type = BRW_SURFACE_NULL; surf->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM; + surf->ss2.width = fb->Width - 1; + surf->ss2.height = fb->Height - 1; + + /* From the Ivy bridge PRM, Vol4 Part1 p65 (Tiled Surface: Programming Notes): + * + * If Surface Type is SURFTYPE_NULL, this field must be TRUE. + */ + gen7_set_surface_tiling(surf, I915_TILING_Y); + gen7_check_surface_setup(surf, true /* is_render_target */); }