diff options
| author | 2021-04-11 02:37:03 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:27 -0400 | |
| commit | ab543f18213133b3076b81f30df386d5cb470e49 (patch) | |
| tree | 7d34e2e5e168225a4e1d5a6750eae31174d2a530 | |
| parent | shader: Move LaneId to the warp emission file and fix AMD (diff) | |
| download | yuzu-ab543f18213133b3076b81f30df386d5cb470e49.tar.gz yuzu-ab543f18213133b3076b81f30df386d5cb470e49.tar.xz yuzu-ab543f18213133b3076b81f30df386d5cb470e49.zip | |
spirv: Guard against typeless image reads on unsupported devices
Diffstat (limited to '')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_spirv.cpp | 4 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_spirv_image.cpp | 4 | ||||
| -rw-r--r-- | src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | 7 | ||||
| -rw-r--r-- | src/shader_recompiler/profile.h | 1 | ||||
| -rw-r--r-- | src/shader_recompiler/shader_info.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 1 |
6 files changed, 17 insertions, 1 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 63ed92a5d..db7b3f1b2 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp | |||
| @@ -238,11 +238,13 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct | |||
| 238 | ctx.AddCapability(spv::Capability::SubgroupVoteKHR); | 238 | ctx.AddCapability(spv::Capability::SubgroupVoteKHR); |
| 239 | } | 239 | } |
| 240 | } | 240 | } |
| 241 | if (info.uses_typeless_image_reads && profile.support_typeless_image_loads) { | ||
| 242 | ctx.AddCapability(spv::Capability::StorageImageReadWithoutFormat); | ||
| 243 | } | ||
| 241 | // TODO: Track this usage | 244 | // TODO: Track this usage |
| 242 | ctx.AddCapability(spv::Capability::ImageGatherExtended); | 245 | ctx.AddCapability(spv::Capability::ImageGatherExtended); |
| 243 | ctx.AddCapability(spv::Capability::ImageQuery); | 246 | ctx.AddCapability(spv::Capability::ImageQuery); |
| 244 | ctx.AddCapability(spv::Capability::SampledBuffer); | 247 | ctx.AddCapability(spv::Capability::SampledBuffer); |
| 245 | ctx.AddCapability(spv::Capability::StorageImageReadWithoutFormat); | ||
| 246 | } | 248 | } |
| 247 | } // Anonymous namespace | 249 | } // Anonymous namespace |
| 248 | 250 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index dd261fd47..17266ce77 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp | |||
| @@ -388,6 +388,10 @@ Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, I | |||
| 388 | 388 | ||
| 389 | Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords) { | 389 | Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords) { |
| 390 | const auto info{inst->Flags<IR::TextureInstInfo>()}; | 390 | const auto info{inst->Flags<IR::TextureInstInfo>()}; |
| 391 | if (info.image_format == ImageFormat::Typeless && !ctx.profile.support_typeless_image_loads) { | ||
| 392 | // LOG_WARNING(..., "Typeless image read not supported by host"); | ||
| 393 | return ctx.ConstantNull(ctx.U32[4]); | ||
| 394 | } | ||
| 391 | return Emit(&EmitContext::OpImageSparseRead, &EmitContext::OpImageRead, ctx, inst, ctx.U32[4], | 395 | return Emit(&EmitContext::OpImageSparseRead, &EmitContext::OpImageRead, ctx, inst, ctx.U32[4], |
| 392 | Image(ctx, index, info), coords, std::nullopt, std::span<const Id>{}); | 396 | Image(ctx, index, info), coords, std::nullopt, std::span<const Id>{}); |
| 393 | } | 397 | } |
diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp index 8c63c9876..9ef8688c9 100644 --- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp +++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | |||
| @@ -421,6 +421,13 @@ void VisitUsages(Info& info, IR::Inst& inst) { | |||
| 421 | inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp) != nullptr; | 421 | inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp) != nullptr; |
| 422 | break; | 422 | break; |
| 423 | } | 423 | } |
| 424 | case IR::Opcode::ImageRead: { | ||
| 425 | const auto flags{inst.Flags<IR::TextureInstInfo>()}; | ||
| 426 | info.uses_typeless_image_reads |= flags.image_format == ImageFormat::Typeless; | ||
| 427 | info.uses_sparse_residency |= | ||
| 428 | inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp) != nullptr; | ||
| 429 | break; | ||
| 430 | } | ||
| 424 | case IR::Opcode::SubgroupEqMask: | 431 | case IR::Opcode::SubgroupEqMask: |
| 425 | case IR::Opcode::SubgroupLtMask: | 432 | case IR::Opcode::SubgroupLtMask: |
| 426 | case IR::Opcode::SubgroupLeMask: | 433 | case IR::Opcode::SubgroupLeMask: |
diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h index e13cb948a..f0d68d516 100644 --- a/src/shader_recompiler/profile.h +++ b/src/shader_recompiler/profile.h | |||
| @@ -36,6 +36,7 @@ struct Profile { | |||
| 36 | bool support_explicit_workgroup_layout{}; | 36 | bool support_explicit_workgroup_layout{}; |
| 37 | bool support_vote{}; | 37 | bool support_vote{}; |
| 38 | bool support_viewport_index_layer_non_geometry{}; | 38 | bool support_viewport_index_layer_non_geometry{}; |
| 39 | bool support_typeless_image_loads{}; | ||
| 39 | bool warp_size_potentially_larger_than_guest{}; | 40 | bool warp_size_potentially_larger_than_guest{}; |
| 40 | 41 | ||
| 41 | // FClamp is broken and OpFMax + OpFMin should be used instead | 42 | // FClamp is broken and OpFMax + OpFMin should be used instead |
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h index 253b6eacf..3fbe99268 100644 --- a/src/shader_recompiler/shader_info.h +++ b/src/shader_recompiler/shader_info.h | |||
| @@ -127,6 +127,7 @@ struct Info { | |||
| 127 | bool uses_subgroup_vote{}; | 127 | bool uses_subgroup_vote{}; |
| 128 | bool uses_subgroup_mask{}; | 128 | bool uses_subgroup_mask{}; |
| 129 | bool uses_fswzadd{}; | 129 | bool uses_fswzadd{}; |
| 130 | bool uses_typeless_image_reads{}; | ||
| 130 | 131 | ||
| 131 | IR::Type used_constant_buffer_types{}; | 132 | IR::Type used_constant_buffer_types{}; |
| 132 | 133 | ||
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index fcebb8f6e..25dbefd5c 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -635,6 +635,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::GPU& gpu_, | |||
| 635 | .support_vote = true, | 635 | .support_vote = true, |
| 636 | .support_viewport_index_layer_non_geometry = | 636 | .support_viewport_index_layer_non_geometry = |
| 637 | device.IsExtShaderViewportIndexLayerSupported(), | 637 | device.IsExtShaderViewportIndexLayerSupported(), |
| 638 | .support_typeless_image_loads = device.IsFormatlessImageLoadSupported(), | ||
| 638 | .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), | 639 | .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), |
| 639 | .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR, | 640 | .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR, |
| 640 | .generic_input_types{}, | 641 | .generic_input_types{}, |