diff --git a/src/graphics/host_gpu/objects/textureCommon.cpp b/src/graphics/host_gpu/objects/textureCommon.cpp index 38a2f4f73..0ca4dda59 100644 --- a/src/graphics/host_gpu/objects/textureCommon.cpp +++ b/src/graphics/host_gpu/objects/textureCommon.cpp @@ -21,7 +21,8 @@ RenderTargetFormatInfo TextureGetRenderTargetFormat(uint32_t raw_layout, uint32_ const auto layout = static_cast(raw_layout); const auto type = static_cast(raw_type); const auto order = static_cast(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(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(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(blocks_w) * blocks_h * bytes_per_block; @@ -737,7 +767,8 @@ TextureUploadLayout TextureCalcUploadLayout(uint32_t fmt, uint64_t width, uint64 (TileIsStandard64KBTextureSupported(static_cast(fmt)) && tile_mode == Prospero::TileMode::kStandard64KB); layout.fmt_tiled_depth = - (allow_depth_tile && Prospero::RenderTargetBytesPerElement(static_cast(fmt)) != 0 && + (allow_depth_tile && + Prospero::RenderTargetBytesPerElement(static_cast(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(layout.tile) == Prospero::TileMode::kLinear && + static_cast(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(fmt)); + const uint32_t bytes_per_element = + Prospero::RenderTargetBytesPerElement(static_cast(fmt)); if (bytes_per_element == 1) { UtilFillImage(ctx, vk_obj, src_data, size, regions, dst_layout); } else { diff --git a/src/graphics/host_gpu/renderer/depthRenderTarget.cpp b/src/graphics/host_gpu/renderer/depthRenderTarget.cpp index 533d76c78..da12f22e3 100644 --- a/src/graphics/host_gpu/renderer/depthRenderTarget.cpp +++ b/src/graphics/host_gpu/renderer/depthRenderTarget.cpp @@ -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 #include #include -#include #include 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; } diff --git a/src/graphics/host_gpu/renderer/textureCache.cpp b/src/graphics/host_gpu/renderer/textureCache.cpp index 52a8ff73d..9f45f248a 100644 --- a/src/graphics/host_gpu/renderer/textureCache.cpp +++ b/src/graphics/host_gpu/renderer/textureCache.cpp @@ -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(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(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(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(command), static_cast(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(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(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)) { diff --git a/src/graphics/host_gpu/vma.cpp b/src/graphics/host_gpu/vma.cpp index 8beb67f66..aab3d9e1b 100644 --- a/src/graphics/host_gpu/vma.cpp +++ b/src/graphics/host_gpu/vma.cpp @@ -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) { diff --git a/src/graphics/host_gpu/vulkanInstance.h b/src/graphics/host_gpu/vulkanInstance.h index 339e19e69..4a76ab52a 100644 --- a/src/graphics/host_gpu/vulkanInstance.h +++ b/src/graphics/host_gpu/vulkanInstance.h @@ -5,6 +5,9 @@ #include "common/common.h" #include "common/threads.h" +#include +#include +#include #include #include @@ -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; + 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 m_format_properties; + mutable std::mutex m_image_format_properties_mutex; + mutable std::map< + std::tuple, + std::pair> + m_image_format_properties; }; } // namespace Libs::Graphics diff --git a/src/graphics/presentation/window/vulkanWindow.cpp b/src/graphics/presentation/window/vulkanWindow.cpp index e0fe64416..271f50a50 100644 --- a/src/graphics/presentation/window/vulkanWindow.cpp +++ b/src/graphics/presentation/window/vulkanWindow.cpp @@ -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);