mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-16 08:58:30 +02:00
nir,spirv: Add support for SPV_QCOM_image_processing.
Initial work was done by Mark Collins, which I significantly rewrote. Signed-off-by: Mark Collins <mark@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38559>
This commit is contained in:
parent
a70cb908e4
commit
e922c2cabc
9 changed files with 185 additions and 5 deletions
|
|
@ -3435,6 +3435,12 @@ nir_tex_instr_result_size(const nir_tex_instr *instr)
|
|||
case nir_texop_custom_border_color_agx:
|
||||
return 4;
|
||||
|
||||
case nir_texop_sample_weighted_qcom:
|
||||
case nir_texop_box_filter_qcom:
|
||||
case nir_texop_block_match_sad_qcom:
|
||||
case nir_texop_block_match_ssd_qcom:
|
||||
return 4;
|
||||
|
||||
default:
|
||||
if (instr->is_shadow && instr->is_new_style_shadow)
|
||||
return 1;
|
||||
|
|
@ -3473,6 +3479,10 @@ nir_tex_instr_is_query(const nir_tex_instr *instr)
|
|||
case nir_texop_samples_identical:
|
||||
case nir_texop_fragment_mask_fetch_amd:
|
||||
case nir_texop_fragment_fetch_amd:
|
||||
case nir_texop_sample_weighted_qcom:
|
||||
case nir_texop_box_filter_qcom:
|
||||
case nir_texop_block_match_sad_qcom:
|
||||
case nir_texop_block_match_ssd_qcom:
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE("Invalid texture opcode");
|
||||
|
|
@ -3499,6 +3509,7 @@ nir_tex_instr_src_type(const nir_tex_instr *instr, unsigned src)
|
|||
{
|
||||
switch (instr->src[src].src_type) {
|
||||
case nir_tex_src_coord:
|
||||
case nir_tex_src_ref_coord:
|
||||
switch (instr->op) {
|
||||
case nir_texop_txf:
|
||||
case nir_texop_txf_ms:
|
||||
|
|
@ -3507,6 +3518,8 @@ nir_tex_instr_src_type(const nir_tex_instr *instr, unsigned src)
|
|||
case nir_texop_samples_identical:
|
||||
case nir_texop_fragment_fetch_amd:
|
||||
case nir_texop_fragment_mask_fetch_amd:
|
||||
case nir_texop_block_match_sad_qcom:
|
||||
case nir_texop_block_match_ssd_qcom:
|
||||
return nir_type_int;
|
||||
|
||||
default:
|
||||
|
|
@ -3535,6 +3548,7 @@ nir_tex_instr_src_type(const nir_tex_instr *instr, unsigned src)
|
|||
case nir_tex_src_ddy:
|
||||
case nir_tex_src_backend1:
|
||||
case nir_tex_src_backend2:
|
||||
case nir_tex_src_box_size:
|
||||
return nir_type_float;
|
||||
|
||||
case nir_tex_src_offset:
|
||||
|
|
@ -3552,6 +3566,11 @@ nir_tex_instr_src_type(const nir_tex_instr *instr, unsigned src)
|
|||
case nir_tex_src_sampler_offset:
|
||||
case nir_tex_src_texture_handle:
|
||||
case nir_tex_src_sampler_handle:
|
||||
case nir_tex_src_texture_2_deref:
|
||||
case nir_tex_src_sampler_2_deref:
|
||||
case nir_tex_src_texture_2_handle:
|
||||
case nir_tex_src_sampler_2_handle:
|
||||
case nir_tex_src_block_size:
|
||||
return nir_type_uint;
|
||||
|
||||
case nir_num_tex_src_types:
|
||||
|
|
@ -3564,13 +3583,24 @@ nir_tex_instr_src_type(const nir_tex_instr *instr, unsigned src)
|
|||
unsigned
|
||||
nir_tex_instr_src_size(const nir_tex_instr *instr, unsigned src)
|
||||
{
|
||||
if (instr->src[src].src_type == nir_tex_src_coord)
|
||||
if (instr->src[src].src_type == nir_tex_src_coord )
|
||||
return instr->coord_components;
|
||||
|
||||
/* The MCS value is expected to be a vec4 returned by a txf_ms_mcs_intel */
|
||||
if (instr->src[src].src_type == nir_tex_src_ms_mcs_intel)
|
||||
return 4;
|
||||
|
||||
if (instr->src[src].src_type == nir_tex_src_box_size)
|
||||
return 2;
|
||||
|
||||
/* These are vec2s at the spirv level, but get lowered to 16_16 packed values
|
||||
* in the backend, so they don't have a single known size
|
||||
*/
|
||||
if (instr->src[src].src_type == nir_tex_src_ref_coord ||
|
||||
instr->src[src].src_type == nir_tex_src_block_size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (instr->src[src].src_type == nir_tex_src_ddx ||
|
||||
instr->src[src].src_type == nir_tex_src_ddy) {
|
||||
|
||||
|
|
|
|||
|
|
@ -2384,6 +2384,15 @@ typedef enum nir_tex_src_type {
|
|||
/** Second backend-specific vec4 tex src argument, see nir_tex_src_backend1. */
|
||||
nir_tex_src_backend2,
|
||||
|
||||
/** VK_QCOM_image_processing sources */
|
||||
nir_tex_src_ref_coord,
|
||||
nir_tex_src_texture_2_deref,
|
||||
nir_tex_src_sampler_2_deref,
|
||||
nir_tex_src_texture_2_handle,
|
||||
nir_tex_src_sampler_2_handle,
|
||||
nir_tex_src_block_size,
|
||||
nir_tex_src_box_size,
|
||||
|
||||
nir_num_tex_src_types
|
||||
} nir_tex_src_type;
|
||||
|
||||
|
|
@ -2450,6 +2459,26 @@ typedef enum nir_texop {
|
|||
nir_texop_tex_type_nv,
|
||||
/** Maps to TXQ.SAMPLER_POS */
|
||||
nir_texop_sample_pos_nv,
|
||||
/**
|
||||
* Returns the weighted average of a region of texels in the texture, using
|
||||
* the filter kernel sampled from ref_texture. (VK_QCOM_image_processing)
|
||||
*/
|
||||
nir_texop_sample_weighted_qcom,
|
||||
/**
|
||||
* Returns the result of a weighted average of the texels in a box of size
|
||||
* box_size centered at coord. (VK_QCOM_image_processing)
|
||||
*/
|
||||
nir_texop_box_filter_qcom,
|
||||
/**
|
||||
* Returns the result of SAD/SSD block matching on 2D textures.
|
||||
* (VK_QCOM_image_processing)
|
||||
*
|
||||
* The textures are always 2D dim, and the coord and ref_coord texture
|
||||
* sources are ivec2s. The size of the block is specified in the block_size
|
||||
* texture source (uvec2 from SPIRV, packed u32 in the backend)
|
||||
*/
|
||||
nir_texop_block_match_sad_qcom,
|
||||
nir_texop_block_match_ssd_qcom,
|
||||
} nir_texop;
|
||||
|
||||
/** Represents a texture instruction */
|
||||
|
|
@ -2493,7 +2522,10 @@ typedef struct nir_tex_instr {
|
|||
/** Number of sources */
|
||||
unsigned num_srcs;
|
||||
|
||||
/** Number of components in the coordinate, if any */
|
||||
/** Number of components in the coordinate, if any.
|
||||
*
|
||||
* This applies to the nir_tex_src_coord and nir_tex_src_ref_coord src types.
|
||||
*/
|
||||
unsigned coord_components;
|
||||
|
||||
/** True if the texture instruction acts on an array texture */
|
||||
|
|
|
|||
|
|
@ -1057,12 +1057,14 @@ visit_tex(nir_tex_instr *instr, struct divergence_state *state)
|
|||
for (unsigned i = 0; i < instr->num_srcs; i++) {
|
||||
switch (instr->src[i].src_type) {
|
||||
case nir_tex_src_sampler_deref:
|
||||
case nir_tex_src_sampler_2_deref:
|
||||
case nir_tex_src_sampler_handle:
|
||||
case nir_tex_src_sampler_offset:
|
||||
is_divergent |= src_divergent(instr->src[i].src, state) &&
|
||||
instr->sampler_non_uniform;
|
||||
break;
|
||||
case nir_tex_src_texture_deref:
|
||||
case nir_tex_src_texture_2_deref:
|
||||
case nir_tex_src_texture_handle:
|
||||
case nir_tex_src_texture_offset:
|
||||
is_divergent |= src_divergent(instr->src[i].src, state) &&
|
||||
|
|
|
|||
|
|
@ -221,6 +221,7 @@ lower_non_uniform_tex_access(struct nu_state *state, nir_tex_instr *tex,
|
|||
case nir_tex_src_texture_offset:
|
||||
case nir_tex_src_texture_handle:
|
||||
case nir_tex_src_texture_deref:
|
||||
case nir_tex_src_texture_2_deref:
|
||||
if (!tex->texture_non_uniform)
|
||||
continue;
|
||||
if (!(opts->types & nir_lower_non_uniform_texture_access))
|
||||
|
|
@ -232,6 +233,7 @@ lower_non_uniform_tex_access(struct nu_state *state, nir_tex_instr *tex,
|
|||
case nir_tex_src_sampler_offset:
|
||||
case nir_tex_src_sampler_handle:
|
||||
case nir_tex_src_sampler_deref:
|
||||
case nir_tex_src_sampler_2_deref:
|
||||
if (!tex->sampler_non_uniform)
|
||||
continue;
|
||||
if (!(opts->types & nir_lower_non_uniform_texture_access))
|
||||
|
|
|
|||
|
|
@ -334,10 +334,12 @@ gcm_pin_instructions(nir_function_impl *impl, struct gcm_state *state)
|
|||
nir_tex_src *src = &tex->src[i];
|
||||
switch (src->src_type) {
|
||||
case nir_tex_src_texture_deref:
|
||||
case nir_tex_src_texture_2_deref:
|
||||
if (!tex->texture_non_uniform && !is_binding_uniform(src->src))
|
||||
instr->pass_flags = GCM_INSTR_PINNED;
|
||||
break;
|
||||
case nir_tex_src_sampler_deref:
|
||||
case nir_tex_src_sampler_2_deref:
|
||||
if (!tex->sampler_non_uniform && !is_binding_uniform(src->src))
|
||||
instr->pass_flags = GCM_INSTR_PINNED;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1188,6 +1188,10 @@ vulkan_descriptor_type_name(VkDescriptorType type)
|
|||
return "inline-UBO";
|
||||
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
|
||||
return "accel-struct";
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM:
|
||||
return "sample-weight-image";
|
||||
case VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM:
|
||||
return "block-match-image";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
|
|
@ -1903,6 +1907,18 @@ print_tex_instr(nir_tex_instr *instr, print_state *state)
|
|||
case nir_texop_sample_pos_nv:
|
||||
fprintf(fp, "sample_pos_nv ");
|
||||
break;
|
||||
case nir_texop_sample_weighted_qcom:
|
||||
fprintf(fp, "sample_weighted_qcom ");
|
||||
break;
|
||||
case nir_texop_box_filter_qcom:
|
||||
fprintf(fp, "box_filter_qcom ");
|
||||
break;
|
||||
case nir_texop_block_match_sad_qcom:
|
||||
fprintf(fp, "block_match_sad_qcom ");
|
||||
break;
|
||||
case nir_texop_block_match_ssd_qcom:
|
||||
fprintf(fp, "block_match_ssd_qcom ");
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE("Invalid texture operation");
|
||||
break;
|
||||
|
|
@ -1927,6 +1943,9 @@ print_tex_instr(nir_tex_instr *instr, print_state *state)
|
|||
case nir_tex_src_coord:
|
||||
fprintf(fp, "(coord)");
|
||||
break;
|
||||
case nir_tex_src_ref_coord:
|
||||
fprintf(fp, "(ref_coord)");
|
||||
break;
|
||||
case nir_tex_src_projector:
|
||||
fprintf(fp, "(projector)");
|
||||
break;
|
||||
|
|
@ -1975,10 +1994,16 @@ print_tex_instr(nir_tex_instr *instr, print_state *state)
|
|||
has_texture_deref = true;
|
||||
fprintf(fp, "(texture_deref)");
|
||||
break;
|
||||
case nir_tex_src_texture_2_deref:
|
||||
fprintf(fp, "(texture_2_deref)");
|
||||
break;
|
||||
case nir_tex_src_sampler_deref:
|
||||
has_sampler_deref = true;
|
||||
fprintf(fp, "(sampler_deref)");
|
||||
break;
|
||||
case nir_tex_src_sampler_2_deref:
|
||||
fprintf(fp, "(sampler_2_deref)");
|
||||
break;
|
||||
case nir_tex_src_texture_offset:
|
||||
fprintf(fp, "(texture_offset)");
|
||||
break;
|
||||
|
|
@ -1988,9 +2013,21 @@ print_tex_instr(nir_tex_instr *instr, print_state *state)
|
|||
case nir_tex_src_texture_handle:
|
||||
fprintf(fp, "(texture_handle)");
|
||||
break;
|
||||
case nir_tex_src_texture_2_handle:
|
||||
fprintf(fp, "(texture_2_handle)");
|
||||
break;
|
||||
case nir_tex_src_sampler_handle:
|
||||
fprintf(fp, "(sampler_handle)");
|
||||
break;
|
||||
case nir_tex_src_sampler_2_handle:
|
||||
fprintf(fp, "(ref_sampler_handle)");
|
||||
break;
|
||||
case nir_tex_src_block_size:
|
||||
fprintf(fp, "(block_size)");
|
||||
break;
|
||||
case nir_tex_src_box_size:
|
||||
fprintf(fp, "(box_size)");
|
||||
break;
|
||||
case nir_tex_src_plane:
|
||||
fprintf(fp, "(plane)");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -981,7 +981,8 @@ validate_tex_instr(nir_tex_instr *instr, validate_state *state)
|
|||
validate_assert(state, instr->op == nir_texop_txd);
|
||||
break;
|
||||
|
||||
case nir_tex_src_texture_deref: {
|
||||
case nir_tex_src_texture_deref:
|
||||
case nir_tex_src_texture_2_deref: {
|
||||
nir_deref_instr *deref = nir_src_as_deref(instr->src[i].src);
|
||||
if (!validate_assert(state, deref))
|
||||
break;
|
||||
|
|
@ -990,7 +991,8 @@ validate_tex_instr(nir_tex_instr *instr, validate_state *state)
|
|||
break;
|
||||
}
|
||||
|
||||
case nir_tex_src_sampler_deref: {
|
||||
case nir_tex_src_sampler_deref:
|
||||
case nir_tex_src_sampler_2_deref: {
|
||||
nir_deref_instr *deref = nir_src_as_deref(instr->src[i].src);
|
||||
if (!validate_assert(state, deref))
|
||||
break;
|
||||
|
|
@ -1016,7 +1018,18 @@ validate_tex_instr(nir_tex_instr *instr, validate_state *state)
|
|||
break;
|
||||
}
|
||||
|
||||
case nir_tex_src_block_size:
|
||||
validate_assert(state,
|
||||
instr->op == nir_texop_block_match_sad_qcom ||
|
||||
instr->op == nir_texop_block_match_ssd_qcom);
|
||||
break;
|
||||
|
||||
case nir_tex_src_box_size:
|
||||
validate_assert(state, instr->op == nir_texop_box_filter_qcom);
|
||||
break;
|
||||
|
||||
case nir_tex_src_coord:
|
||||
case nir_tex_src_ref_coord:
|
||||
case nir_tex_src_projector:
|
||||
case nir_tex_src_offset:
|
||||
case nir_tex_src_min_lod:
|
||||
|
|
@ -1026,6 +1039,8 @@ validate_tex_instr(nir_tex_instr *instr, validate_state *state)
|
|||
case nir_tex_src_plane:
|
||||
case nir_tex_src_texture_handle:
|
||||
case nir_tex_src_sampler_handle:
|
||||
case nir_tex_src_texture_2_handle:
|
||||
case nir_tex_src_sampler_2_handle:
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -203,6 +203,9 @@ static const struct spirv_capabilities implemented_capabilities = {
|
|||
.SubgroupVoteKHR = true,
|
||||
.Tessellation = true,
|
||||
.TessellationPointSize = true,
|
||||
.TextureBlockMatchQCOM = true,
|
||||
.TextureBoxFilterQCOM = true,
|
||||
.TextureSampleWeightedQCOM = true,
|
||||
.TransformFeedback = true,
|
||||
.UniformAndStorageBuffer8BitAccess = true,
|
||||
.UniformBufferArrayDynamicIndexing = true,
|
||||
|
|
@ -3565,6 +3568,22 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
|
|||
dest_type = nir_type_uint32;
|
||||
break;
|
||||
|
||||
case SpvOpImageSampleWeightedQCOM:
|
||||
texop = nir_texop_sample_weighted_qcom;
|
||||
break;
|
||||
|
||||
case SpvOpImageBoxFilterQCOM:
|
||||
texop = nir_texop_box_filter_qcom;
|
||||
break;
|
||||
|
||||
case SpvOpImageBlockMatchSADQCOM:
|
||||
texop = nir_texop_block_match_sad_qcom;
|
||||
break;
|
||||
|
||||
case SpvOpImageBlockMatchSSDQCOM:
|
||||
texop = nir_texop_block_match_ssd_qcom;
|
||||
break;
|
||||
|
||||
default:
|
||||
vtn_fail_with_opcode("Unhandled opcode", opcode);
|
||||
}
|
||||
|
|
@ -3583,6 +3602,10 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
|
|||
case nir_texop_txd:
|
||||
case nir_texop_tg4:
|
||||
case nir_texop_lod:
|
||||
case nir_texop_sample_weighted_qcom:
|
||||
case nir_texop_box_filter_qcom:
|
||||
case nir_texop_block_match_sad_qcom:
|
||||
case nir_texop_block_match_ssd_qcom:
|
||||
vtn_fail_if(sampler == NULL,
|
||||
"%s requires an image of type OpTypeSampledImage",
|
||||
spirv_op_to_string(opcode));
|
||||
|
|
@ -3653,7 +3676,11 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
|
|||
case SpvOpImageSparseDrefGather:
|
||||
case SpvOpImageQueryLod:
|
||||
case SpvOpFragmentFetchAMD:
|
||||
case SpvOpFragmentMaskFetchAMD: {
|
||||
case SpvOpFragmentMaskFetchAMD:
|
||||
case SpvOpImageSampleWeightedQCOM:
|
||||
case SpvOpImageBoxFilterQCOM:
|
||||
case SpvOpImageBlockMatchSADQCOM:
|
||||
case SpvOpImageBlockMatchSSDQCOM: {
|
||||
/* All these types have the coordinate as their first real argument */
|
||||
coord_components = glsl_get_sampler_dim_coordinate_components(sampler_dim);
|
||||
|
||||
|
|
@ -3767,6 +3794,31 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
|
|||
if (opcode == SpvOpFragmentFetchAMD)
|
||||
(*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ms_index);
|
||||
|
||||
/* For SpvOpImageBoxFilterQCOM, we always have a box size */
|
||||
if (opcode == SpvOpImageBoxFilterQCOM)
|
||||
(*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_box_size);
|
||||
|
||||
/* For SpvOpImageSampleWeightedQCOM and block matching, we have a secondary sampled image. */
|
||||
if (opcode == SpvOpImageSampleWeightedQCOM ||
|
||||
opcode == SpvOpImageBlockMatchSADQCOM ||
|
||||
opcode == SpvOpImageBlockMatchSSDQCOM) {
|
||||
struct vtn_value *sampled_val = vtn_untyped_value(b, w[idx]);
|
||||
if (sampled_val->type->base_type == vtn_base_type_sampled_image) {
|
||||
struct vtn_sampled_image si = vtn_get_sampled_image(b, w[idx]);
|
||||
(*p++) = nir_tex_src_for_ssa(nir_tex_src_texture_2_deref, &si.image->def);
|
||||
(*p++) = nir_tex_src_for_ssa(nir_tex_src_sampler_2_deref, &si.sampler->def);
|
||||
} else {
|
||||
vtn_err("Failed to look up sampled image for QCOM_image_processing");
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (opcode == SpvOpImageBlockMatchSADQCOM ||
|
||||
opcode == SpvOpImageBlockMatchSSDQCOM) {
|
||||
(*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ref_coord);
|
||||
(*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_block_size);
|
||||
}
|
||||
|
||||
/* Now we need to handle some number of optional arguments */
|
||||
struct vtn_value *gather_offsets = NULL;
|
||||
uint32_t operands = SpvImageOperandsMaskNone;
|
||||
|
|
@ -6594,6 +6646,10 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
|
|||
case SpvOpImageDrefGather:
|
||||
case SpvOpImageSparseDrefGather:
|
||||
case SpvOpImageQueryLod:
|
||||
case SpvOpImageSampleWeightedQCOM:
|
||||
case SpvOpImageBoxFilterQCOM:
|
||||
case SpvOpImageBlockMatchSADQCOM:
|
||||
case SpvOpImageBlockMatchSSDQCOM:
|
||||
vtn_handle_texture(b, opcode, w, count);
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -1561,6 +1561,10 @@ apply_var_decoration(struct vtn_builder *b,
|
|||
"NodeMaxPayloadsAMDX decoration only allowed in compute shaders");
|
||||
break;
|
||||
|
||||
case SpvDecorationWeightTextureQCOM:
|
||||
case SpvDecorationBlockMatchTextureQCOM:
|
||||
break;
|
||||
|
||||
default:
|
||||
vtn_fail_with_decoration("Unhandled decoration", dec->decoration);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue