parent
34fdb6471d
commit
0a0b0a73d8
|
@ -433,8 +433,7 @@ void EmitContext::DefineHelperFunctions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EmitContext::DefineGlobalMemoryFunctions() {
|
std::string EmitContext::DefineGlobalMemoryFunctions() {
|
||||||
const auto define_body{[&](std::string& func, size_t index, u32 num_components,
|
const auto define_body{[&](std::string& func, size_t index, std::string_view return_statement) {
|
||||||
std::string_view return_statement) {
|
|
||||||
const auto& ssbo{info.storage_buffers_descriptors[index]};
|
const auto& ssbo{info.storage_buffers_descriptors[index]};
|
||||||
const u32 size_cbuf_offset{ssbo.cbuf_offset + 8};
|
const u32 size_cbuf_offset{ssbo.cbuf_offset + 8};
|
||||||
const auto ssbo_addr{fmt::format("ssbo_addr{}", index)};
|
const auto ssbo_addr{fmt::format("ssbo_addr{}", index)};
|
||||||
|
@ -458,42 +457,31 @@ std::string EmitContext::DefineGlobalMemoryFunctions() {
|
||||||
func += comparison;
|
func += comparison;
|
||||||
|
|
||||||
const auto ssbo_name{fmt::format("{}_ssbo{}", stage_name, index)};
|
const auto ssbo_name{fmt::format("{}_ssbo{}", stage_name, index)};
|
||||||
switch (num_components) {
|
|
||||||
case 1:
|
|
||||||
func += fmt::format(return_statement, ssbo_name, ssbo_addr);
|
func += fmt::format(return_statement, ssbo_name, ssbo_addr);
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
func += fmt::format(return_statement, ssbo_name, ssbo_addr, ssbo_name, ssbo_addr);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
func += fmt::format(return_statement, ssbo_name, ssbo_addr, ssbo_name, ssbo_addr,
|
|
||||||
ssbo_name, ssbo_addr, ssbo_name, ssbo_addr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}};
|
}};
|
||||||
std::string write_func{"void WriteGlobal32(uint64_t addr,uint data){\n"};
|
std::string write_func{"void WriteGlobal32(uint64_t addr,uint data){"};
|
||||||
std::string write_func_64{"void WriteGlobal64(uint64_t addr,uvec2 data){\n"};
|
std::string write_func_64{"void WriteGlobal64(uint64_t addr,uvec2 data){"};
|
||||||
std::string write_func_128{"void WriteGlobal128(uint64_t addr,uvec4 data){\n"};
|
std::string write_func_128{"void WriteGlobal128(uint64_t addr,uvec4 data){"};
|
||||||
std::string load_func{"uint LoadGlobal32(uint64_t addr){\n"};
|
std::string load_func{"uint LoadGlobal32(uint64_t addr){"};
|
||||||
std::string load_func_64{"uvec2 LoadGlobal64(uint64_t addr){\n"};
|
std::string load_func_64{"uvec2 LoadGlobal64(uint64_t addr){"};
|
||||||
std::string load_func_128{"uvec4 LoadGlobal128(uint64_t addr){\n"};
|
std::string load_func_128{"uvec4 LoadGlobal128(uint64_t addr){"};
|
||||||
const size_t num_buffers{info.storage_buffers_descriptors.size()};
|
const size_t num_buffers{info.storage_buffers_descriptors.size()};
|
||||||
for (size_t index = 0; index < num_buffers; ++index) {
|
for (size_t index = 0; index < num_buffers; ++index) {
|
||||||
if (!info.nvn_buffer_used[index]) {
|
if (!info.nvn_buffer_used[index]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
define_body(write_func, index, 1, "{}[uint(addr-{})>>2]=data;return;}}");
|
define_body(write_func, index, "{0}[uint(addr-{1})>>2]=data;return;}}");
|
||||||
define_body(write_func_64, index, 2,
|
define_body(write_func_64, index,
|
||||||
"{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;return;}}");
|
"{0}[uint(addr-{1})>>2]=data.x;{0}[uint(addr-{1}+4)>>2]=data.y;return;}}");
|
||||||
define_body(write_func_128, index, 4,
|
define_body(write_func_128, index,
|
||||||
"{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;{}[uint("
|
"{0}[uint(addr-{1})>>2]=data.x;{0}[uint(addr-{1}+4)>>2]=data.y;{0}[uint("
|
||||||
"addr-{}+8)>>2]=data.z;{}[uint(addr-{}+12)>>2]=data.w;return;}}");
|
"addr-{1}+8)>>2]=data.z;{0}[uint(addr-{1}+12)>>2]=data.w;return;}}");
|
||||||
define_body(load_func, index, 1, "return {}[uint(addr-{})>>2];}}");
|
define_body(load_func, index, "return {0}[uint(addr-{1})>>2];}}");
|
||||||
define_body(load_func_64, index, 2,
|
define_body(load_func_64, index,
|
||||||
"return uvec2({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2]);}}");
|
"return uvec2({0}[uint(addr-{1})>>2],{0}[uint(addr-{1}+4)>>2]);}}");
|
||||||
define_body(load_func_128, index, 4,
|
define_body(load_func_128, index,
|
||||||
"return uvec4({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2],{}["
|
"return uvec4({0}[uint(addr-{1})>>2],{0}[uint(addr-{1}+4)>>2],{0}["
|
||||||
"uint(addr-{}+8)>>2],{}[uint(addr-{}+12)>>2]);}}");
|
"uint(addr-{1}+8)>>2],{0}[uint(addr-{1}+12)>>2]);}}");
|
||||||
}
|
}
|
||||||
write_func += "}";
|
write_func += "}";
|
||||||
write_func_64 += "}";
|
write_func_64 += "}";
|
||||||
|
|
|
@ -11,11 +11,8 @@
|
||||||
|
|
||||||
namespace Shader::Backend::GLSL {
|
namespace Shader::Backend::GLSL {
|
||||||
namespace {
|
namespace {
|
||||||
constexpr const char cas_loop[]{R"(for (;;){{
|
constexpr char cas_loop[]{
|
||||||
uint old_value={};
|
"for (;;){{uint old={};{}=atomicCompSwap({},old,{}({},{}));if({}==old){{break;}}}}"};
|
||||||
{}=atomicCompSwap({},old_value,{}({},{}));
|
|
||||||
if ({}==old_value){{break;}}
|
|
||||||
}})"};
|
|
||||||
|
|
||||||
void SharedCasFunction(EmitContext& ctx, IR::Inst& inst, std::string_view offset,
|
void SharedCasFunction(EmitContext& ctx, IR::Inst& inst, std::string_view offset,
|
||||||
std::string_view value, std::string_view function) {
|
std::string_view value, std::string_view function) {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
namespace Shader::Backend::GLSL {
|
namespace Shader::Backend::GLSL {
|
||||||
namespace {
|
namespace {
|
||||||
static constexpr std::string_view SWIZZLE{"xyzw"};
|
constexpr char SWIZZLE[]{"xyzw"};
|
||||||
|
|
||||||
u32 CbufIndex(u32 offset) {
|
u32 CbufIndex(u32 offset) {
|
||||||
return (offset / 4) % 4;
|
return (offset / 4) % 4;
|
||||||
|
|
|
@ -9,6 +9,18 @@
|
||||||
#include "shader_recompiler/frontend/ir/value.h"
|
#include "shader_recompiler/frontend/ir/value.h"
|
||||||
|
|
||||||
namespace Shader::Backend::GLSL {
|
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) {
|
void EmitLoadGlobalU8([[maybe_unused]] EmitContext& ctx) {
|
||||||
NotImplemented();
|
NotImplemented();
|
||||||
}
|
}
|
||||||
|
@ -125,9 +137,8 @@ void EmitWriteStorageU8([[maybe_unused]] EmitContext& ctx,
|
||||||
[[maybe_unused]] const IR::Value& offset,
|
[[maybe_unused]] const IR::Value& offset,
|
||||||
[[maybe_unused]] std::string_view value) {
|
[[maybe_unused]] std::string_view value) {
|
||||||
const auto offset_var{ctx.var_alloc.Consume(offset)};
|
const auto offset_var{ctx.var_alloc.Consume(offset)};
|
||||||
ctx.Add("{}_ssbo{}[{}>>2]=bitfieldInsert({}_ssbo{}[{}>>2],{},int({}%4)*8,8);", ctx.stage_name,
|
const auto bit_offset{fmt::format("int({}%4)*8", offset_var)};
|
||||||
binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, value,
|
SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 8);
|
||||||
offset_var);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitWriteStorageS8([[maybe_unused]] EmitContext& ctx,
|
void EmitWriteStorageS8([[maybe_unused]] EmitContext& ctx,
|
||||||
|
@ -135,9 +146,8 @@ void EmitWriteStorageS8([[maybe_unused]] EmitContext& ctx,
|
||||||
[[maybe_unused]] const IR::Value& offset,
|
[[maybe_unused]] const IR::Value& offset,
|
||||||
[[maybe_unused]] std::string_view value) {
|
[[maybe_unused]] std::string_view value) {
|
||||||
const auto offset_var{ctx.var_alloc.Consume(offset)};
|
const auto offset_var{ctx.var_alloc.Consume(offset)};
|
||||||
ctx.Add("{}_ssbo{}[{}>>2]=bitfieldInsert({}_ssbo{}[{}>>2],{},int({}%4)*8,8);", ctx.stage_name,
|
const auto bit_offset{fmt::format("int({}%4)*8", offset_var)};
|
||||||
binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, value,
|
SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 8);
|
||||||
offset_var);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitWriteStorageU16([[maybe_unused]] EmitContext& ctx,
|
void EmitWriteStorageU16([[maybe_unused]] EmitContext& ctx,
|
||||||
|
@ -145,9 +155,8 @@ void EmitWriteStorageU16([[maybe_unused]] EmitContext& ctx,
|
||||||
[[maybe_unused]] const IR::Value& offset,
|
[[maybe_unused]] const IR::Value& offset,
|
||||||
[[maybe_unused]] std::string_view value) {
|
[[maybe_unused]] std::string_view value) {
|
||||||
const auto offset_var{ctx.var_alloc.Consume(offset)};
|
const auto offset_var{ctx.var_alloc.Consume(offset)};
|
||||||
ctx.Add("{}_ssbo{}[{}>>2]=bitfieldInsert({}_ssbo{}[{}>>2],{},int(({}>>1)%2)*16,16);",
|
const auto bit_offset{fmt::format("int(({}>>1)%2)*16", offset_var)};
|
||||||
ctx.stage_name, binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var,
|
SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 16);
|
||||||
value, offset_var);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitWriteStorageS16([[maybe_unused]] EmitContext& ctx,
|
void EmitWriteStorageS16([[maybe_unused]] EmitContext& ctx,
|
||||||
|
@ -155,9 +164,8 @@ void EmitWriteStorageS16([[maybe_unused]] EmitContext& ctx,
|
||||||
[[maybe_unused]] const IR::Value& offset,
|
[[maybe_unused]] const IR::Value& offset,
|
||||||
[[maybe_unused]] std::string_view value) {
|
[[maybe_unused]] std::string_view value) {
|
||||||
const auto offset_var{ctx.var_alloc.Consume(offset)};
|
const auto offset_var{ctx.var_alloc.Consume(offset)};
|
||||||
ctx.Add("{}_ssbo{}[{}>>2]=bitfieldInsert({}_ssbo{}[{}>>2],{},int(({}>>1)%2)*16,16);",
|
const auto bit_offset{fmt::format("int(({}>>1)%2)*16", offset_var)};
|
||||||
ctx.stage_name, binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var,
|
SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 16);
|
||||||
value, offset_var);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset,
|
void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset,
|
||||||
|
|
Reference in New Issue