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:
committed by
Marge Bot
parent
0ae1231879
commit
64e0ca15d6
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user