summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2016-07-01 13:56:47 -0700
committerFrancisco Jerez <currojerez@riseup.net>2016-08-25 18:36:08 -0700
commit786108e7b27e4728353d69ff60aa046987859d8e (patch)
tree078bf09a5d35e969f6f08551c91f7c34fd196cd1
parentdc96968dbf7b359a24a991def16e382379f4b11a (diff)
i965: Upload surface state for non-coherent framebuffer fetch.
This iterates over the list of attached render buffers and binds appropriate surface state structures to the binding table block allocated for shader framebuffer read. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
-rw-r--r--src/mesa/drivers/dri/i965/brw_state.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_upload.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c89
3 files changed, 94 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index eb138b3c02e..43bab9ebe1e 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -85,6 +85,7 @@ extern const struct brw_tracked_state brw_gs_abo_surfaces;
extern const struct brw_tracked_state brw_gs_image_surfaces;
extern const struct brw_tracked_state brw_vs_unit;
extern const struct brw_tracked_state brw_renderbuffer_surfaces;
+extern const struct brw_tracked_state brw_renderbuffer_read_surfaces;
extern const struct brw_tracked_state brw_texture_surfaces;
extern const struct brw_tracked_state brw_wm_binding_table;
extern const struct brw_tracked_state brw_gs_binding_table;
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index 6d45856326d..69acf3b2036 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -61,6 +61,7 @@ static const struct brw_tracked_state *gen4_atoms[] =
&brw_vs_pull_constants,
&brw_wm_pull_constants,
&brw_renderbuffer_surfaces,
+ &brw_renderbuffer_read_surfaces,
&brw_texture_surfaces,
&brw_vs_binding_table,
&brw_wm_binding_table,
@@ -130,6 +131,7 @@ static const struct brw_tracked_state *gen6_atoms[] =
&brw_wm_pull_constants,
&brw_wm_ubo_surfaces,
&gen6_renderbuffer_surfaces,
+ &brw_renderbuffer_read_surfaces,
&brw_texture_surfaces,
&gen6_sol_surface,
&brw_vs_binding_table,
@@ -214,6 +216,7 @@ static const struct brw_tracked_state *gen7_render_atoms[] =
&brw_wm_ubo_surfaces,
&brw_wm_abo_surfaces,
&gen6_renderbuffer_surfaces,
+ &brw_renderbuffer_read_surfaces,
&brw_texture_surfaces,
&brw_vs_binding_table,
&brw_tcs_binding_table,
@@ -317,6 +320,7 @@ static const struct brw_tracked_state *gen8_render_atoms[] =
&brw_wm_ubo_surfaces,
&brw_wm_abo_surfaces,
&gen6_renderbuffer_surfaces,
+ &brw_renderbuffer_read_surfaces,
&brw_texture_surfaces,
&brw_vs_binding_table,
&brw_tcs_binding_table,
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 77560207502..e07e8dacace 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -1026,6 +1026,95 @@ const struct brw_tracked_state gen6_renderbuffer_surfaces = {
.emit = update_renderbuffer_surfaces,
};
+static void
+update_renderbuffer_read_surfaces(struct brw_context *brw)
+{
+ const struct gl_context *ctx = &brw->ctx;
+
+ /* BRW_NEW_FRAGMENT_PROGRAM */
+ if (!ctx->Extensions.MESA_shader_framebuffer_fetch &&
+ brw->fragment_program &&
+ brw->fragment_program->Base.OutputsRead) {
+ /* _NEW_BUFFERS */
+ const struct gl_framebuffer *fb = ctx->DrawBuffer;
+
+ for (unsigned i = 0; i < fb->_NumColorDrawBuffers; i++) {
+ struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[i];
+ const struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+ const unsigned surf_index =
+ brw->wm.prog_data->binding_table.render_target_read_start + i;
+ uint32_t *surf_offset = &brw->wm.base.surf_offset[surf_index];
+
+ if (irb) {
+ const unsigned format = brw->render_target_format[
+ _mesa_get_render_format(ctx, intel_rb_format(irb))];
+ assert(isl_format_supports_sampling(brw->intelScreen->devinfo,
+ format));
+
+ /* Override the target of the texture if the render buffer is a
+ * single slice of a 3D texture (since the minimum array element
+ * field of the surface state structure is ignored by the sampler
+ * unit for 3D textures on some hardware), or if the render buffer
+ * is a 1D array (since shaders always provide the array index
+ * coordinate at the Z component to avoid state-dependent
+ * recompiles when changing the texture target of the
+ * framebuffer).
+ */
+ const GLenum target =
+ (irb->mt->target == GL_TEXTURE_3D &&
+ irb->layer_count == 1) ? GL_TEXTURE_2D :
+ irb->mt->target == GL_TEXTURE_1D_ARRAY ? GL_TEXTURE_2D_ARRAY :
+ irb->mt->target;
+
+ /* intel_renderbuffer::mt_layer is expressed in sample units for
+ * the UMS and CMS multisample layouts, but
+ * intel_renderbuffer::layer_count is expressed in units of whole
+ * logical layers regardless of the multisample layout.
+ */
+ const unsigned mt_layer_unit =
+ (irb->mt->msaa_layout == INTEL_MSAA_LAYOUT_UMS ||
+ irb->mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) ?
+ MAX2(irb->mt->num_samples, 1) : 1;
+
+ const struct isl_view view = {
+ .format = format,
+ .base_level = irb->mt_level - irb->mt->first_level,
+ .levels = 1,
+ .base_array_layer = irb->mt_layer / mt_layer_unit,
+ .array_len = irb->layer_count,
+ .channel_select = {
+ ISL_CHANNEL_SELECT_RED,
+ ISL_CHANNEL_SELECT_GREEN,
+ ISL_CHANNEL_SELECT_BLUE,
+ ISL_CHANNEL_SELECT_ALPHA,
+ },
+ .usage = ISL_SURF_USAGE_TEXTURE_BIT,
+ };
+
+ brw_emit_surface_state(brw, irb->mt, target, view,
+ surface_state_infos[brw->gen].tex_mocs,
+ surf_offset, surf_index,
+ I915_GEM_DOMAIN_SAMPLER, 0);
+
+ } else {
+ brw->vtbl.emit_null_surface_state(
+ brw, _mesa_geometric_width(fb), _mesa_geometric_height(fb),
+ _mesa_geometric_samples(fb), surf_offset);
+ }
+ }
+
+ brw->ctx.NewDriverState |= BRW_NEW_SURFACES;
+ }
+}
+
+const struct brw_tracked_state brw_renderbuffer_read_surfaces = {
+ .dirty = {
+ .mesa = _NEW_BUFFERS,
+ .brw = BRW_NEW_BATCH |
+ BRW_NEW_FRAGMENT_PROGRAM,
+ },
+ .emit = update_renderbuffer_read_surfaces,
+};
static void
update_stage_texture_surfaces(struct brw_context *brw,