Browse Source

VUID-vkCmdDraw-None-09600

xbzk/vulkan-vuid-goodies-pack
xbzk 4 weeks ago
parent
commit
60fd8380fb
  1. 69
      src/video_core/renderer_vulkan/vk_texture_cache.cpp
  2. 1
      src/video_core/renderer_vulkan/vk_texture_cache.h

69
src/video_core/renderer_vulkan/vk_texture_cache.cpp

@ -128,6 +128,17 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
return usage;
}
[[nodiscard]] VkImageUsageFlags ImageUsageFlags(const Device& device,
const MaxwellToVK::FormatInfo& info,
PixelFormat format) {
VkImageUsageFlags usage = ImageUsageFlags(info, format);
// ASTC recompression requires STORAGE_BIT for the GPU decoder pass
if (IsPixelFormatASTC(format) && !device.IsOptimalAstcSupported()) {
usage |= VK_IMAGE_USAGE_STORAGE_BIT;
}
return usage;
}
[[nodiscard]] VkImageCreateInfo MakeImageCreateInfo(const Device& device, const ImageInfo& info) {
const auto format_info =
MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, false, info.format);
@ -155,7 +166,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
.arrayLayers = static_cast<u32>(info.resources.layers),
.samples = ConvertSampleCount(info.num_samples),
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = ImageUsageFlags(format_info, info.format),
.usage = ImageUsageFlags(device, format_info, info.format),
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,
@ -1670,14 +1681,13 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu
}
current_image = &Image::original_image;
storage_image_views.resize(info.resources.levels);
if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported() &&
Settings::values.astc_recompression.GetValue() ==
Settings::AstcRecompression::Uncompressed) {
const auto& device = runtime->device.GetLogical();
for (s32 level = 0; level < info.resources.levels; ++level) {
storage_image_views[level] =
MakeStorageView(device, level, *original_image, VK_FORMAT_A8B8G8R8_UNORM_PACK32);
}
// Transition render targets to GENERAL layout
const auto format_info =
MaxwellToVK::SurfaceFormat(runtime->device, FormatType::Optimal, false, info.format);
const VkImageUsageFlags usage = ImageUsageFlags(runtime->device, format_info, info.format);
if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) != 0) {
runtime->TransitionImageLayout(*this);
}
}
@ -2054,8 +2064,15 @@ void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferIm
}
VkImageView Image::StorageImageView(s32 level) noexcept {
// Storage views require the image to have been created with VK_IMAGE_USAGE_STORAGE_BIT
if (!(original_image.UsageFlags() & VK_IMAGE_USAGE_STORAGE_BIT)) {
// Image doesn't support storage usage, return null
return nullptr;
}
auto& view = storage_image_views[level];
if (!view) {
// Ensure image is in VK_IMAGE_LAYOUT_GENERAL before using as storage image
runtime->TransitionImageLayout(*this);
const auto format_info =
MaxwellToVK::SurfaceFormat(runtime->device, FormatType::Optimal, true, info.format);
view = MakeStorageView(runtime->device.GetLogical(), level, *(this->*current_image),
@ -2088,6 +2105,9 @@ bool Image::ScaleUp(bool ignore) {
scaled_info.size.height = scaled_height;
scaled_image = MakeImage(runtime->device, runtime->memory_allocator, scaled_info,
runtime->ViewFormats(info.format));
const VkImageAspectFlags init_aspect =
aspect_mask != 0 ? aspect_mask : ImageAspectMask(info.format);
runtime->TransitionImageLayout(*scaled_image, init_aspect);
ignore = false;
}
current_image = &Image::scaled_image;
@ -2207,6 +2227,9 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
samples(ConvertSampleCount(image.info.num_samples)) {
using Shader::TextureType;
// Ensure image is transitioned to GENERAL layout before creating views
runtime.TransitionImageLayout(image);
const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info);
std::array<SwizzleSource, 4> swizzle{
SwizzleSource::R,
@ -2318,6 +2341,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageV
null_image = MakeImage(*device, runtime.memory_allocator, info, {});
image_handle = *null_image;
runtime.TransitionImageLayout(*null_image, VK_IMAGE_ASPECT_COLOR_BIT);
for (u32 i = 0; i < Shader::NUM_TEXTURE_TYPES; i++) {
image_views[i] = MakeView(VK_FORMAT_A8B8G8R8_UNORM_PACK32, VK_IMAGE_ASPECT_COLOR_BIT);
}
@ -2596,21 +2620,25 @@ void TextureCacheRuntime::AccelerateImageUpload(
}
void TextureCacheRuntime::TransitionImageLayout(Image& image) {
if (!image.ExchangeInitialization()) {
if (image.ExchangeInitialization()) {
return;
}
TransitionImageLayout(image.Handle(), image.AspectMask());
}
void TextureCacheRuntime::TransitionImageLayout(VkImage image, VkImageAspectFlags aspect_mask) {
VkImageMemoryBarrier barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_NONE,
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = image.Handle(),
.image = image,
.subresourceRange{
.aspectMask = image.AspectMask(),
.aspectMask = aspect_mask,
.baseMipLevel = 0,
.levelCount = VK_REMAINING_MIP_LEVELS,
.baseArrayLayer = 0,
@ -2619,18 +2647,9 @@ void TextureCacheRuntime::TransitionImageLayout(Image& image) {
};
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([barrier](vk::CommandBuffer cmdbuf) {
// After layout transition, image may be used in shaders or as attachment
const VkPipelineStageFlags dst_stages_layout =
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_TRANSFER_BIT;
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
dst_stages_layout, 0, barrier);
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, barrier);
});
}
}
} // namespace Vulkan

1
src/video_core/renderer_vulkan/vk_texture_cache.h

@ -97,6 +97,7 @@ public:
void InsertUploadMemoryBarrier() {}
void TransitionImageLayout(Image& image);
void TransitionImageLayout(VkImage image, VkImageAspectFlags aspect_mask);
bool HasBrokenTextureViewFormats() const noexcept {
// No known Vulkan driver has broken image views

Loading…
Cancel
Save