diff --git a/src/gallium/drivers/zink/zink_blit.c b/src/gallium/drivers/zink/zink_blit.c index 8055111afe0..6734b562604 100644 --- a/src/gallium/drivers/zink/zink_blit.c +++ b/src/gallium/drivers/zink/zink_blit.c @@ -176,7 +176,10 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info) region.srcOffsets[1].x = info->src.box.x + info->src.box.width; region.srcOffsets[1].y = info->src.box.y + info->src.box.height; - switch (src->base.b.target) { + enum pipe_texture_target src_target = src->base.b.target; + if (src->need_2D_zs) + src_target = src_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY; + switch (src_target) { case PIPE_TEXTURE_CUBE: case PIPE_TEXTURE_CUBE_ARRAY: case PIPE_TEXTURE_2D_ARRAY: @@ -211,7 +214,10 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info) assert(region.dstOffsets[0].x != region.dstOffsets[1].x); assert(region.dstOffsets[0].y != region.dstOffsets[1].y); - switch (dst->base.b.target) { + enum pipe_texture_target dst_target = dst->base.b.target; + if (dst->need_2D_zs) + dst_target = dst_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY; + switch (dst_target) { case PIPE_TEXTURE_CUBE: case PIPE_TEXTURE_CUBE_ARRAY: case PIPE_TEXTURE_2D_ARRAY: diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 9de3604928a..ec34ddac2d4 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -1637,6 +1637,70 @@ get_shader_base_prim_type(struct nir_shader *nir) return PIPE_PRIM_MAX; } +static bool +convert_1d_shadow_tex(nir_builder *b, nir_instr *instr, void *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; + tex->sampler_dim = GLSL_SAMPLER_DIM_2D; + b->cursor = nir_before_instr(instr); + tex->coord_components++; + unsigned srcs[] = { + nir_tex_src_coord, + nir_tex_src_offset, + nir_tex_src_ddx, + nir_tex_src_ddy, + }; + for (unsigned i = 0; i < ARRAY_SIZE(srcs); i++) { + unsigned c = nir_tex_instr_src_index(tex, srcs[i]); + if (c == -1) + continue; + if (tex->src[c].src.ssa->num_components == tex->coord_components) + continue; + nir_ssa_def *def; + nir_ssa_def *zero = nir_imm_zero(b, 1, tex->src[c].src.ssa->bit_size); + if (tex->src[c].src.ssa->num_components == 1) + def = nir_vec2(b, tex->src[c].src.ssa, zero); + else + def = nir_vec3(b, nir_channel(b, tex->src[c].src.ssa, 0), zero, nir_channel(b, tex->src[c].src.ssa, 1)); + nir_instr_rewrite_src_ssa(instr, &tex->src[c].src, def); + } + b->cursor = nir_after_instr(instr); + unsigned needed_components = nir_tex_instr_dest_size(tex); + unsigned num_components = tex->dest.ssa.num_components; + if (needed_components > num_components) { + tex->dest.ssa.num_components = needed_components; + assert(num_components < 3); + /* take either xz or just x since this is promoted to 2D from 1D */ + uint32_t mask = num_components == 2 ? (1|4) : 1; + nir_ssa_def *dst = nir_channels(b, &tex->dest.ssa, mask); + nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, dst, dst->parent_instr); + } + return true; +} + +static bool +lower_1d_shadow(nir_shader *shader) +{ + bool found = false; + nir_foreach_variable_with_modes(var, shader, nir_var_uniform | nir_var_image) { + const struct glsl_type *type = glsl_without_array(var->type); + unsigned length = glsl_get_length(var->type); + if (!glsl_type_is_sampler(type) || !glsl_sampler_type_is_shadow(type) || glsl_get_sampler_dim(type) != GLSL_SAMPLER_DIM_1D) + continue; + const struct glsl_type *sampler = glsl_sampler_type(GLSL_SAMPLER_DIM_2D, true, glsl_sampler_type_is_array(type), glsl_get_sampler_result_type(type)); + var->type = type != var->type ? glsl_array_type(sampler, length, glsl_get_explicit_stride(var->type)) : sampler; + + found = true; + } + if (found) + nir_shader_instructions_pass(shader, convert_1d_shadow_tex, nir_metadata_dominance, NULL); + return found; +} + struct zink_shader * zink_shader_create(struct zink_screen *screen, struct nir_shader *nir, const struct pipe_stream_output_info *so_info) @@ -1673,6 +1737,9 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir, NIR_PASS_V(nir, nir_lower_regs_to_ssa); NIR_PASS_V(nir, lower_baseinstance); + if (screen->need_2D_zs) + NIR_PASS_V(nir, lower_1d_shadow); + { nir_lower_subgroups_options subgroup_options = {0}; subgroup_options.lower_to_scalar = true; diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 48d701a139e..75b376369c9 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -3398,7 +3398,10 @@ zink_copy_image_buffer(struct zink_context *ctx, struct zink_resource *dst, stru region.bufferRowLength = 0; region.bufferImageHeight = 0; region.imageSubresource.mipLevel = buf2img ? dst_level : src_level; - switch (img->base.b.target) { + enum pipe_texture_target img_target = img->base.b.target; + if (img->need_2D_zs) + img_target = img_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY; + switch (img_target) { case PIPE_TEXTURE_CUBE: case PIPE_TEXTURE_CUBE_ARRAY: case PIPE_TEXTURE_2D_ARRAY: @@ -3494,7 +3497,10 @@ zink_resource_copy_region(struct pipe_context *pctx, region.srcSubresource.aspectMask = src->aspect; region.srcSubresource.mipLevel = src_level; - switch (src->base.b.target) { + enum pipe_texture_target src_target = src->base.b.target; + if (src->need_2D_zs) + src_target = src_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY; + switch (src_target) { case PIPE_TEXTURE_CUBE: case PIPE_TEXTURE_CUBE_ARRAY: case PIPE_TEXTURE_2D_ARRAY: @@ -3525,7 +3531,10 @@ zink_resource_copy_region(struct pipe_context *pctx, region.dstSubresource.aspectMask = dst->aspect; region.dstSubresource.mipLevel = dst_level; - switch (dst->base.b.target) { + enum pipe_texture_target dst_target = dst->base.b.target; + if (dst->need_2D_zs) + dst_target = dst_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY; + switch (dst_target) { case PIPE_TEXTURE_CUBE: case PIPE_TEXTURE_CUBE_ARRAY: case PIPE_TEXTURE_2D_ARRAY: diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index 384d2c7dd42..d8254a19f7d 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -334,10 +334,12 @@ create_ici(struct zink_screen *screen, VkImageCreateInfo *ici, const struct pipe ici->usage = 0; ici->queueFamilyIndexCount = 0; + bool need_2D_zs = false; switch (templ->target) { case PIPE_TEXTURE_1D: case PIPE_TEXTURE_1D_ARRAY: - ici->imageType = VK_IMAGE_TYPE_1D; + 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; break; case PIPE_TEXTURE_CUBE: @@ -787,6 +789,8 @@ resource_create(struct pipe_screen *pscreen, } } else { 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); 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 8602c1b69cf..7dd07c72b5b 100644 --- a/src/gallium/drivers/zink/zink_resource.h +++ b/src/gallium/drivers/zink/zink_resource.h @@ -110,6 +110,7 @@ struct zink_resource { VkImageLayout layout; VkImageAspectFlags aspect; bool optimal_tiling; + bool need_2D_zs; 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 393ec41d477..061ed27d890 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -1571,6 +1571,13 @@ populate_format_props(struct zink_screen *screen) } else VKSCR(GetPhysicalDeviceFormatProperties)(screen->pdev, format, &screen->format_props[i]); } + VkImageFormatProperties image_props; + VkResult ret = VKSCR(GetPhysicalDeviceImageFormatProperties)(screen->pdev, VK_FORMAT_D32_SFLOAT, + VK_IMAGE_TYPE_1D, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, + 0, &image_props); + screen->need_2D_zs = ret != VK_SUCCESS; } bool diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h index a1b7811935d..e16cdae8dcf 100644 --- a/src/gallium/drivers/zink/zink_screen.h +++ b/src/gallium/drivers/zink/zink_screen.h @@ -126,6 +126,7 @@ struct zink_screen { bool have_X8_D24_UNORM_PACK32; bool have_D24_UNORM_S8_UINT; bool have_triangle_fans; + bool need_2D_zs; uint32_t gfx_queue; uint32_t max_queues; diff --git a/src/gallium/drivers/zink/zink_surface.c b/src/gallium/drivers/zink/zink_surface.c index e7af9963529..dc1ddf05acd 100644 --- a/src/gallium/drivers/zink/zink_surface.c +++ b/src/gallium/drivers/zink/zink_surface.c @@ -45,11 +45,11 @@ create_ivci(struct zink_screen *screen, switch (target) { case PIPE_TEXTURE_1D: - ivci.viewType = VK_IMAGE_VIEW_TYPE_1D; + ivci.viewType = res->need_2D_zs ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_1D; break; case PIPE_TEXTURE_1D_ARRAY: - ivci.viewType = VK_IMAGE_VIEW_TYPE_1D_ARRAY; + ivci.viewType = res->need_2D_zs ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_1D_ARRAY; break; case PIPE_TEXTURE_2D: