Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ struct VulkanDevice::State {
bool viewportIndexLayer = false;
bool imageFormatList = false;
bool fmaFloat16 = false;
bool fmaFloat32 = false;
bool primitiveListRestart = false;
bool depthClipControl = false;
bool graphicsPipelineLibrary = false;
Expand Down Expand Up @@ -1711,15 +1712,18 @@ VulkanDevice::VulkanDevice(const PresentationWindow* window, bool compileOnly) :
state->float32DenormPreserve = floatControls.shaderDenormPreserveFloat32 == VK_TRUE && floatControls.denormBehaviorIndependence != VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE && std::getenv("APS5_NO_HW_F32_PRESERVE") == nullptr;
if ((state->float16DenormPreserve || state->float32DenormPreserve) && std::find(state->capabilities.begin(), state->capabilities.end(), static_cast<std::uint32_t>(spv::CapabilityDenormPreserve)) == state->capabilities.end()) state->capabilities.push_back(spv::CapabilityDenormPreserve);
VkPhysicalDeviceShaderFmaFeaturesKHR fmaFeatures{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FMA_FEATURES_KHR};
if (float16Rte && hasExtension(VK_KHR_SHADER_FMA_EXTENSION_NAME)) {
if (hasExtension(VK_KHR_SHADER_FMA_EXTENSION_NAME)) {
VkPhysicalDeviceFeatures2 features{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, &fmaFeatures};
state->InstanceFunction<PFN_vkGetPhysicalDeviceFeatures2>("vkGetPhysicalDeviceFeatures2")(selected, &features);
}
const bool float16Fma = float16Rte && fmaFeatures.shaderFmaFloat16 == VK_TRUE;
const bool float32Fma = hasExtension(VK_KHR_SHADER_FMA_EXTENSION_NAME) && fmaFeatures.shaderFmaFloat32 == VK_TRUE;
fmaFeatures = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FMA_FEATURES_KHR};
fmaFeatures.shaderFmaFloat16 = VK_TRUE;
fmaFeatures.shaderFmaFloat16 = float16Fma ? VK_TRUE : VK_FALSE;
fmaFeatures.shaderFmaFloat32 = float32Fma ? VK_TRUE : VK_FALSE;
state->fmaFloat16 = float16Fma;
if (float16Fma) {
state->fmaFloat32 = float32Fma;
if (float16Fma || float32Fma) {
deviceExtensions.push_back(VK_KHR_SHADER_FMA_EXTENSION_NAME);
state->capabilities.push_back(spv::CapabilityFMAKHR);
state->spirvExtensions.push_back("SPV_KHR_fma");
Expand Down Expand Up @@ -2209,7 +2213,7 @@ VulkanDevice::VulkanDevice(const PresentationWindow* window, bool compileOnly) :
float16Features.pNext = byteFeatures.pNext;
byteFeatures.pNext = &float16Features;
}
if (float16Fma) {
if (float16Fma || float32Fma) {
fmaFeatures.pNext = byteFeatures.pNext;
byteFeatures.pNext = &fmaFeatures;
}
Expand Down Expand Up @@ -4585,6 +4589,7 @@ Graphics::Context VulkanDevice::buildContext() const {
context.demoteToHelperInvocation = state->demoteToHelperInvocation;
context.earlyFragmentSampleMaskTestBeforeSampleCounting = state->earlyFragmentSampleMaskTestBeforeSampleCounting;
context.fmaFloat16 = state->fmaFloat16;
context.fmaFloat32 = state->fmaFloat32;
context.primitiveListRestart = state->primitiveListRestart;
context.imageViewMinLod = state->imageViewMinLod;
context.shaderResourceMinLod = state->shaderResourceMinLod;
Expand Down
1 change: 1 addition & 0 deletions core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ struct Context {
bool demoteToHelperInvocation = false;
bool earlyFragmentSampleMaskTestBeforeSampleCounting = false;
bool fmaFloat16 = false;
bool fmaFloat32 = false;
bool primitiveListRestart = false;
bool imageViewMinLod = false;
bool shaderResourceMinLod = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ bool ShadersWriteMemory(std::span<const CompiledShader> shaders);
bool DeclaresEarlyFragmentTests(const ShaderRecompiler::RecompileResult& program);
void ValidateSampleMask(const Context& context, const State& state, std::span<const CompiledShader> shaders);
// Returns the color attachment locations the pixel shader writes.
std::set<std::uint32_t> ValidateShaders(std::span<const CompiledShader> shaders, const State& state, const VkPhysicalDeviceSubgroupProperties& subgroup, bool fragmentShaderBarycentric, bool descriptorIndexing = false, bool imageInt64Atomics = false, bool geometryShader = false, bool sampleRateShading = false, bool bufferInt64Atomics = false, bool shaderClipDistance = false, bool shaderCullDistance = false, bool viewportIndexLayer = false, bool runtimeDescriptorArray = false, bool demoteToHelperInvocation = false, bool shaderTerminateInvocation = false, bool meshShader = true, bool shaderResourceMinLod = false, bool fmaFloat16 = false);
std::set<std::uint32_t> ValidateShaders(std::span<const CompiledShader> shaders, const State& state, const VkPhysicalDeviceSubgroupProperties& subgroup, bool fragmentShaderBarycentric, bool descriptorIndexing = false, bool imageInt64Atomics = false, bool geometryShader = false, bool sampleRateShading = false, bool bufferInt64Atomics = false, bool shaderClipDistance = false, bool shaderCullDistance = false, bool viewportIndexLayer = false, bool runtimeDescriptorArray = false, bool demoteToHelperInvocation = false, bool shaderTerminateInvocation = false, bool meshShader = true, bool shaderResourceMinLod = false, bool fmaFloat16 = false, bool fmaFloat32 = false);

}

Expand Down
2 changes: 1 addition & 1 deletion core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,7 @@ std::uint32_t CachedFragmentOutputs(const Context& context, std::span<const Comp
}
std::uint32_t outputs = 0;
try {
for (const auto location : ValidateShaders(shaders, state, context.subgroup, context.fragmentShaderBarycentric, context.descriptorIndexing, context.imageInt64Atomics, context.geometryShader, context.sampleRateShading, context.bufferInt64Atomics, context.shaderClipDistance, context.shaderCullDistance, context.viewportIndexLayer, context.runtimeDescriptorArray, context.demoteToHelperInvocation, context.shaderTerminateInvocation, context.meshShader, context.shaderResourceMinLod, context.fmaFloat16)) {
for (const auto location : ValidateShaders(shaders, state, context.subgroup, context.fragmentShaderBarycentric, context.descriptorIndexing, context.imageInt64Atomics, context.geometryShader, context.sampleRateShading, context.bufferInt64Atomics, context.shaderClipDistance, context.shaderCullDistance, context.viewportIndexLayer, context.runtimeDescriptorArray, context.demoteToHelperInvocation, context.shaderTerminateInvocation, context.meshShader, context.shaderResourceMinLod, context.fmaFloat16, context.fmaFloat32)) {
Require(location < 32, "fragment output location exceeds the output mask");
outputs |= 1u << location;
}
Expand Down
10 changes: 5 additions & 5 deletions core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ struct Module {
}
};

Module Inspect(const CompiledShader& compiled, const State& state, const VkPhysicalDeviceSubgroupProperties& subgroup, bool fragmentShaderBarycentric, bool descriptorIndexing, bool imageInt64Atomics, bool geometryShader, bool sampleRateShading, bool bufferInt64Atomics, bool shaderClipDistance, bool shaderCullDistance, bool viewportIndexLayer, bool runtimeDescriptorArray, bool demoteToHelperInvocation, bool shaderTerminateInvocation, bool shaderResourceMinLod, bool fmaFloat16, std::span<const std::uint32_t> primitiveLocations = {}) {
Module Inspect(const CompiledShader& compiled, const State& state, const VkPhysicalDeviceSubgroupProperties& subgroup, bool fragmentShaderBarycentric, bool descriptorIndexing, bool imageInt64Atomics, bool geometryShader, bool sampleRateShading, bool bufferInt64Atomics, bool shaderClipDistance, bool shaderCullDistance, bool viewportIndexLayer, bool runtimeDescriptorArray, bool demoteToHelperInvocation, bool shaderTerminateInvocation, bool shaderResourceMinLod, bool fmaFloat16, bool fmaFloat32, std::span<const std::uint32_t> primitiveLocations = {}) {
using Stage = ShaderRecompiler::ShaderStage;
Require(compiled.program != nullptr, "missing compiled shader");
const auto& shader = *compiled.program;
Expand Down Expand Up @@ -299,7 +299,7 @@ Module Inspect(const CompiledShader& compiled, const State& state, const VkPhysi
capability == spv::CapabilityRoundingModeRTE ||
capability == spv::CapabilityDenormPreserve ||
capability == spv::CapabilityDenormFlushToZero ||
(fmaFloat16 && capability == spv::CapabilityFMAKHR) ||
((fmaFloat16 || fmaFloat32) && capability == spv::CapabilityFMAKHR) ||
capability == spv::CapabilityFloat64 ||
capability == spv::CapabilityStorageBuffer8BitAccess ||
capability == spv::CapabilityPhysicalStorageBufferAddresses ||
Expand Down Expand Up @@ -360,7 +360,7 @@ Module Inspect(const CompiledShader& compiled, const State& state, const VkPhysi
terminateExtension = true;
break;
}
Require(extension == "SPV_KHR_float_controls" || (fmaFloat16 && extension == "SPV_KHR_fma") || (imageInt64Atomics && extension == "SPV_EXT_shader_image_int64") || (viewportIndexLayer && extension == "SPV_EXT_shader_viewport_index_layer") || (fragment && demoteToHelperInvocation && extension == "SPV_EXT_demote_to_helper_invocation") || (mesh && (extension == "SPV_EXT_mesh_shader" || extension == "SPV_KHR_physical_storage_buffer")) || (fragment && !primitiveLocations.empty() && extension == "SPV_EXT_mesh_shader") || (geometry && state.tessellationCapture && extension == "SPV_KHR_physical_storage_buffer") || ((descriptorIndexing || runtimeDescriptorArray) && extension == "SPV_EXT_descriptor_indexing") || (shader.bdaAbiVersion == ShaderRecompiler::BdaAbi::Version && (extension == "SPV_KHR_physical_storage_buffer" || extension == "SPV_KHR_8bit_storage")), "unsupported SPIR-V extension");
Require(extension == "SPV_KHR_float_controls" || ((fmaFloat16 || fmaFloat32) && extension == "SPV_KHR_fma") || (imageInt64Atomics && extension == "SPV_EXT_shader_image_int64") || (viewportIndexLayer && extension == "SPV_EXT_shader_viewport_index_layer") || (fragment && demoteToHelperInvocation && extension == "SPV_EXT_demote_to_helper_invocation") || (mesh && (extension == "SPV_EXT_mesh_shader" || extension == "SPV_KHR_physical_storage_buffer")) || (fragment && !primitiveLocations.empty() && extension == "SPV_EXT_mesh_shader") || (geometry && state.tessellationCapture && extension == "SPV_KHR_physical_storage_buffer") || ((descriptorIndexing || runtimeDescriptorArray) && extension == "SPV_EXT_descriptor_indexing") || (shader.bdaAbiVersion == ShaderRecompiler::BdaAbi::Version && (extension == "SPV_KHR_physical_storage_buffer" || extension == "SPV_KHR_8bit_storage")), "unsupported SPIR-V extension");
break;
}
case spv::OpTerminateInvocation:
Expand Down Expand Up @@ -670,7 +670,7 @@ bool DeclaresEarlyFragmentTests(const ShaderRecompiler::RecompileResult& program
return false;
}

std::set<std::uint32_t> ValidateShaders(std::span<const CompiledShader> shaders, const State& state, const VkPhysicalDeviceSubgroupProperties& subgroup, bool fragmentShaderBarycentric, bool descriptorIndexing, bool imageInt64Atomics, bool geometryShader, bool sampleRateShading, bool bufferInt64Atomics, bool shaderClipDistance, bool shaderCullDistance, bool viewportIndexLayer, bool runtimeDescriptorArray, bool demoteToHelperInvocation, bool shaderTerminateInvocation, bool meshShader, bool shaderResourceMinLod, bool fmaFloat16) {
std::set<std::uint32_t> ValidateShaders(std::span<const CompiledShader> shaders, const State& state, const VkPhysicalDeviceSubgroupProperties& subgroup, bool fragmentShaderBarycentric, bool descriptorIndexing, bool imageInt64Atomics, bool geometryShader, bool sampleRateShading, bool bufferInt64Atomics, bool shaderClipDistance, bool shaderCullDistance, bool viewportIndexLayer, bool runtimeDescriptorArray, bool demoteToHelperInvocation, bool shaderTerminateInvocation, bool meshShader, bool shaderResourceMinLod, bool fmaFloat16, bool fmaFloat32) {
using Stage = ShaderRecompiler::ShaderStage;
const bool tessellation = state.stages.path == ShaderPath::Tessellation;
const bool mesh = state.stages.path == ShaderPath::Geometry;
Expand Down Expand Up @@ -708,7 +708,7 @@ std::set<std::uint32_t> ValidateShaders(std::span<const CompiledShader> shaders,
Require(shaders[i].program != nullptr, "missing compiled shader");
Require(shaders[i].stage == expected, "graphics stage order disagrees");
for (const auto& binding : shaders[i].program->bindings) Require(binding.descriptorSet == ShaderRecompiler::RuntimeAbi::DescriptorSet || (shaders[i].stage == ShaderRecompiler::ShaderStage::Fragment && binding.descriptorSet == ShaderRecompiler::RuntimeAbi::FragmentDescriptorSet), "graphics resource uses a descriptor set other than its stage's");
const auto current = Inspect(shaders[i], state, subgroup, fragmentShaderBarycentric, descriptorIndexing, imageInt64Atomics, geometryShader, sampleRateShading, bufferInt64Atomics, shaderClipDistance, shaderCullDistance, viewportIndexLayer, runtimeDescriptorArray, demoteToHelperInvocation, shaderTerminateInvocation, shaderResourceMinLod, fmaFloat16, primitiveLocations);
const auto current = Inspect(shaders[i], state, subgroup, fragmentShaderBarycentric, descriptorIndexing, imageInt64Atomics, geometryShader, sampleRateShading, bufferInt64Atomics, shaderClipDistance, shaderCullDistance, viewportIndexLayer, runtimeDescriptorArray, demoteToHelperInvocation, shaderTerminateInvocation, shaderResourceMinLod, fmaFloat16, fmaFloat32, primitiveLocations);
if (i != 0) {
for (const auto& [location, signature] : current.inputs) {
const auto output = previous.outputs.find(location);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1943,6 +1943,13 @@ std::uint32_t EmitPackHalf2x16Value(SpirvEmitterState& state, const IrValue& ins
}

std::uint32_t EmitFPFma32(SpirvEmitterState& state, std::uint32_t arg0, std::uint32_t arg1, std::uint32_t arg2) {
if (std::find(state.supportedCapabilities.begin(), state.supportedCapabilities.end(), static_cast<std::uint32_t>(spv::CapabilityFMAKHR)) != state.supportedCapabilities.end()) {
state.module.EmitCapability(spv::CapabilityFMAKHR);
state.module.EmitExtension("SPV_KHR_fma");
const auto result = state.module.AllocateId();
state.module.AddFunction(spv::OpFmaKHR, TypeF32(state), result, arg0, arg1, arg2);
return Exact(state, result);
}
return Exact(state, EmitGlsl<GLSLstd450Fma, IrType::F32>(state, arg0, arg1, arg2));
}

Expand Down
Loading