Mesa (main): zink: semi-handle 1D sparse texture rewrites for drivers that don't support them

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue May 10 05:54:51 UTC 2022


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

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Thu Apr 21 12:24:01 2022 -0400

zink: semi-handle 1D sparse texture rewrites for drivers that don't support them

nvidia can't do this, but also nothing uses it, so I've gone ahead and
done the bare minimum here to make cts pass

I think the work to do the shader rewrites should be easy, but without a test
case, I see no point in spending the time for it

Acked-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16100>

---

 src/gallium/drivers/zink/zink_blit.c     |  4 ++--
 src/gallium/drivers/zink/zink_compiler.c | 12 +++++++++---
 src/gallium/drivers/zink/zink_context.c  |  6 +++---
 src/gallium/drivers/zink/zink_resource.c | 15 ++++++++++-----
 src/gallium/drivers/zink/zink_resource.h |  2 +-
 src/gallium/drivers/zink/zink_screen.c   |  5 ++++-
 src/gallium/drivers/zink/zink_screen.h   |  1 +
 src/gallium/drivers/zink/zink_surface.c  |  4 ++--
 8 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_blit.c b/src/gallium/drivers/zink/zink_blit.c
index 71acba25899..5df459f838c 100644
--- a/src/gallium/drivers/zink/zink_blit.c
+++ b/src/gallium/drivers/zink/zink_blit.c
@@ -184,7 +184,7 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info, bool *n
    region.srcOffsets[1].y = info->src.box.y + info->src.box.height;
 
    enum pipe_texture_target src_target = src->base.b.target;
