HLSL: Add option to treat certain SSBO bindings as UAV, even with readonly.

This commit is contained in:
Bryan Bernhart 2020-05-27 13:08:15 -07:00
parent 61cddd6307
commit 17bccc9f7e
2 changed files with 30 additions and 3 deletions

View File

@ -1966,7 +1966,7 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
if (is_uav)
{
Bitset flags = ir.get_buffer_block_flags(var);
bool is_readonly = flags.get(DecorationNonWritable) && !hlsl_options.force_storage_buffer_as_uav;
bool is_readonly = flags.get(DecorationNonWritable) && !is_hlsl_force_storage_buffer_as_uav(var.self);
bool is_coherent = flags.get(DecorationCoherent) && !is_readonly;
bool is_interlocked = interlocked_resources.count(var.self) > 0;
const char *type_name = "ByteAddressBuffer ";
@ -3098,7 +3098,7 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
if (has_decoration(type.self, DecorationBufferBlock))
{
Bitset flags = ir.get_buffer_block_flags(var);
bool is_readonly = flags.get(DecorationNonWritable) && !hlsl_options.force_storage_buffer_as_uav;
bool is_readonly = flags.get(DecorationNonWritable) && !is_hlsl_force_storage_buffer_as_uav(var.self);
space = is_readonly ? 't' : 'u'; // UAV
resource_flags = is_readonly ? HLSL_BINDING_AUTO_SRV_BIT : HLSL_BINDING_AUTO_UAV_BIT;
}
@ -3117,7 +3117,7 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
{
// UAV or SRV depending on readonly flag.
Bitset flags = ir.get_buffer_block_flags(var);
bool is_readonly = flags.get(DecorationNonWritable) && !hlsl_options.force_storage_buffer_as_uav;
bool is_readonly = flags.get(DecorationNonWritable) && !is_hlsl_force_storage_buffer_as_uav(var.self);
space = is_readonly ? 't' : 'u';
resource_flags = is_readonly ? HLSL_BINDING_AUTO_SRV_BIT : HLSL_BINDING_AUTO_UAV_BIT;
}
@ -5545,3 +5545,19 @@ CompilerHLSL::BitcastType CompilerHLSL::get_bitcast_type(uint32_t result_type, u
return BitcastType::TypeNormal;
}
bool CompilerHLSL::is_hlsl_force_storage_buffer_as_uav(ID binding) const
{
if (hlsl_options.force_storage_buffer_as_uav)
{
return true;
};
return (hlsl_options.force_storage_buffer_as_uav_by_id &&
force_uav_buffer_bindings.find(binding) != force_uav_buffer_bindings.end());
}
void CompilerHLSL::set_hlsl_force_storage_buffer_as_uav(ID binding)
{
assert(hlsl_options.force_storage_buffer_as_uav_by_id);
force_uav_buffer_bindings.insert(binding);
}

View File

@ -114,6 +114,10 @@ public:
// By default, a readonly storage buffer will be declared as ByteAddressBuffer (SRV) instead.
bool force_storage_buffer_as_uav = false;
// Similar to force_storage_buffer_as_uav but only forces set bindings.
// Use set_hlsl_force_storage_buffer_as_uav to specify the binding by ID.
bool force_storage_buffer_as_uav_by_id = false;
// Forces any storage image type marked as NonWritable to be considered an SRV instead.
// For this to work with function call parameters, NonWritable must be considered to be part of the type system
// so that NonWritable image arguments are also translated to Texture rather than RWTexture.
@ -186,6 +190,9 @@ public:
void add_hlsl_resource_binding(const HLSLResourceBinding &resource);
bool is_hlsl_resource_binding_used(spv::ExecutionModel model, uint32_t set, uint32_t binding) const;
// Controls which storage buffer bindings will be forced to be declared as UAVs.
void set_hlsl_force_storage_buffer_as_uav(ID binding);
private:
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
std::string image_type_hlsl(const SPIRType &type, uint32_t id);
@ -245,6 +252,8 @@ private:
const char *to_storage_qualifiers_glsl(const SPIRVariable &var) override;
void replace_illegal_names() override;
bool is_hlsl_force_storage_buffer_as_uav(ID binding) const;
Options hlsl_options;
// TODO: Refactor this to be more similar to MSL, maybe have some common system in place?
@ -338,6 +347,8 @@ private:
std::unordered_map<StageSetBinding, std::pair<HLSLResourceBinding, bool>, InternalHasher> resource_bindings;
void remap_hlsl_resource_binding(HLSLBindingFlagBits type, uint32_t &desc_set, uint32_t &binding);
std::unordered_set<ID> force_uav_buffer_bindings;
};
} // namespace SPIRV_CROSS_NAMESPACE