Skip to content

Commit

Permalink
Merge pull request #117 from HansKristian-Work/robust-atomic-bda
Browse files Browse the repository at this point in the history
Implement robust BDA UAV counter updates.
  • Loading branch information
HansKristian-Work committed Jun 30, 2022
2 parents 089593d + 07022b7 commit 90f772f
Show file tree
Hide file tree
Showing 12 changed files with 2,770 additions and 2,508 deletions.
12 changes: 3 additions & 9 deletions dxil_converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -456,16 +456,10 @@ spv::Id Converter::Impl::create_bindless_heap_variable(const BindlessInfo &info)
{
if (info.counters)
{
if (!physical_counter_type)
{
spv::Id counter_type_id = get_struct_type({ builder().makeUintType(32) }, "AtomicCounter");
builder().addDecoration(counter_type_id, spv::DecorationBlock);
builder().addMemberDecoration(counter_type_id, 0, spv::DecorationOffset, 0);
physical_counter_type =
builder().makePointer(spv::StorageClassPhysicalStorageBuffer, counter_type_id);
}
spv::Id uint_type = builder().makeUintType(32);
spv::Id uvec2_type = builder().makeVectorType(uint_type, 2);

spv::Id runtime_array_type_id = builder().makeRuntimeArray(physical_counter_type);
spv::Id runtime_array_type_id = builder().makeRuntimeArray(uvec2_type);
builder().addDecoration(runtime_array_type_id, spv::DecorationArrayStride, sizeof(uint64_t));

type_id = get_struct_type({ runtime_array_type_id }, "AtomicCounters");
Expand Down
1 change: 0 additions & 1 deletion opcodes/converter_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,6 @@ struct Converter::Impl
spv::Id cmpxchg_type = 0;
spv::Id texture_sample_pos_lut_id = 0;
spv::Id rasterizer_sample_count_id = 0;
spv::Id physical_counter_type = 0;
spv::Id shader_record_buffer_id = 0;
Vector<spv::Id> shader_record_buffer_types;

Expand Down
49 changes: 25 additions & 24 deletions opcodes/dxil/dxil_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "dxil_sampling.hpp"
#include "logging.hpp"
#include "opcodes/converter_impl.hpp"
#include "spirv_module.hpp"

namespace dxil_spv
{
Expand Down Expand Up @@ -1355,46 +1356,46 @@ bool emit_buffer_update_counter_instruction(Converter::Impl &impl, const llvm::C
const auto &meta = impl.handle_to_resource_meta[image_id];
int direction = llvm::cast<llvm::ConstantInt>(instruction->getOperand(2))->getUniqueInteger().getSExtValue();

Operation *counter_ptr_op;

if (meta.counter_is_physical_pointer)
{
counter_ptr_op = impl.allocate(
spv::OpAccessChain, builder.makePointer(spv::StorageClassPhysicalStorageBuffer, builder.makeUintType(32)));
counter_ptr_op->add_id(meta.counter_var_id);
counter_ptr_op->add_id(builder.makeUintConstant(0));
spv::Id func_id = impl.spirv_module.get_helper_call_id(HelperCall::RobustAtomicCounter);
auto *op = impl.allocate(spv::OpFunctionCall, instruction);
op->add_id(func_id);
op->add_id(meta.counter_var_id);
op->add_id(builder.makeUintConstant(direction));
op->add_id(builder.makeUintConstant(direction < 0 ? -1u : 0u));
impl.add(op);
}
else
{
counter_ptr_op = impl.allocate(spv::OpImageTexelPointer,
builder.makePointer(spv::StorageClassImage, builder.makeUintType(32)));
auto *counter_ptr_op = impl.allocate(spv::OpImageTexelPointer,
builder.makePointer(spv::StorageClassImage, builder.makeUintType(32)));

counter_ptr_op->add_id(meta.counter_var_id);
counter_ptr_op->add_id(builder.makeUintConstant(0));
counter_ptr_op->add_id(builder.makeUintConstant(0));

if (meta.non_uniform)
builder.addDecoration(counter_ptr_op->id, spv::DecorationNonUniformEXT);
}
impl.add(counter_ptr_op);

impl.add(counter_ptr_op);

Operation *op = impl.allocate(spv::OpAtomicIAdd, instruction);

op->add_id(counter_ptr_op->id);
op->add_id(builder.makeUintConstant(spv::ScopeDevice));
op->add_id(builder.makeUintConstant(0));
op->add_id(builder.makeUintConstant(direction));
auto *op = impl.allocate(spv::OpAtomicIAdd, instruction);

impl.add(op);
op->add_id(counter_ptr_op->id);
op->add_id(builder.makeUintConstant(spv::ScopeDevice));
op->add_id(builder.makeUintConstant(0));
op->add_id(builder.makeUintConstant(direction));
impl.add(op);

if (direction < 0)
{
spv::Id result_id = op->id;
op = impl.allocate(spv::OpISub, builder.makeUintType(32));
op->add_ids({ result_id, builder.makeUintConstant(1) });
impl.add(op);
impl.rewrite_value(instruction, op->id);

if (direction < 0)
{
op = impl.allocate(spv::OpISub, builder.makeUintType(32));
op->add_ids({ result_id, builder.makeUintConstant(1) });
impl.add(op);
impl.rewrite_value(instruction, op->id);
}
}

return true;
Expand Down
7 changes: 5 additions & 2 deletions opcodes/dxil/dxil_resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,8 +626,11 @@ static spv::Id build_load_physical_pointer(Converter::Impl &impl, const Converte
{
auto &builder = impl.builder();

spv::Id uint_type = builder.makeUintType(32);
spv::Id uvec2_type = builder.makeVectorType(uint_type, 2);

auto *chain_op = impl.allocate(spv::OpAccessChain,
builder.makePointer(spv::StorageClassStorageBuffer, impl.physical_counter_type));
builder.makePointer(spv::StorageClassStorageBuffer, uvec2_type));
chain_op->add_id(counter.var_id);
chain_op->add_id(builder.makeUintConstant(0));

Expand All @@ -638,7 +641,7 @@ static spv::Id build_load_physical_pointer(Converter::Impl &impl, const Converte
chain_op->add_id(offset_id);
impl.add(chain_op);

auto *load_op = impl.allocate(spv::OpLoad, impl.physical_counter_type);
auto *load_op = impl.allocate(spv::OpLoad, uvec2_type);
load_op->add_id(chain_op->id);
impl.add(load_op);

Expand Down

0 comments on commit 90f772f

Please sign in to comment.