[Mesa-dev] [PATCH 03/10] i965: Set width, height, and tiling properly for null render targets.
Paul Berry
stereotype441 at gmail.com
Wed Jul 18 08:15:14 PDT 2012
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.
---
src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 33 +++++++++++++++++++-
src/mesa/drivers/dri/i965/gen7_wm_surface_state.c | 29 ++++++++++++++++++
2 files changed, 60 insertions(+), 2 deletions(-)
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 82e44f9..c2e629c 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 869f943..2522276 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 */);
}
--
1.7.7.6
More information about the mesa-dev
mailing list