|
|
|
@ -9,6 +9,18 @@ |
|
|
|
#include "shader_recompiler/frontend/ir/value.h"
|
|
|
|
|
|
|
|
namespace Shader::Backend::GLSL { |
|
|
|
namespace { |
|
|
|
constexpr char cas_loop[]{"for(;;){{uint old_value={};uint " |
|
|
|
"cas_result=atomicCompSwap({},old_value,bitfieldInsert({},{},{},{}));" |
|
|
|
"if(cas_result==old_value){{break;}}}}"}; |
|
|
|
|
|
|
|
void SsboWriteCas(EmitContext& ctx, const IR::Value& binding, std::string_view offset_var, |
|
|
|
std::string_view value, std::string_view bit_offset, u32 num_bits) { |
|
|
|
const auto ssbo{fmt::format("{}_ssbo{}[{}>>2]", ctx.stage_name, binding.U32(), offset_var)}; |
|
|
|
ctx.Add(cas_loop, ssbo, ssbo, ssbo, value, bit_offset, num_bits); |
|
|
|
} |
|
|
|
} // Anonymous namespace
|
|
|
|
|
|
|
|
void EmitLoadGlobalU8([[maybe_unused]] EmitContext& ctx) { |
|
|
|
NotImplemented(); |
|
|
|
} |
|
|
|
@ -125,9 +137,8 @@ void EmitWriteStorageU8([[maybe_unused]] EmitContext& ctx, |
|
|
|
[[maybe_unused]] const IR::Value& offset, |
|
|
|
[[maybe_unused]] std::string_view value) { |
|
|
|
const auto offset_var{ctx.var_alloc.Consume(offset)}; |
|
|
|
ctx.Add("{}_ssbo{}[{}>>2]=bitfieldInsert({}_ssbo{}[{}>>2],{},int({}%4)*8,8);", ctx.stage_name, |
|
|
|
binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, value, |
|
|
|
offset_var); |
|
|
|
const auto bit_offset{fmt::format("int({}%4)*8", offset_var)}; |
|
|
|
SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 8); |
|
|
|
} |
|
|
|
|
|
|
|
void EmitWriteStorageS8([[maybe_unused]] EmitContext& ctx, |
|
|
|
@ -135,9 +146,8 @@ void EmitWriteStorageS8([[maybe_unused]] EmitContext& ctx, |
|
|
|
[[maybe_unused]] const IR::Value& offset, |
|
|
|
[[maybe_unused]] std::string_view value) { |
|
|
|
const auto offset_var{ctx.var_alloc.Consume(offset)}; |
|
|
|
ctx.Add("{}_ssbo{}[{}>>2]=bitfieldInsert({}_ssbo{}[{}>>2],{},int({}%4)*8,8);", ctx.stage_name, |
|
|
|
binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, value, |
|
|
|
offset_var); |
|
|
|
const auto bit_offset{fmt::format("int({}%4)*8", offset_var)}; |
|
|
|
SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 8); |
|
|
|
} |
|
|
|
|
|
|
|
void EmitWriteStorageU16([[maybe_unused]] EmitContext& ctx, |
|
|
|
@ -145,9 +155,8 @@ void EmitWriteStorageU16([[maybe_unused]] EmitContext& ctx, |
|
|
|
[[maybe_unused]] const IR::Value& offset, |
|
|
|
[[maybe_unused]] std::string_view value) { |
|
|
|
const auto offset_var{ctx.var_alloc.Consume(offset)}; |
|
|
|
ctx.Add("{}_ssbo{}[{}>>2]=bitfieldInsert({}_ssbo{}[{}>>2],{},int(({}>>1)%2)*16,16);", |
|
|
|
ctx.stage_name, binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, |
|
|
|
value, offset_var); |
|
|
|
const auto bit_offset{fmt::format("int(({}>>1)%2)*16", offset_var)}; |
|
|
|
SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 16); |
|
|
|
} |
|
|
|
|
|
|
|
void EmitWriteStorageS16([[maybe_unused]] EmitContext& ctx, |
|
|
|
@ -155,9 +164,8 @@ void EmitWriteStorageS16([[maybe_unused]] EmitContext& ctx, |
|
|
|
[[maybe_unused]] const IR::Value& offset, |
|
|
|
[[maybe_unused]] std::string_view value) { |
|
|
|
const auto offset_var{ctx.var_alloc.Consume(offset)}; |
|
|
|
ctx.Add("{}_ssbo{}[{}>>2]=bitfieldInsert({}_ssbo{}[{}>>2],{},int(({}>>1)%2)*16,16);", |
|
|
|
ctx.stage_name, binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, |
|
|
|
value, offset_var); |
|
|
|
const auto bit_offset{fmt::format("int(({}>>1)%2)*16", offset_var)}; |
|
|
|
SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 16); |
|
|
|
} |
|
|
|
|
|
|
|
void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, |
|
|
|
|