Mesa (main): tu: Add debug option to use emulated renderpass support

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jul 27 20:15:22 UTC 2022


Module: Mesa
Branch: main
Commit: 9b844d7c42129925525d613c19622b11aee16298
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9b844d7c42129925525d613c19622b11aee16298

Author: Connor Abbott <cwabbott0 at gmail.com>
Date:   Mon Jul 18 16:49:59 2022 +0200

tu: Add debug option to use emulated renderpass support

This should be useful for stress-testing dynamic rendering.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17378>

---

 src/freedreno/ci/deqp-freedreno-a630-vk.toml | 11 ++++++
 src/freedreno/vulkan/tu_cmd_buffer.c         | 59 ++++++++++++++++++++++++----
 src/freedreno/vulkan/tu_descriptor_set.c     |  7 ++++
 src/freedreno/vulkan/tu_device.c             | 12 ++++++
 src/freedreno/vulkan/tu_pass.c               | 11 ++++++
 src/freedreno/vulkan/tu_pipeline.c           | 15 +++++++
 src/freedreno/vulkan/tu_private.h            |  2 +
 src/freedreno/vulkan/tu_shader.c             | 20 +++++-----
 8 files changed, 120 insertions(+), 17 deletions(-)

diff --git a/src/freedreno/ci/deqp-freedreno-a630-vk.toml b/src/freedreno/ci/deqp-freedreno-a630-vk.toml
index e83db59f505..3ac25c75258 100644
--- a/src/freedreno/ci/deqp-freedreno-a630-vk.toml
+++ b/src/freedreno/ci/deqp-freedreno-a630-vk.toml
@@ -49,3 +49,14 @@ prefix = "spill-"
 fraction = 10
 [deqp.env]
 IR3_SHADER_DEBUG = "spillall"
+
+# dynamic rendering testing using emulated renderpass
+[[deqp]]
+deqp = "/deqp/external/vulkancts/modules/vulkan/deqp-vk"
+caselists = ["/deqp/mustpass/vk-master.txt"]
+skips = ["install/freedreno-a630-premerge-skips.txt"]
+include = ["dEQP-VK.renderpass2.*"]
+prefix = "dynamic-"
+fraction = 10
+[deqp.env]
+TU_DEBUG = "dynamic"
diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c
index 4843b37be8c..285d2c9872b 100644
--- a/src/freedreno/vulkan/tu_cmd_buffer.c
+++ b/src/freedreno/vulkan/tu_cmd_buffer.c
@@ -31,6 +31,7 @@
 #include "adreno_common.xml.h"
 
 #include "vk_format.h"
+#include "vk_render_pass.h"
 #include "vk_util.h"
 
 #include "tu_cs.h"
