Vulkan driver query caching

This commit is contained in:
nmzik
2026-07-17 18:09:20 +02:00
parent c7b00d666f
commit 75d20486ba
6 changed files with 168 additions and 102 deletions
+72 -39
View File
@@ -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;
}
+22 -28
View File
@@ -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)) {
+4 -6
View File
@@ -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) {
+59 -13
View File
@@ -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);