From c0c69b1be15ece82798d21dd561cf0aa5d3da750 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 21 Apr 2022 12:24:01 -0400 Subject: [PATCH] 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 Part-of: --- 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 71acba2..5df459f 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 a32132b..56b0fc5 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 1a9bbda..1364a77 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 dd69a99..5efb8da 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 4ea411c..23f8685 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 b573bc6..3bee017 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 7cac6c8..ebad3c4 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 9a3eca5..daddb0c 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: -- 2.7.4