-   if (src->need_2D_zs)
+   if (src->need_2D)
       src_target = src_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY;
    switch (src_target) {
    case PIPE_TEXTURE_CUBE:
@@ -222,7 +222,7 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info, bool *n
    assert(region.dstOffsets[0].y != region.dstOffsets[1].y);
 
    enum pipe_texture_target dst_target = dst->base.b.target;
-   if (dst->need_2D_zs)
+   if (dst->need_2D)
       dst_target = dst_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY;
    switch (dst_target) {
    case PIPE_TEXTURE_CUBE:
diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c
index a32132b5a18..56b0fc56141 100644
--- a/src/gallium/drivers/zink/zink_compiler.c
+++ b/src/gallium/drivers/zink/zink_compiler.c
@@ -1843,11 +1843,17 @@ get_shader_base_prim_type(struct nir_shader *nir)
 static bool
 convert_1d_shadow_tex(nir_builder *b, nir_instr *instr, void *data)
 {
+   struct zink_screen *screen = data;
    if (instr->type != nir_instr_type_tex)
       return false;
    nir_tex_instr *tex = nir_instr_as_tex(instr);
    if (tex->sampler_dim != GLSL_SAMPLER_DIM_1D || !tex->is_shadow)
       return false;
+   if (tex->is_sparse && screen->need_2D_sparse) {
+      /* no known case of this exists: only nvidia can hit it, and nothing uses it */
+      mesa_loge("unhandled/unsupported 1D sparse texture!");
+      abort();
+   }
    tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
    b->cursor = nir_before_instr(instr);
    tex->coord_components++;
@@ -1886,7 +1892,7 @@ convert_1d_shadow_tex(nir_builder *b, nir_instr *instr, void *data)
 }
 
 static bool
-lower_1d_shadow(nir_shader *shader)
+lower_1d_shadow(nir_shader *shader, struct zink_screen *screen)
 {
    bool found = false;
    nir_foreach_variable_with_modes(var, shader, nir_var_uniform | nir_var_image) {
@@ -1900,7 +1906,7 @@ lower_1d_shadow(nir_shader *shader)
       found = true;
    }
    if (found)
-      nir_shader_instructions_pass(shader, convert_1d_shadow_tex, nir_metadata_dominance, NULL);
+      nir_shader_instructions_pass(shader, convert_1d_shadow_tex, nir_metadata_dominance, screen);
    return found;
 }
 
@@ -2039,7 +2045,7 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir,
    NIR_PASS_V(nir, lower_sparse);
 
    if (screen->need_2D_zs)
-      NIR_PASS_V(nir, lower_1d_shadow);
+      NIR_PASS_V(nir, lower_1d_shadow, screen);
 
    {
       nir_lower_subgroups_options subgroup_options = {0};
diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 1a9bbdaae4f..1364a77f019 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -3549,7 +3549,7 @@ zink_copy_image_buffer(struct zink_context *ctx, struct zink_resource *dst, stru
    region.bufferImageHeight = 0;
    region.imageSubresource.mipLevel = buf2img ? dst_level : src_level;
    enum pipe_texture_target img_target = img->base.b.target;
-   if (img->need_2D_zs)
+   if (img->need_2D)
       img_target = img_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY;
    switch (img_target) {
    case PIPE_TEXTURE_CUBE:
@@ -3650,7 +3650,7 @@ zink_resource_copy_region(struct pipe_context *pctx,
       region.srcSubresource.aspectMask = src->aspect;
       region.srcSubresource.mipLevel = src_level;
       enum pipe_texture_target src_target = src->base.b.target;
-      if (src->need_2D_zs)
+      if (src->need_2D)
          src_target = src_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY;
       switch (src_target) {
       case PIPE_TEXTURE_CUBE:
@@ -3684,7 +3684,7 @@ zink_resource_copy_region(struct pipe_context *pctx,
       region.dstSubresource.aspectMask = dst->aspect;
       region.dstSubresource.mipLevel = dst_level;
       enum pipe_texture_target dst_target = dst->base.b.target;
-      if (dst->need_2D_zs)
+      if (dst->need_2D)
          dst_target = dst_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY;
       switch (dst_target) {
       case PIPE_TEXTURE_CUBE:
diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c
index dd69a99d3a1..5efb8daa59b 100644
--- a/src/gallium/drivers/zink/zink_resource.c
+++ b/src/gallium/drivers/zink/zink_resource.c
@@ -363,12 +363,15 @@ create_ici(struct zink_screen *screen, VkImageCreateInfo *ici, const struct pipe
    if (templ->flags & PIPE_RESOURCE_FLAG_SPARSE)
       ici->flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;
 
-   bool need_2D_zs = false;
+   bool need_2D = false;
    switch (templ->target) {
    case PIPE_TEXTURE_1D:
    case PIPE_TEXTURE_1D_ARRAY:
-      need_2D_zs = screen->need_2D_zs && util_format_is_depth_or_stencil(templ->format);
-      ici->imageType = need_2D_zs ? VK_IMAGE_TYPE_2D : VK_IMAGE_TYPE_1D;
+      if (templ->flags & PIPE_RESOURCE_FLAG_SPARSE)
+         need_2D |= screen->need_2D_sparse;
+      if (util_format_is_depth_or_stencil(templ->format))
+         need_2D |= screen->need_2D_zs;
+      ici->imageType = need_2D ? VK_IMAGE_TYPE_2D : VK_IMAGE_TYPE_1D;
       break;
 
    case PIPE_TEXTURE_CUBE:
@@ -942,8 +945,10 @@ resource_create(struct pipe_screen *pscreen,
          res->base.b.nr_sparse_levels = res->sparse.imageMipTailFirstLod;
       }
       res->format = zink_get_format(screen, templ->format);
-      res->need_2D_zs = screen->need_2D_zs && util_format_is_depth_or_stencil(templ->format) &&
-                        (templ->target == PIPE_TEXTURE_1D || templ->target == PIPE_TEXTURE_1D_ARRAY);
+      if (templ->target == PIPE_TEXTURE_1D || templ->target == PIPE_TEXTURE_1D_ARRAY) {
+         res->need_2D = (screen->need_2D_zs && util_format_is_depth_or_stencil(templ->format)) ||
+                        (screen->need_2D_sparse && (templ->flags & PIPE_RESOURCE_FLAG_SPARSE));
+      }
       res->dmabuf_acquire = whandle && whandle->type == WINSYS_HANDLE_TYPE_FD;
       res->layout = res->dmabuf_acquire ? VK_IMAGE_LAYOUT_PREINITIALIZED : VK_IMAGE_LAYOUT_UNDEFINED;
       res->optimal_tiling = optimal_tiling;
diff --git a/src/gallium/drivers/zink/zink_resource.h b/src/gallium/drivers/zink/zink_resource.h
index 4ea411c56c7..23f86850893 100644
--- a/src/gallium/drivers/zink/zink_resource.h
+++ b/src/gallium/drivers/zink/zink_resource.h
@@ -128,7 +128,7 @@ struct zink_resource {
          VkImageLayout layout;
          VkImageAspectFlags aspect;
          bool optimal_tiling;
-         bool need_2D_zs;
+         bool need_2D;
          uint8_t fb_binds; //not counted in all_binds
       };
    };
diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c
index b573bc6a1aa..3bee0174a8e 100644
--- a/src/gallium/drivers/zink/zink_screen.c
+++ b/src/gallium/drivers/zink/zink_screen.c
@@ -1680,6 +1680,9 @@ populate_format_props(struct zink_screen *screen)
       mesa_loge("ZINK: vkGetPhysicalDeviceImageFormatProperties failed");
    }
    screen->need_2D_zs = ret != VK_SUCCESS;
+
+   if (screen->info.feats.features.sparseResidencyImage2D)
+      screen->need_2D_sparse = !screen->base.get_sparse_texture_virtual_page_size(&screen->base, PIPE_TEXTURE_1D, false, PIPE_FORMAT_R32_FLOAT, 0, 16, NULL, NULL, NULL);
 }
 
 bool
@@ -1848,7 +1851,7 @@ zink_get_sparse_texture_virtual_page_size(struct pipe_screen *pscreen,
    VkImageType type;
    switch (target) {
    case PIPE_TEXTURE_1D:
-      type = screen->need_2D_zs && is_zs ? VK_IMAGE_TYPE_2D : VK_IMAGE_TYPE_1D;
+      type = (screen->need_2D_sparse || (screen->need_2D_zs && is_zs)) ? VK_IMAGE_TYPE_2D : VK_IMAGE_TYPE_1D;
       break;
 
    case PIPE_TEXTURE_2D:
diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h
index 7cac6c893c1..ebad3c45281 100644
--- a/src/gallium/drivers/zink/zink_screen.h
+++ b/src/gallium/drivers/zink/zink_screen.h
@@ -137,6 +137,7 @@ struct zink_screen {
    bool have_D24_UNORM_S8_UINT;
    bool have_triangle_fans;
    bool need_2D_zs;
+   bool need_2D_sparse;
    bool faked_e5sparse; //drivers may not expose R9G9B9E5 but cts requires it
 
    uint32_t gfx_queue;
diff --git a/src/gallium/drivers/zink/zink_surface.c b/src/gallium/drivers/zink/zink_surface.c
index 9a3eca57756..daddb0c9242 100644
--- a/src/gallium/drivers/zink/zink_surface.c
+++ b/src/gallium/drivers/zink/zink_surface.c
@@ -46,11 +46,11 @@ create_ivci(struct zink_screen *screen,
 
    switch (target) {
    case PIPE_TEXTURE_1D:
-      ivci.viewType = res->need_2D_zs ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_1D;
+      ivci.viewType = res->need_2D ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_1D;
       break;
 
    case PIPE_TEXTURE_1D_ARRAY:
-      ivci.viewType = res->need_2D_zs ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_1D_ARRAY;
+      ivci.viewType = res->need_2D ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_1D_ARRAY;
       break;
 
    case PIPE_TEXTURE_2D:



More information about the mesa-commit mailing list