diff options
Diffstat (limited to 'src')
5 files changed, 61 insertions, 57 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp index 2a12feddc..dde0f6e9c 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp | |||
| @@ -7,15 +7,12 @@ | |||
| 7 | 7 | ||
| 8 | namespace Shader::Backend::SPIRV { | 8 | namespace Shader::Backend::SPIRV { |
| 9 | namespace { | 9 | namespace { |
| 10 | Id Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) { | 10 | Id Image(EmitContext& ctx, IR::TextureInstInfo info) { |
| 11 | if (!index.IsImmediate()) { | ||
| 12 | throw NotImplementedException("Indirect image indexing"); | ||
| 13 | } | ||
| 14 | if (info.type == TextureType::Buffer) { | 11 | if (info.type == TextureType::Buffer) { |
| 15 | const ImageBufferDefinition def{ctx.image_buffers.at(index.U32())}; | 12 | const ImageBufferDefinition def{ctx.image_buffers.at(info.descriptor_index)}; |
| 16 | return def.id; | 13 | return def.id; |
| 17 | } else { | 14 | } else { |
| 18 | const ImageDefinition def{ctx.images.at(index.U32())}; | 15 | const ImageDefinition def{ctx.images.at(info.descriptor_index)}; |
| 19 | return def.id; | 16 | return def.id; |
| 20 | } | 17 | } |
| 21 | } | 18 | } |
| @@ -28,8 +25,12 @@ std::pair<Id, Id> AtomicArgs(EmitContext& ctx) { | |||
| 28 | 25 | ||
| 29 | Id ImageAtomicU32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id value, | 26 | Id ImageAtomicU32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id value, |
| 30 | Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) { | 27 | Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) { |
| 28 | if (!index.IsImmediate() || index.U32() != 0) { | ||
| 29 | // TODO: handle layers | ||
| 30 | throw NotImplementedException("Image indexing"); | ||
| 31 | } | ||
| 31 | const auto info{inst->Flags<IR::TextureInstInfo>()}; | 32 | const auto info{inst->Flags<IR::TextureInstInfo>()}; |
| 32 | const Id image{Image(ctx, index, info)}; | 33 | const Id image{Image(ctx, info)}; |
| 33 | const Id pointer{ctx.OpImageTexelPointer(ctx.image_u32, image, coords, ctx.Const(0U))}; | 34 | const Id pointer{ctx.OpImageTexelPointer(ctx.image_u32, image, coords, ctx.Const(0U))}; |
| 34 | const auto [scope, semantics]{AtomicArgs(ctx)}; | 35 | const auto [scope, semantics]{AtomicArgs(ctx)}; |
| 35 | return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics, value); | 36 | return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics, value); |
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index 72f69b7aa..57df6fc34 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp | |||
| @@ -74,11 +74,6 @@ spv::ImageFormat GetImageFormat(ImageFormat format) { | |||
| 74 | throw InvalidArgument("Invalid image format {}", format); | 74 | throw InvalidArgument("Invalid image format {}", format); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | spv::ImageFormat GetImageFormatForBuffer(ImageFormat format) { | ||
| 78 | const auto spv_format = GetImageFormat(format); | ||
| 79 | return spv_format == spv::ImageFormat::Unknown ? spv::ImageFormat::R32ui : spv_format; | ||
| 80 | } | ||
| 81 | |||
| 82 | Id ImageType(EmitContext& ctx, const ImageDescriptor& desc) { | 77 | Id ImageType(EmitContext& ctx, const ImageDescriptor& desc) { |
| 83 | const spv::ImageFormat format{GetImageFormat(desc.format)}; | 78 | const spv::ImageFormat format{GetImageFormat(desc.format)}; |
| 84 | const Id type{ctx.U32[1]}; | 79 | const Id type{ctx.U32[1]}; |
| @@ -1275,7 +1270,7 @@ void EmitContext::DefineImageBuffers(const Info& info, u32& binding) { | |||
| 1275 | if (desc.count != 1) { | 1270 | if (desc.count != 1) { |
| 1276 | throw NotImplementedException("Array of image buffers"); | 1271 | throw NotImplementedException("Array of image buffers"); |
| 1277 | } | 1272 | } |
| 1278 | const spv::ImageFormat format{GetImageFormatForBuffer(desc.format)}; | 1273 | const spv::ImageFormat format{GetImageFormat(desc.format)}; |
| 1279 | const Id image_type{TypeImage(U32[1], spv::Dim::Buffer, false, false, false, 2, format)}; | 1274 | const Id image_type{TypeImage(U32[1], spv::Dim::Buffer, false, false, false, 2, format)}; |
| 1280 | const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)}; | 1275 | const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)}; |
| 1281 | const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant)}; | 1276 | const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant)}; |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 285a50ea4..1f9e7acaa 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -120,19 +120,9 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { | |||
| 120 | return usage; | 120 | return usage; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | /// Returns the preferred format for a VkImage | ||
| 124 | [[nodiscard]] PixelFormat StorageFormat(PixelFormat format) { | ||
| 125 | switch (format) { | ||
| 126 | case PixelFormat::A8B8G8R8_SRGB: | ||
| 127 | return PixelFormat::A8B8G8R8_UNORM; | ||
| 128 | default: | ||
| 129 | return format; | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | [[nodiscard]] VkImageCreateInfo MakeImageCreateInfo(const Device& device, const ImageInfo& info) { | 123 | [[nodiscard]] VkImageCreateInfo MakeImageCreateInfo(const Device& device, const ImageInfo& info) { |
| 134 | const PixelFormat format = StorageFormat(info.format); | 124 | const auto format_info = |
| 135 | const auto format_info = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, false, format); | 125 | MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, false, info.format); |
| 136 | VkImageCreateFlags flags{}; | 126 | VkImageCreateFlags flags{}; |
| 137 | if (info.type == ImageType::e2D && info.resources.layers >= 6 && | 127 | if (info.type == ImageType::e2D && info.resources.layers >= 6 && |
| 138 | info.size.width == info.size.height && !device.HasBrokenCubeImageCompability()) { | 128 | info.size.width == info.size.height && !device.HasBrokenCubeImageCompability()) { |
| @@ -157,7 +147,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { | |||
| 157 | .arrayLayers = static_cast<u32>(info.resources.layers), | 147 | .arrayLayers = static_cast<u32>(info.resources.layers), |
| 158 | .samples = ConvertSampleCount(info.num_samples), | 148 | .samples = ConvertSampleCount(info.num_samples), |
| 159 | .tiling = VK_IMAGE_TILING_OPTIMAL, | 149 | .tiling = VK_IMAGE_TILING_OPTIMAL, |
| 160 | .usage = ImageUsageFlags(format_info, format), | 150 | .usage = ImageUsageFlags(format_info, info.format), |
| 161 | .sharingMode = VK_SHARING_MODE_EXCLUSIVE, | 151 | .sharingMode = VK_SHARING_MODE_EXCLUSIVE, |
| 162 | .queueFamilyIndexCount = 0, | 152 | .queueFamilyIndexCount = 0, |
| 163 | .pQueueFamilyIndices = nullptr, | 153 | .pQueueFamilyIndices = nullptr, |
| @@ -1049,15 +1039,27 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst | |||
| 1049 | dst_region, src_region, filter, operation); | 1039 | dst_region, src_region, filter, operation); |
| 1050 | return; | 1040 | return; |
| 1051 | } | 1041 | } |
| 1042 | ASSERT(src.format == dst.format); | ||
| 1052 | if (aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { | 1043 | if (aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { |
| 1053 | if (!device.IsBlitDepthStencilSupported()) { | 1044 | const auto format = src.format; |
| 1045 | const auto can_blit_depth_stencil = [this, format] { | ||
| 1046 | switch (format) { | ||
| 1047 | case VideoCore::Surface::PixelFormat::D24_UNORM_S8_UINT: | ||
| 1048 | case VideoCore::Surface::PixelFormat::S8_UINT_D24_UNORM: | ||
| 1049 | return device.IsBlitDepth24Stencil8Supported(); | ||
| 1050 | case VideoCore::Surface::PixelFormat::D32_FLOAT_S8_UINT: | ||
| 1051 | return device.IsBlitDepth32Stencil8Supported(); | ||
| 1052 | default: | ||
| 1053 | UNREACHABLE(); | ||
| 1054 | } | ||
| 1055 | }(); | ||
| 1056 | if (!can_blit_depth_stencil) { | ||
| 1054 | UNIMPLEMENTED_IF(is_src_msaa || is_dst_msaa); | 1057 | UNIMPLEMENTED_IF(is_src_msaa || is_dst_msaa); |
| 1055 | blit_image_helper.BlitDepthStencil(dst_framebuffer, src.DepthView(), src.StencilView(), | 1058 | blit_image_helper.BlitDepthStencil(dst_framebuffer, src.DepthView(), src.StencilView(), |
| 1056 | dst_region, src_region, filter, operation); | 1059 | dst_region, src_region, filter, operation); |
| 1057 | return; | 1060 | return; |
| 1058 | } | 1061 | } |
| 1059 | } | 1062 | } |
| 1060 | ASSERT(src.format == dst.format); | ||
| 1061 | ASSERT(!(is_dst_msaa && !is_src_msaa)); | 1063 | ASSERT(!(is_dst_msaa && !is_src_msaa)); |
| 1062 | ASSERT(operation == Fermi2D::Operation::SrcCopy); | 1064 | ASSERT(operation == Fermi2D::Operation::SrcCopy); |
| 1063 | 1065 | ||
| @@ -1631,8 +1633,8 @@ bool Image::NeedsScaleHelper() const { | |||
| 1631 | return true; | 1633 | return true; |
| 1632 | } | 1634 | } |
| 1633 | static constexpr auto OPTIMAL_FORMAT = FormatType::Optimal; | 1635 | static constexpr auto OPTIMAL_FORMAT = FormatType::Optimal; |
| 1634 | const PixelFormat format = StorageFormat(info.format); | 1636 | const auto vk_format = |
| 1635 | const auto vk_format = MaxwellToVK::SurfaceFormat(device, OPTIMAL_FORMAT, false, format).format; | 1637 | MaxwellToVK::SurfaceFormat(device, OPTIMAL_FORMAT, false, info.format).format; |
| 1636 | const auto blit_usage = VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; | 1638 | const auto blit_usage = VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; |
| 1637 | const bool needs_blit_helper = !device.IsFormatSupported(vk_format, blit_usage, OPTIMAL_FORMAT); | 1639 | const bool needs_blit_helper = !device.IsFormatSupported(vk_format, blit_usage, OPTIMAL_FORMAT); |
| 1638 | return needs_blit_helper; | 1640 | return needs_blit_helper; |
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index a88ff5ca5..18185610f 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -428,7 +428,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 428 | first_next = &diagnostics_nv; | 428 | first_next = &diagnostics_nv; |
| 429 | } | 429 | } |
| 430 | 430 | ||
| 431 | is_blit_depth_stencil_supported = TestDepthStencilBlits(); | 431 | is_blit_depth24_stencil8_supported = TestDepthStencilBlits(VK_FORMAT_D24_UNORM_S8_UINT); |
| 432 | is_blit_depth32_stencil8_supported = TestDepthStencilBlits(VK_FORMAT_D32_SFLOAT_S8_UINT); | ||
| 432 | is_optimal_astc_supported = ComputeIsOptimalAstcSupported(); | 433 | is_optimal_astc_supported = ComputeIsOptimalAstcSupported(); |
| 433 | is_warp_potentially_bigger = !extensions.subgroup_size_control || | 434 | is_warp_potentially_bigger = !extensions.subgroup_size_control || |
| 434 | properties.subgroup_size_control.maxSubgroupSize > GuestWarpSize; | 435 | properties.subgroup_size_control.maxSubgroupSize > GuestWarpSize; |
| @@ -782,14 +783,13 @@ bool Device::ComputeIsOptimalAstcSupported() const { | |||
| 782 | return true; | 783 | return true; |
| 783 | } | 784 | } |
| 784 | 785 | ||
| 785 | bool Device::TestDepthStencilBlits() const { | 786 | bool Device::TestDepthStencilBlits(VkFormat format) const { |
| 786 | static constexpr VkFormatFeatureFlags required_features = | 787 | static constexpr VkFormatFeatureFlags required_features = |
| 787 | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; | 788 | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; |
| 788 | const auto test_features = [](VkFormatProperties props) { | 789 | const auto test_features = [](VkFormatProperties props) { |
| 789 | return (props.optimalTilingFeatures & required_features) == required_features; | 790 | return (props.optimalTilingFeatures & required_features) == required_features; |
| 790 | }; | 791 | }; |
| 791 | return test_features(format_properties.at(VK_FORMAT_D32_SFLOAT_S8_UINT)) && | 792 | return test_features(format_properties.at(format)); |
| 792 | test_features(format_properties.at(VK_FORMAT_D24_UNORM_S8_UINT)); | ||
| 793 | } | 793 | } |
| 794 | 794 | ||
| 795 | bool Device::IsFormatSupported(VkFormat wanted_format, VkFormatFeatureFlags wanted_usage, | 795 | bool Device::IsFormatSupported(VkFormat wanted_format, VkFormatFeatureFlags wanted_usage, |
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 6c7fa34e5..8c5355a28 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h | |||
| @@ -362,9 +362,14 @@ public: | |||
| 362 | return features.features.depthBounds; | 362 | return features.features.depthBounds; |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | /// Returns true when blitting from and to depth stencil images is supported. | 365 | /// Returns true when blitting from and to D24S8 images is supported. |
| 366 | bool IsBlitDepthStencilSupported() const { | 366 | bool IsBlitDepth24Stencil8Supported() const { |
| 367 | return is_blit_depth_stencil_supported; | 367 | return is_blit_depth24_stencil8_supported; |
| 368 | } | ||
| 369 | |||
| 370 | /// Returns true when blitting from and to D32S8 images is supported. | ||
| 371 | bool IsBlitDepth32Stencil8Supported() const { | ||
| 372 | return is_blit_depth32_stencil8_supported; | ||
| 368 | } | 373 | } |
| 369 | 374 | ||
| 370 | /// Returns true if the device supports VK_NV_viewport_swizzle. | 375 | /// Returns true if the device supports VK_NV_viewport_swizzle. |
| @@ -674,7 +679,7 @@ private: | |||
| 674 | bool ComputeIsOptimalAstcSupported() const; | 679 | bool ComputeIsOptimalAstcSupported() const; |
| 675 | 680 | ||
| 676 | /// Returns true if the device natively supports blitting depth stencil images. | 681 | /// Returns true if the device natively supports blitting depth stencil images. |
| 677 | bool TestDepthStencilBlits() const; | 682 | bool TestDepthStencilBlits(VkFormat format) const; |
| 678 | 683 | ||
| 679 | private: | 684 | private: |
| 680 | VkInstance instance; ///< Vulkan instance. | 685 | VkInstance instance; ///< Vulkan instance. |
| @@ -738,25 +743,26 @@ private: | |||
| 738 | VkPhysicalDeviceProperties2 properties2{}; | 743 | VkPhysicalDeviceProperties2 properties2{}; |
| 739 | 744 | ||
| 740 | // Misc features | 745 | // Misc features |
| 741 | bool is_optimal_astc_supported{}; ///< Support for all guest ASTC formats. | 746 | bool is_optimal_astc_supported{}; ///< Support for all guest ASTC formats. |
| 742 | bool is_blit_depth_stencil_supported{}; ///< Support for blitting from and to depth stencil. | 747 | bool is_blit_depth24_stencil8_supported{}; ///< Support for blitting from and to D24S8. |
| 743 | bool is_warp_potentially_bigger{}; ///< Host warp size can be bigger than guest. | 748 | bool is_blit_depth32_stencil8_supported{}; ///< Support for blitting from and to D32S8. |
| 744 | bool is_integrated{}; ///< Is GPU an iGPU. | 749 | bool is_warp_potentially_bigger{}; ///< Host warp size can be bigger than guest. |
| 745 | bool is_virtual{}; ///< Is GPU a virtual GPU. | 750 | bool is_integrated{}; ///< Is GPU an iGPU. |
| 746 | bool is_non_gpu{}; ///< Is SoftwareRasterizer, FPGA, non-GPU device. | 751 | bool is_virtual{}; ///< Is GPU a virtual GPU. |
| 747 | bool has_broken_compute{}; ///< Compute shaders can cause crashes | 752 | bool is_non_gpu{}; ///< Is SoftwareRasterizer, FPGA, non-GPU device. |
| 748 | bool has_broken_cube_compatibility{}; ///< Has broken cube compatibility bit | 753 | bool has_broken_compute{}; ///< Compute shaders can cause crashes |
| 749 | bool has_renderdoc{}; ///< Has RenderDoc attached | 754 | bool has_broken_cube_compatibility{}; ///< Has broken cube compatibility bit |
| 750 | bool has_nsight_graphics{}; ///< Has Nsight Graphics attached | 755 | bool has_renderdoc{}; ///< Has RenderDoc attached |
| 751 | bool supports_d24_depth{}; ///< Supports D24 depth buffers. | 756 | bool has_nsight_graphics{}; ///< Has Nsight Graphics attached |
| 752 | bool cant_blit_msaa{}; ///< Does not support MSAA<->MSAA blitting. | 757 | bool supports_d24_depth{}; ///< Supports D24 depth buffers. |
| 753 | bool must_emulate_scaled_formats{}; ///< Requires scaled vertex format emulation | 758 | bool cant_blit_msaa{}; ///< Does not support MSAA<->MSAA blitting. |
| 754 | bool must_emulate_bgr565{}; ///< Emulates BGR565 by swizzling RGB565 format. | 759 | bool must_emulate_scaled_formats{}; ///< Requires scaled vertex format emulation |
| 755 | bool dynamic_state3_blending{}; ///< Has all blending features of dynamic_state3. | 760 | bool must_emulate_bgr565{}; ///< Emulates BGR565 by swizzling RGB565 format. |
| 756 | bool dynamic_state3_enables{}; ///< Has all enables features of dynamic_state3. | 761 | bool dynamic_state3_blending{}; ///< Has all blending features of dynamic_state3. |
| 757 | bool supports_conditional_barriers{}; ///< Allows barriers in conditional control flow. | 762 | bool dynamic_state3_enables{}; ///< Has all enables features of dynamic_state3. |
| 758 | u64 device_access_memory{}; ///< Total size of device local memory in bytes. | 763 | bool supports_conditional_barriers{}; ///< Allows barriers in conditional control flow. |
| 759 | u32 sets_per_pool{}; ///< Sets per Description Pool | 764 | u64 device_access_memory{}; ///< Total size of device local memory in bytes. |
| 765 | u32 sets_per_pool{}; ///< Sets per Description Pool | ||
| 760 | 766 | ||
| 761 | // Telemetry parameters | 767 | // Telemetry parameters |
| 762 | std::set<std::string, std::less<>> supported_extensions; ///< Reported Vulkan extensions. | 768 | std::set<std::string, std::less<>> supported_extensions; ///< Reported Vulkan extensions. |