mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-08-03 11:23:49 +00:00
61 lines
2.5 KiB
C++
61 lines
2.5 KiB
C++
#include "graphics/host_gpu/renderer/pipeline/shaderSubgroup.h"
|
|
|
|
#include "graphics/shader/recompiler/emitter/SpirvEmitter.h"
|
|
|
|
namespace Libs::Graphics {
|
|
|
|
ShaderSubgroupCapabilities::ShaderSubgroupCapabilities(const GraphicContext& graphics)
|
|
: subgroup_size(graphics.subgroup_size), min_subgroup_size(graphics.min_subgroup_size),
|
|
max_subgroup_size(graphics.max_subgroup_size),
|
|
required_subgroup_size_stages(graphics.required_subgroup_size_stages),
|
|
subgroup_size_control_enabled(graphics.subgroup_size_control_enabled) {}
|
|
|
|
ShaderLaneMaskMode SelectGraphicsLaneMaskMode(uint32_t guest_wave_size) {
|
|
// A 64-wide guest wave can't assume the host GPU's lane layout matches
|
|
// GCN's. AMD RDNA also reports a 64-wide subgroup but uses a different
|
|
// lane/pixel layout, which corrupted rendering under "native wave" mode.
|
|
// Per-invocation emulation works regardless of the host's lane layout.
|
|
if (guest_wave_size == 64u) {
|
|
return ShaderLaneMaskMode::PerInvocation;
|
|
}
|
|
return ShaderLaneMaskMode::NativeWave;
|
|
}
|
|
|
|
ShaderSubgroupConfiguration ConfigureShaderSubgroup(const ShaderSubgroupCapabilities& capabilities,
|
|
vk::ShaderStageFlagBits stage,
|
|
const ShaderRecompiler::IR::Program& program) {
|
|
const auto guest_wave_size = program.wave_size;
|
|
if (guest_wave_size != 32u && guest_wave_size != 64u) {
|
|
return {};
|
|
}
|
|
if (stage != vk::ShaderStageFlagBits::eCompute) {
|
|
const auto expected = SelectGraphicsLaneMaskMode(guest_wave_size);
|
|
if (program.lane_mask_mode != expected || (capabilities.subgroup_size != guest_wave_size &&
|
|
expected != ShaderLaneMaskMode::PerInvocation)) {
|
|
return {};
|
|
}
|
|
return {expected == ShaderLaneMaskMode::NativeWave
|
|
? ShaderSubgroupMode::Natural
|
|
: ShaderSubgroupMode::PerInvocationGraphics,
|
|
0};
|
|
}
|
|
if (program.lane_mask_mode != ShaderLaneMaskMode::NativeWave) {
|
|
return {};
|
|
}
|
|
if (capabilities.subgroup_size == guest_wave_size) {
|
|
return {ShaderSubgroupMode::Natural, 0};
|
|
}
|
|
if (capabilities.subgroup_size_control_enabled &&
|
|
(capabilities.required_subgroup_size_stages & stage) &&
|
|
guest_wave_size >= capabilities.min_subgroup_size &&
|
|
guest_wave_size <= capabilities.max_subgroup_size) {
|
|
return {ShaderSubgroupMode::Controlled, guest_wave_size};
|
|
}
|
|
if (!ShaderRecompiler::Spirv::ProgramRequiresExactSubgroupSize(program)) {
|
|
return {ShaderSubgroupMode::FlattenedMasks, 0};
|
|
}
|
|
return {};
|
|
}
|
|
|
|
} // namespace Libs::Graphics
|