panvk: Implement texture/image queries

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16276>
This commit is contained in:
Jason Ekstrand 2022-04-29 18:31:11 -05:00 committed by Marge Bot
parent 714e125ae4
commit 38a0742f6a
4 changed files with 192 additions and 9 deletions

View file

@ -24,7 +24,11 @@ include = [
"dEQP-VK.glsl.derivate.*.constant.*",
"dEQP-VK.glsl.derivate.*.linear.*",
"dEQP-VK.glsl.derivate.*.uniform_*",
"dEQP-VK.glsl.texture_functions.query.texturesize*",
"dEQP-VK.glsl.texture_functions.query.texturesamples.*",
"dEQP-VK.glsl.texture_functions.query.texturequerylevels.*",
"dEQP-VK.glsl.operator.*",
"dEQP-VK.image.image_size.*",
"dEQP-VK.image.load_store.with_format.*",
"dEQP-VK.pipeline.depth.format.d24_unorm_s8_uint.depth_test_disabled.depth_write_enabled",
"dEQP-VK.pipeline.input_assembly.*",

View file

@ -42,6 +42,44 @@
#include "pan_bo.h"
#include "panvk_cs.h"
#define PANVK_DESCRIPTOR_ALIGN 16
struct panvk_bview_desc {
uint32_t elems;
};
static void
panvk_fill_bview_desc(struct panvk_bview_desc *desc,
struct panvk_buffer_view *view)
{
desc->elems = view->elems;
}
struct panvk_image_desc {
uint32_t width;
uint32_t height;
uint32_t depth;
uint16_t levels;
uint16_t samples;
};
static void
panvk_fill_image_desc(struct panvk_image_desc *desc,
struct panvk_image_view *view)
{
desc->width = view->vk.extent.width;
desc->height = view->vk.extent.height;
desc->depth = view->vk.extent.depth;
desc->levels = view->vk.level_count;
desc->samples = view->vk.image->samples;
/* Stick array layer count after the last valid size component */
if (view->vk.image->image_type == VK_IMAGE_TYPE_1D)
desc->height = view->vk.layer_count;
else if (view->vk.image->image_type == VK_IMAGE_TYPE_2D)
desc->depth = view->vk.layer_count;
}
VkResult
panvk_per_arch(CreateDescriptorSetLayout)(VkDevice _device,
const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
@ -124,15 +162,18 @@ panvk_per_arch(CreateDescriptorSetLayout)(VkDevice _device,
binding_layout->tex_idx = tex_idx;
sampler_idx += binding_layout->array_size;
tex_idx += binding_layout->array_size;
binding_layout->desc_ubo_stride = sizeof(struct panvk_image_desc);
break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
binding_layout->tex_idx = tex_idx;
tex_idx += binding_layout->array_size;
binding_layout->desc_ubo_stride = sizeof(struct panvk_image_desc);
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
binding_layout->tex_idx = tex_idx;
tex_idx += binding_layout->array_size;
binding_layout->desc_ubo_stride = sizeof(struct panvk_bview_desc);
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
binding_layout->dyn_ubo_idx = dyn_ubo_idx;
@ -152,15 +193,18 @@ panvk_per_arch(CreateDescriptorSetLayout)(VkDevice _device,
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
binding_layout->img_idx = img_idx;
img_idx += binding_layout->array_size;
binding_layout->desc_ubo_stride = sizeof(struct panvk_image_desc);
break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
binding_layout->img_idx = img_idx;
img_idx += binding_layout->array_size;
binding_layout->desc_ubo_stride = sizeof(struct panvk_bview_desc);
break;
default:
unreachable("Invalid descriptor type");
}
desc_ubo_size = ALIGN_POT(desc_ubo_size, PANVK_DESCRIPTOR_ALIGN);
binding_layout->desc_ubo_offset = desc_ubo_size;
desc_ubo_size += binding_layout->desc_ubo_stride *
binding_layout->array_size;
@ -407,6 +451,12 @@ panvk_set_tex_desc(struct panvk_descriptor_set *set,
#else
((mali_ptr *)set->textures)[tex_idx] = view->bo->ptr.gpu;
#endif
void *desc = (char *)set->desc_bo->ptr.cpu +
binding_layout->desc_ubo_offset +
elem * binding_layout->desc_ubo_stride;
panvk_fill_image_desc(desc, view);
}
static void
@ -425,6 +475,12 @@ panvk_set_tex_buf_desc(struct panvk_descriptor_set *set,
#else
((mali_ptr *)set->textures)[tex_idx] = view->bo->ptr.gpu;
#endif
void *desc = (char *)set->desc_bo->ptr.cpu +
binding_layout->desc_ubo_offset +
elem * binding_layout->desc_ubo_stride;
panvk_fill_bview_desc(desc, view);
}
static void
@ -444,6 +500,12 @@ panvk_set_img_desc(struct panvk_device *dev,
set->img_fmts[img_idx] = pdev->formats[view->pview.format].hw;
memcpy(attrib_buf, view->descs.img_attrib_buf, pan_size(ATTRIBUTE_BUFFER) * 2);
void *desc = (char *)set->desc_bo->ptr.cpu +
binding_layout->desc_ubo_offset +
elem * binding_layout->desc_ubo_stride;
panvk_fill_image_desc(desc, view);
}
static void
@ -463,6 +525,12 @@ panvk_set_img_buf_desc(struct panvk_device *dev,
set->img_fmts[img_idx] = pdev->formats[view->fmt].hw;
memcpy(attrib_buf, view->descs.img_attrib_buf, pan_size(ATTRIBUTE_BUFFER) * 2);
void *desc = (char *)set->desc_bo->ptr.cpu +
binding_layout->desc_ubo_offset +
elem * binding_layout->desc_ubo_stride;
panvk_fill_bview_desc(desc, view);
}
static void

View file

@ -337,16 +337,92 @@ get_resource_deref_binding(nir_deref_instr *deref,
*binding = var->data.binding;
}
static nir_ssa_def *
load_resource_deref_desc(nir_builder *b, nir_deref_instr *deref,
unsigned desc_offset,
unsigned num_components, unsigned bit_size,
const struct apply_descriptors_ctx *ctx)
{
uint32_t set, binding, index_imm;
nir_ssa_def *index_ssa;
get_resource_deref_binding(deref, &set, &binding,
&index_imm, &index_ssa);
const struct panvk_descriptor_set_layout *set_layout =
ctx->layout->sets[set].layout;
const struct panvk_descriptor_set_binding_layout *bind_layout =
&set_layout->bindings[binding];
assert(index_ssa == NULL || index_imm == 0);
if (index_ssa == NULL)
index_ssa = nir_imm_int(b, index_imm);
const unsigned set_ubo_idx =
panvk_pipeline_layout_ubo_start(ctx->layout, set, false) +
set_layout->desc_ubo_index;
nir_ssa_def *desc_ubo_offset =
nir_iadd_imm(b, nir_imul_imm(b, index_ssa,
bind_layout->desc_ubo_stride),
bind_layout->desc_ubo_offset + desc_offset);
assert(bind_layout->desc_ubo_stride > 0);
unsigned desc_align = (1 << (ffs(bind_layout->desc_ubo_stride) - 1));
desc_align = MIN2(desc_align, 16);
return nir_load_ubo(b, num_components, bit_size,
nir_imm_int(b, set_ubo_idx),
desc_ubo_offset,
.align_mul=desc_align,
.align_offset=(desc_offset % desc_align),
.range=~0);
}
static bool
lower_tex(nir_builder *b, nir_tex_instr *tex,
const struct apply_descriptors_ctx *ctx)
{
bool progress = false;
int sampler_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_sampler_deref);
b->cursor = nir_before_instr(&tex->instr);
if (tex->op == nir_texop_txs ||
tex->op == nir_texop_query_levels ||
tex->op == nir_texop_texture_samples) {
int tex_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_texture_deref);
assert(tex_src_idx >= 0);
nir_deref_instr *deref = nir_src_as_deref(tex->src[tex_src_idx].src);
assert(tex->dest.is_ssa);
nir_ssa_def *desc = load_resource_deref_desc(b, deref, 0, 4, 32, ctx);
nir_ssa_def *res;
switch (tex->op) {
case nir_texop_txs:
assert(tex->dest.ssa.num_components <= 3);
res = nir_channels(b, desc,
nir_component_mask(tex->dest.ssa.num_components));
break;
case nir_texop_query_levels:
assert(tex->dest.ssa.num_components == 1);
res = nir_extract_u16(b, nir_channel(b, desc, 3),
nir_imm_int(b, 0));
break;
case nir_texop_texture_samples:
assert(tex->dest.ssa.num_components == 1);
res = nir_extract_u16(b, nir_channel(b, desc, 3),
nir_imm_int(b, 1));
break;
default:
unreachable("Unsupported texture query op");
}
nir_ssa_def_rewrite_uses(&tex->dest.ssa, res);
nir_instr_remove(&tex->instr);
return true;
}
int sampler_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_sampler_deref);
if (sampler_src_idx >= 0) {
nir_deref_instr *deref = nir_src_as_deref(tex->src[sampler_src_idx].src);
nir_tex_instr_remove_src(tex, sampler_src_idx);
@ -420,6 +496,42 @@ get_img_index(nir_builder *b, nir_deref_instr *deref,
}
}
static bool
lower_img_intrinsic(nir_builder *b, nir_intrinsic_instr *intr,
struct apply_descriptors_ctx *ctx)
{
b->cursor = nir_before_instr(&intr->instr);
nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
if (intr->intrinsic == nir_intrinsic_image_deref_size ||
intr->intrinsic == nir_intrinsic_image_deref_samples) {
assert(intr->dest.is_ssa);
nir_ssa_def *desc = load_resource_deref_desc(b, deref, 0, 4, 32, ctx);
nir_ssa_def *res;
switch (intr->intrinsic) {
case nir_intrinsic_image_deref_size:
res = nir_channels(b, desc,
nir_component_mask(intr->dest.ssa.num_components));
break;
case nir_intrinsic_image_deref_samples:
res = nir_extract_u16(b, nir_channel(b, desc, 3),
nir_imm_int(b, 1));
break;
default:
unreachable("Unsupported image query op");
}
nir_ssa_def_rewrite_uses(&intr->dest.ssa, res);
nir_instr_remove(&intr->instr);
} else {
nir_rewrite_image_intrinsic(intr, get_img_index(b, deref, ctx), false);
ctx->has_img_access = true;
}
return true;
}
static bool
lower_intrinsic(nir_builder *b, nir_intrinsic_instr *intr,
struct apply_descriptors_ctx *ctx)
@ -445,14 +557,8 @@ lower_intrinsic(nir_builder *b, nir_intrinsic_instr *intr,
case nir_intrinsic_image_deref_atomic_comp_swap:
case nir_intrinsic_image_deref_atomic_fadd:
case nir_intrinsic_image_deref_size:
case nir_intrinsic_image_deref_samples: {
nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
b->cursor = nir_before_instr(&intr->instr);
nir_rewrite_image_intrinsic(intr, get_img_index(b, deref, ctx), false);
ctx->has_img_access = true;
return true;
}
case nir_intrinsic_image_deref_samples:
return lower_img_intrinsic(b, intr, ctx);
default:
return false;
}

View file

@ -396,6 +396,11 @@ panvk_per_arch(shader_create)(struct panvk_device *dev,
panvk_lower_blend(pdev, nir, &inputs, blend_state, static_blend_constants);
}
nir_lower_tex_options lower_tex_options = {
.lower_txs_lod = true,
};
NIR_PASS_V(nir, nir_lower_tex, &lower_tex_options);
NIR_PASS_V(nir, panvk_per_arch(nir_lower_descriptors),
dev, layout, &shader->has_img_access);