@@ -1845,17 +1846,24 @@ tu_BeginCommandBuffer(VkCommandBuffer commandBuffer,
       }
 
       if (pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) {
-         if (pBeginInfo->pInheritanceInfo->renderPass) {
-            cmd_buffer->state.pass = tu_render_pass_from_handle(pBeginInfo->pInheritanceInfo->renderPass);
-            cmd_buffer->state.subpass =
-               &cmd_buffer->state.pass->subpasses[pBeginInfo->pInheritanceInfo->subpass];
-         } else {
-            const VkCommandBufferInheritanceRenderingInfo *rendering_info =
-               vk_find_struct_const(pBeginInfo->pInheritanceInfo->pNext,
-                                    COMMAND_BUFFER_INHERITANCE_RENDERING_INFO);
+         const VkCommandBufferInheritanceRenderingInfo *rendering_info =
+            vk_find_struct_const(pBeginInfo->pInheritanceInfo->pNext,
+                                 COMMAND_BUFFER_INHERITANCE_RENDERING_INFO);
+
+         if (unlikely(cmd_buffer->device->instance->debug_flags & TU_DEBUG_DYNAMIC)) {
+            rendering_info =
+               vk_get_command_buffer_inheritance_rendering_info(cmd_buffer->vk.level,
+                                                                pBeginInfo);
+         }
+
+         if (rendering_info) {
             tu_setup_dynamic_inheritance(cmd_buffer, rendering_info);
             cmd_buffer->state.pass = &cmd_buffer->dynamic_pass;
             cmd_buffer->state.subpass = &cmd_buffer->dynamic_subpass;
+         } else {
+            cmd_buffer->state.pass = tu_render_pass_from_handle(pBeginInfo->pInheritanceInfo->renderPass);
+            cmd_buffer->state.subpass =
+               &cmd_buffer->state.pass->subpasses[pBeginInfo->pInheritanceInfo->subpass];
          }
          tu_lrz_begin_secondary_cmdbuf(cmd_buffer);
       } else {
@@ -3822,6 +3830,13 @@ tu_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
                        const VkSubpassBeginInfo *pSubpassBeginInfo)
 {
    TU_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer);
+
+   if (unlikely(cmd->device->instance->debug_flags & TU_DEBUG_DYNAMIC)) {
+      vk_common_CmdBeginRenderPass2(commandBuffer, pRenderPassBegin,
+                                    pSubpassBeginInfo);
+      return;
+   }
+
    TU_FROM_HANDLE(tu_render_pass, pass, pRenderPassBegin->renderPass);
    TU_FROM_HANDLE(tu_framebuffer, fb, pRenderPassBegin->framebuffer);
 
@@ -3937,6 +3952,22 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer,
       }
    }
 
+   if (unlikely(cmd->device->instance->debug_flags & TU_DEBUG_DYNAMIC)) {
+      const VkRenderingSelfDependencyInfoMESA *self_dependency =
+         vk_find_struct_const(pRenderingInfo->pNext, RENDERING_SELF_DEPENDENCY_INFO_MESA);
+      if (self_dependency &&
+          (self_dependency->colorSelfDependencies ||
+           self_dependency->depthSelfDependency ||
+           self_dependency->stencilSelfDependency)) {
+         /* Mesa's renderpass emulation requires us to use normal attachments
+          * for input attachments, and currently doesn't try to keep track of
+          * which color/depth attachment an input attachment corresponds to.
+          * So when there's a self-dependency, we have to use sysmem.
+          */
+         cmd->state.rp.disable_gmem = true;
+      }
+   }
+
    cmd->state.renderpass_cache.pending_flush_bits =
       cmd->state.cache.pending_flush_bits;
    cmd->state.renderpass_cache.flush_bits = 0;
@@ -4008,6 +4039,13 @@ tu_CmdNextSubpass2(VkCommandBuffer commandBuffer,
                    const VkSubpassEndInfo *pSubpassEndInfo)
 {
    TU_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer);
+
+   if (unlikely(cmd->device->instance->debug_flags & TU_DEBUG_DYNAMIC)) {
+      vk_common_CmdNextSubpass2(commandBuffer, pSubpassBeginInfo,
+                                pSubpassEndInfo);
+      return;
+   }
+
    const struct tu_render_pass *pass = cmd->state.pass;
    struct tu_cs *cs = &cmd->draw_cs;
    const struct tu_subpass *last_subpass = cmd->state.subpass;
