i965: Upload surface state for non-coherent framebuffer fetch.
authorFrancisco Jerez <currojerez@riseup.net>
Fri, 1 Jul 2016 20:56:47 +0000 (13:56 -0700)
committerFrancisco Jerez <currojerez@riseup.net>
Fri, 26 Aug 2016 01:36:08 +0000 (18:36 -0700)
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>
src/mesa/drivers/dri/i965/brw_state.h
src/mesa/drivers/dri/i965/brw_state_upload.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c

index eb138b3c02e256fbfe64926f15a9c3befb60a358..43bab9ebe1ed745d28012f072e98dbd7101f91b5 100644 (file)
@@ -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;
index 6d45856326deffc20c5d680d9d2d319692f9b0cc..69acf3b203632ab1adced8dd8129609e6e673709 100644 (file)
@@ -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,
index 77560207502635d688cc5023903d1c4995e937c6..e07e8dacacefea0df0c7a908f7ea8b25c2a82d3a 100644 (file)
@@ -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,