mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02:00
Scope native barriers to shaders with shared execution
This commit is contained in:
@@ -559,6 +559,10 @@ void EmitVoid(ValueEmitContext&) {}
|
|||||||
|
|
||||||
void EmitBarrier(EmitterState& state) {
|
void EmitBarrier(EmitterState& state) {
|
||||||
const auto tessellation = state.program.stage == ShaderType::TessellationControl;
|
const auto tessellation = state.program.stage == ShaderType::TessellationControl;
|
||||||
|
if (!tessellation && ShaderWorkgroupInput(state.program.stage, state.input_info) == nullptr) {
|
||||||
|
// Independent graphics invocations have no native workgroup left to synchronize.
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto memory_scope = tessellation ? spv::ScopeInvocation : spv::ScopeWorkgroup;
|
const auto memory_scope = tessellation ? spv::ScopeInvocation : spv::ScopeWorkgroup;
|
||||||
const auto semantics = tessellation ? spv::MemorySemanticsMaskNone
|
const auto semantics = tessellation ? spv::MemorySemanticsMaskNone
|
||||||
: spv::MemorySemanticsAcquireReleaseMask |
|
: spv::MemorySemanticsAcquireReleaseMask |
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h"
|
#include "graphics/shader/recompiler/backend/spirv/spirvEmitterInstructions.h"
|
||||||
|
|
||||||
namespace Libs::Graphics::ShaderRecompiler::Spirv::Emitter {
|
namespace Libs::Graphics::ShaderRecompiler::Spirv::Emitter {
|
||||||
namespace {
|
namespace {
|
||||||
@@ -127,10 +127,7 @@ void EmitMeshEntryPoint(EmitterState& state) {
|
|||||||
state.builder.AddFunction(spv::OpFunctionCall, TypeVoid(state), state.builder.AllocateId(),
|
state.builder.AddFunction(spv::OpFunctionCall, TypeVoid(state), state.builder.AllocateId(),
|
||||||
state.mesh_guest_func);
|
state.mesh_guest_func);
|
||||||
// All guest waves finish before the uniform Vulkan allocation and output stores.
|
// All guest waves finish before the uniform Vulkan allocation and output stores.
|
||||||
state.builder.AddFunction(spv::OpControlBarrier, ConstantU32(state, spv::ScopeWorkgroup),
|
EmitBarrier(state);
|
||||||
ConstantU32(state, spv::ScopeWorkgroup),
|
|
||||||
ConstantU32(state, spv::MemorySemanticsAcquireReleaseMask |
|
|
||||||
spv::MemorySemanticsWorkgroupMemoryMask));
|
|
||||||
const auto vertices = MeshLoad(state, state.mesh_allocation, spv::StorageClassWorkgroup,
|
const auto vertices = MeshLoad(state, state.mesh_allocation, spv::StorageClassWorkgroup,
|
||||||
TypeU32(state), ConstantU32(state, 0));
|
TypeU32(state), ConstantU32(state, 0));
|
||||||
const auto primitives = MeshLoad(state, state.mesh_allocation, spv::StorageClassWorkgroup,
|
const auto primitives = MeshLoad(state, state.mesh_allocation, spv::StorageClassWorkgroup,
|
||||||
|
|||||||
+10
-34
@@ -1679,45 +1679,14 @@ void TestNewShaderRecompilerSMovB32() {
|
|||||||
CheckSpirvBinaryValidates(result.spirv);
|
CheckSpirvBinaryValidates(result.spirv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestNewShaderRecompilerSoppMarkers() {
|
void TestShaderStageBarriers() {
|
||||||
const uint32_t shader[] = {
|
const uint32_t shader[] = {
|
||||||
EncodeSopp(0x00, 3), // s_nop 3
|
|
||||||
EncodeSopp(0x0c, 0), // s_waitcnt 0
|
|
||||||
EncodeSopp(0x10, 0x0f), // s_sendmsg 15
|
|
||||||
EncodeSopp(0x16, 0x2a), // s_ttracedata 42
|
|
||||||
EncodeSopp(0x20, 1), // s_inst_prefetch 1
|
|
||||||
EncodeSopp(0x0a, 0), // s_barrier
|
EncodeSopp(0x0a, 0), // s_barrier
|
||||||
EncodeSopp(0x01, 0), // s_endpgm
|
EncodeSopp(0x01, 0), // s_endpgm
|
||||||
};
|
};
|
||||||
|
|
||||||
auto options = MakeCompileOptions(ShaderType::Compute);
|
const auto result =
|
||||||
options.dump_ir = true;
|
RecompileForTest(shader, MakeCompileOptions(ShaderType::Compute));
|
||||||
|
|
||||||
auto result = RecompileForTest(shader, options);
|
|
||||||
Check((result.decoded_dump.find("s_nop 0x00000003") != std::string::npos),
|
|
||||||
"new decoder did not decode SOPP s_nop");
|
|
||||||
Check((result.decoded_dump.find("s_waitcnt 0x00000000") != std::string::npos),
|
|
||||||
"new decoder did not decode SOPP s_waitcnt");
|
|
||||||
Check((result.decoded_dump.find("s_sendmsg 0x0000000f") != std::string::npos),
|
|
||||||
"new decoder did not decode SOPP s_sendmsg");
|
|
||||||
Check((result.decoded_dump.find("s_ttracedata 0x0000002a") != std::string::npos),
|
|
||||||
"new decoder did not decode SOPP s_ttracedata");
|
|
||||||
Check((result.decoded_dump.find("s_inst_prefetch 0x00000001") != std::string::npos),
|
|
||||||
"new decoder did not decode SOPP s_inst_prefetch");
|
|
||||||
Check((result.decoded_dump.find("s_barrier") != std::string::npos),
|
|
||||||
"new decoder did not decode SOPP s_barrier");
|
|
||||||
Check((result.ir_dump.find("ControlNop null, 0x00000003") != std::string::npos),
|
|
||||||
"SOPP s_nop did not lower to an IR marker");
|
|
||||||
Check((result.ir_dump.find("Waitcnt null, 0x00000000") != std::string::npos),
|
|
||||||
"SOPP s_waitcnt did not lower to an IR marker");
|
|
||||||
Check((result.ir_dump.find("Sendmsg null, 0x0000000f") != std::string::npos),
|
|
||||||
"SOPP s_sendmsg did not lower to an IR marker");
|
|
||||||
Check((result.ir_dump.find("TtraceData null, 0x0000002a") != std::string::npos),
|
|
||||||
"SOPP s_ttracedata did not lower to an IR marker");
|
|
||||||
Check((result.ir_dump.find("InstPrefetch null, 0x00000001") != std::string::npos),
|
|
||||||
"SOPP s_inst_prefetch did not lower to an IR marker");
|
|
||||||
Check((result.ir_dump.find("Barrier null") != std::string::npos),
|
|
||||||
"SOPP s_barrier did not lower to an IR marker");
|
|
||||||
Check(SpirvContainsOpcode(result.spirv, 224),
|
Check(SpirvContainsOpcode(result.spirv, 224),
|
||||||
"SPIR-V binary does not contain OpControlBarrier");
|
"SPIR-V binary does not contain OpControlBarrier");
|
||||||
Check(
|
Check(
|
||||||
@@ -1725,6 +1694,12 @@ void TestNewShaderRecompilerSoppMarkers() {
|
|||||||
result.spirv.end(),
|
result.spirv.end(),
|
||||||
"SPIR-V barrier does not use workgroup acquire-release memory semantics");
|
"SPIR-V barrier does not use workgroup acquire-release memory semantics");
|
||||||
CheckSpirvBinaryValidates(result.spirv);
|
CheckSpirvBinaryValidates(result.spirv);
|
||||||
|
|
||||||
|
const auto vertex_result =
|
||||||
|
RecompileForTest(shader, MakeCompileOptions(ShaderType::Vertex));
|
||||||
|
CheckSpirvBinaryValidates(vertex_result.spirv);
|
||||||
|
Check(!SpirvContainsOpcode(vertex_result.spirv, 224),
|
||||||
|
"independent vertex invocations retained a workgroup barrier");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestNewShaderRecompilerSopkWaitcntMarkers() {
|
void TestNewShaderRecompilerSopkWaitcntMarkers() {
|
||||||
@@ -13443,6 +13418,7 @@ int main() {
|
|||||||
TestNewShaderRecompilerSpirvSizeBaselines();
|
TestNewShaderRecompilerSpirvSizeBaselines();
|
||||||
TestDemandDrivenSpirvDeclarations();
|
TestDemandDrivenSpirvDeclarations();
|
||||||
TestNewShaderRecompilerSMovB32();
|
TestNewShaderRecompilerSMovB32();
|
||||||
|
TestShaderStageBarriers();
|
||||||
TestNewShaderRecompilerClipDisabledPosition();
|
TestNewShaderRecompilerClipDisabledPosition();
|
||||||
TestNewShaderRecompilerAuxPositionExports();
|
TestNewShaderRecompilerAuxPositionExports();
|
||||||
TestNewShaderRecompilerNativeWideScalarMemoryIr();
|
TestNewShaderRecompilerNativeWideScalarMemoryIr();
|
||||||
|
|||||||
Reference in New Issue
Block a user