@@ -5116,6 +5154,11 @@ tu_CmdEndRenderPass2(VkCommandBuffer commandBuffer,
 {
    TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
 
+   if (unlikely(cmd_buffer->device->instance->debug_flags & TU_DEBUG_DYNAMIC)) {
+      vk_common_CmdEndRenderPass2(commandBuffer, pSubpassEndInfo);
+      return;
+   }
+
    cmd_buffer->trace_renderpass_end = u_trace_end_iterator(&cmd_buffer->trace);
 
    tu_cs_end(&cmd_buffer->draw_cs);
diff --git a/src/freedreno/vulkan/tu_descriptor_set.c b/src/freedreno/vulkan/tu_descriptor_set.c
index 7cf268f49d9..b40c3f7f590 100644
--- a/src/freedreno/vulkan/tu_descriptor_set.c
+++ b/src/freedreno/vulkan/tu_descriptor_set.c
@@ -58,6 +58,9 @@ descriptor_size(struct tu_device *dev, VkDescriptorType type)
 {
    switch (type) {
    case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+      if (unlikely(dev->instance->debug_flags & TU_DEBUG_DYNAMIC))
+         return A6XX_TEX_CONST_DWORDS * 4;
+
       /* Input attachment doesn't use descriptor sets at all */
       return 0;
    case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
@@ -1079,6 +1082,8 @@ tu_update_descriptor_sets(const struct tu_device *device,
             break;
          case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
             /* nothing in descriptor set - framebuffer state is used instead */
+            if (unlikely(device->instance->debug_flags & TU_DEBUG_DYNAMIC))
+               write_image_descriptor(ptr, writeset->descriptorType, writeset->pImageInfo + j);
             break;
          default:
             unreachable("unimplemented descriptor type");
@@ -1306,6 +1311,8 @@ tu_update_descriptor_set_with_template(
             break;
          case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
             /* nothing in descriptor set - framebuffer state is used instead */
+            if (unlikely(device->instance->debug_flags & TU_DEBUG_DYNAMIC))
+               write_image_descriptor(ptr, templ->entry[i].descriptor_type, src);
             break;
          default:
             unreachable("unimplemented descriptor type");
diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c
index f5b7778f25a..b484a482813 100644
--- a/src/freedreno/vulkan/tu_device.c
+++ b/src/freedreno/vulkan/tu_device.c
@@ -373,6 +373,7 @@ static const struct debug_control tu_debug_options[] = {
    { "rast_order", TU_DEBUG_RAST_ORDER },
    { "unaligned_store", TU_DEBUG_UNALIGNED_STORE },
    { "log_skip_gmem_ops", TU_DEBUG_LOG_SKIP_GMEM_OPS },
+   { "dynamic", TU_DEBUG_DYNAMIC },
    { NULL, 0 }
 };
 
@@ -2637,6 +2638,11 @@ tu_CreateFramebuffer(VkDevice _device,
                      VkFramebuffer *pFramebuffer)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
+
+   if (unlikely(device->instance->debug_flags & TU_DEBUG_DYNAMIC))
+      return vk_common_CreateFramebuffer(_device, pCreateInfo, pAllocator,
+                                         pFramebuffer);
+
    TU_FROM_HANDLE(tu_render_pass, pass, pCreateInfo->renderPass);
    struct tu_framebuffer *framebuffer;
 
@@ -2694,6 +2700,12 @@ tu_DestroyFramebuffer(VkDevice _device,
                       const VkAllocationCallbacks *pAllocator)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
+
+   if (unlikely(device->instance->debug_flags & TU_DEBUG_DYNAMIC)) {
+      vk_common_DestroyFramebuffer(_device, _fb, pAllocator);
+      return;
+   }
+
    TU_FROM_HANDLE(tu_framebuffer, fb, _fb);
 
    if (!fb)
diff --git a/src/freedreno/vulkan/tu_pass.c b/src/freedreno/vulkan/tu_pass.c
index 8031b1439cd..2ecbb47527b 100644
--- a/src/freedreno/vulkan/tu_pass.c
+++ b/src/freedreno/vulkan/tu_pass.c
@@ -749,6 +749,11 @@ tu_CreateRenderPass2(VkDevice _device,
                      VkRenderPass *pRenderPass)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
+
+   if (unlikely(device->instance->debug_flags & TU_DEBUG_DYNAMIC))
+      return vk_common_CreateRenderPass2(_device, pCreateInfo, pAllocator,
+                                         pRenderPass);
+
    struct tu_render_pass *pass;
    size_t size;
    size_t attachments_offset;
@@ -938,6 +943,12 @@ tu_DestroyRenderPass(VkDevice _device,
                      const VkAllocationCallbacks *pAllocator)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
+
+   if (unlikely(device->instance->debug_flags & TU_DEBUG_DYNAMIC)) {
+      vk_common_DestroyRenderPass(_device, _pass, pAllocator);
+      return;
+   }
+
    TU_FROM_HANDLE(tu_render_pass, pass, _pass);
 
    if (!_pass)
diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c
index 90acc12a3f2..b96ca44f7f0 100644
--- a/src/freedreno/vulkan/tu_pipeline.c
+++ b/src/freedreno/vulkan/tu_pipeline.c
@@ -38,6 +38,7 @@
 #include "util/u_atomic.h"
 #include "vk_format.h"
 #include "vk_pipeline.h"
+#include "vk_render_pass.h"
 #include "vk_util.h"
 
 #include "tu_cs.h"
@@ -3897,6 +3898,9 @@ tu_pipeline_builder_init_graphics(
    const VkPipelineRenderingCreateInfo *rendering_info =
       vk_find_struct_const(create_info->pNext, PIPELINE_RENDERING_CREATE_INFO);
 
+   if (unlikely(dev->instance->debug_flags & TU_DEBUG_DYNAMIC) && !rendering_info)
+      rendering_info = vk_get_pipeline_rendering_create_info(create_info);
+
    if (rendering_info) {
       builder->subpass_raster_order_attachment_access = false;
       builder->subpass_feedback_loop_ds = false;
@@ -3914,6 +3918,17 @@ tu_pipeline_builder_init_graphics(
        */
       builder->emit_msaa_state = !builder->rasterizer_discard;
 
+      const VkRenderingSelfDependencyInfoMESA *self_dependency =
+         vk_find_struct_const(rendering_info->pNext, RENDERING_SELF_DEPENDENCY_INFO_MESA);
+
+      if (self_dependency) {
+         builder->subpass_feedback_loop_ds =
+            self_dependency->depthSelfDependency ||
+            self_dependency->stencilSelfDependency;
+         builder->subpass_feedback_loop_color =
+            self_dependency->colorSelfDependencies;
+      }
+
       if (!builder->rasterizer_discard) {
          builder->depth_attachment_format =
             rendering_info->depthAttachmentFormat == VK_FORMAT_UNDEFINED ?
diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h
index 91f63d3e676..3ae319b6ee1 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -95,6 +95,7 @@ typedef uint32_t xcb_window_t;
 #include <vulkan/vulkan.h>
 
 #include "tu_entrypoints.h"
+#include "vulkan/runtime/vk_common_entrypoints.h"
 
 #include "vk_format.h"
 #include "vk_image.h"
@@ -266,6 +267,7 @@ enum tu_debug_flags
    TU_DEBUG_LOG_SKIP_GMEM_OPS = 1 << 17,
    TU_DEBUG_PERF = 1 << 18,
    TU_DEBUG_NOLRZFC = 1 << 19,
+   TU_DEBUG_DYNAMIC = 1 << 20,
 };
 
 struct tu_instance
diff --git a/src/freedreno/vulkan/tu_shader.c b/src/freedreno/vulkan/tu_shader.c
index ca5af8b2bf3..24a43f0fddd 100644
--- a/src/freedreno/vulkan/tu_shader.c
+++ b/src/freedreno/vulkan/tu_shader.c
@@ -329,7 +329,8 @@ lower_ssbo_ubo_intrinsic(struct tu_device *dev,
 }
 
 static nir_ssa_def *
-build_bindless(nir_builder *b, nir_deref_instr *deref, bool is_sampler,
+build_bindless(struct tu_device *dev, nir_builder *b,
+               nir_deref_instr *deref, bool is_sampler,
                struct tu_shader *shader,
                const struct tu_pipeline_layout *layout)
 {
@@ -341,7 +342,8 @@ build_bindless(nir_builder *b, nir_deref_instr *deref, bool is_sampler,
       &layout->set[set].layout->binding[binding];
 
    /* input attachments use non bindless workaround */
-   if (bind_layout->type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) {
+   if (bind_layout->type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT &&
+       likely(!(dev->instance->debug_flags & TU_DEBUG_DYNAMIC))) {
       const struct glsl_type *glsl_type = glsl_without_array(var->type);
       uint32_t idx = var->data.index * 2;
 
@@ -388,12 +390,12 @@ build_bindless(nir_builder *b, nir_deref_instr *deref, bool is_sampler,
 }
 
 static void
-lower_image_deref(nir_builder *b,
+lower_image_deref(struct tu_device *dev, nir_builder *b,
                   nir_intrinsic_instr *instr, struct tu_shader *shader,
                   const struct tu_pipeline_layout *layout)
 {
    nir_deref_instr *deref = nir_src_as_deref(instr->src[0]);
-   nir_ssa_def *bindless = build_bindless(b, deref, false, shader, layout);
+   nir_ssa_def *bindless = build_bindless(dev, b, deref, false, shader, layout);
    nir_rewrite_image_intrinsic(instr, bindless, true);
 }
 
@@ -454,7 +456,7 @@ lower_intrinsic(nir_builder *b, nir_intrinsic_instr *instr,
    case nir_intrinsic_image_deref_atomic_comp_swap:
    case nir_intrinsic_image_deref_size:
    case nir_intrinsic_image_deref_samples:
-      lower_image_deref(b, instr, shader, layout);
+      lower_image_deref(dev, b, instr, shader, layout);
       return true;
 
    default:
@@ -533,7 +535,7 @@ lower_tex_ycbcr(const struct tu_pipeline_layout *layout,
 }
 
 static bool
-lower_tex(nir_builder *b, nir_tex_instr *tex,
+lower_tex(nir_builder *b, nir_tex_instr *tex, struct tu_device *dev,
           struct tu_shader *shader, const struct tu_pipeline_layout *layout)
 {
    lower_tex_ycbcr(layout, b, tex);
@@ -541,7 +543,7 @@ lower_tex(nir_builder *b, nir_tex_instr *tex,
    int sampler_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_sampler_deref);
    if (sampler_src_idx >= 0) {
       nir_deref_instr *deref = nir_src_as_deref(tex->src[sampler_src_idx].src);
-      nir_ssa_def *bindless = build_bindless(b, deref, true, shader, layout);
+      nir_ssa_def *bindless = build_bindless(dev, b, deref, true, shader, layout);
       nir_instr_rewrite_src(&tex->instr, &tex->src[sampler_src_idx].src,
                             nir_src_for_ssa(bindless));
       tex->src[sampler_src_idx].src_type = nir_tex_src_sampler_handle;
@@ -550,7 +552,7 @@ lower_tex(nir_builder *b, nir_tex_instr *tex,
    int tex_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_texture_deref);
    if (tex_src_idx >= 0) {
       nir_deref_instr *deref = nir_src_as_deref(tex->src[tex_src_idx].src);
-      nir_ssa_def *bindless = build_bindless(b, deref, false, shader, layout);
+      nir_ssa_def *bindless = build_bindless(dev, b, deref, false, shader, layout);
       nir_instr_rewrite_src(&tex->instr, &tex->src[tex_src_idx].src,
                             nir_src_for_ssa(bindless));
       tex->src[tex_src_idx].src_type = nir_tex_src_texture_handle;
@@ -576,7 +578,7 @@ lower_instr(nir_builder *b, nir_instr *instr, void *cb_data)
    b->cursor = nir_before_instr(instr);
    switch (instr->type) {
    case nir_instr_type_tex:
-      return lower_tex(b, nir_instr_as_tex(instr), params->shader, params->layout);
+      return lower_tex(b, nir_instr_as_tex(instr), params->dev, params->shader, params->layout);
    case nir_instr_type_intrinsic:
       return lower_intrinsic(b, nir_instr_as_intrinsic(instr), params->dev, params->shader, params->layout);
    default:



More information about the mesa-commit mailing list