summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp68
-rw-r--r--src/video_core/engines/maxwell_3d.h2
-rw-r--r--src/video_core/memory_manager.cpp26
-rw-r--r--src/video_core/memory_manager.h3
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.cpp29
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.h12
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp5
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp12
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp73
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h2
-rw-r--r--src/video_core/shader/async_shaders.cpp18
-rw-r--r--src/video_core/shader/node.h8
-rw-r--r--src/video_core/shader/shader_ir.cpp51
-rw-r--r--src/video_core/shader/shader_ir.h3
-rw-r--r--src/video_core/texture_cache/util.cpp59
-rw-r--r--src/video_core/vulkan_common/vulkan_debug_callback.cpp1
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp23
17 files changed, 194 insertions, 201 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 9be651e24..116ad1722 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -179,22 +179,22 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume
return ProcessMacroBind(argument);
case MAXWELL3D_REG_INDEX(firmware[4]):
return ProcessFirmwareCall4();
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[1]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[2]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[3]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[4]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[5]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[6]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[7]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[8]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[9]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[10]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[11]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[12]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]):
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data):
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 1:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 2:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 3:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 4:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 5:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 6:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 7:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 8:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 9:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 10:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 11:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 12:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15:
return StartCBData(method);
case MAXWELL3D_REG_INDEX(cb_bind[0]):
return ProcessCBBind(0);
@@ -287,22 +287,22 @@ void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
return;
}
switch (method) {
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[1]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[2]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[3]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[4]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[5]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[6]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[7]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[8]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[9]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[10]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[11]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[12]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]):
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data):
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 1:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 2:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 3:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 4:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 5:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 6:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 7:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 8:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 9:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 10:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 11:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 12:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14:
+ case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15:
ProcessCBMultiData(method, base_start, amount);
break;
default:
@@ -592,7 +592,7 @@ void Maxwell3D::ProcessCBData(u32 value) {
}
void Maxwell3D::StartCBData(u32 method) {
- constexpr u32 first_cb_data = MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]);
+ constexpr u32 first_cb_data = MAXWELL3D_REG_INDEX(const_buffer.cb_data);
cb_data_state.start_pos = regs.const_buffer.cb_pos;
cb_data_state.id = method - first_cb_data;
cb_data_state.current = method;
@@ -605,7 +605,7 @@ void Maxwell3D::ProcessCBMultiData(u32 method, const u32* start_base, u32 amount
if (cb_data_state.current != null_cb_data) {
FinishCBData();
}
- constexpr u32 first_cb_data = MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]);
+ constexpr u32 first_cb_data = MAXWELL3D_REG_INDEX(const_buffer.cb_data);
cb_data_state.start_pos = regs.const_buffer.cb_pos;
cb_data_state.id = method - first_cb_data;
cb_data_state.current = method;
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 326b32228..002d1b3f9 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -1337,7 +1337,7 @@ public:
u32 cb_address_high;
u32 cb_address_low;
u32 cb_pos;
- u32 cb_data[NumCBData];
+ std::array<u32, NumCBData> cb_data;
GPUVAddr BufferAddress() const {
return static_cast<GPUVAddr>(
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index 65feff588..f5cdf548e 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -314,17 +314,29 @@ void MemoryManager::WriteBlockUnsafe(GPUVAddr gpu_dest_addr, const void* src_buf
}
}
+void MemoryManager::FlushRegion(GPUVAddr gpu_addr, size_t size) const {
+ size_t remaining_size{size};
+ size_t page_index{gpu_addr >> page_bits};
+ size_t page_offset{gpu_addr & page_mask};
+ while (remaining_size > 0) {
+ const size_t num_bytes{std::min(page_size - page_offset, remaining_size)};
+ if (const auto page_addr{GpuToCpuAddress(page_index << page_bits)}; page_addr) {
+ rasterizer->FlushRegion(*page_addr + page_offset, num_bytes);
+ }
+ ++page_index;
+ page_offset = 0;
+ remaining_size -= num_bytes;
+ }
+}
+
void MemoryManager::CopyBlock(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, std::size_t size) {
std::vector<u8> tmp_buffer(size);
ReadBlock(gpu_src_addr, tmp_buffer.data(), size);
- WriteBlock(gpu_dest_addr, tmp_buffer.data(), size);
-}
-void MemoryManager::CopyBlockUnsafe(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr,
- std::size_t size) {
- std::vector<u8> tmp_buffer(size);
- ReadBlockUnsafe(gpu_src_addr, tmp_buffer.data(), size);
- WriteBlockUnsafe(gpu_dest_addr, tmp_buffer.data(), size);
+ // The output block must be flushed in case it has data modified from the GPU.
+ // Fixes NPC geometry in Zombie Panic in Wonderland DX
+ FlushRegion(gpu_dest_addr, size);
+ WriteBlock(gpu_dest_addr, tmp_buffer.data(), size);
}
bool MemoryManager::IsGranularRange(GPUVAddr gpu_addr, std::size_t size) const {
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h
index c35e57689..a52fbbd8c 100644
--- a/src/video_core/memory_manager.h
+++ b/src/video_core/memory_manager.h
@@ -107,7 +107,6 @@ public:
*/
void ReadBlockUnsafe(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size) const;
void WriteBlockUnsafe(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size);
- void CopyBlockUnsafe(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, std::size_t size);
/**
* IsGranularRange checks if a gpu region can be simply read with a pointer.
@@ -131,6 +130,8 @@ private:
void TryLockPage(PageEntry page_entry, std::size_t size);
void TryUnlockPage(PageEntry page_entry, std::size_t size);
+ void FlushRegion(GPUVAddr gpu_addr, size_t size) const;
+
[[nodiscard]] static constexpr std::size_t PageEntryIndex(GPUVAddr gpu_addr) {
return (gpu_addr >> page_bits) & page_table_mask;
}
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
index ca7c2c579..85121d9fd 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
@@ -110,8 +110,8 @@ VkCompareOp DepthCompareFunction(Tegra::Texture::DepthCompareFunc depth_compare_
} // namespace Sampler
namespace {
-
-enum : u32 { Attachable = 1, Storage = 2 };
+constexpr u32 Attachable = 1 << 0;
+constexpr u32 Storage = 1 << 1;
struct FormatTuple {
VkFormat format; ///< Vulkan format
@@ -222,22 +222,27 @@ constexpr bool IsZetaFormat(PixelFormat pixel_format) {
} // Anonymous namespace
-FormatInfo SurfaceFormat(const Device& device, FormatType format_type, PixelFormat pixel_format) {
- ASSERT(static_cast<std::size_t>(pixel_format) < std::size(tex_format_tuples));
-
- auto tuple = tex_format_tuples[static_cast<std::size_t>(pixel_format)];
+FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with_srgb,
+ PixelFormat pixel_format) {
+ ASSERT(static_cast<size_t>(pixel_format) < std::size(tex_format_tuples));
+ FormatTuple tuple = tex_format_tuples[static_cast<size_t>(pixel_format)];
if (tuple.format == VK_FORMAT_UNDEFINED) {
UNIMPLEMENTED_MSG("Unimplemented texture format with pixel format={}", pixel_format);
- return {VK_FORMAT_A8B8G8R8_UNORM_PACK32, true, true};
+ return FormatInfo{VK_FORMAT_A8B8G8R8_UNORM_PACK32, true, true};
}
// Use A8B8G8R8_UNORM on hardware that doesn't support ASTC natively
if (!device.IsOptimalAstcSupported() && VideoCore::Surface::IsPixelFormatASTC(pixel_format)) {
- const bool is_srgb = VideoCore::Surface::IsPixelFormatSRGB(pixel_format);
- tuple.format = is_srgb ? VK_FORMAT_A8B8G8R8_SRGB_PACK32 : VK_FORMAT_A8B8G8R8_UNORM_PACK32;
+ const bool is_srgb = with_srgb && VideoCore::Surface::IsPixelFormatSRGB(pixel_format);
+ if (is_srgb) {
+ tuple.format = VK_FORMAT_A8B8G8R8_SRGB_PACK32;
+ } else {
+ tuple.format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
+ tuple.usage |= Storage;
+ }
}
- const bool attachable = tuple.usage & Attachable;
- const bool storage = tuple.usage & Storage;
+ const bool attachable = (tuple.usage & Attachable) != 0;
+ const bool storage = (tuple.usage & Storage) != 0;
VkFormatFeatureFlags usage{};
switch (format_type) {
@@ -671,7 +676,7 @@ VkFrontFace FrontFace(Maxwell::FrontFace front_face) {
return {};
}
-VkCullModeFlags CullFace(Maxwell::CullFace cull_face) {
+VkCullModeFlagBits CullFace(Maxwell::CullFace cull_face) {
switch (cull_face) {
case Maxwell::CullFace::Front:
return VK_CULL_MODE_FRONT_BIT;
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.h b/src/video_core/renderer_vulkan/maxwell_to_vk.h
index 537969840..7c34b47dc 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.h
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.h
@@ -35,7 +35,15 @@ struct FormatInfo {
bool storage;
};
-FormatInfo SurfaceFormat(const Device& device, FormatType format_type, PixelFormat pixel_format);
+/**
+ * Returns format properties supported in the host
+ * @param device Host device
+ * @param format_type Type of image the buffer will use
+ * @param with_srgb True when the format can be sRGB when converted to another format (ASTC)
+ * @param pixel_format Guest pixel format to describe
+ */
+[[nodiscard]] FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with_srgb,
+ PixelFormat pixel_format);
VkShaderStageFlagBits ShaderStage(Tegra::Engines::ShaderType stage);
@@ -55,7 +63,7 @@ VkBlendFactor BlendFactor(Maxwell::Blend::Factor factor);
VkFrontFace FrontFace(Maxwell::FrontFace front_face);
-VkCullModeFlags CullFace(Maxwell::CullFace cull_face);
+VkCullModeFlagBits CullFace(Maxwell::CullFace cull_face);
VkComponentSwizzle SwizzleSource(Tegra::Texture::SwizzleSource swizzle);
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index a5214d0bc..d50dca604 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -181,6 +181,7 @@ std::vector<vk::ShaderModule> VKGraphicsPipeline::CreateShaderModules(
.pNext = nullptr,
.flags = 0,
.codeSize = 0,
+ .pCode = nullptr,
};
std::vector<vk::ShaderModule> shader_modules;
@@ -326,8 +327,8 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const SPIRVProgram& program,
.rasterizerDiscardEnable =
static_cast<VkBool32>(state.rasterize_enable == 0 ? VK_TRUE : VK_FALSE),
.polygonMode = VK_POLYGON_MODE_FILL,
- .cullMode =
- dynamic.cull_enable ? MaxwellToVK::CullFace(dynamic.CullFace()) : VK_CULL_MODE_NONE,
+ .cullMode = static_cast<VkCullModeFlags>(
+ dynamic.cull_enable ? MaxwellToVK::CullFace(dynamic.CullFace()) : VK_CULL_MODE_NONE),
.frontFace = MaxwellToVK::FrontFace(dynamic.FrontFace()),
.depthBiasEnable = state.depth_bias_enable,
.depthBiasConstantFactor = 0.0f,
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 02282e36f..8991505ca 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -355,14 +355,12 @@ VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) {
SPIRVProgram program;
std::vector<VkDescriptorSetLayoutBinding> bindings;
- for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
+ for (std::size_t index = 1; index < Maxwell::MaxShaderProgram; ++index) {
const auto program_enum = static_cast<Maxwell::ShaderProgram>(index);
-
// Skip stages that are not enabled
if (!maxwell3d.regs.IsShaderConfigEnabled(index)) {
continue;
}
-
const GPUVAddr gpu_addr = GetShaderAddress(maxwell3d, program_enum);
const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
Shader* const shader = cpu_addr ? TryGet(*cpu_addr) : null_shader.get();
@@ -372,12 +370,8 @@ VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) {
const auto& entries = shader->GetEntries();
program[stage] = {
Decompile(device, shader->GetIR(), program_type, shader->GetRegistry(), specialization),
- entries};
-
- if (program_enum == Maxwell::ShaderProgram::VertexA) {
- // VertexB was combined with VertexA, so we skip the VertexB iteration
- ++index;
- }
+ entries,
+ };
const u32 old_binding = specialization.base_binding;
specialization.base_binding =
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index ab14922d7..aa7c5d7c6 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -95,20 +95,12 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
}
}
-[[nodiscard]] VkImageCreateInfo MakeImageCreateInfo(const Device& device, const ImageInfo& info) {
- const auto format_info = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, info.format);
- VkImageCreateFlags flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
- if (info.type == ImageType::e2D && info.resources.layers >= 6 &&
- info.size.width == info.size.height) {
- flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
- }
- if (info.type == ImageType::e3D) {
- flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
- }
+[[nodiscard]] VkImageUsageFlags ImageUsageFlags(const MaxwellToVK::FormatInfo& info,
+ PixelFormat format) {
VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT;
- if (format_info.attachable) {
- switch (VideoCore::Surface::GetFormatType(info.format)) {
+ if (info.attachable) {
+ switch (VideoCore::Surface::GetFormatType(format)) {
case VideoCore::Surface::SurfaceType::ColorTexture:
usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
break;
@@ -120,9 +112,33 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
UNREACHABLE_MSG("Invalid surface type");
}
}
- if (format_info.storage) {
+ if (info.storage) {
usage |= VK_IMAGE_USAGE_STORAGE_BIT;
}
+ return usage;
+}
+
+/// Returns the preferred format for a VkImage
+[[nodiscard]] PixelFormat StorageFormat(PixelFormat format) {
+ switch (format) {
+ case PixelFormat::A8B8G8R8_SRGB:
+ return PixelFormat::A8B8G8R8_UNORM;
+ default:
+ return format;
+ }
+}
+
+[[nodiscard]] VkImageCreateInfo MakeImageCreateInfo(const Device& device, const ImageInfo& info) {
+ const PixelFormat format = StorageFormat(info.format);
+ const auto format_info = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, false, format);
+ VkImageCreateFlags flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
+ if (info.type == ImageType::e2D && info.resources.layers >= 6 &&
+ info.size.width == info.size.height) {
+ flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
+ }
+ if (info.type == ImageType::e3D) {
+ flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
+ }
const auto [samples_x, samples_y] = VideoCommon::SamplesLog2(info.num_samples);
return VkImageCreateInfo{
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
@@ -130,17 +146,16 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
.flags = flags,
.imageType = ConvertImageType(info.type),
.format = format_info.format,
- .extent =
- {
- .width = info.size.width >> samples_x,
- .height = info.size.height >> samples_y,
- .depth = info.size.depth,
- },
+ .extent{
+ .width = info.size.width >> samples_x,
+ .height = info.size.height >> samples_y,
+ .depth = info.size.depth,
+ },
.mipLevels = static_cast<u32>(info.resources.levels),
.arrayLayers = static_cast<u32>(info.resources.layers),
.samples = ConvertSampleCount(info.num_samples),
.tiling = VK_IMAGE_TILING_OPTIMAL,
- .usage = usage,
+ .usage = ImageUsageFlags(format_info, format),
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,
@@ -209,10 +224,11 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
[[nodiscard]] VkAttachmentDescription AttachmentDescription(const Device& device,
const ImageView* image_view) {
- const auto pixel_format = image_view->format;
+ using MaxwellToVK::SurfaceFormat;
+ const PixelFormat pixel_format = image_view->format;
return VkAttachmentDescription{
.flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT,
- .format = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, pixel_format).format,
+ .format = SurfaceFormat(device, FormatType::Optimal, true, pixel_format).format,
.samples = image_view->Samples(),
.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
@@ -868,11 +884,16 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
std::ranges::transform(swizzle, swizzle.begin(), ConvertGreenRed);
}
}
- const VkFormat vk_format =
- MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, format).format;
+ const auto format_info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format);
+ const VkFormat vk_format = format_info.format;
+ const VkImageViewUsageCreateInfo image_view_usage{
+ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
+ .pNext = nullptr,
+ .usage = ImageUsageFlags(format_info, format),
+ };
const VkImageViewCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
- .pNext = nullptr,
+ .pNext = &image_view_usage,
.flags = 0,
.image = image.Handle(),
.viewType = VkImageViewType{},
@@ -962,7 +983,7 @@ vk::ImageView ImageView::MakeDepthStencilView(VkImageAspectFlags aspect_mask) {
.flags = 0,
.image = image_handle,
.viewType = ImageViewType(type),
- .format = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, format).format,
+ .format = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format).format,
.components{
.r = VK_COMPONENT_SWIZZLE_IDENTITY,
.g = VK_COMPONENT_SWIZZLE_IDENTITY,
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index a55d405d1..8d29361a1 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -72,7 +72,7 @@ struct TextureCacheRuntime {
MemoryAllocator& memory_allocator;
StagingBufferPool& staging_buffer_pool;
BlitImageHelper& blit_image_helper;
- std::unordered_map<RenderPassKey, vk::RenderPass> renderpass_cache;
+ std::unordered_map<RenderPassKey, vk::RenderPass> renderpass_cache{};
void Finish();
diff --git a/src/video_core/shader/async_shaders.cpp b/src/video_core/shader/async_shaders.cpp
index 9707136e9..3b40db9bc 100644
--- a/src/video_core/shader/async_shaders.cpp
+++ b/src/video_core/shader/async_shaders.cpp
@@ -129,6 +129,15 @@ void AsyncShaders::QueueOpenGLShader(const OpenGL::Device& device,
.compiler_settings = compiler_settings,
.registry = registry,
.cpu_address = cpu_addr,
+ .pp_cache = nullptr,
+ .vk_device = nullptr,
+ .scheduler = nullptr,
+ .descriptor_pool = nullptr,
+ .update_descriptor_queue = nullptr,
+ .bindings{},
+ .program{},
+ .key{},
+ .num_color_buffers = 0,
});
cv.notify_one();
}
@@ -143,6 +152,15 @@ void AsyncShaders::QueueVulkanShader(Vulkan::VKPipelineCache* pp_cache,
std::unique_lock lock(queue_mutex);
pending_queue.push({
.backend = Backend::Vulkan,
+ .device = nullptr,
+ .shader_type{},
+ .uid = 0,
+ .code{},
+ .code_b{},
+ .main_offset = 0,
+ .compiler_settings{},
+ .registry{},
+ .cpu_address = 0,
.pp_cache = pp_cache,
.vk_device = &device,
.scheduler = &scheduler,
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h
index c9840b75e..b54d33763 100644
--- a/src/video_core/shader/node.h
+++ b/src/video_core/shader/node.h
@@ -465,14 +465,6 @@ public:
return operands.size();
}
- NodeBlock& GetOperands() {
- return operands;
- }
-
- const NodeBlock& GetOperands() const {
- return operands;
- }
-
[[nodiscard]] const Node& operator[](std::size_t operand_index) const {
return operands.at(operand_index);
}
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 625a5eb46..a4987ffc6 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -388,54 +388,9 @@ void ShaderIR::SetInternalFlagsFromInteger(NodeBlock& bb, Node value, bool sets_
if (!sets_cc) {
return;
}
- switch (value->index()) {
- case 0: // Operation Node
- SearchOperands(bb, value);
- break;
- case 2: // General Purpose Node
- if (const auto* gpr = std::get_if<GprNode>(value.get())) {
- LOG_DEBUG(HW_GPU, "GprNode: index={}", gpr->GetIndex());
- Node zerop = Operation(OperationCode::LogicalIEqual, std::move(value),
- Immediate(gpr->GetIndex()));
- SetInternalFlag(bb, InternalFlag::Zero, std::move(zerop));
- }
- break;
-
- default:
- Node zerop = Operation(OperationCode::LogicalIEqual, std::move(value), Immediate(0));
- SetInternalFlag(bb, InternalFlag::Zero, std::move(zerop));
- LOG_WARNING(HW_GPU, "Node Type: {}", value->index());
- break;
- }
-}
-
-void ShaderIR::SearchOperands(NodeBlock& nb, Node var) {
- const auto* op = std::get_if<OperationNode>(var.get());
- if (op == nullptr) {
- return;
- }
-
- if (op->GetOperandsCount() == 0) {
- return;
- }
-
- for (auto& operand : op->GetOperands()) {
- switch (operand->index()) {
- case 0: // Operation Node
- return SearchOperands(nb, operand);
- case 2: // General Purpose Node
- if (const auto* gpr = std::get_if<GprNode>(operand.get())) {
- LOG_DEBUG(HW_GPU, "Child GprNode: index={}", gpr->GetIndex());
- Node zerop = Operation(OperationCode::LogicalIEqual, std::move(operand),
- Immediate(gpr->GetIndex()));
- SetInternalFlag(nb, InternalFlag::Zero, std::move(zerop));
- }
- break;
- default:
- LOG_WARNING(HW_GPU, "Child Node Type: {}", operand->index());
- break;
- }
- }
+ Node zerop = Operation(OperationCode::LogicalIEqual, std::move(value), Immediate(0));
+ SetInternalFlag(bb, InternalFlag::Zero, std::move(zerop));
+ LOG_WARNING(HW_GPU, "Condition codes implementation is incomplete");
}
Node ShaderIR::BitfieldExtract(Node value, u32 offset, u32 bits) {
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 0afa39531..0c6ab0f07 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -346,9 +346,6 @@ private:
/// Access a bindless image sampler.
ImageEntry& GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type);
- /// Recursive Iteration over the OperationNode operands, searching for GprNodes.
- void SearchOperands(NodeBlock& nb, Node var);
-
/// Extracts a sequence of bits from a node
Node BitfieldExtract(Node value, u32 offset, u32 bits);
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp
index b23424523..bb2cdef81 100644
--- a/src/video_core/texture_cache/util.cpp
+++ b/src/video_core/texture_cache/util.cpp
@@ -1193,25 +1193,35 @@ u32 MapSizeBytes(const ImageBase& image) {
}
}
-using P = PixelFormat;
-
-static_assert(CalculateLevelSize(LevelInfo{{1920, 1080}, {0, 2, 0}, {1, 1}, 2, 0}, 0) == 0x7f8000);
-static_assert(CalculateLevelSize(LevelInfo{{32, 32}, {0, 0, 4}, {1, 1}, 4, 0}, 0) == 0x4000);
-
-static_assert(CalculateLevelOffset(P::R8_SINT, {1920, 1080}, {0, 2}, 1, 0, 7) == 0x2afc00);
-static_assert(CalculateLevelOffset(P::ASTC_2D_12X12_UNORM, {8192, 4096}, {0, 2}, 1, 0, 12) ==
- 0x50d200);
-
-static_assert(CalculateLevelOffset(P::A8B8G8R8_UNORM, {1024, 1024}, {0, 4}, 1, 0, 0) == 0);
-static_assert(CalculateLevelOffset(P::A8B8G8R8_UNORM, {1024, 1024}, {0, 4}, 1, 0, 1) == 0x400000);
-static_assert(CalculateLevelOffset(P::A8B8G8R8_UNORM, {1024, 1024}, {0, 4}, 1, 0, 2) == 0x500000);
-static_assert(CalculateLevelOffset(P::A8B8G8R8_UNORM, {1024, 1024}, {0, 4}, 1, 0, 3) == 0x540000);
-static_assert(CalculateLevelOffset(P::A8B8G8R8_UNORM, {1024, 1024}, {0, 4}, 1, 0, 4) == 0x550000);
-static_assert(CalculateLevelOffset(P::A8B8G8R8_UNORM, {1024, 1024}, {0, 4}, 1, 0, 5) == 0x554000);
-static_assert(CalculateLevelOffset(P::A8B8G8R8_UNORM, {1024, 1024}, {0, 4}, 1, 0, 6) == 0x555000);
-static_assert(CalculateLevelOffset(P::A8B8G8R8_UNORM, {1024, 1024}, {0, 4}, 1, 0, 7) == 0x555400);
-static_assert(CalculateLevelOffset(P::A8B8G8R8_UNORM, {1024, 1024}, {0, 4}, 1, 0, 8) == 0x555600);
-static_assert(CalculateLevelOffset(P::A8B8G8R8_UNORM, {1024, 1024}, {0, 4}, 1, 0, 9) == 0x555800);
+static_assert(CalculateLevelSize(LevelInfo{{1920, 1080, 1}, {0, 2, 0}, {1, 1}, 2, 0}, 0) ==
+ 0x7f8000);
+static_assert(CalculateLevelSize(LevelInfo{{32, 32, 1}, {0, 0, 4}, {1, 1}, 4, 0}, 0) == 0x4000);
+
+static_assert(CalculateLevelOffset(PixelFormat::R8_SINT, {1920, 1080, 1}, {0, 2, 0}, 1, 0, 7) ==
+ 0x2afc00);
+static_assert(CalculateLevelOffset(PixelFormat::ASTC_2D_12X12_UNORM, {8192, 4096, 1}, {0, 2, 0}, 1,
+ 0, 12) == 0x50d200);
+
+static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0,
+ 0) == 0);
+static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0,
+ 1) == 0x400000);
+static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0,
+ 2) == 0x500000);
+static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0,
+ 3) == 0x540000);
+static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0,
+ 4) == 0x550000);
+static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0,
+ 5) == 0x554000);
+static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0,
+ 6) == 0x555000);
+static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0,
+ 7) == 0x555400);
+static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0,
+ 8) == 0x555600);
+static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0,
+ 9) == 0x555800);
constexpr u32 ValidateLayerSize(PixelFormat format, u32 width, u32 height, u32 block_height,
u32 tile_width_spacing, u32 level) {
@@ -1221,13 +1231,14 @@ constexpr u32 ValidateLayerSize(PixelFormat format, u32 width, u32 height, u32 b
return AlignLayerSize(offset, size, block, DefaultBlockHeight(format), tile_width_spacing);
}
-static_assert(ValidateLayerSize(P::ASTC_2D_12X12_UNORM, 8192, 4096, 2, 0, 12) == 0x50d800);
-static_assert(ValidateLayerSize(P::A8B8G8R8_UNORM, 1024, 1024, 2, 0, 10) == 0x556000);
-static_assert(ValidateLayerSize(P::BC3_UNORM, 128, 128, 2, 0, 8) == 0x6000);
+static_assert(ValidateLayerSize(PixelFormat::ASTC_2D_12X12_UNORM, 8192, 4096, 2, 0, 12) ==
+ 0x50d800);
+static_assert(ValidateLayerSize(PixelFormat::A8B8G8R8_UNORM, 1024, 1024, 2, 0, 10) == 0x556000);
+static_assert(ValidateLayerSize(PixelFormat::BC3_UNORM, 128, 128, 2, 0, 8) == 0x6000);
-static_assert(ValidateLayerSize(P::A8B8G8R8_UNORM, 518, 572, 4, 3, 1) == 0x190000,
+static_assert(ValidateLayerSize(PixelFormat::A8B8G8R8_UNORM, 518, 572, 4, 3, 1) == 0x190000,
"Tile width spacing is not working");
-static_assert(ValidateLayerSize(P::BC5_UNORM, 1024, 1024, 3, 4, 11) == 0x160000,
+static_assert(ValidateLayerSize(PixelFormat::BC5_UNORM, 1024, 1024, 3, 4, 11) == 0x160000,
"Compressed tile width spacing is not working");
} // namespace VideoCommon
diff --git a/src/video_core/vulkan_common/vulkan_debug_callback.cpp b/src/video_core/vulkan_common/vulkan_debug_callback.cpp
index ea7af8ad4..5c64c9bf7 100644
--- a/src/video_core/vulkan_common/vulkan_debug_callback.cpp
+++ b/src/video_core/vulkan_common/vulkan_debug_callback.cpp
@@ -39,6 +39,7 @@ vk::DebugUtilsMessenger CreateDebugCallback(const vk::Instance& instance) {
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
.pfnUserCallback = Callback,
+ .pUserData = nullptr,
});
}
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 37d7b45a3..5b4209c72 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -84,21 +84,6 @@ VkFormatFeatureFlags GetFormatFeatures(VkFormatProperties properties, FormatType
}
}
-[[nodiscard]] bool IsRDNA(std::string_view device_name, VkDriverIdKHR driver_id) {
- static constexpr std::array RDNA_DEVICES{
- "5700",
- "5600",
- "5500",
- "5300",
- };
- if (driver_id != VK_DRIVER_ID_AMD_PROPRIETARY_KHR) {
- return false;
- }
- return std::any_of(RDNA_DEVICES.begin(), RDNA_DEVICES.end(), [device_name](const char* name) {
- return device_name.find(name) != std::string_view::npos;
- });
-}
-
std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(vk::PhysicalDevice physical) {
static constexpr std::array formats{
VK_FORMAT_A8B8G8R8_UNORM_PACK32,
@@ -436,14 +421,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
"Blacklisting RADV for VK_EXT_extended_dynamic state, likely due to a bug in yuzu");
ext_extended_dynamic_state = false;
}
- if (ext_extended_dynamic_state && IsRDNA(properties.deviceName, driver_id)) {
- // AMD's proprietary driver supports VK_EXT_extended_dynamic_state but on RDNA devices it
- // seems to cause stability issues
- LOG_WARNING(
- Render_Vulkan,
- "Blacklisting AMD proprietary on RDNA devices from VK_EXT_extended_dynamic_state");
- ext_extended_dynamic_state = false;
- }
graphics_queue = logical.GetQueue(graphics_family);
present_queue = logical.GetQueue(present_family);