* hardware discard the target 0 color output..
*/
static void
-brw_update_null_renderbuffer_surface(struct brw_context *brw, unsigned int unit)
+brw_emit_null_surface_state(struct brw_context *brw,
+ unsigned width,
+ unsigned height,
+ unsigned samples,
+ uint32_t *out_offset)
{
/* From the Sandy bridge PRM, Vol4 Part1 p71 (Surface Type: Programming
* Notes):
*
* - Surface Format must be R8G8B8A8_UNORM.
*/
- struct gl_context *ctx = &brw->ctx;
- uint32_t *surf;
unsigned surface_type = BRW_SURFACE_NULL;
drm_intel_bo *bo = NULL;
unsigned pitch_minus_1 = 0;
uint32_t multisampling_state = 0;
- /* BRW_NEW_FS_PROG_DATA */
- uint32_t surf_index =
- brw->wm.prog_data->binding_table.render_target_start + unit;
-
- /* _NEW_BUFFERS */
- const struct gl_framebuffer *fb = ctx->DrawBuffer;
-
- surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 6 * 4, 32,
- &brw->wm.base.surf_offset[surf_index]);
+ uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 6 * 4, 32,
+ out_offset);
- if (fb->Visual.samples > 1) {
+ if (samples > 1) {
/* On Gen6, null render targets seem to cause GPU hangs when
* multisampling. So work around this problem by rendering into dummy
* color buffer.
* width_in_tiles and height_in_tiles by dividing the width and height
* by 16 rather than the normal Y-tile size of 32.
*/
- unsigned width_in_tiles = ALIGN(fb->Width, 16) / 16;
- unsigned height_in_tiles = ALIGN(fb->Height, 16) / 16;
+ unsigned width_in_tiles = ALIGN(width, 16) / 16;
+ unsigned height_in_tiles = ALIGN(height, 16) / 16;
unsigned size_needed = (width_in_tiles + height_in_tiles - 1) * 4096;
brw_get_scratch_bo(brw, &brw->wm.multisampled_null_render_target_bo,
size_needed);
bo = brw->wm.multisampled_null_render_target_bo;
surface_type = BRW_SURFACE_2D;
pitch_minus_1 = 127;
- multisampling_state =
- brw_get_surface_num_multisamples(fb->Visual.samples);
+ multisampling_state = brw_get_surface_num_multisamples(samples);
}
surf[0] = (surface_type << BRW_SURFACE_TYPE_SHIFT |
1 << BRW_SURFACE_WRITEDISABLE_A_SHIFT);
}
surf[1] = bo ? bo->offset64 : 0;
- surf[2] = ((fb->Width - 1) << BRW_SURFACE_WIDTH_SHIFT |
- (fb->Height - 1) << BRW_SURFACE_HEIGHT_SHIFT);
+ surf[2] = ((width - 1) << BRW_SURFACE_WIDTH_SHIFT |
+ (height - 1) << BRW_SURFACE_HEIGHT_SHIFT);
/* From Sandy bridge PRM, Vol4 Part1 p82 (Tiled Surface: Programming
* Notes):
if (bo) {
drm_intel_bo_emit_reloc(brw->batch.bo,
- brw->wm.base.surf_offset[surf_index] + 4,
+ *out_offset + 4,
bo, 0,
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
}
brw_update_renderbuffer_surfaces(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
+ /* _NEW_BUFFERS */
+ const struct gl_framebuffer *fb = ctx->DrawBuffer;
GLuint i;
/* _NEW_BUFFERS | _NEW_COLOR */
brw->vtbl.update_renderbuffer_surface(brw, ctx->DrawBuffer->_ColorDrawBuffers[i],
ctx->DrawBuffer->MaxNumLayers > 0, i);
} else {
- brw->vtbl.update_null_renderbuffer_surface(brw, i);
+ const uint32_t surf_index =
+ brw->wm.prog_data->binding_table.render_target_start + i;
+
+ brw->vtbl.emit_null_surface_state(
+ brw, fb->Width, fb->Height, fb->Visual.samples,
+ &brw->wm.base.surf_offset[surf_index]);
}
}
} else {
- brw->vtbl.update_null_renderbuffer_surface(brw, 0);
+ const uint32_t surf_index =
+ brw->wm.prog_data->binding_table.render_target_start;
+
+ brw->vtbl.emit_null_surface_state(
+ brw, fb->Width, fb->Height, fb->Visual.samples,
+ &brw->wm.base.surf_offset[surf_index]);
}
brw->state.dirty.brw |= BRW_NEW_SURFACES;
}
{
brw->vtbl.update_texture_surface = brw_update_texture_surface;
brw->vtbl.update_renderbuffer_surface = brw_update_renderbuffer_surface;
- brw->vtbl.update_null_renderbuffer_surface =
- brw_update_null_renderbuffer_surface;
+ brw->vtbl.emit_null_surface_state = brw_emit_null_surface_state;
brw->vtbl.emit_buffer_surface_state = gen4_emit_buffer_surface_state;
}
}
/**
- * Creates a null renderbuffer surface.
+ * Creates a null surface.
*
* This is used when the shader doesn't write to any color output. An FB
* write to target 0 will still be emitted, because that's how the thread is
* hardware discard the target 0 color output..
*/
static void
-gen7_update_null_renderbuffer_surface(struct brw_context *brw, unsigned unit)
+gen7_emit_null_surface_state(struct brw_context *brw,
+ unsigned width,
+ unsigned height,
+ unsigned samples,
+ uint32_t *out_offset)
{
/* From the Ivy bridge PRM, Vol4 Part1 p62 (Surface Type: Programming
* Notes):
* depth buffer’s corresponding state for all render target surfaces,
* including null.
*/
- struct gl_context *ctx = &brw->ctx;
-
- /* _NEW_BUFFERS */
- const struct gl_framebuffer *fb = ctx->DrawBuffer;
- uint32_t surf_index =
- brw->wm.prog_data->binding_table.render_target_start + unit;
-
uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 8 * 4, 32,
- &brw->wm.base.surf_offset[surf_index]);
+ out_offset);
memset(surf, 0, 8 * 4);
/* From the Ivybridge PRM, Volume 4, Part 1, page 65,
BRW_SURFACEFORMAT_B8G8R8A8_UNORM << BRW_SURFACE_FORMAT_SHIFT |
GEN7_SURFACE_TILING_Y;
- surf[2] = SET_FIELD(fb->Width - 1, GEN7_SURFACE_WIDTH) |
- SET_FIELD(fb->Height - 1, GEN7_SURFACE_HEIGHT);
+ surf[2] = SET_FIELD(width - 1, GEN7_SURFACE_WIDTH) |
+ SET_FIELD(height - 1, GEN7_SURFACE_HEIGHT);
gen7_check_surface_setup(surf, true /* is_render_target */);
}
{
brw->vtbl.update_texture_surface = gen7_update_texture_surface;
brw->vtbl.update_renderbuffer_surface = gen7_update_renderbuffer_surface;
- brw->vtbl.update_null_renderbuffer_surface =
- gen7_update_null_renderbuffer_surface;
+ brw->vtbl.emit_null_surface_state = gen7_emit_null_surface_state;
brw->vtbl.create_raw_surface = gen7_create_raw_surface;
brw->vtbl.emit_buffer_surface_state = gen7_emit_buffer_surface_state;
}
}
/**
- * Creates a null renderbuffer surface.
+ * Creates a null surface.
*
* This is used when the shader doesn't write to any color output. An FB
* write to target 0 will still be emitted, because that's how the thread is
* hardware discard the target 0 color output..
*/
static void
-gen8_update_null_renderbuffer_surface(struct brw_context *brw, unsigned unit)
+gen8_emit_null_surface_state(struct brw_context *brw,
+ unsigned width,
+ unsigned height,
+ unsigned samples,
+ uint32_t *out_offset)
{
- struct gl_context *ctx = &brw->ctx;
-
- /* _NEW_BUFFERS */
- const struct gl_framebuffer *fb = ctx->DrawBuffer;
- uint32_t surf_index =
- brw->wm.prog_data->binding_table.render_target_start + unit;
-
- uint32_t *surf =
- allocate_surface_state(brw, &brw->wm.base.surf_offset[surf_index]);
+ uint32_t *surf = allocate_surface_state(brw, out_offset);
surf[0] = BRW_SURFACE_NULL << BRW_SURFACE_TYPE_SHIFT |
BRW_SURFACEFORMAT_B8G8R8A8_UNORM << BRW_SURFACE_FORMAT_SHIFT |
GEN8_SURFACE_TILING_Y;
- surf[2] = SET_FIELD(fb->Width - 1, GEN7_SURFACE_WIDTH) |
- SET_FIELD(fb->Height - 1, GEN7_SURFACE_HEIGHT);
+ surf[2] = SET_FIELD(width - 1, GEN7_SURFACE_WIDTH) |
+ SET_FIELD(height - 1, GEN7_SURFACE_HEIGHT);
}
/**
{
brw->vtbl.update_texture_surface = gen8_update_texture_surface;
brw->vtbl.update_renderbuffer_surface = gen8_update_renderbuffer_surface;
- brw->vtbl.update_null_renderbuffer_surface =
- gen8_update_null_renderbuffer_surface;
+ brw->vtbl.emit_null_surface_state = gen8_emit_null_surface_state;
brw->vtbl.create_raw_surface = gen8_create_raw_surface;
brw->vtbl.emit_buffer_surface_state = gen8_emit_buffer_surface_state;
}