summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2019-01-19 10:23:28 -0600
committerJason Ekstrand <[email protected]>2019-01-26 13:41:50 -0600
commit86e5f76d3d5a5608861813c051af2af4c075e814 (patch)
tree9538236d485eb99aabfa10335bc386a22ca3b42d /src
parentfb282a68bc46a1e28eaedb2670be241401f2b9da (diff)
spirv: Add support for SPV_EXT_physical_storage_buffer
Reviewed-by: Bas Nieuwenhuizen <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/compiler/shader_info.h1
-rw-r--r--src/compiler/spirv/nir_spirv.h1
-rw-r--r--src/compiler/spirv/spirv_to_nir.c12
-rw-r--r--src/compiler/spirv/vtn_private.h1
-rw-r--r--src/compiler/spirv/vtn_variables.c43
5 files changed, 55 insertions, 3 deletions
diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h
index 7af36a66d13..c3dbe764961 100644
--- a/src/compiler/shader_info.h
+++ b/src/compiler/shader_info.h
@@ -51,6 +51,7 @@ struct spirv_supported_capabilities {
bool kernel;
bool min_lod;
bool multiview;
+ bool physical_storage_buffer_address;
bool post_depth_coverage;
bool runtime_descriptor_array;
bool shader_viewport_index_layer;
diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h
index 7e7db373a3a..35b30660e29 100644
--- a/src/compiler/spirv/nir_spirv.h
+++ b/src/compiler/spirv/nir_spirv.h
@@ -67,6 +67,7 @@ struct spirv_to_nir_options {
/* Storage types for various kinds of pointers. */
const struct glsl_type *ubo_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 *shared_ptr_type;
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index 022a90eff7e..9bfe5805919 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -1308,6 +1308,9 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
case SpvStorageClassStorageBuffer:
val->type->type = b->options->ssbo_ptr_type;
break;
+ case SpvStorageClassPhysicalStorageBufferEXT:
+ val->type->type = b->options->phys_ssbo_ptr_type;
+ break;
case SpvStorageClassPushConstant:
val->type->type = b->options->push_const_ptr_type;
break;
@@ -3718,6 +3721,10 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
spv_check_supported(post_depth_coverage, cap);
break;
+ case SpvCapabilityPhysicalStorageBufferAddressesEXT:
+ spv_check_supported(physical_storage_buffer_address, cap);
+ break;
+
default:
vtn_fail("Unhandled capability");
}
@@ -3729,7 +3736,10 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
break;
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 ||
w[2] == SpvMemoryModelGLSL450);
break;
diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h
index 3a5c5f32224..cba2bd665fa 100644
--- a/src/compiler/spirv/vtn_private.h
+++ b/src/compiler/spirv/vtn_private.h
@@ -417,6 +417,7 @@ enum vtn_variable_mode {
vtn_variable_mode_uniform,
vtn_variable_mode_ubo,
vtn_variable_mode_ssbo,
+ vtn_variable_mode_phys_ssbo,
vtn_variable_mode_push_constant,
vtn_variable_mode_workgroup,
vtn_variable_mode_cross_workgroup,
diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c
index 4f7e2a15af9..b1ac0b99784 100644
--- a/src/compiler/spirv/vtn_variables.c
+++ b/src/compiler/spirv/vtn_variables.c
@@ -62,6 +62,7 @@ vtn_pointer_is_external_block(struct vtn_builder *b,
{
return ptr->mode == vtn_variable_mode_ssbo ||
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_workgroup &&
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. */
break;
+ case SpvDecorationRestrictPointerEXT:
+ case SpvDecorationAliasedPointerEXT:
+ /* TODO: We should actually plumb alias information through NIR. */
+ break;
+
default:
vtn_fail("Unhandled decoration");
}
@@ -1682,6 +1688,10 @@ vtn_storage_class_to_mode(struct vtn_builder *b,
mode = vtn_variable_mode_ssbo;
nir_mode = nir_var_mem_ssbo;
break;
+ case SpvStorageClassPhysicalStorageBufferEXT:
+ mode = vtn_variable_mode_phys_ssbo;
+ nir_mode = nir_var_mem_global;
+ break;
case SpvStorageClassUniformConstant:
mode = vtn_variable_mode_uniform;
nir_mode = nir_var_uniform;
@@ -1760,13 +1770,23 @@ vtn_pointer_to_ssa(struct vtn_builder *b, struct vtn_pointer *ptr)
}
} else {
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 num_components =
glsl_get_vector_elements(ptr->ptr_type->type);
/* In this case, we're looking for a block index and not an actual
* 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 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);
ptr->deref = nir_build_deref_cast(&b->nb, ssa, nir_mode,
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
* pointer to somewhere inside the block. We squashed it into a
* 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 {
/* This is a pointer to something internal or a pointer inside a
* 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_type->deref->type,
@@ -1933,6 +1963,12 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
case vtn_variable_mode_push_constant:
b->shader->num_uniforms = vtn_type_block_size(b, type);
break;
+
+ case vtn_variable_mode_phys_ssbo:
+ vtn_fail("Cannot create a variable with the "
+ "PhysicalStorageBufferEXT storage class");
+ break;
+
default:
/* No tallying is needed */
break;
@@ -2087,6 +2123,9 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
case vtn_variable_mode_cross_workgroup:
/* These don't need actual variables. */
break;
+
+ case vtn_variable_mode_phys_ssbo:
+ unreachable("Should have been caught before");
}
if (initializer) {