zink: add 1DShadow sampler handling for drivers (radv) that don't support it

some drivers won't create zs textures in any shape but 2D. this can be
handled instead by using 2D textures and then performing shader rewrites to
convert shadow samplers for 1D and 1DArray types to 2D/array

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13583>
This commit is contained in:
Mike Blumenkrantz
2021-10-28 15:17:11 -04:00
committed by Marge Bot
parent 0ae1231879
commit 64e0ca15d6
8 changed files with 103 additions and 8 deletions
+8 -2
View File
@@ -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:
+67
View File
@@ -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;
+12 -3
View File
@@ -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:
+5 -1
View File
@@ -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;
+1
View File
@@ -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
};
};
+7
View File
@@ -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
+1
View File
@@ -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;
+2 -2
View File
@@ -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: