Clyde/molten vk 64bit fix

This commit is contained in:
Nick Majkic 2024-03-12 01:25:24 +00:00 committed by Crimson Hawk
parent de83c5e6a6
commit b2b769e45b

View file

@ -29,21 +29,21 @@
namespace Vulkan { namespace Vulkan {
using Tegra::Engines::Fermi2D; using Tegra::Engines::Fermi2D;
using Tegra::Texture::SwizzleSource; using Tegra::Texture::SwizzleSource;
using Tegra::Texture::TextureMipmapFilter; using Tegra::Texture::TextureMipmapFilter;
using VideoCommon::BufferImageCopy; using VideoCommon::BufferImageCopy;
using VideoCommon::ImageFlagBits; using VideoCommon::ImageFlagBits;
using VideoCommon::ImageInfo; using VideoCommon::ImageInfo;
using VideoCommon::ImageType; using VideoCommon::ImageType;
using VideoCommon::SubresourceRange; using VideoCommon::SubresourceRange;
using VideoCore::Surface::BytesPerBlock; using VideoCore::Surface::BytesPerBlock;
using VideoCore::Surface::IsPixelFormatASTC; using VideoCore::Surface::IsPixelFormatASTC;
using VideoCore::Surface::IsPixelFormatInteger; using VideoCore::Surface::IsPixelFormatInteger;
using VideoCore::Surface::SurfaceType; using VideoCore::Surface::SurfaceType;
namespace { namespace {
constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
if (color == std::array<float, 4>{0, 0, 0, 0}) { if (color == std::array<float, 4>{0, 0, 0, 0}) {
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
} else if (color == std::array<float, 4>{0, 0, 0, 1}) { } else if (color == std::array<float, 4>{0, 0, 0, 1}) {
@ -59,9 +59,9 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
} else { } else {
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
} }
} }
[[nodiscard]] VkImageType ConvertImageType(const ImageType type) { [[nodiscard]] VkImageType ConvertImageType(const ImageType type) {
switch (type) { switch (type) {
case ImageType::e1D: case ImageType::e1D:
return VK_IMAGE_TYPE_1D; return VK_IMAGE_TYPE_1D;
@ -75,9 +75,9 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
} }
ASSERT_MSG(false, "Invalid image type={}", type); ASSERT_MSG(false, "Invalid image type={}", type);
return {}; return {};
} }
[[nodiscard]] VkSampleCountFlagBits ConvertSampleCount(u32 num_samples) { [[nodiscard]] VkSampleCountFlagBits ConvertSampleCount(u32 num_samples) {
switch (num_samples) { switch (num_samples) {
case 1: case 1:
return VK_SAMPLE_COUNT_1_BIT; return VK_SAMPLE_COUNT_1_BIT;
@ -93,9 +93,9 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
ASSERT_MSG(false, "Invalid number of samples={}", num_samples); ASSERT_MSG(false, "Invalid number of samples={}", num_samples);
return VK_SAMPLE_COUNT_1_BIT; return VK_SAMPLE_COUNT_1_BIT;
} }
} }
[[nodiscard]] VkImageUsageFlags ImageUsageFlags(const MaxwellToVK::FormatInfo& info, [[nodiscard]] VkImageUsageFlags ImageUsageFlags(const MaxwellToVK::FormatInfo& info,
PixelFormat format) { PixelFormat format) {
VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT; VK_IMAGE_USAGE_SAMPLED_BIT;
@ -118,18 +118,25 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
usage |= VK_IMAGE_USAGE_STORAGE_BIT; usage |= VK_IMAGE_USAGE_STORAGE_BIT;
} }
return usage; return usage;
} }
[[nodiscard]] VkImageCreateInfo MakeImageCreateInfo(const Device& device, const ImageInfo& info) { [[nodiscard]] VkImageCreateInfo MakeImageCreateInfo(const Device& device, const ImageInfo& info) {
const bool is_2d = (info.type == ImageType::e2D);
const bool is_3d = (info.type == ImageType::e3D);
const auto format_info = const auto format_info =
MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, false, info.format); MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, false, info.format);
VkImageCreateFlags flags{}; VkImageCreateFlags flags{};
if (info.type == ImageType::e2D && info.resources.layers >= 6 && if (is_2d && info.resources.layers >= 6 && info.size.width == info.size.height &&
info.size.width == info.size.height && !device.HasBrokenCubeImageCompatibility()) { !device.HasBrokenCubeImageCompatibility()) {
flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
} }
if (info.type == ImageType::e3D) {
// fix moltenVK issues with some 3D games
// credit to Jarrod Norwell from Sudachi https://github.com/jarrodnorwell/Sudachi
auto usage = ImageUsageFlags(format_info, info.format);
if (is_3d) {
flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
} }
const auto [samples_x, samples_y] = VideoCommon::SamplesLog2(info.num_samples); const auto [samples_x, samples_y] = VideoCommon::SamplesLog2(info.num_samples);
return VkImageCreateInfo{ return VkImageCreateInfo{
@ -147,17 +154,18 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
.arrayLayers = static_cast<u32>(info.resources.layers), .arrayLayers = static_cast<u32>(info.resources.layers),
.samples = ConvertSampleCount(info.num_samples), .samples = ConvertSampleCount(info.num_samples),
.tiling = VK_IMAGE_TILING_OPTIMAL, .tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = ImageUsageFlags(format_info, info.format), .usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0, .queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr, .pQueueFamilyIndices = nullptr,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
}; };
} }
[[nodiscard]] vk::Image MakeImage(const Device& device, const MemoryAllocator& allocator, [[nodiscard]] vk::Image MakeImage(const Device& device, const MemoryAllocator& allocator,
const ImageInfo& info, std::span<const VkFormat> view_formats) { const ImageInfo& info, std::span<const VkFormat> view_formats) {
if (info.type == ImageType::Buffer) { const bool is_buffer = (info.type == ImageType::Buffer);
if (is_buffer) {
return vk::Image{}; return vk::Image{};
} }
VkImageCreateInfo image_ci = MakeImageCreateInfo(device, info); VkImageCreateInfo image_ci = MakeImageCreateInfo(device, info);
@ -174,9 +182,9 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
} }
} }
return allocator.CreateImage(image_ci); return allocator.CreateImage(image_ci);
} }
[[nodiscard]] vk::ImageView MakeStorageView(const vk::Device& device, u32 level, VkImage image, [[nodiscard]] vk::ImageView MakeStorageView(const vk::Device& device, u32 level, VkImage image,
VkFormat format) { VkFormat format) {
static constexpr VkImageViewUsageCreateInfo storage_image_view_usage_create_info{ static constexpr VkImageViewUsageCreateInfo storage_image_view_usage_create_info{
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
@ -204,9 +212,9 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
.layerCount = VK_REMAINING_ARRAY_LAYERS, .layerCount = VK_REMAINING_ARRAY_LAYERS,
}, },
}); });
} }
[[nodiscard]] VkImageAspectFlags ImageAspectMask(PixelFormat format) { [[nodiscard]] VkImageAspectFlags ImageAspectMask(PixelFormat format) {
switch (VideoCore::Surface::GetFormatType(format)) { switch (VideoCore::Surface::GetFormatType(format)) {
case VideoCore::Surface::SurfaceType::ColorTexture: case VideoCore::Surface::SurfaceType::ColorTexture:
return VK_IMAGE_ASPECT_COLOR_BIT; return VK_IMAGE_ASPECT_COLOR_BIT;
@ -220,9 +228,9 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
ASSERT_MSG(false, "Invalid surface type"); ASSERT_MSG(false, "Invalid surface type");
return VkImageAspectFlags{}; return VkImageAspectFlags{};
} }
} }
[[nodiscard]] VkImageAspectFlags ImageViewAspectMask(const VideoCommon::ImageViewInfo& info) { [[nodiscard]] VkImageAspectFlags ImageViewAspectMask(const VideoCommon::ImageViewInfo& info) {
if (info.IsRenderTarget()) { if (info.IsRenderTarget()) {
return ImageAspectMask(info.format); return ImageAspectMask(info.format);
} }
@ -245,9 +253,9 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
default: default:
return VK_IMAGE_ASPECT_COLOR_BIT; return VK_IMAGE_ASPECT_COLOR_BIT;
} }
} }
[[nodiscard]] VkComponentSwizzle ComponentSwizzle(SwizzleSource swizzle) { [[nodiscard]] VkComponentSwizzle ComponentSwizzle(SwizzleSource swizzle) {
switch (swizzle) { switch (swizzle) {
case SwizzleSource::Zero: case SwizzleSource::Zero:
return VK_COMPONENT_SWIZZLE_ZERO; return VK_COMPONENT_SWIZZLE_ZERO;
@ -265,9 +273,9 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
} }
ASSERT_MSG(false, "Invalid swizzle={}", swizzle); ASSERT_MSG(false, "Invalid swizzle={}", swizzle);
return VK_COMPONENT_SWIZZLE_ZERO; return VK_COMPONENT_SWIZZLE_ZERO;
} }
[[nodiscard]] VkImageViewType ImageViewType(Shader::TextureType type) { [[nodiscard]] VkImageViewType ImageViewType(Shader::TextureType type) {
switch (type) { switch (type) {
case Shader::TextureType::Color1D: case Shader::TextureType::Color1D:
return VK_IMAGE_VIEW_TYPE_1D; return VK_IMAGE_VIEW_TYPE_1D;
@ -290,9 +298,9 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
} }
ASSERT_MSG(false, "Invalid image view type={}", type); ASSERT_MSG(false, "Invalid image view type={}", type);
return VK_IMAGE_VIEW_TYPE_2D; return VK_IMAGE_VIEW_TYPE_2D;
} }
[[nodiscard]] VkImageViewType ImageViewType(VideoCommon::ImageViewType type) { [[nodiscard]] VkImageViewType ImageViewType(VideoCommon::ImageViewType type) {
switch (type) { switch (type) {
case VideoCommon::ImageViewType::e1D: case VideoCommon::ImageViewType::e1D:
return VK_IMAGE_VIEW_TYPE_1D; return VK_IMAGE_VIEW_TYPE_1D;
@ -315,9 +323,9 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
} }
ASSERT_MSG(false, "Invalid image view type={}", type); ASSERT_MSG(false, "Invalid image view type={}", type);
return VK_IMAGE_VIEW_TYPE_2D; return VK_IMAGE_VIEW_TYPE_2D;
} }
[[nodiscard]] VkImageSubresourceLayers MakeImageSubresourceLayers( [[nodiscard]] VkImageSubresourceLayers MakeImageSubresourceLayers(
VideoCommon::SubresourceLayers subresource, VkImageAspectFlags aspect_mask) { VideoCommon::SubresourceLayers subresource, VkImageAspectFlags aspect_mask) {
return VkImageSubresourceLayers{ return VkImageSubresourceLayers{
.aspectMask = aspect_mask, .aspectMask = aspect_mask,
@ -325,25 +333,25 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
.baseArrayLayer = static_cast<u32>(subresource.base_layer), .baseArrayLayer = static_cast<u32>(subresource.base_layer),
.layerCount = static_cast<u32>(subresource.num_layers), .layerCount = static_cast<u32>(subresource.num_layers),
}; };
} }
[[nodiscard]] VkOffset3D MakeOffset3D(VideoCommon::Offset3D offset3d) { [[nodiscard]] VkOffset3D MakeOffset3D(VideoCommon::Offset3D offset3d) {
return VkOffset3D{ return VkOffset3D{
.x = offset3d.x, .x = offset3d.x,
.y = offset3d.y, .y = offset3d.y,
.z = offset3d.z, .z = offset3d.z,
}; };
} }
[[nodiscard]] VkExtent3D MakeExtent3D(VideoCommon::Extent3D extent3d) { [[nodiscard]] VkExtent3D MakeExtent3D(VideoCommon::Extent3D extent3d) {
return VkExtent3D{ return VkExtent3D{
.width = static_cast<u32>(extent3d.width), .width = static_cast<u32>(extent3d.width),
.height = static_cast<u32>(extent3d.height), .height = static_cast<u32>(extent3d.height),
.depth = static_cast<u32>(extent3d.depth), .depth = static_cast<u32>(extent3d.depth),
}; };
} }
[[nodiscard]] VkImageCopy MakeImageCopy(const VideoCommon::ImageCopy& copy, [[nodiscard]] VkImageCopy MakeImageCopy(const VideoCommon::ImageCopy& copy,
VkImageAspectFlags aspect_mask) noexcept { VkImageAspectFlags aspect_mask) noexcept {
return VkImageCopy{ return VkImageCopy{
.srcSubresource = MakeImageSubresourceLayers(copy.src_subresource, aspect_mask), .srcSubresource = MakeImageSubresourceLayers(copy.src_subresource, aspect_mask),
@ -356,15 +364,15 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
[[nodiscard]] VkBufferImageCopy MakeBufferImageCopy(const VideoCommon::ImageCopy& copy, bool is_src, [[nodiscard]] VkBufferImageCopy MakeBufferImageCopy(const VideoCommon::ImageCopy& copy, bool is_src,
VkImageAspectFlags aspect_mask) noexcept { VkImageAspectFlags aspect_mask) noexcept {
return VkBufferImageCopy{ return VkBufferImageCopy{
.bufferOffset = 0, .bufferOffset = 0,
.bufferRowLength = 0, .bufferRowLength = 0,
.bufferImageHeight = 0, .bufferImageHeight = 0,
.imageSubresource = MakeImageSubresourceLayers( .imageSubresource = MakeImageSubresourceLayers(
is_src ? copy.src_subresource : copy.dst_subresource, aspect_mask), is_src ? copy.src_subresource : copy.dst_subresource, aspect_mask),
.imageOffset = MakeOffset3D(is_src ? copy.src_offset : copy.dst_offset), .imageOffset = MakeOffset3D(is_src ? copy.src_offset : copy.dst_offset),
.imageExtent = MakeExtent3D(copy.extent), .imageExtent = MakeExtent3D(copy.extent),
}; };
} }
[[maybe_unused]] [[nodiscard]] boost::container::small_vector<VkBufferCopy, 16> [[maybe_unused]] [[nodiscard]] boost::container::small_vector<VkBufferCopy, 16>
@ -697,7 +705,7 @@ struct RangedBarrierRange {
void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const ImageInfo& info, void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const ImageInfo& info,
VkImageAspectFlags aspect_mask, const Settings::ResolutionScalingInfo& resolution, VkImageAspectFlags aspect_mask, const Settings::ResolutionScalingInfo& resolution,
bool up_scaling = true) { bool up_scaling = true) {
const bool is_2d = info.type == ImageType::e2D; const bool is_2d = (info.type == ImageType::e2D);
const auto resources = info.resources; const auto resources = info.resources;
const VkExtent2D extent{ const VkExtent2D extent{
.width = info.size.width, .width = info.size.width,
@ -1536,18 +1544,18 @@ void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferIm
} }
VkImageView Image::StorageImageView(s32 level) noexcept { VkImageView Image::StorageImageView(s32 level) noexcept {
auto& view = storage_image_views[level]; auto& view = storage_image_views[level];
if (!view) { if (!view) {
const auto format_info = const auto format_info =
MaxwellToVK::SurfaceFormat(runtime->device, FormatType::Optimal, true, info.format); MaxwellToVK::SurfaceFormat(runtime->device, FormatType::Optimal, true, info.format);
view = view =
MakeStorageView(runtime->device.GetLogical(), level, current_image, format_info.format); MakeStorageView(runtime->device.GetLogical(), level, current_image, format_info.format);
} }
return *view; return *view;
} }
bool Image::IsRescaled() const noexcept { bool Image::IsRescaled() const noexcept {
return True(flags & ImageFlagBits::Rescaled); return True(flags & ImageFlagBits::Rescaled);
} }
bool Image::ScaleUp(bool ignore) { bool Image::ScaleUp(bool ignore) {
@ -1562,7 +1570,7 @@ bool Image::ScaleUp(bool ignore) {
flags |= ImageFlagBits::Rescaled; flags |= ImageFlagBits::Rescaled;
has_scaled = true; has_scaled = true;
if (!scaled_image) { if (!scaled_image) {
const bool is_2d = info.type == ImageType::e2D; const bool is_2d = (info.type == ImageType::e2D);
const u32 scaled_width = resolution.ScaleUp(info.size.width); const u32 scaled_width = resolution.ScaleUp(info.size.width);
const u32 scaled_height = is_2d ? resolution.ScaleUp(info.size.height) : info.size.height; const u32 scaled_height = is_2d ? resolution.ScaleUp(info.size.height) : info.size.height;
auto scaled_info = info; auto scaled_info = info;
@ -1620,7 +1628,7 @@ bool Image::BlitScaleHelper(bool scale_up) {
const auto operation = is_bilinear ? Tegra::Engines::Fermi2D::Filter::Bilinear const auto operation = is_bilinear ? Tegra::Engines::Fermi2D::Filter::Bilinear
: Tegra::Engines::Fermi2D::Filter::Point; : Tegra::Engines::Fermi2D::Filter::Point;
const bool is_2d = info.type == ImageType::e2D; const bool is_2d = (info.type == ImageType::e2D);
const auto& resolution = runtime->resolution; const auto& resolution = runtime->resolution;
const u32 scaled_width = resolution.ScaleUp(info.size.width); const u32 scaled_width = resolution.ScaleUp(info.size.width);
const u32 scaled_height = is_2d ? resolution.ScaleUp(info.size.height) : info.size.height; const u32 scaled_height = is_2d ? resolution.ScaleUp(info.size.height) : info.size.height;
@ -1862,12 +1870,12 @@ VkImageView ImageView::StorageView(Shader::TextureType texture_type,
} }
bool ImageView::IsRescaled() const noexcept { bool ImageView::IsRescaled() const noexcept {
if (!slot_images) { if (!slot_images) {
return false; return false;
} }
const auto& slots = *slot_images; const auto& slots = *slot_images;
const auto& src_image = slots[image_id]; const auto& src_image = slots[image_id];
return src_image.IsRescaled(); return src_image.IsRescaled();
} }
vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) { vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) {
@ -1954,7 +1962,7 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM
: render_area{VkExtent2D{ : render_area{VkExtent2D{
.width = key.size.width, .width = key.size.width,
.height = key.size.height, .height = key.size.height,
}} { }} {
CreateFramebuffer(runtime, color_buffers, depth_buffer, key.is_rescaled); CreateFramebuffer(runtime, color_buffers, depth_buffer, key.is_rescaled);
if (runtime.device.HasDebuggingToolAttached()) { if (runtime.device.HasDebuggingToolAttached()) {
framebuffer.SetObjectNameEXT(VideoCommon::Name(key).c_str()); framebuffer.SetObjectNameEXT(VideoCommon::Name(key).c_str());