spirv: Add support for SPV_EXT_physical_storage_buffer
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:
@@ -51,6 +51,7 @@ struct spirv_supported_capabilities {
|
|||||||
bool kernel;
|
bool kernel;
|
||||||
bool min_lod;
|
bool min_lod;
|
||||||
bool multiview;
|
bool multiview;
|
||||||
|
bool physical_storage_buffer_address;
|
||||||
bool post_depth_coverage;
|
bool post_depth_coverage;
|
||||||
bool runtime_descriptor_array;
|
bool runtime_descriptor_array;
|
||||||
bool shader_viewport_index_layer;
|
bool shader_viewport_index_layer;
|
||||||
|
@@ -67,6 +67,7 @@ struct spirv_to_nir_options {
|
|||||||
/* Storage types for various kinds of pointers. */
|
/* Storage types for various kinds of pointers. */
|
||||||
const struct glsl_type *ubo_ptr_type;
|
const struct glsl_type *ubo_ptr_type;
|
||||||
const struct glsl_type *ssbo_ptr_type;
|
const struct glsl_type *ssbo_ptr_type;
|
||||||
|
const struct glsl_type *phys_ssbo_ptr_type;
|
||||||
const struct glsl_type *push_const_ptr_type;
|
const struct glsl_type *push_const_ptr_type;
|
||||||
const struct glsl_type *shared_ptr_type;
|
const struct glsl_type *shared_ptr_type;
|
||||||
|
|
||||||
|
@@ -1308,6 +1308,9 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
|
|||||||
case SpvStorageClassStorageBuffer:
|
case SpvStorageClassStorageBuffer:
|
||||||
val->type->type = b->options->ssbo_ptr_type;
|
val->type->type = b->options->ssbo_ptr_type;
|
||||||
break;
|
break;
|
||||||
|
case SpvStorageClassPhysicalStorageBufferEXT:
|
||||||
|
val->type->type = b->options->phys_ssbo_ptr_type;
|
||||||
|
break;
|
||||||
case SpvStorageClassPushConstant:
|
case SpvStorageClassPushConstant:
|
||||||
val->type->type = b->options->push_const_ptr_type;
|
val->type->type = b->options->push_const_ptr_type;
|
||||||
break;
|
break;
|
||||||
@@ -3718,6 +3721,10 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
|
|||||||
spv_check_supported(post_depth_coverage, cap);
|
spv_check_supported(post_depth_coverage, cap);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SpvCapabilityPhysicalStorageBufferAddressesEXT:
|
||||||
|
spv_check_supported(physical_storage_buffer_address, cap);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
vtn_fail("Unhandled capability");
|
vtn_fail("Unhandled capability");
|
||||||
}
|
}
|
||||||
@@ -3729,7 +3736,10 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SpvOpMemoryModel:
|
case SpvOpMemoryModel:
|
||||||
vtn_assert(w[1] == SpvAddressingModelLogical);
|
vtn_assert(w[1] == SpvAddressingModelLogical ||
|
||||||
|
(b->options &&
|
||||||
|
b->options->caps.physical_storage_buffer_address &&
|
||||||
|
w[1] == SpvAddressingModelPhysicalStorageBuffer64EXT));
|
||||||
vtn_assert(w[2] == SpvMemoryModelSimple ||
|
vtn_assert(w[2] == SpvMemoryModelSimple ||
|
||||||
w[2] == SpvMemoryModelGLSL450);
|
w[2] == SpvMemoryModelGLSL450);
|
||||||
break;
|
break;
|
||||||
|
@@ -417,6 +417,7 @@ enum vtn_variable_mode {
|
|||||||
vtn_variable_mode_uniform,
|
vtn_variable_mode_uniform,
|
||||||
vtn_variable_mode_ubo,
|
vtn_variable_mode_ubo,
|
||||||
vtn_variable_mode_ssbo,
|
vtn_variable_mode_ssbo,
|
||||||
|
vtn_variable_mode_phys_ssbo,
|
||||||
vtn_variable_mode_push_constant,
|
vtn_variable_mode_push_constant,
|
||||||
vtn_variable_mode_workgroup,
|
vtn_variable_mode_workgroup,
|
||||||
vtn_variable_mode_cross_workgroup,
|
vtn_variable_mode_cross_workgroup,
|
||||||
|
@@ -62,6 +62,7 @@ vtn_pointer_is_external_block(struct vtn_builder *b,
|
|||||||
{
|
{
|
||||||
return ptr->mode == vtn_variable_mode_ssbo ||
|
return ptr->mode == vtn_variable_mode_ssbo ||
|
||||||
ptr->mode == vtn_variable_mode_ubo ||
|
ptr->mode == vtn_variable_mode_ubo ||
|
||||||
|
ptr->mode == vtn_variable_mode_phys_ssbo ||
|
||||||
ptr->mode == vtn_variable_mode_push_constant ||
|
ptr->mode == vtn_variable_mode_push_constant ||
|
||||||
(ptr->mode == vtn_variable_mode_workgroup &&
|
(ptr->mode == vtn_variable_mode_workgroup &&
|
||||||
b->options->lower_workgroup_access_to_offsets);
|
b->options->lower_workgroup_access_to_offsets);
|
||||||
@@ -1521,6 +1522,11 @@ apply_var_decoration(struct vtn_builder *b,
|
|||||||
/* HLSL semantic decorations can safely be ignored by the driver. */
|
/* HLSL semantic decorations can safely be ignored by the driver. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SpvDecorationRestrictPointerEXT:
|
||||||
|
case SpvDecorationAliasedPointerEXT:
|
||||||
|
/* TODO: We should actually plumb alias information through NIR. */
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
vtn_fail("Unhandled decoration");
|
vtn_fail("Unhandled decoration");
|
||||||
}
|
}
|
||||||
@@ -1682,6 +1688,10 @@ vtn_storage_class_to_mode(struct vtn_builder *b,
|
|||||||
mode = vtn_variable_mode_ssbo;
|
mode = vtn_variable_mode_ssbo;
|
||||||
nir_mode = nir_var_mem_ssbo;
|
nir_mode = nir_var_mem_ssbo;
|
||||||
break;
|
break;
|
||||||
|
case SpvStorageClassPhysicalStorageBufferEXT:
|
||||||
|
mode = vtn_variable_mode_phys_ssbo;
|
||||||
|
nir_mode = nir_var_mem_global;
|
||||||
|
break;
|
||||||
case SpvStorageClassUniformConstant:
|
case SpvStorageClassUniformConstant:
|
||||||
mode = vtn_variable_mode_uniform;
|
mode = vtn_variable_mode_uniform;
|
||||||
nir_mode = nir_var_uniform;
|
nir_mode = nir_var_uniform;
|
||||||
@@ -1760,13 +1770,23 @@ vtn_pointer_to_ssa(struct vtn_builder *b, struct vtn_pointer *ptr)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (vtn_pointer_is_external_block(b, ptr) &&
|
if (vtn_pointer_is_external_block(b, ptr) &&
|
||||||
vtn_type_contains_block(b, ptr->type)) {
|
vtn_type_contains_block(b, ptr->type) &&
|
||||||
|
ptr->mode != vtn_variable_mode_phys_ssbo) {
|
||||||
const unsigned bit_size = glsl_get_bit_size(ptr->ptr_type->type);
|
const unsigned bit_size = glsl_get_bit_size(ptr->ptr_type->type);
|
||||||
const unsigned num_components =
|
const unsigned num_components =
|
||||||
glsl_get_vector_elements(ptr->ptr_type->type);
|
glsl_get_vector_elements(ptr->ptr_type->type);
|
||||||
|
|
||||||
/* In this case, we're looking for a block index and not an actual
|
/* In this case, we're looking for a block index and not an actual
|
||||||
* deref.
|
* deref.
|
||||||
|
*
|
||||||
|
* For PhysicalStorageBufferEXT pointers, we don't have a block index
|
||||||
|
* at all because we get the pointer directly from the client. This
|
||||||
|
* assumes that there will never be a SSBO binding variable using the
|
||||||
|
* PhysicalStorageBufferEXT storage class. This assumption appears
|
||||||
|
* to be correct according to the Vulkan spec because the table,
|
||||||
|
* "Shader Resource and Storage Class Correspondence," the only the
|
||||||
|
* Uniform storage class with BufferBlock or the StorageBuffer
|
||||||
|
* storage class with Block can be used.
|
||||||
*/
|
*/
|
||||||
if (!ptr->block_index) {
|
if (!ptr->block_index) {
|
||||||
/* If we don't have a block_index then we must be a pointer to the
|
/* If we don't have a block_index then we must be a pointer to the
|
||||||
@@ -1843,7 +1863,8 @@ vtn_pointer_from_ssa(struct vtn_builder *b, nir_ssa_def *ssa,
|
|||||||
assert(ssa->bit_size == 32 && ssa->num_components == 1);
|
assert(ssa->bit_size == 32 && ssa->num_components == 1);
|
||||||
ptr->deref = nir_build_deref_cast(&b->nb, ssa, nir_mode,
|
ptr->deref = nir_build_deref_cast(&b->nb, ssa, nir_mode,
|
||||||
glsl_get_bare_type(deref_type), 0);
|
glsl_get_bare_type(deref_type), 0);
|
||||||
} else if (vtn_type_contains_block(b, ptr->type)) {
|
} else if (vtn_type_contains_block(b, ptr->type) &&
|
||||||
|
ptr->mode != vtn_variable_mode_phys_ssbo) {
|
||||||
/* This is a pointer to somewhere in an array of blocks, not a
|
/* This is a pointer to somewhere in an array of blocks, not a
|
||||||
* pointer to somewhere inside the block. We squashed it into a
|
* pointer to somewhere inside the block. We squashed it into a
|
||||||
* random vector type before so just pick off the first channel and
|
* random vector type before so just pick off the first channel and
|
||||||
@@ -1853,6 +1874,15 @@ vtn_pointer_from_ssa(struct vtn_builder *b, nir_ssa_def *ssa,
|
|||||||
} else {
|
} else {
|
||||||
/* This is a pointer to something internal or a pointer inside a
|
/* This is a pointer to something internal or a pointer inside a
|
||||||
* block. It's just a regular cast.
|
* block. It's just a regular cast.
|
||||||
|
*
|
||||||
|
* For PhysicalStorageBufferEXT pointers, we don't have a block index
|
||||||
|
* at all because we get the pointer directly from the client. This
|
||||||
|
* assumes that there will never be a SSBO binding variable using the
|
||||||
|
* PhysicalStorageBufferEXT storage class. This assumption appears
|
||||||
|
* to be correct according to the Vulkan spec because the table,
|
||||||
|
* "Shader Resource and Storage Class Correspondence," the only the
|
||||||
|
* Uniform storage class with BufferBlock or the StorageBuffer
|
||||||
|
* storage class with Block can be used.
|
||||||
*/
|
*/
|
||||||
ptr->deref = nir_build_deref_cast(&b->nb, ssa, nir_mode,
|
ptr->deref = nir_build_deref_cast(&b->nb, ssa, nir_mode,
|
||||||
ptr_type->deref->type,
|
ptr_type->deref->type,
|
||||||
@@ -1933,6 +1963,12 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
|
|||||||
case vtn_variable_mode_push_constant:
|
case vtn_variable_mode_push_constant:
|
||||||
b->shader->num_uniforms = vtn_type_block_size(b, type);
|
b->shader->num_uniforms = vtn_type_block_size(b, type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case vtn_variable_mode_phys_ssbo:
|
||||||
|
vtn_fail("Cannot create a variable with the "
|
||||||
|
"PhysicalStorageBufferEXT storage class");
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* No tallying is needed */
|
/* No tallying is needed */
|
||||||
break;
|
break;
|
||||||
@@ -2087,6 +2123,9 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
|
|||||||
case vtn_variable_mode_cross_workgroup:
|
case vtn_variable_mode_cross_workgroup:
|
||||||
/* These don't need actual variables. */
|
/* These don't need actual variables. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case vtn_variable_mode_phys_ssbo:
|
||||||
|
unreachable("Should have been caught before");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initializer) {
|
if (initializer) {
|
||||||
|
Reference in New Issue
Block a user