anv: Emit null render targets
authorJason Ekstrand <jason.ekstrand@intel.com>
Fri, 26 Feb 2016 19:31:04 +0000 (11:31 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Sun, 6 Mar 2016 04:47:10 +0000 (20:47 -0800)
v2 (Francisco Jerez): Add the state_offset to the surface state offset

src/intel/vulkan/anv_cmd_buffer.c
src/intel/vulkan/anv_private.h
src/intel/vulkan/genX_cmd_buffer.c

index 5ec242fbf2a985f98f364154bc65d7dddc8825e8..9dca21d527aa95a19d67ce31266c2bb976934ce7 100644 (file)
@@ -705,6 +705,26 @@ anv_format_for_descriptor_type(VkDescriptorType type)
    }
 }
 
+static struct anv_state
+anv_cmd_buffer_alloc_null_surface_state(struct anv_cmd_buffer *cmd_buffer,
+                                        struct anv_framebuffer *fb)
+{
+   switch (cmd_buffer->device->info.gen) {
+   case 7:
+      if (cmd_buffer->device->info.is_haswell) {
+         return gen75_cmd_buffer_alloc_null_surface_state(cmd_buffer, fb);
+      } else {
+         return gen7_cmd_buffer_alloc_null_surface_state(cmd_buffer, fb);
+      }
+   case 8:
+      return gen8_cmd_buffer_alloc_null_surface_state(cmd_buffer, fb);
+   case 9:
+      return gen9_cmd_buffer_alloc_null_surface_state(cmd_buffer, fb);
+   default:
+      unreachable("Invalid hardware generation");
+   }
+}
+
 VkResult
 anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
                                   gl_shader_stage stage,
@@ -713,27 +733,24 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
    struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
    struct anv_subpass *subpass = cmd_buffer->state.subpass;
    struct anv_pipeline_bind_map *map;
-   uint32_t color_count, bias, state_offset;
+   uint32_t bias, state_offset;
 
    switch (stage) {
    case  MESA_SHADER_FRAGMENT:
       map = &cmd_buffer->state.pipeline->bindings[stage];
       bias = MAX_RTS;
-      color_count = subpass->color_count;
       break;
    case  MESA_SHADER_COMPUTE:
       map = &cmd_buffer->state.compute_pipeline->bindings[stage];
       bias = 1;
-      color_count = 0;
       break;
    default:
       map = &cmd_buffer->state.pipeline->bindings[stage];
       bias = 0;
-      color_count = 0;
       break;
    }
 
-   if (color_count + map->surface_count == 0) {
+   if (bias + map->surface_count == 0) {
       *bt_state = (struct anv_state) { 0, };
       return VK_SUCCESS;
    }
@@ -746,14 +763,23 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
    if (bt_state->map == NULL)
       return VK_ERROR_OUT_OF_DEVICE_MEMORY;
 
-   for (uint32_t a = 0; a < color_count; a++) {
-      const struct anv_image_view *iview =
-         fb->attachments[subpass->color_attachments[a]];
-
-      assert(iview->color_rt_surface_state.alloc_size);
-      bt_map[a] = iview->color_rt_surface_state.offset + state_offset;
-      add_surface_state_reloc(cmd_buffer, iview->color_rt_surface_state,
-                              iview->bo, iview->offset);
+   if (stage == MESA_SHADER_FRAGMENT) {
+      if (subpass->color_count == 0) {
+         struct anv_state null_surface =
+            anv_cmd_buffer_alloc_null_surface_state(cmd_buffer,
+                                                    cmd_buffer->state.framebuffer);
+         bt_map[0] = null_surface.offset + state_offset;
+      } else {
+         for (uint32_t a = 0; a < subpass->color_count; a++) {
+            const struct anv_image_view *iview =
+               fb->attachments[subpass->color_attachments[a]];
+
+            assert(iview->color_rt_surface_state.alloc_size);
+            bt_map[a] = iview->color_rt_surface_state.offset + state_offset;
+            add_surface_state_reloc(cmd_buffer, iview->color_rt_surface_state,
+                                    iview->bo, iview->offset);
+         }
+      }
    }
 
    if (stage == MESA_SHADER_COMPUTE &&
index 8c3318816c6534e0acee075cfebb41a02ef51252..7791bbc16491d530e365ea02324d9c53647573ca 100644 (file)
@@ -1299,6 +1299,19 @@ void anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer);
 void anv_cmd_state_setup_attachments(struct anv_cmd_buffer *cmd_buffer,
                                      const VkRenderPassBeginInfo *info);
 
+struct anv_state
+gen7_cmd_buffer_alloc_null_surface_state(struct anv_cmd_buffer *cmd_buffer,
+                                         struct anv_framebuffer *fb);
+struct anv_state
+gen75_cmd_buffer_alloc_null_surface_state(struct anv_cmd_buffer *cmd_buffer,
+                                          struct anv_framebuffer *fb);
+struct anv_state
+gen8_cmd_buffer_alloc_null_surface_state(struct anv_cmd_buffer *cmd_buffer,
+                                         struct anv_framebuffer *fb);
+struct anv_state
+gen9_cmd_buffer_alloc_null_surface_state(struct anv_cmd_buffer *cmd_buffer,
+                                         struct anv_framebuffer *fb);
+
 void gen7_cmd_buffer_set_subpass(struct anv_cmd_buffer *cmd_buffer,
                                    struct anv_subpass *subpass);
 void gen75_cmd_buffer_set_subpass(struct anv_cmd_buffer *cmd_buffer,
index 2606a66f2a7dcf3798e984905e7c13f34413e128..b969fab35bc8cdd7bd6251f864d6508c3d5026a1 100644 (file)
@@ -590,6 +590,36 @@ genX(flush_pipeline_select_3d)(struct anv_cmd_buffer *cmd_buffer)
    }
 }
 
+struct anv_state
+genX(cmd_buffer_alloc_null_surface_state)(struct anv_cmd_buffer *cmd_buffer,
+                                          struct anv_framebuffer *fb)
+{
+   struct anv_state state =
+      anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
+
+   struct GENX(RENDER_SURFACE_STATE) null_ss = {
+      .SurfaceType = SURFTYPE_NULL,
+      .SurfaceArray = fb->layers > 0,
+      .SurfaceFormat = ISL_FORMAT_R8G8B8A8_UNORM,
+#if GEN_GEN >= 8
+      .TileMode = YMAJOR,
+#else
+      .TiledSurface = true,
+#endif
+      .Width = fb->width - 1,
+      .Height = fb->height - 1,
+      .Depth = fb->layers - 1,
+      .RenderTargetViewExtent = fb->layers - 1,
+   };
+
+   GENX(RENDER_SURFACE_STATE_pack)(NULL, state.map, &null_ss);
+
+   if (!cmd_buffer->device->info.has_llc)
+      anv_state_clflush(state);
+
+   return state;
+}
+
 static void
 cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer)
 {