summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp15
-rw-r--r--src/shader_recompiler/backend/spirv/spirv_emit_context.cpp7
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp36
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp8
-rw-r--r--src/video_core/vulkan_common/vulkan_device.h52
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
8namespace Shader::Backend::SPIRV { 8namespace Shader::Backend::SPIRV {
9namespace { 9namespace {
10Id Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) { 10Id 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
29Id ImageAtomicU32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id value, 26Id 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
77spv::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
82Id ImageType(EmitContext& ctx, const ImageDescriptor& desc) { 77Id 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
785bool Device::TestDepthStencilBlits() const { 786bool 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
795bool Device::IsFormatSupported(VkFormat wanted_format, VkFormatFeatureFlags wanted_usage, 795bool 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
679private: 684private:
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.