[vk] Even more validation fixes that require extensive testing
Some checks failed
eden-license / license-header (pull_request) Failing after 28s
Some checks failed
eden-license / license-header (pull_request) Failing after 28s
This commit is contained in:
parent
2d97d0f108
commit
334856d585
8 changed files with 116 additions and 17 deletions
|
@ -1432,6 +1432,9 @@ void EmitContext::DefineInputs(const IR::Program& program) {
|
|||
}
|
||||
if (info.uses_sample_id) {
|
||||
sample_id = DefineInput(*this, U32[1], false, spv::BuiltIn::SampleId);
|
||||
if (stage == Stage::Fragment) {
|
||||
Decorate(sample_id, spv::Decoration::Flat);
|
||||
}
|
||||
}
|
||||
if (info.uses_is_helper_invocation) {
|
||||
is_helper_invocation = DefineInput(*this, U1, false, spv::BuiltIn::HelperInvocation);
|
||||
|
@ -1442,6 +1445,13 @@ void EmitContext::DefineInputs(const IR::Program& program) {
|
|||
subgroup_mask_le = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupLeMaskKHR);
|
||||
subgroup_mask_gt = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupGtMaskKHR);
|
||||
subgroup_mask_ge = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupGeMaskKHR);
|
||||
if (stage == Stage::Fragment) {
|
||||
Decorate(subgroup_mask_eq, spv::Decoration::Flat);
|
||||
Decorate(subgroup_mask_lt, spv::Decoration::Flat);
|
||||
Decorate(subgroup_mask_le, spv::Decoration::Flat);
|
||||
Decorate(subgroup_mask_gt, spv::Decoration::Flat);
|
||||
Decorate(subgroup_mask_ge, spv::Decoration::Flat);
|
||||
}
|
||||
}
|
||||
if (info.uses_fswzadd || info.uses_subgroup_invocation_id || info.uses_subgroup_shuffles ||
|
||||
(profile.warp_size_potentially_larger_than_guest &&
|
||||
|
@ -1461,6 +1471,9 @@ void EmitContext::DefineInputs(const IR::Program& program) {
|
|||
}
|
||||
if (loads[IR::Attribute::PrimitiveId]) {
|
||||
primitive_id = DefineInput(*this, U32[1], false, spv::BuiltIn::PrimitiveId);
|
||||
if (stage == Stage::Fragment) {
|
||||
Decorate(primitive_id, spv::Decoration::Flat);
|
||||
}
|
||||
}
|
||||
if (loads[IR::Attribute::Layer]) {
|
||||
AddCapability(spv::Capability::Geometry);
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
#extension GL_ARB_shader_stencil_export : require
|
||||
|
||||
layout(binding = 0) uniform sampler2D depth_tex;
|
||||
layout(binding = 1) uniform isampler2D stencil_tex;
|
||||
layout(binding = 1) uniform usampler2D stencil_tex;
|
||||
|
||||
layout(location = 0) in vec2 texcoord;
|
||||
|
||||
void main() {
|
||||
gl_FragDepth = textureLod(depth_tex, texcoord, 0).r;
|
||||
gl_FragStencilRefARB = textureLod(stencil_tex, texcoord, 0).r;
|
||||
gl_FragStencilRefARB = int(textureLod(stencil_tex, texcoord, 0).r);
|
||||
}
|
||||
|
|
|
@ -193,8 +193,8 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
|
|||
const Sampler& sampler{texture_cache.GetSampler(sampler_id)};
|
||||
const bool use_fallback_sampler{sampler.HasAddedAnisotropy() &&
|
||||
!image_view.SupportsAnisotropy()};
|
||||
const bool enable_compare =
|
||||
sampler.DepthCompareEnabled() && image_view.SupportsDepthCompare();
|
||||
const bool enable_compare = sampler.DepthCompareEnabled() &&
|
||||
image_view.SupportsDepthCompare(desc.type);
|
||||
const VkSampler vk_sampler =
|
||||
sampler.HandleForUsage(use_fallback_sampler, enable_compare);
|
||||
guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler);
|
||||
|
|
|
@ -306,14 +306,48 @@ void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities) {
|
|||
swapchain_ci.queueFamilyIndexCount = static_cast<u32>(queue_indices.size());
|
||||
swapchain_ci.pQueueFamilyIndices = queue_indices.data();
|
||||
}
|
||||
static constexpr std::array view_formats{VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_SRGB};
|
||||
const VkFormat swapchain_format = surface_format.format;
|
||||
const bool has_mutable_swapchain = device.IsKhrSwapchainMutableFormatEnabled();
|
||||
#ifdef ANDROID
|
||||
// Android is already ordered the same as Switch.
|
||||
VkFormat preferred_view_format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
#else
|
||||
VkFormat preferred_view_format = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
#endif
|
||||
if (!has_mutable_swapchain) {
|
||||
preferred_view_format = swapchain_format;
|
||||
}
|
||||
std::array<VkFormat, 4> view_formats{};
|
||||
u32 view_format_count = 0;
|
||||
const auto push_format = [&](VkFormat format) {
|
||||
if (format == VK_FORMAT_UNDEFINED || view_format_count >= static_cast<u32>(view_formats.size())) {
|
||||
return;
|
||||
}
|
||||
const auto end_iterator = view_formats.begin() + view_format_count;
|
||||
if (std::find(view_formats.begin(), end_iterator, format) != end_iterator) {
|
||||
return;
|
||||
}
|
||||
view_formats[view_format_count++] = format;
|
||||
};
|
||||
push_format(swapchain_format);
|
||||
if (has_mutable_swapchain) {
|
||||
push_format(preferred_view_format);
|
||||
if (swapchain_format == VK_FORMAT_B8G8R8A8_UNORM ||
|
||||
preferred_view_format == VK_FORMAT_B8G8R8A8_UNORM) {
|
||||
push_format(VK_FORMAT_B8G8R8A8_SRGB);
|
||||
}
|
||||
if (swapchain_format == VK_FORMAT_R8G8B8A8_UNORM ||
|
||||
preferred_view_format == VK_FORMAT_R8G8B8A8_UNORM) {
|
||||
push_format(VK_FORMAT_R8G8B8A8_SRGB);
|
||||
}
|
||||
}
|
||||
VkImageFormatListCreateInfo format_list{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,
|
||||
.pNext = nullptr,
|
||||
.viewFormatCount = static_cast<u32>(view_formats.size()),
|
||||
.viewFormatCount = view_format_count,
|
||||
.pViewFormats = view_formats.data(),
|
||||
};
|
||||
if (device.IsKhrSwapchainMutableFormatEnabled()) {
|
||||
if (has_mutable_swapchain && view_format_count > 1) {
|
||||
format_list.pNext = std::exchange(swapchain_ci.pNext, &format_list);
|
||||
swapchain_ci.flags |= VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR;
|
||||
}
|
||||
|
@ -331,12 +365,7 @@ void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities) {
|
|||
|
||||
images = swapchain.GetImages();
|
||||
image_count = static_cast<u32>(images.size());
|
||||
#ifdef ANDROID
|
||||
// Android is already ordered the same as Switch.
|
||||
image_view_format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
#else
|
||||
image_view_format = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
#endif
|
||||
image_view_format = preferred_view_format;
|
||||
}
|
||||
|
||||
void Swapchain::CreateSemaphores() {
|
||||
|
|
|
@ -2010,6 +2010,8 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
|
|||
samples(ConvertSampleCount(image.info.num_samples)) {
|
||||
using Shader::TextureType;
|
||||
|
||||
sampled_formats.fill(VK_FORMAT_UNDEFINED);
|
||||
|
||||
const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info);
|
||||
std::array<SwizzleSource, 4> swizzle{
|
||||
SwizzleSource::R,
|
||||
|
@ -2026,6 +2028,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
|
|||
}
|
||||
}
|
||||
const auto format_info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format);
|
||||
view_format = format_info.format;
|
||||
VkImageUsageFlags view_usage = ImageUsageFlags(format_info, format);
|
||||
const VkImageUsageFlags image_usage = image.UsageFlags();
|
||||
const VkImageUsageFlags original_view_usage = view_usage;
|
||||
|
@ -2074,6 +2077,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
|
|||
handle.SetObjectNameEXT(VideoCommon::Name(*this, gpu_addr).c_str());
|
||||
}
|
||||
image_views[static_cast<size_t>(tex_type)] = std::move(handle);
|
||||
sampled_formats[static_cast<size_t>(tex_type)] = ci.format;
|
||||
};
|
||||
switch (info.type) {
|
||||
case VideoCommon::ImageViewType::e1D:
|
||||
|
@ -2113,10 +2117,14 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
|
|||
ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageInfo& info,
|
||||
const VideoCommon::ImageViewInfo& view_info, GPUVAddr gpu_addr_)
|
||||
: VideoCommon::ImageViewBase{info, view_info, gpu_addr_},
|
||||
buffer_size{VideoCommon::CalculateGuestSizeInBytes(info)} {}
|
||||
buffer_size{VideoCommon::CalculateGuestSizeInBytes(info)} {
|
||||
sampled_formats.fill(VK_FORMAT_UNDEFINED);
|
||||
view_format = VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageViewParams& params)
|
||||
: VideoCommon::ImageViewBase{params}, device{&runtime.device} {
|
||||
sampled_formats.fill(VK_FORMAT_UNDEFINED);
|
||||
if (device->HasNullDescriptor()) {
|
||||
return;
|
||||
}
|
||||
|
@ -2129,7 +2137,9 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageV
|
|||
image_handle = *null_image;
|
||||
for (u32 i = 0; i < Shader::NUM_TEXTURE_TYPES; i++) {
|
||||
image_views[i] = MakeView(VK_FORMAT_A8B8G8R8_UNORM_PACK32, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
sampled_formats[i] = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
|
||||
}
|
||||
view_format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
|
||||
}
|
||||
|
||||
ImageView::~ImageView() = default;
|
||||
|
@ -2200,9 +2210,22 @@ bool ImageView::IsRescaled() const noexcept {
|
|||
return src_image.IsRescaled();
|
||||
}
|
||||
|
||||
bool ImageView::SupportsDepthCompare() const noexcept {
|
||||
bool ImageView::SupportsDepthCompare(Shader::TextureType texture_type) const noexcept {
|
||||
if (device == nullptr || image_handle == VK_NULL_HANDLE) {
|
||||
return false;
|
||||
}
|
||||
const auto surface_type = VideoCore::Surface::GetFormatType(format);
|
||||
return surface_type == SurfaceType::Depth || surface_type == SurfaceType::DepthStencil;
|
||||
if (surface_type != SurfaceType::Depth && surface_type != SurfaceType::DepthStencil) {
|
||||
return false;
|
||||
}
|
||||
const VkFormat sampled_format = sampled_formats[static_cast<size_t>(texture_type)];
|
||||
if (sampled_format != VK_FORMAT_UNDEFINED) {
|
||||
return device->SupportsDepthComparisonSampling(sampled_format);
|
||||
}
|
||||
if (view_format == VK_FORMAT_UNDEFINED) {
|
||||
return false;
|
||||
}
|
||||
return device->SupportsDepthComparisonSampling(view_format);
|
||||
}
|
||||
|
||||
vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) {
|
||||
|
|
|
@ -237,7 +237,7 @@ public:
|
|||
Shader::ImageFormat image_format);
|
||||
|
||||
[[nodiscard]] bool IsRescaled() const noexcept;
|
||||
[[nodiscard]] bool SupportsDepthCompare() const noexcept;
|
||||
[[nodiscard]] bool SupportsDepthCompare(Shader::TextureType texture_type) const noexcept;
|
||||
|
||||
[[nodiscard]] VkImageView Handle(Shader::TextureType texture_type) const noexcept {
|
||||
return *image_views[static_cast<size_t>(texture_type)];
|
||||
|
@ -283,6 +283,8 @@ private:
|
|||
VkImage image_handle = VK_NULL_HANDLE;
|
||||
VkImageView render_target = VK_NULL_HANDLE;
|
||||
VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
VkFormat view_format = VK_FORMAT_UNDEFINED;
|
||||
std::array<VkFormat, Shader::NUM_TEXTURE_TYPES> sampled_formats{};
|
||||
u32 buffer_size = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -886,6 +886,34 @@ bool Device::IsFormatSupported(VkFormat wanted_format, VkFormatFeatureFlags want
|
|||
return (supported_usage & wanted_usage) == wanted_usage;
|
||||
}
|
||||
|
||||
bool Device::SupportsDepthComparisonSampling(VkFormat format) const {
|
||||
const auto it = format_properties.find(format);
|
||||
if (it == format_properties.end()) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented depth comparison query format={}", format);
|
||||
return false;
|
||||
}
|
||||
#if defined(VK_FORMAT_FEATURE_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT)
|
||||
const auto features = it->second.optimalTilingFeatures;
|
||||
return (features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT) != 0;
|
||||
#elif defined(VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT)
|
||||
const auto get_props2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties2>(
|
||||
dld.vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2"));
|
||||
if (!get_props2) {
|
||||
const auto fallback_features = it->second.optimalTilingFeatures;
|
||||
return (fallback_features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0;
|
||||
}
|
||||
VkFormatProperties3 format_props3{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3};
|
||||
VkFormatProperties2 format_props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
|
||||
format_props2.pNext = &format_props3;
|
||||
get_props2(physical, format, &format_props2);
|
||||
return (format_props3.optimalTilingFeatures &
|
||||
VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT) != 0;
|
||||
#else
|
||||
const auto fallback_features = it->second.optimalTilingFeatures;
|
||||
return (fallback_features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string Device::GetDriverName() const {
|
||||
switch (properties.driver.driverID) {
|
||||
case VK_DRIVER_ID_AMD_PROPRIETARY:
|
||||
|
@ -1448,3 +1476,4 @@ std::vector<VkDeviceQueueCreateInfo> Device::GetDeviceQueueCreateInfos() const {
|
|||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
|
|
|
@ -213,6 +213,9 @@ public:
|
|||
bool IsFormatSupported(VkFormat wanted_format, VkFormatFeatureFlags wanted_usage,
|
||||
FormatType format_type) const;
|
||||
|
||||
/// Returns true when the format supports depth comparison sampling on optimal tiling images.
|
||||
bool SupportsDepthComparisonSampling(VkFormat format) const;
|
||||
|
||||
/// Reports a device loss.
|
||||
void ReportLoss() const;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue