spirv: Use nir_var_mem_image
Use the new nir_var_mem_image mode for images that are not known to be used with a sampler (i.e. storage images). Reviewed-by: Jason Ekstrand <jason@jlekstrand.net> Reviewed-by: Jesse Natalie <jenatali@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4743>
This commit is contained in:

committed by
Marge Bot

parent
219ac26ea3
commit
cfdc7ee066
@@ -367,8 +367,10 @@ vtn_get_image(struct vtn_builder *b, uint32_t value_id,
|
|||||||
vtn_assert(type->base_type == vtn_base_type_image);
|
vtn_assert(type->base_type == vtn_base_type_image);
|
||||||
if (access)
|
if (access)
|
||||||
*access |= spirv_to_gl_access_qualifier(b, type->access_qualifier);
|
*access |= spirv_to_gl_access_qualifier(b, type->access_qualifier);
|
||||||
|
nir_variable_mode mode = glsl_type_is_image(type->glsl_image) ?
|
||||||
|
nir_var_mem_image : nir_var_uniform;
|
||||||
return nir_build_deref_cast(&b->nb, vtn_get_nir_ssa(b, value_id),
|
return nir_build_deref_cast(&b->nb, vtn_get_nir_ssa(b, value_id),
|
||||||
nir_var_uniform, type->glsl_image, 0);
|
mode, type->glsl_image, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -415,10 +417,16 @@ vtn_get_sampled_image(struct vtn_builder *b, uint32_t value_id)
|
|||||||
vtn_assert(type->base_type == vtn_base_type_sampled_image);
|
vtn_assert(type->base_type == vtn_base_type_sampled_image);
|
||||||
nir_ssa_def *si_vec2 = vtn_get_nir_ssa(b, value_id);
|
nir_ssa_def *si_vec2 = vtn_get_nir_ssa(b, value_id);
|
||||||
|
|
||||||
|
/* Even though this is a sampled image, we can end up here with a storage
|
||||||
|
* image because OpenCL doesn't distinguish between the two.
|
||||||
|
*/
|
||||||
|
const struct glsl_type *image_type = type->image->glsl_image;
|
||||||
|
nir_variable_mode image_mode = glsl_type_is_image(image_type) ?
|
||||||
|
nir_var_mem_image : nir_var_uniform;
|
||||||
|
|
||||||
struct vtn_sampled_image si = { NULL, };
|
struct vtn_sampled_image si = { NULL, };
|
||||||
si.image = nir_build_deref_cast(&b->nb, nir_channel(&b->nb, si_vec2, 0),
|
si.image = nir_build_deref_cast(&b->nb, nir_channel(&b->nb, si_vec2, 0),
|
||||||
nir_var_uniform,
|
image_mode, image_type, 0);
|
||||||
type->image->glsl_image, 0);
|
|
||||||
si.sampler = nir_build_deref_cast(&b->nb, nir_channel(&b->nb, si_vec2, 1),
|
si.sampler = nir_build_deref_cast(&b->nb, nir_channel(&b->nb, si_vec2, 1),
|
||||||
nir_var_uniform,
|
nir_var_uniform,
|
||||||
glsl_bare_sampler_type(), 0);
|
glsl_bare_sampler_type(), 0);
|
||||||
@@ -942,6 +950,7 @@ vtn_type_get_nir_type(struct vtn_builder *b, struct vtn_type *type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case vtn_base_type_image:
|
case vtn_base_type_image:
|
||||||
|
vtn_assert(glsl_type_is_sampler(type->glsl_image));
|
||||||
return type->glsl_image;
|
return type->glsl_image;
|
||||||
|
|
||||||
case vtn_base_type_sampler:
|
case vtn_base_type_sampler:
|
||||||
@@ -955,6 +964,12 @@ vtn_type_get_nir_type(struct vtn_builder *b, struct vtn_type *type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mode == vtn_variable_mode_image) {
|
||||||
|
struct vtn_type *image_type = vtn_type_without_array(type);
|
||||||
|
vtn_assert(image_type->base_type == vtn_base_type_image);
|
||||||
|
return wrap_type_in_array(image_type->glsl_image, type->type);
|
||||||
|
}
|
||||||
|
|
||||||
/* Layout decorations are allowed but ignored in certain conditions,
|
/* Layout decorations are allowed but ignored in certain conditions,
|
||||||
* to allow SPIR-V generators perform type deduplication. Discard
|
* to allow SPIR-V generators perform type deduplication. Discard
|
||||||
* unnecessary ones when passing to NIR.
|
* unnecessary ones when passing to NIR.
|
||||||
@@ -2397,18 +2412,15 @@ vtn_mem_semantics_to_nir_var_modes(struct vtn_builder *b,
|
|||||||
SpvMemorySemanticsAtomicCounterMemoryMask);
|
SpvMemorySemanticsAtomicCounterMemoryMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Consider adding nir_var_mem_image mode to NIR so it can be used
|
|
||||||
* for SpvMemorySemanticsImageMemoryMask.
|
|
||||||
*/
|
|
||||||
|
|
||||||
nir_variable_mode modes = 0;
|
nir_variable_mode modes = 0;
|
||||||
if (semantics & (SpvMemorySemanticsUniformMemoryMask |
|
if (semantics & SpvMemorySemanticsUniformMemoryMask) {
|
||||||
SpvMemorySemanticsImageMemoryMask)) {
|
|
||||||
modes |= nir_var_uniform |
|
modes |= nir_var_uniform |
|
||||||
nir_var_mem_ubo |
|
nir_var_mem_ubo |
|
||||||
nir_var_mem_ssbo |
|
nir_var_mem_ssbo |
|
||||||
nir_var_mem_global;
|
nir_var_mem_global;
|
||||||
}
|
}
|
||||||
|
if (semantics & SpvMemorySemanticsImageMemoryMask)
|
||||||
|
modes |= nir_var_mem_image;
|
||||||
if (semantics & SpvMemorySemanticsWorkgroupMemoryMask)
|
if (semantics & SpvMemorySemanticsWorkgroupMemoryMask)
|
||||||
modes |= nir_var_mem_shared;
|
modes |= nir_var_mem_shared;
|
||||||
if (semantics & SpvMemorySemanticsCrossWorkgroupMemoryMask)
|
if (semantics & SpvMemorySemanticsCrossWorkgroupMemoryMask)
|
||||||
@@ -6121,22 +6133,25 @@ vtn_emit_kernel_entry_point_wrapper(struct vtn_builder *b,
|
|||||||
|
|
||||||
/* input variable */
|
/* input variable */
|
||||||
nir_variable *in_var = rzalloc(b->nb.shader, nir_variable);
|
nir_variable *in_var = rzalloc(b->nb.shader, nir_variable);
|
||||||
in_var->data.mode = nir_var_uniform;
|
|
||||||
in_var->data.read_only = true;
|
if (is_by_val) {
|
||||||
in_var->data.location = i;
|
in_var->data.mode = nir_var_uniform;
|
||||||
if (param_type->base_type == vtn_base_type_image) {
|
in_var->type = param_type->deref->type;
|
||||||
|
} else if (param_type->base_type == vtn_base_type_image) {
|
||||||
|
in_var->data.mode = nir_var_mem_image;
|
||||||
|
in_var->type = param_type->glsl_image;
|
||||||
in_var->data.access =
|
in_var->data.access =
|
||||||
spirv_to_gl_access_qualifier(b, param_type->access_qualifier);
|
spirv_to_gl_access_qualifier(b, param_type->access_qualifier);
|
||||||
|
} else if (param_type->base_type == vtn_base_type_sampler) {
|
||||||
|
in_var->data.mode = nir_var_uniform;
|
||||||
|
in_var->type = glsl_bare_sampler_type();
|
||||||
|
} else {
|
||||||
|
in_var->data.mode = nir_var_uniform;
|
||||||
|
in_var->type = param_type->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_by_val)
|
in_var->data.read_only = true;
|
||||||
in_var->type = param_type->deref->type;
|
in_var->data.location = i;
|
||||||
else if (param_type->base_type == vtn_base_type_image)
|
|
||||||
in_var->type = param_type->glsl_image;
|
|
||||||
else if (param_type->base_type == vtn_base_type_sampler)
|
|
||||||
in_var->type = glsl_bare_sampler_type();
|
|
||||||
else
|
|
||||||
in_var->type = param_type->type;
|
|
||||||
|
|
||||||
nir_shader_add_variable(b->nb.shader, in_var);
|
nir_shader_add_variable(b->nb.shader, in_var);
|
||||||
|
|
||||||
|
@@ -597,7 +597,8 @@ _vtn_variable_load_store(struct vtn_builder *b, bool load,
|
|||||||
enum gl_access_qualifier access,
|
enum gl_access_qualifier access,
|
||||||
struct vtn_ssa_value **inout)
|
struct vtn_ssa_value **inout)
|
||||||
{
|
{
|
||||||
if (ptr->mode == vtn_variable_mode_uniform) {
|
if (ptr->mode == vtn_variable_mode_uniform ||
|
||||||
|
ptr->mode == vtn_variable_mode_image) {
|
||||||
if (ptr->type->base_type == vtn_base_type_image ||
|
if (ptr->type->base_type == vtn_base_type_image ||
|
||||||
ptr->type->base_type == vtn_base_type_sampler) {
|
ptr->type->base_type == vtn_base_type_sampler) {
|
||||||
/* See also our handling of OpTypeSampler and OpTypeImage */
|
/* See also our handling of OpTypeSampler and OpTypeImage */
|
||||||
@@ -1415,7 +1416,8 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
|
|||||||
} else if (vtn_var->mode == vtn_variable_mode_call_data ||
|
} else if (vtn_var->mode == vtn_variable_mode_call_data ||
|
||||||
vtn_var->mode == vtn_variable_mode_ray_payload) {
|
vtn_var->mode == vtn_variable_mode_ray_payload) {
|
||||||
/* This location is fine as-is */
|
/* This location is fine as-is */
|
||||||
} else if (vtn_var->mode != vtn_variable_mode_uniform) {
|
} else if (vtn_var->mode != vtn_variable_mode_uniform &&
|
||||||
|
vtn_var->mode != vtn_variable_mode_image) {
|
||||||
vtn_warn("Location must be on input, output, uniform, sampler or "
|
vtn_warn("Location must be on input, output, uniform, sampler or "
|
||||||
"image variable");
|
"image variable");
|
||||||
return;
|
return;
|
||||||
@@ -1498,7 +1500,19 @@ vtn_storage_class_to_mode(struct vtn_builder *b,
|
|||||||
nir_mode = nir_var_mem_global;
|
nir_mode = nir_var_mem_global;
|
||||||
break;
|
break;
|
||||||
case SpvStorageClassUniformConstant:
|
case SpvStorageClassUniformConstant:
|
||||||
if (b->shader->info.stage == MESA_SHADER_KERNEL) {
|
/* interface_type is only NULL when OpTypeForwardPointer is used and
|
||||||
|
* OpTypeForwardPointer can only be used for struct types, not images or
|
||||||
|
* acceleration structures.
|
||||||
|
*/
|
||||||
|
if (interface_type)
|
||||||
|
interface_type = vtn_type_without_array(interface_type);
|
||||||
|
|
||||||
|
if (interface_type &&
|
||||||
|
interface_type->base_type == vtn_base_type_image &&
|
||||||
|
glsl_type_is_image(interface_type->glsl_image)) {
|
||||||
|
mode = vtn_variable_mode_image;
|
||||||
|
nir_mode = nir_var_mem_image;
|
||||||
|
} else if (b->shader->info.stage == MESA_SHADER_KERNEL) {
|
||||||
mode = vtn_variable_mode_constant;
|
mode = vtn_variable_mode_constant;
|
||||||
nir_mode = nir_var_mem_constant;
|
nir_mode = nir_var_mem_constant;
|
||||||
} else {
|
} else {
|
||||||
@@ -1507,7 +1521,6 @@ vtn_storage_class_to_mode(struct vtn_builder *b,
|
|||||||
* storage class.
|
* storage class.
|
||||||
*/
|
*/
|
||||||
assert(interface_type != NULL);
|
assert(interface_type != NULL);
|
||||||
interface_type = vtn_type_without_array(interface_type);
|
|
||||||
if (interface_type->base_type == vtn_base_type_accel_struct) {
|
if (interface_type->base_type == vtn_base_type_accel_struct) {
|
||||||
mode = vtn_variable_mode_accel_struct;
|
mode = vtn_variable_mode_accel_struct;
|
||||||
nir_mode = nir_var_uniform;
|
nir_mode = nir_var_uniform;
|
||||||
@@ -1551,7 +1564,7 @@ vtn_storage_class_to_mode(struct vtn_builder *b,
|
|||||||
break;
|
break;
|
||||||
case SpvStorageClassImage:
|
case SpvStorageClassImage:
|
||||||
mode = vtn_variable_mode_image;
|
mode = vtn_variable_mode_image;
|
||||||
nir_mode = nir_var_mem_ubo;
|
nir_mode = nir_var_mem_image;
|
||||||
break;
|
break;
|
||||||
case SpvStorageClassCallableDataKHR:
|
case SpvStorageClassCallableDataKHR:
|
||||||
mode = vtn_variable_mode_call_data;
|
mode = vtn_variable_mode_call_data;
|
||||||
@@ -1833,7 +1846,10 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case vtn_variable_mode_image:
|
case vtn_variable_mode_image:
|
||||||
vtn_fail("Cannot create a variable with the Image storage class");
|
if (storage_class == SpvStorageClassImage)
|
||||||
|
vtn_fail("Cannot create a variable with the Image storage class");
|
||||||
|
else
|
||||||
|
vtn_assert(storage_class == SpvStorageClassUniformConstant);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case vtn_variable_mode_phys_ssbo:
|
case vtn_variable_mode_phys_ssbo:
|
||||||
@@ -1866,6 +1882,7 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
|
|||||||
case vtn_variable_mode_constant:
|
case vtn_variable_mode_constant:
|
||||||
case vtn_variable_mode_call_data:
|
case vtn_variable_mode_call_data:
|
||||||
case vtn_variable_mode_call_data_in:
|
case vtn_variable_mode_call_data_in:
|
||||||
|
case vtn_variable_mode_image:
|
||||||
case vtn_variable_mode_ray_payload:
|
case vtn_variable_mode_ray_payload:
|
||||||
case vtn_variable_mode_ray_payload_in:
|
case vtn_variable_mode_ray_payload_in:
|
||||||
case vtn_variable_mode_hit_attrib:
|
case vtn_variable_mode_hit_attrib:
|
||||||
@@ -2006,7 +2023,6 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case vtn_variable_mode_image:
|
|
||||||
case vtn_variable_mode_phys_ssbo:
|
case vtn_variable_mode_phys_ssbo:
|
||||||
case vtn_variable_mode_generic:
|
case vtn_variable_mode_generic:
|
||||||
unreachable("Should have been caught before");
|
unreachable("Should have been caught before");
|
||||||
@@ -2105,6 +2121,7 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (var->mode == vtn_variable_mode_uniform ||
|
if (var->mode == vtn_variable_mode_uniform ||
|
||||||
|
var->mode == vtn_variable_mode_image ||
|
||||||
var->mode == vtn_variable_mode_ssbo) {
|
var->mode == vtn_variable_mode_ssbo) {
|
||||||
/* SSBOs and images are assumed to not alias in the Simple, GLSL and Vulkan memory models */
|
/* SSBOs and images are assumed to not alias in the Simple, GLSL and Vulkan memory models */
|
||||||
var->var->data.access |= b->mem_model != SpvMemoryModelOpenCL ? ACCESS_RESTRICT : 0;
|
var->var->data.access |= b->mem_model != SpvMemoryModelOpenCL ? ACCESS_RESTRICT : 0;
|
||||||
@@ -2123,6 +2140,7 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (var->mode == vtn_variable_mode_uniform ||
|
if (var->mode == vtn_variable_mode_uniform ||
|
||||||
|
var->mode == vtn_variable_mode_image ||
|
||||||
var->mode == vtn_variable_mode_ubo ||
|
var->mode == vtn_variable_mode_ubo ||
|
||||||
var->mode == vtn_variable_mode_ssbo ||
|
var->mode == vtn_variable_mode_ssbo ||
|
||||||
var->mode == vtn_variable_mode_atomic_counter) {
|
var->mode == vtn_variable_mode_atomic_counter) {
|
||||||
|
Reference in New Issue
Block a user