mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-08-03 11:23:49 +00:00
Vulkan driver query caching
This commit is contained in:
@@ -21,7 +21,8 @@ RenderTargetFormatInfo TextureGetRenderTargetFormat(uint32_t raw_layout, uint32_
|
||||
const auto layout = static_cast<Prospero::ChannelLayout>(raw_layout);
|
||||
const auto type = static_cast<Prospero::ChannelType>(raw_type);
|
||||
const auto order = static_cast<Prospero::ChannelOrder>(raw_order);
|
||||
const auto is = [=](Prospero::ChannelLayout l, Prospero::ChannelType t, Prospero::ChannelOrder o) {
|
||||
const auto is = [=](Prospero::ChannelLayout l, Prospero::ChannelType t,
|
||||
Prospero::ChannelOrder o) {
|
||||
return layout == l && type == t && order == o;
|
||||
};
|
||||
|
||||
@@ -29,82 +30,108 @@ RenderTargetFormatInfo TextureGetRenderTargetFormat(uint32_t raw_layout, uint32_
|
||||
raw_order <= Prospero::GpuEnumValue(Prospero::ChannelOrder::kAltReversed)) {
|
||||
return {VK_FORMAT_R8_UNORM, 1};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k8_8, Prospero::ChannelType::kUNorm, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k8_8, Prospero::ChannelType::kUNorm,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R8G8_UNORM, 2};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k8_8_8_8, Prospero::ChannelType::kUNorm, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k8_8_8_8, Prospero::ChannelType::kUNorm,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R8G8B8A8_UNORM, 4};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k8_8_8_8, Prospero::ChannelType::kSNorm, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k8_8_8_8, Prospero::ChannelType::kSNorm,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R8G8B8A8_SNORM, 4};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k8_8_8_8, Prospero::ChannelType::kSrgb, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k8_8_8_8, Prospero::ChannelType::kSrgb,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R8G8B8A8_SRGB, 4};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k8_8_8_8, Prospero::ChannelType::kUNorm, Prospero::ChannelOrder::kAlt)) {
|
||||
if (is(Prospero::ChannelLayout::k8_8_8_8, Prospero::ChannelType::kUNorm,
|
||||
Prospero::ChannelOrder::kAlt)) {
|
||||
return {VK_FORMAT_B8G8R8A8_UNORM, 4};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k8_8_8_8, Prospero::ChannelType::kSNorm, Prospero::ChannelOrder::kAlt)) {
|
||||
if (is(Prospero::ChannelLayout::k8_8_8_8, Prospero::ChannelType::kSNorm,
|
||||
Prospero::ChannelOrder::kAlt)) {
|
||||
return {VK_FORMAT_B8G8R8A8_SNORM, 4};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k8_8_8_8, Prospero::ChannelType::kSrgb, Prospero::ChannelOrder::kAlt)) {
|
||||
if (is(Prospero::ChannelLayout::k8_8_8_8, Prospero::ChannelType::kSrgb,
|
||||
Prospero::ChannelOrder::kAlt)) {
|
||||
return {VK_FORMAT_B8G8R8A8_SRGB, 4};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k5_5_5_1, Prospero::ChannelType::kUNorm, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k5_5_5_1, Prospero::ChannelType::kUNorm,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R5G5B5A1_UNORM_PACK16, 2};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k4_4_4_4, Prospero::ChannelType::kUNorm, Prospero::ChannelOrder::kReversed)) {
|
||||
if (is(Prospero::ChannelLayout::k4_4_4_4, Prospero::ChannelType::kUNorm,
|
||||
Prospero::ChannelOrder::kReversed)) {
|
||||
return {VK_FORMAT_B4G4R4A4_UNORM_PACK16, 2};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k10_10_10_2, Prospero::ChannelType::kUNorm, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k10_10_10_2, Prospero::ChannelType::kUNorm,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_A2B10G10R10_UNORM_PACK32, 4};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k10_10_10_2, Prospero::ChannelType::kUNorm, Prospero::ChannelOrder::kAlt)) {
|
||||
if (is(Prospero::ChannelLayout::k10_10_10_2, Prospero::ChannelType::kUNorm,
|
||||
Prospero::ChannelOrder::kAlt)) {
|
||||
return {VK_FORMAT_A2R10G10B10_UNORM_PACK32, 4};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k11_11_10, Prospero::ChannelType::kFloat, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k11_11_10, Prospero::ChannelType::kFloat,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_B10G11R11_UFLOAT_PACK32, 4};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k16, Prospero::ChannelType::kUNorm, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k16, Prospero::ChannelType::kUNorm,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R16_UNORM, 2};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k16, Prospero::ChannelType::kUInt, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k16, Prospero::ChannelType::kUInt,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R16_UINT, 2};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k16, Prospero::ChannelType::kFloat, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k16, Prospero::ChannelType::kFloat,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R16_SFLOAT, 2};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k16_16, Prospero::ChannelType::kUNorm, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k16_16, Prospero::ChannelType::kUNorm,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R16G16_UNORM, 4};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k16_16, Prospero::ChannelType::kSNorm, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k16_16, Prospero::ChannelType::kSNorm,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R16G16_SNORM, 4};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k16_16, Prospero::ChannelType::kUInt, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k16_16, Prospero::ChannelType::kUInt,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R16G16_UINT, 4};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k16_16, Prospero::ChannelType::kFloat, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k16_16, Prospero::ChannelType::kFloat,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R16G16_SFLOAT, 4};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k16_16_16_16, Prospero::ChannelType::kUNorm, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k16_16_16_16, Prospero::ChannelType::kUNorm,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R16G16B16A16_UNORM, 8};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k16_16_16_16, Prospero::ChannelType::kFloat, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k16_16_16_16, Prospero::ChannelType::kFloat,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R16G16B16A16_SFLOAT, 8};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k16_16_16_16, Prospero::ChannelType::kFloat, Prospero::ChannelOrder::kReversed)) {
|
||||
if (is(Prospero::ChannelLayout::k16_16_16_16, Prospero::ChannelType::kFloat,
|
||||
Prospero::ChannelOrder::kReversed)) {
|
||||
return {VK_FORMAT_R16G16B16A16_SFLOAT, 8, Prospero::ColorMappingAbgr};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k32, Prospero::ChannelType::kFloat, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k32, Prospero::ChannelType::kFloat,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R32_SFLOAT, 4};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k32_32, Prospero::ChannelType::kUInt, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k32_32, Prospero::ChannelType::kUInt,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R32G32_UINT, 8};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k32_32, Prospero::ChannelType::kFloat, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k32_32, Prospero::ChannelType::kFloat,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R32G32_SFLOAT, 8};
|
||||
}
|
||||
if (is(Prospero::ChannelLayout::k32_32_32_32, Prospero::ChannelType::kFloat, Prospero::ChannelOrder::kStandard)) {
|
||||
if (is(Prospero::ChannelLayout::k32_32_32_32, Prospero::ChannelType::kFloat,
|
||||
Prospero::ChannelOrder::kStandard)) {
|
||||
return {VK_FORMAT_R32G32B32A32_SFLOAT, 16};
|
||||
}
|
||||
EXIT("unsupported render-target format combination: layout=%u type=%u order=%u\n", raw_layout,
|
||||
@@ -230,9 +257,9 @@ VkComponentMapping TextureGetComponentMapping(uint32_t swizzle) {
|
||||
|
||||
bool TextureCheckFormat(GraphicContext* ctx, VkImageCreateInfo* image_info) {
|
||||
VkImageFormatProperties props {};
|
||||
if (vkGetPhysicalDeviceImageFormatProperties(
|
||||
ctx->physical_device, image_info->format, image_info->imageType, image_info->tiling,
|
||||
image_info->usage, image_info->flags, &props) == VK_ERROR_FORMAT_NOT_SUPPORTED) {
|
||||
if (ctx->GetImageFormatProperties(image_info->format, image_info->imageType, image_info->tiling,
|
||||
image_info->usage, image_info->flags,
|
||||
&props) == VK_ERROR_FORMAT_NOT_SUPPORTED) {
|
||||
auto apply_fallback = [&](VkFormat replacement, const char* message) {
|
||||
image_info->format = replacement;
|
||||
const bool result = TextureCheckFormat(ctx, image_info);
|
||||
@@ -257,9 +284,9 @@ bool TextureCheckFormat(GraphicContext* ctx, VkImageCreateInfo* image_info) {
|
||||
|
||||
static bool TextureCheckFormatExact(GraphicContext* ctx, const VkImageCreateInfo& image_info) {
|
||||
VkImageFormatProperties props {};
|
||||
return vkGetPhysicalDeviceImageFormatProperties(
|
||||
ctx->physical_device, image_info.format, image_info.imageType, image_info.tiling,
|
||||
image_info.usage, image_info.flags, &props) != VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
return ctx->GetImageFormatProperties(image_info.format, image_info.imageType, image_info.tiling,
|
||||
image_info.usage, image_info.flags,
|
||||
&props) != VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
bool TextureCheckStorageSwizzle(VkImageCreateInfo* image_info, VkComponentMapping* components) {
|
||||
@@ -453,7 +480,8 @@ bool TextureIsCubeTexture(uint64_t type) {
|
||||
|
||||
bool TextureIsLayeredTexture(uint64_t type) {
|
||||
const auto image_type = static_cast<Prospero::ImageType>(type);
|
||||
return image_type == Prospero::ImageType::kCube || image_type == Prospero::ImageType::kColor1DArray ||
|
||||
return image_type == Prospero::ImageType::kCube ||
|
||||
image_type == Prospero::ImageType::kColor1DArray ||
|
||||
image_type == Prospero::ImageType::kColor2DArray ||
|
||||
image_type == Prospero::ImageType::kColor2DMsaaArray;
|
||||
}
|
||||
@@ -664,11 +692,13 @@ static uint64_t CalcTextureSliceStride(const TileSizeOffset* level_sizes, uint64
|
||||
}
|
||||
|
||||
static uint64_t CalcLinearUploadLevelSize(uint32_t fmt, uint32_t pitch, uint32_t height) {
|
||||
if (const uint32_t bytes_per_element = Prospero::NumBytesPerElement(fmt); bytes_per_element != 0) {
|
||||
if (const uint32_t bytes_per_element = Prospero::NumBytesPerElement(fmt);
|
||||
bytes_per_element != 0) {
|
||||
return static_cast<uint64_t>(pitch) * height * bytes_per_element;
|
||||
}
|
||||
|
||||
if (const uint32_t bytes_per_block = Prospero::BlockCompressedBytesPerBlock(fmt); bytes_per_block != 0) {
|
||||
if (const uint32_t bytes_per_block = Prospero::BlockCompressedBytesPerBlock(fmt);
|
||||
bytes_per_block != 0) {
|
||||
const uint32_t blocks_w = std::max((pitch + 3u) / 4u, 1u);
|
||||
const uint32_t blocks_h = std::max((height + 3u) / 4u, 1u);
|
||||
return static_cast<uint64_t>(blocks_w) * blocks_h * bytes_per_block;
|
||||
@@ -737,7 +767,8 @@ TextureUploadLayout TextureCalcUploadLayout(uint32_t fmt, uint64_t width, uint64
|
||||
(TileIsStandard64KBTextureSupported(static_cast<uint32_t>(fmt)) &&
|
||||
tile_mode == Prospero::TileMode::kStandard64KB);
|
||||
layout.fmt_tiled_depth =
|
||||
(allow_depth_tile && Prospero::RenderTargetBytesPerElement(static_cast<uint32_t>(fmt)) != 0 &&
|
||||
(allow_depth_tile &&
|
||||
Prospero::RenderTargetBytesPerElement(static_cast<uint32_t>(fmt)) != 0 &&
|
||||
tile_mode == Prospero::TileMode::kDepth);
|
||||
if (!layout.fmt_tiled_render_target && !layout.fmt_tiled_standard256b &&
|
||||
!layout.fmt_tiled_standard4kb && !layout.fmt_tiled_standard64kb &&
|
||||
@@ -827,7 +858,8 @@ TextureBuildUploadRegions(const TextureUploadLayout& layout, VkFormat image_form
|
||||
if (layout.fmt_tiled_depth && layout.level_sizes[i].x != 0) {
|
||||
regions[region_index].pitch = layout.level_sizes[i].x;
|
||||
} else if (!layout.volume_texture &&
|
||||
static_cast<Prospero::TileMode>(layout.tile) == Prospero::TileMode::kLinear &&
|
||||
static_cast<Prospero::TileMode>(layout.tile) ==
|
||||
Prospero::TileMode::kLinear &&
|
||||
layout.padded_sizes[i].width != 0) {
|
||||
regions[region_index].pitch = layout.padded_sizes[i].width;
|
||||
} else {
|
||||
@@ -958,7 +990,8 @@ void TextureUploadGuestImage(GraphicContext* ctx, VulkanImage* vk_obj, const voi
|
||||
UploadFmaskIdentity(ctx, vk_obj, regions, dst_layout, owner);
|
||||
return;
|
||||
}
|
||||
const uint32_t bytes_per_element = Prospero::RenderTargetBytesPerElement(static_cast<uint32_t>(fmt));
|
||||
const uint32_t bytes_per_element =
|
||||
Prospero::RenderTargetBytesPerElement(static_cast<uint32_t>(fmt));
|
||||
if (bytes_per_element == 1) {
|
||||
UtilFillImage(ctx, vk_obj, src_data, size, regions, dst_layout);
|
||||
} else {
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#include "graphics/guest_gpu/tile.h"
|
||||
#include "graphics/host_gpu/graphicContext.h"
|
||||
#include "graphics/host_gpu/objects/textureCommon.h"
|
||||
#include "graphics/host_gpu/renderer/descriptorCache.h"
|
||||
#include "graphics/host_gpu/renderer/debug.h"
|
||||
#include "graphics/host_gpu/renderer/descriptorCache.h"
|
||||
#include "graphics/host_gpu/renderer/framebufferCache.h"
|
||||
#include "graphics/host_gpu/renderer/render.h"
|
||||
#include "graphics/host_gpu/renderer/renderContext.h"
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
#include <vulkan/vk_enum_string_helper.h>
|
||||
|
||||
namespace Libs::Graphics {
|
||||
@@ -74,21 +73,15 @@ static bool UsesStencilOpValue(uint8_t fail, uint8_t pass, uint8_t depth_fail) {
|
||||
if (ctx == nullptr) {
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
// Kyty selects one physical device. Query its optional D16S8-compatible formats once.
|
||||
static std::once_flag once;
|
||||
static VkFormat selected = VK_FORMAT_UNDEFINED;
|
||||
std::call_once(once, [&] {
|
||||
for (const auto format: policy.stencil_attachment_formats) {
|
||||
VkImageFormatProperties properties {};
|
||||
if (vkGetPhysicalDeviceImageFormatProperties(
|
||||
ctx->physical_device, format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
|
||||
DepthTargetImageUsage(), 0, &properties) == VK_SUCCESS) {
|
||||
selected = format;
|
||||
break;
|
||||
}
|
||||
for (const auto format: policy.stencil_attachment_formats) {
|
||||
VkImageFormatProperties properties {};
|
||||
if (ctx->GetImageFormatProperties(format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
|
||||
DepthTargetImageUsage(), 0,
|
||||
&properties) == VK_SUCCESS) {
|
||||
return format;
|
||||
}
|
||||
});
|
||||
return selected;
|
||||
}
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
default: return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
@@ -416,9 +416,9 @@ struct TextureCache::ReadbackWorker {
|
||||
cached.info, Prospero::SurfaceFormat(cached.info.format),
|
||||
Prospero::NumBytesPerElement(cached.info.format))
|
||||
: MakeColorImageTransferInfo(cached.target);
|
||||
const bool linear = info.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kLinear);
|
||||
const bool tiled = target && IsTiledRenderTarget(cached.target);
|
||||
bool single_layer_storage = false;
|
||||
const bool linear = info.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kLinear);
|
||||
const bool tiled = target && IsTiledRenderTarget(cached.target);
|
||||
bool single_layer_storage = false;
|
||||
if (storage) {
|
||||
switch (static_cast<Prospero::ImageType>(cached.info.type)) {
|
||||
case Prospero::ImageType::kColor2D:
|
||||
@@ -785,8 +785,7 @@ TextureImageCreateParams MakeImageParams(const ImageInfo& info, bool storage) {
|
||||
}
|
||||
|
||||
bool FormatSupportsStorage(GraphicContext* ctx, VkFormat format) {
|
||||
VkFormatProperties properties {};
|
||||
vkGetPhysicalDeviceFormatProperties(ctx->physical_device, format, &properties);
|
||||
const auto properties = ctx->GetFormatProperties(format);
|
||||
return (properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0;
|
||||
}
|
||||
|
||||
@@ -818,9 +817,8 @@ VkImageUsageFlags RenderTargetUsage(GraphicContext* ctx, VkFormat format,
|
||||
usage |= VK_IMAGE_USAGE_STORAGE_BIT;
|
||||
}
|
||||
VkImageFormatProperties properties {};
|
||||
if (vkGetPhysicalDeviceImageFormatProperties(ctx->physical_device, format, VK_IMAGE_TYPE_2D,
|
||||
VK_IMAGE_TILING_OPTIMAL, usage, flags,
|
||||
&properties) != VK_SUCCESS) {
|
||||
if (ctx->GetImageFormatProperties(format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, usage,
|
||||
flags, &properties) != VK_SUCCESS) {
|
||||
EXIT("TextureCache: render-target format does not support required usage, format=%d "
|
||||
"usage=0x%x\n",
|
||||
static_cast<int>(format), usage);
|
||||
@@ -958,7 +956,7 @@ void UploadRenderTargetLayers(GraphicContext* ctx, RenderTextureVulkanImage* ima
|
||||
}
|
||||
const auto slice_size = info.size / info.layers;
|
||||
const auto upload_size = slice_size * layer_count;
|
||||
const bool standard64 = IsSupportedStandard64RenderTarget(info);
|
||||
const bool standard64 = IsSupportedStandard64RenderTarget(info);
|
||||
if (standard64 || info.levels > 1 || info.layers > 1) {
|
||||
const auto format = RenderTargetTransferFormat(info.bytes_per_element);
|
||||
auto layout = TextureCalcUploadLayout(format, info.width, info.height, info.levels,
|
||||
@@ -966,9 +964,8 @@ void UploadRenderTargetLayers(GraphicContext* ctx, RenderTextureVulkanImage* ima
|
||||
false, false, false, "TextureCache render target");
|
||||
const bool render_target_tiled =
|
||||
info.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget);
|
||||
if (!standard64 &&
|
||||
((render_target_tiled && !layout.fmt_tiled_render_target) ||
|
||||
layout.pitch != info.pitch)) {
|
||||
if (!standard64 && ((render_target_tiled && !layout.fmt_tiled_render_target) ||
|
||||
layout.pitch != info.pitch)) {
|
||||
EXIT("TextureCache: unsupported render-target mip upload layout, pitch=%u/%u tile=%u\n",
|
||||
info.pitch, layout.pitch, info.tile_mode);
|
||||
}
|
||||
@@ -1099,9 +1096,8 @@ DepthStencilVulkanImage* CreateDepthTarget(GraphicContext* ctx, const DepthTarge
|
||||
create.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
create.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
VkImageFormatProperties properties {};
|
||||
if (vkGetPhysicalDeviceImageFormatProperties(ctx->physical_device, info.format,
|
||||
VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
|
||||
create.usage, 0, &properties) != VK_SUCCESS) {
|
||||
if (ctx->GetImageFormatProperties(info.format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
|
||||
create.usage, 0, &properties) != VK_SUCCESS) {
|
||||
EXIT("TextureCache: depth format does not support required usage, format=%d usage=0x%x\n",
|
||||
static_cast<int>(info.format), create.usage);
|
||||
}
|
||||
@@ -1770,8 +1766,8 @@ VulkanImage* TextureCache::FindTexture(CommandBuffer* command, GraphicContext* c
|
||||
if (command == nullptr || ctx == nullptr || info.address == 0 || info.size == 0 ||
|
||||
info.address >= TRACKER_ADDRESS_SIZE || info.size > TRACKER_ADDRESS_SIZE - info.address ||
|
||||
info.width == 0 || info.height == 0 || info.depth == 0 || info.levels == 0 ||
|
||||
info.levels >= 16 ||
|
||||
info.view_levels == 0 || info.base_level + info.view_levels > info.levels) {
|
||||
info.levels >= 16 || info.view_levels == 0 ||
|
||||
info.base_level + info.view_levels > info.levels) {
|
||||
EXIT("TextureCache: invalid sampled-image request, command=%p ctx=%p addr=0x%016" PRIx64
|
||||
" size=0x%016" PRIx64 " extent=%ux%ux%u levels=%u\n",
|
||||
static_cast<const void*>(command), static_cast<const void*>(ctx), info.address,
|
||||
@@ -3086,9 +3082,9 @@ void TextureCache::PrepareHostWrite(uint64_t vaddr, uint64_t size) {
|
||||
}
|
||||
|
||||
void TextureCache::SynchronizeColorImageToBufferLocked(CachedImage& cached) {
|
||||
const bool render_target = cached.kind == CachedImage::Kind::RenderTarget;
|
||||
const bool video_out = cached.kind == CachedImage::Kind::VideoOut;
|
||||
RenderTargetInfo target = cached.target;
|
||||
const bool render_target = cached.kind == CachedImage::Kind::RenderTarget;
|
||||
const bool video_out = cached.kind == CachedImage::Kind::VideoOut;
|
||||
RenderTargetInfo target = cached.target;
|
||||
if (video_out) {
|
||||
const auto& info = cached.video_out;
|
||||
target.address = info.address;
|
||||
@@ -3100,8 +3096,8 @@ void TextureCache::SynchronizeColorImageToBufferLocked(CachedImage& cached) {
|
||||
target.bytes_per_element = info.bytes_per_element;
|
||||
target.tile_mode = info.tile_mode;
|
||||
}
|
||||
const bool linear = target.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kLinear);
|
||||
const bool tiled = IsTiledRenderTarget(target);
|
||||
const bool linear = target.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kLinear);
|
||||
const bool tiled = IsTiledRenderTarget(target);
|
||||
TileSizeAlign exact {};
|
||||
bool single_slice = false;
|
||||
if (IsSupportedStandard64RenderTarget(target)) {
|
||||
@@ -3114,9 +3110,8 @@ void TextureCache::SynchronizeColorImageToBufferLocked(CachedImage& cached) {
|
||||
const bool layered_size =
|
||||
single_slice && static_cast<uint64_t>(exact.size) * target.layers == target.size;
|
||||
const bool exact_tiled = tiled && exact.align == 65536 && layered_size;
|
||||
const bool valid_kind = render_target ||
|
||||
(video_out && cached.video_out.compression ==
|
||||
VideoOutCompression::Uncompressed);
|
||||
const bool valid_kind = render_target || (video_out && cached.video_out.compression ==
|
||||
VideoOutCompression::Uncompressed);
|
||||
if (!valid_kind || !cached.gpu_modified || cached.buffer_modified || target.levels != 1 ||
|
||||
target.size > UINT32_MAX || (!linear && !exact_tiled) ||
|
||||
HasMetaOverlapLocked(target.address, target.size)) {
|
||||
@@ -3130,9 +3125,8 @@ void TextureCache::SynchronizeColorImageToBufferLocked(CachedImage& cached) {
|
||||
video_out ? static_cast<uint32_t>(cached.video_out.compression) : 0,
|
||||
cached.gpu_modified, cached.buffer_modified);
|
||||
}
|
||||
const auto slice_size = target.size / target.layers;
|
||||
if (cached.image->format != target.format ||
|
||||
cached.image->extent.width != target.width ||
|
||||
const auto slice_size = target.size / target.layers;
|
||||
if (cached.image->format != target.format || cached.image->extent.width != target.width ||
|
||||
cached.image->extent.height != target.height ||
|
||||
(tiled && !IsSupportedRenderTargetElementSize(target.bytes_per_element)) ||
|
||||
HasMetaOverlapLocked(target.address, target.size)) {
|
||||
|
||||
@@ -99,9 +99,8 @@ void VulkanLogMemoryBudget(GraphicContext* ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
VkPhysicalDeviceMemoryProperties properties {};
|
||||
vkGetPhysicalDeviceMemoryProperties(ctx->physical_device, &properties);
|
||||
VmaBudget budgets[VK_MAX_MEMORY_HEAPS] {};
|
||||
const auto& properties = ctx->GetPhysicalDeviceMemoryProperties();
|
||||
VmaBudget budgets[VK_MAX_MEMORY_HEAPS] {};
|
||||
vmaGetHeapBudgets(ctx->allocator, budgets);
|
||||
for (uint32_t i = 0; i < properties.memoryHeapCount; i++) {
|
||||
LOGF("VMA heap %u: usage=%" PRIu64 ", budget=%" PRIu64 ", allocation=%" PRIu64
|
||||
@@ -118,9 +117,8 @@ bool VulkanAllocate(GraphicContext* ctx, VulkanMemory* memory) {
|
||||
memory->allocation != nullptr || ctx->allocator == nullptr ||
|
||||
memory->requirements.size == 0);
|
||||
|
||||
VkPhysicalDeviceMemoryProperties properties {};
|
||||
vkGetPhysicalDeviceMemoryProperties(ctx->physical_device, &properties);
|
||||
uint32_t index = 0;
|
||||
const auto& properties = ctx->GetPhysicalDeviceMemoryProperties();
|
||||
uint32_t index = 0;
|
||||
for (; index < properties.memoryTypeCount; index++) {
|
||||
if ((memory->requirements.memoryTypeBits & (uint32_t {1} << index)) != 0 &&
|
||||
(properties.memoryTypes[index].propertyFlags & memory->property) == memory->property) {
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
#include "common/common.h"
|
||||
#include "common/threads.h"
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <tuple>
|
||||
#include <vk_mem_alloc.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
@@ -30,28 +33,71 @@ struct VulkanInstance {
|
||||
static constexpr int QUEUE_COMPUTE_START = 0;
|
||||
static constexpr int QUEUE_COMPUTE_NUM = 8;
|
||||
|
||||
VkInstance instance = nullptr;
|
||||
VkDebugUtilsMessengerEXT debug_messenger = nullptr;
|
||||
VkPhysicalDevice physical_device = nullptr;
|
||||
VkPhysicalDeviceProperties physical_device_properties = {};
|
||||
VkDevice device = nullptr;
|
||||
VmaAllocator allocator = nullptr;
|
||||
bool memory_budget_ext_enabled = false;
|
||||
bool subgroup_size_control_enabled = false;
|
||||
uint32_t subgroup_size = 0;
|
||||
uint32_t min_subgroup_size = 0;
|
||||
uint32_t max_subgroup_size = 0;
|
||||
VkShaderStageFlags required_subgroup_size_stages = 0;
|
||||
VulkanQueueInfo queues[QUEUES_NUM];
|
||||
VkInstance instance = nullptr;
|
||||
VkDebugUtilsMessengerEXT debug_messenger = nullptr;
|
||||
VkPhysicalDevice physical_device = nullptr;
|
||||
VkPhysicalDeviceProperties physical_device_properties = {};
|
||||
VkPhysicalDeviceMemoryProperties physical_device_memory_properties = {};
|
||||
VkDevice device = nullptr;
|
||||
VmaAllocator allocator = nullptr;
|
||||
bool memory_budget_ext_enabled = false;
|
||||
bool subgroup_size_control_enabled = false;
|
||||
uint32_t subgroup_size = 0;
|
||||
uint32_t min_subgroup_size = 0;
|
||||
uint32_t max_subgroup_size = 0;
|
||||
VkShaderStageFlags required_subgroup_size_stages = 0;
|
||||
VulkanQueueInfo queues[QUEUES_NUM];
|
||||
|
||||
[[nodiscard]] const VkPhysicalDeviceProperties& GetPhysicalDeviceProperties() const {
|
||||
return physical_device_properties;
|
||||
}
|
||||
|
||||
[[nodiscard]] const VkPhysicalDeviceMemoryProperties&
|
||||
GetPhysicalDeviceMemoryProperties() const {
|
||||
return physical_device_memory_properties;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkFormatProperties GetFormatProperties(VkFormat format) const {
|
||||
std::scoped_lock lock(m_format_properties_mutex);
|
||||
auto [it, inserted] = m_format_properties.try_emplace(format);
|
||||
if (inserted) {
|
||||
vkGetPhysicalDeviceFormatProperties(physical_device, format, &it->second);
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkResult GetImageFormatProperties(VkFormat format, VkImageType type,
|
||||
VkImageTiling tiling, VkImageUsageFlags usage,
|
||||
VkImageCreateFlags flags,
|
||||
VkImageFormatProperties* properties) const {
|
||||
using Key =
|
||||
std::tuple<VkFormat, VkImageType, VkImageTiling, VkImageUsageFlags, VkImageCreateFlags>;
|
||||
std::scoped_lock lock(m_image_format_properties_mutex);
|
||||
auto [it, inserted] =
|
||||
m_image_format_properties.try_emplace(Key {format, type, tiling, usage, flags});
|
||||
if (inserted) {
|
||||
it->second.first = vkGetPhysicalDeviceImageFormatProperties(
|
||||
physical_device, format, type, tiling, usage, flags, &it->second.second);
|
||||
}
|
||||
if (properties != nullptr) {
|
||||
*properties = it->second.second;
|
||||
}
|
||||
return it->second.first;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkDeviceSize StorageMinAlignment() const {
|
||||
const auto alignment = physical_device_properties.limits.minStorageBufferOffsetAlignment;
|
||||
return alignment != 0 ? alignment : 1;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::mutex m_format_properties_mutex;
|
||||
mutable std::map<VkFormat, VkFormatProperties> m_format_properties;
|
||||
mutable std::mutex m_image_format_properties_mutex;
|
||||
mutable std::map<
|
||||
std::tuple<VkFormat, VkImageType, VkImageTiling, VkImageUsageFlags, VkImageCreateFlags>,
|
||||
std::pair<VkResult, VkImageFormatProperties>>
|
||||
m_image_format_properties;
|
||||
};
|
||||
|
||||
} // namespace Libs::Graphics
|
||||
|
||||
@@ -1073,6 +1073,8 @@ void VulkanCreate(WindowContext* ctx) {
|
||||
|
||||
vkGetPhysicalDeviceProperties(ctx->graphic_ctx.physical_device,
|
||||
&ctx->graphic_ctx.physical_device_properties);
|
||||
vkGetPhysicalDeviceMemoryProperties(ctx->graphic_ctx.physical_device,
|
||||
&ctx->graphic_ctx.physical_device_memory_properties);
|
||||
const auto& device_properties = ctx->graphic_ctx.GetPhysicalDeviceProperties();
|
||||
|
||||
LOGF("Select device: %s\n", device_properties.deviceName);
|
||||
|
||||
Reference in New Issue
Block a user