mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
centralize swizzles
This commit is contained in:
@@ -66,32 +66,42 @@ enum class VulkanImageType {
|
|||||||
RenderTexture
|
RenderTexture
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ImageViewInfo {
|
||||||
|
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||||
|
VkImageViewType type = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
VkImageAspectFlags aspect = 0;
|
||||||
|
uint32_t base_level = 0;
|
||||||
|
uint32_t level_count = 0;
|
||||||
|
uint32_t base_layer = 0;
|
||||||
|
uint32_t layer_count = 1;
|
||||||
|
uint32_t swizzle = 0;
|
||||||
|
bool is_storage = false;
|
||||||
|
|
||||||
|
bool operator==(const ImageViewInfo&) const = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CachedImageView {
|
||||||
|
ImageViewInfo info;
|
||||||
|
VkImageView view = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ImageViewCache {
|
||||||
|
std::mutex mutex;
|
||||||
|
std::vector<CachedImageView> views;
|
||||||
|
|
||||||
|
ImageViewCache() = default;
|
||||||
|
KYTY_CLASS_NO_COPY(ImageViewCache);
|
||||||
|
};
|
||||||
|
|
||||||
struct VulkanImage {
|
struct VulkanImage {
|
||||||
static constexpr int VIEW_MAX = 22;
|
static constexpr int VIEW_MAX = 4;
|
||||||
static constexpr int VIEW_DEFAULT = 0;
|
static constexpr int VIEW_DEFAULT = 0;
|
||||||
static constexpr int VIEW_BGRA = 1;
|
static constexpr int VIEW_DEFAULT_ARRAY = 1;
|
||||||
static constexpr int VIEW_DEPTH_TEXTURE = 2;
|
static constexpr int VIEW_STORAGE = 2;
|
||||||
static constexpr int VIEW_R001 = 3;
|
static constexpr int VIEW_STORAGE_ARRAY = 3;
|
||||||
static constexpr int VIEW_RGB1 = 4;
|
|
||||||
static constexpr int VIEW_R000 = 5;
|
|
||||||
static constexpr int VIEW_RG01 = 6;
|
|
||||||
static constexpr int VIEW_000R = 7;
|
|
||||||
static constexpr int VIEW_DEFAULT_ARRAY = 8;
|
|
||||||
static constexpr int VIEW_BGRA_ARRAY = 9;
|
|
||||||
static constexpr int VIEW_DEPTH_TEXTURE_ARRAY = 10;
|
|
||||||
static constexpr int VIEW_R001_ARRAY = 11;
|
|
||||||
static constexpr int VIEW_RGB1_ARRAY = 12;
|
|
||||||
static constexpr int VIEW_R000_ARRAY = 13;
|
|
||||||
static constexpr int VIEW_RG01_ARRAY = 14;
|
|
||||||
static constexpr int VIEW_000R_ARRAY = 15;
|
|
||||||
static constexpr int VIEW_STENCIL_TEXTURE = 16;
|
|
||||||
static constexpr int VIEW_STENCIL_TEXTURE_ARRAY = 17;
|
|
||||||
static constexpr int VIEW_STORAGE = 18;
|
|
||||||
static constexpr int VIEW_STORAGE_ARRAY = 19;
|
|
||||||
static constexpr int VIEW_BGRA_TO_RGBA = 20;
|
|
||||||
static constexpr int VIEW_ABGR = 21;
|
|
||||||
|
|
||||||
explicit VulkanImage(VulkanImageType type): type(type) {}
|
explicit VulkanImage(VulkanImageType type): type(type) {}
|
||||||
|
KYTY_CLASS_NO_COPY(VulkanImage);
|
||||||
|
|
||||||
VulkanImageType type = VulkanImageType::Unknown;
|
VulkanImageType type = VulkanImageType::Unknown;
|
||||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||||
@@ -103,6 +113,7 @@ struct VulkanImage {
|
|||||||
VkImageView image_view[VIEW_MAX] = {};
|
VkImageView image_view[VIEW_MAX] = {};
|
||||||
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
Graphics::VulkanMemory memory;
|
Graphics::VulkanMemory memory;
|
||||||
|
ImageViewCache view_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VideoOutVulkanImage: public VulkanImage {
|
struct VideoOutVulkanImage: public VulkanImage {
|
||||||
@@ -130,23 +141,7 @@ struct TextureVulkanImage: public GpuTextureVulkanImage {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct StorageTextureVulkanImage: public GpuTextureVulkanImage {
|
struct StorageTextureVulkanImage: public GpuTextureVulkanImage {
|
||||||
struct StorageView {
|
|
||||||
uint32_t base_level = 0;
|
|
||||||
VkImageView view = nullptr;
|
|
||||||
};
|
|
||||||
struct SampledView {
|
|
||||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
|
||||||
uint32_t swizzle = 0;
|
|
||||||
uint32_t type = 0;
|
|
||||||
uint32_t base_level = 0;
|
|
||||||
uint32_t level_count = 0;
|
|
||||||
VkImageView view = nullptr;
|
|
||||||
};
|
|
||||||
StorageTextureVulkanImage(): GpuTextureVulkanImage(VulkanImageType::StorageTexture) {}
|
StorageTextureVulkanImage(): GpuTextureVulkanImage(VulkanImageType::StorageTexture) {}
|
||||||
std::mutex sampled_view_mutex;
|
|
||||||
std::vector<SampledView> sampled_views;
|
|
||||||
std::mutex storage_view_mutex;
|
|
||||||
std::vector<StorageView> storage_views;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RenderTextureVulkanImage: public VulkanImage {
|
struct RenderTextureVulkanImage: public VulkanImage {
|
||||||
@@ -157,33 +152,10 @@ struct RenderTextureVulkanImage: public VulkanImage {
|
|||||||
uint32_t layer_count = 1;
|
uint32_t layer_count = 1;
|
||||||
VkImageView view = nullptr;
|
VkImageView view = nullptr;
|
||||||
};
|
};
|
||||||
struct SampledView {
|
|
||||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
|
||||||
VkImageViewType type = VK_IMAGE_VIEW_TYPE_2D;
|
|
||||||
uint32_t base_level = 0;
|
|
||||||
uint32_t level_count = 0;
|
|
||||||
uint32_t base_layer = 0;
|
|
||||||
uint32_t layer_count = 1;
|
|
||||||
int variant = VIEW_DEFAULT;
|
|
||||||
VkImageView view = nullptr;
|
|
||||||
};
|
|
||||||
struct StorageView {
|
|
||||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
|
||||||
VkImageViewType type = VK_IMAGE_VIEW_TYPE_2D;
|
|
||||||
uint32_t base_level = 0;
|
|
||||||
uint32_t level_count = 0;
|
|
||||||
uint32_t base_layer = 0;
|
|
||||||
uint32_t layer_count = 1;
|
|
||||||
VkImageView view = nullptr;
|
|
||||||
};
|
|
||||||
RenderTextureVulkanImage(): VulkanImage(VulkanImageType::RenderTexture) {}
|
RenderTextureVulkanImage(): VulkanImage(VulkanImageType::RenderTexture) {}
|
||||||
VkImageView render_view[16] = {};
|
VkImageView render_view[16] = {};
|
||||||
std::mutex attachment_view_mutex;
|
std::mutex attachment_view_mutex;
|
||||||
std::vector<AttachmentView> attachment_views;
|
std::vector<AttachmentView> attachment_views;
|
||||||
std::mutex sampled_view_mutex;
|
|
||||||
std::vector<SampledView> sampled_views;
|
|
||||||
std::mutex storage_view_mutex;
|
|
||||||
std::vector<StorageView> storage_views;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VulkanBuffer {
|
struct VulkanBuffer {
|
||||||
|
|||||||
@@ -84,14 +84,6 @@ static int SampledArrayViewIndex(const VulkanImage* image, int view_index) {
|
|||||||
|
|
||||||
switch (view_index) {
|
switch (view_index) {
|
||||||
case VulkanImage::VIEW_DEFAULT: return VulkanImage::VIEW_DEFAULT_ARRAY;
|
case VulkanImage::VIEW_DEFAULT: return VulkanImage::VIEW_DEFAULT_ARRAY;
|
||||||
case VulkanImage::VIEW_BGRA: return VulkanImage::VIEW_BGRA_ARRAY;
|
|
||||||
case VulkanImage::VIEW_DEPTH_TEXTURE: return VulkanImage::VIEW_DEPTH_TEXTURE_ARRAY;
|
|
||||||
case VulkanImage::VIEW_STENCIL_TEXTURE: return VulkanImage::VIEW_STENCIL_TEXTURE_ARRAY;
|
|
||||||
case VulkanImage::VIEW_R001: return VulkanImage::VIEW_R001_ARRAY;
|
|
||||||
case VulkanImage::VIEW_RGB1: return VulkanImage::VIEW_RGB1_ARRAY;
|
|
||||||
case VulkanImage::VIEW_R000: return VulkanImage::VIEW_R000_ARRAY;
|
|
||||||
case VulkanImage::VIEW_RG01: return VulkanImage::VIEW_RG01_ARRAY;
|
|
||||||
case VulkanImage::VIEW_000R: return VulkanImage::VIEW_000R_ARRAY;
|
|
||||||
default: return view_index;
|
default: return view_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -334,6 +326,16 @@ ResolveTargetTextureView(const ShaderRecompiler::IR::ImageResource& resource,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsSupportedSampledVideoOutView(const ShaderRecompiler::IR::ImageResource& resource,
|
||||||
|
const ShaderTextureResource& descriptor,
|
||||||
|
const VulkanImage& image) {
|
||||||
|
return image.type == VulkanImageType::VideoOut && image.layers == 1 &&
|
||||||
|
IsSupportedSampledColorResource(resource) &&
|
||||||
|
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D &&
|
||||||
|
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) &&
|
||||||
|
descriptor.Depth() == 0 && descriptor.BaseArray5() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor,
|
bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor,
|
||||||
const VulkanImage& image) {
|
const VulkanImage& image) {
|
||||||
const auto width = static_cast<uint32_t>(descriptor.Width5()) + 1u;
|
const auto width = static_cast<uint32_t>(descriptor.Width5()) + 1u;
|
||||||
@@ -588,7 +590,9 @@ NativeTexture(uint64_t submit_id, CommandBuffer* command_buffer,
|
|||||||
image = nullptr;
|
image = nullptr;
|
||||||
} else {
|
} else {
|
||||||
ValidateDepthTargetBinding(resource, descriptor, image, view_format, size.size);
|
ValidateDepthTargetBinding(resource, descriptor, image, view_format, size.size);
|
||||||
view = SelectSampledDepthView(image->format, view_format, swizzle);
|
image_view = g_render_ctx->GetTextureCache()->GetDepthTargetSampledView(
|
||||||
|
g_render_ctx->GetGraphicCtx(), static_cast<DepthStencilVulkanImage*>(image),
|
||||||
|
view_format, swizzle, 0, 1, VK_IMAGE_VIEW_TYPE_2D, 0, 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!(storage ? IsSupportedStorageImageResource(resource)
|
if (!(storage ? IsSupportedStorageImageResource(resource)
|
||||||
@@ -611,19 +615,17 @@ NativeTexture(uint64_t submit_id, CommandBuffer* command_buffer,
|
|||||||
image->mip_levels, base_level, descriptor.BaseArray5(),
|
image->mip_levels, base_level, descriptor.BaseArray5(),
|
||||||
static_cast<uint32_t>(type));
|
static_cast<uint32_t>(type));
|
||||||
}
|
}
|
||||||
view = storage ? SelectStorageColorView(image->format, view_format, swizzle)
|
|
||||||
: SelectSampledColorView(image->format, view_format, swizzle);
|
|
||||||
if (storage) {
|
if (storage) {
|
||||||
|
view = SelectStorageColorView(image->format, view_format, swizzle);
|
||||||
image_view = g_render_ctx->GetTextureCache()->GetRenderTargetStorageView(
|
image_view = g_render_ctx->GetTextureCache()->GetRenderTargetStorageView(
|
||||||
g_render_ctx->GetGraphicCtx(),
|
g_render_ctx->GetGraphicCtx(),
|
||||||
static_cast<RenderTextureVulkanImage*>(image), view_format, base_level,
|
static_cast<RenderTextureVulkanImage*>(image), view_format, base_level,
|
||||||
view_levels, target_view.type, target_view.base_layer,
|
view_levels, target_view.type, target_view.base_layer,
|
||||||
target_view.layer_count);
|
target_view.layer_count);
|
||||||
} else {
|
} else {
|
||||||
image_view = g_render_ctx->GetTextureCache()->GetRenderTargetSampledView(
|
image_view = g_render_ctx->GetTextureCache()->GetSampledColorView(
|
||||||
g_render_ctx->GetGraphicCtx(),
|
g_render_ctx->GetGraphicCtx(), image, view_format, swizzle, base_level,
|
||||||
static_cast<RenderTextureVulkanImage*>(image), view_format, view,
|
view_levels, target_view.type, target_view.base_layer,
|
||||||
base_level, view_levels, target_view.type, target_view.base_layer,
|
|
||||||
target_view.layer_count);
|
target_view.layer_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -661,10 +663,27 @@ NativeTexture(uint64_t submit_id, CommandBuffer* command_buffer,
|
|||||||
view = VulkanImage::VIEW_STORAGE;
|
view = VulkanImage::VIEW_STORAGE;
|
||||||
g_render_ctx->GetTextureCache()->MarkGpuWritten(image);
|
g_render_ctx->GetTextureCache()->MarkGpuWritten(image);
|
||||||
} else {
|
} else {
|
||||||
image = video.image;
|
const bool exact =
|
||||||
if (swizzle == DstSel(6, 5, 4, 7)) {
|
IsSupportedSampledVideoOutView(resource, descriptor, *video.image) &&
|
||||||
view = VulkanImage::VIEW_BGRA;
|
width == video.image->extent.width && height == video.image->extent.height &&
|
||||||
|
levels == 1 && base_level == 0 && view_levels == 1 && video.size == size.size &&
|
||||||
|
video.pitch == pitch;
|
||||||
|
if (!exact) {
|
||||||
|
EXIT("unsupported sampled access to video-out surface: resource=%u dimension=%u"
|
||||||
|
" image_format=%d view_format=%d swizzle=0x%03x extent=%ux%u/%ux%u"
|
||||||
|
" depth=%u levels=%u base=%u count=%u type=%u size=0x%016" PRIx64
|
||||||
|
"/0x%016" PRIx64 " pitch=%u/%u\n",
|
||||||
|
static_cast<uint32_t>(resource.kind),
|
||||||
|
static_cast<uint32_t>(resource.dimension),
|
||||||
|
static_cast<int>(video.image->format), static_cast<int>(view_format),
|
||||||
|
swizzle, width, height, video.image->extent.width,
|
||||||
|
video.image->extent.height, depth, levels, base_level, view_levels,
|
||||||
|
static_cast<uint32_t>(type), size.size, video.size, pitch, video.pitch);
|
||||||
}
|
}
|
||||||
|
image = video.image;
|
||||||
|
image_view = g_render_ctx->GetTextureCache()->GetSampledColorView(
|
||||||
|
g_render_ctx->GetGraphicCtx(), video.image, view_format, swizzle, 0, 1,
|
||||||
|
VK_IMAGE_VIEW_TYPE_2D, 0, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ struct VulkanImage;
|
|||||||
|
|
||||||
[[nodiscard]] bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor,
|
[[nodiscard]] bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor,
|
||||||
const VulkanImage& image);
|
const VulkanImage& image);
|
||||||
|
[[nodiscard]] bool
|
||||||
|
IsSupportedSampledVideoOutView(const ShaderRecompiler::IR::ImageResource& resource,
|
||||||
|
const ShaderTextureResource& descriptor, const VulkanImage& image);
|
||||||
void ValidateMetadataReuseTexture(const ShaderRecompiler::IR::ImageResource& resource,
|
void ValidateMetadataReuseTexture(const ShaderRecompiler::IR::ImageResource& resource,
|
||||||
const ShaderTextureResource& descriptor, uint64_t size);
|
const ShaderTextureResource& descriptor, uint64_t size);
|
||||||
void ValidateStorageTexture(const ShaderRecompiler::IR::ImageResource& resource,
|
void ValidateStorageTexture(const ShaderRecompiler::IR::ImageResource& resource,
|
||||||
|
|||||||
@@ -86,41 +86,67 @@ namespace Libs::Graphics {
|
|||||||
return view_format == BgraSrgbStorageViewFormat(image_format) && swizzle == DstSel(6, 5, 4, 7);
|
return view_format == BgraSrgbStorageViewFormat(image_format) && swizzle == DstSel(6, 5, 4, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline int SelectSampledColorView(VkFormat image_format, VkFormat view_format,
|
[[nodiscard]] inline bool IsValidSampledColorSwizzle(uint32_t swizzle) noexcept {
|
||||||
uint32_t swizzle) noexcept {
|
if ((swizzle & ~0xfffu) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (uint32_t channel = 0; channel < 4; channel++) {
|
||||||
|
switch (GetDstSel(swizzle, channel)) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
case 7: break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline bool IsSupportedSampledColorView(VkFormat image_format,
|
||||||
|
VkFormat view_format,
|
||||||
|
uint32_t swizzle) noexcept {
|
||||||
|
if (!IsValidSampledColorSwizzle(swizzle)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (image_format == view_format || IsRgba8SrgbReinterpretation(image_format, view_format)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if ((IsRgba16UintFloatReinterpretation(image_format, view_format) ||
|
if ((IsRgba16UintFloatReinterpretation(image_format, view_format) ||
|
||||||
IsRgba8UnormUintReinterpretation(image_format, view_format)) &&
|
IsRgba8UnormUintReinterpretation(image_format, view_format)) &&
|
||||||
swizzle == DstSel(4, 5, 6, 7)) {
|
swizzle == DstSel(4, 5, 6, 7)) {
|
||||||
return VulkanImage::VIEW_DEFAULT;
|
return true;
|
||||||
}
|
}
|
||||||
if (image_format == view_format) {
|
return IsBgraToRgbaSampledView(image_format, view_format) &&
|
||||||
switch (swizzle) {
|
swizzle == DstSel(6, 5, 4, 7);
|
||||||
case DstSel(4, 5, 6, 7): return VulkanImage::VIEW_DEFAULT;
|
}
|
||||||
case DstSel(4, 0, 0, 1): return VulkanImage::VIEW_R001;
|
|
||||||
case DstSel(4, 5, 0, 1): return VulkanImage::VIEW_RG01;
|
[[nodiscard]] inline uint32_t SelectSampledColorView(VkFormat image_format, VkFormat view_format,
|
||||||
case DstSel(4, 5, 6, 1): return VulkanImage::VIEW_RGB1;
|
uint32_t swizzle) noexcept {
|
||||||
default: break;
|
if (IsSupportedSampledColorView(image_format, view_format, swizzle)) {
|
||||||
}
|
return swizzle;
|
||||||
}
|
|
||||||
if (image_format == VK_FORMAT_R16G16B16A16_SFLOAT && view_format == image_format &&
|
|
||||||
swizzle == DstSel(7, 6, 5, 4)) {
|
|
||||||
return VulkanImage::VIEW_ABGR;
|
|
||||||
}
|
|
||||||
if (IsBgraToRgbaSampledView(image_format, view_format) && swizzle == DstSel(6, 5, 4, 7)) {
|
|
||||||
return VulkanImage::VIEW_BGRA_TO_RGBA;
|
|
||||||
}
|
}
|
||||||
UnsupportedColorView("sampled", image_format, view_format, swizzle);
|
UnsupportedColorView("sampled", image_format, view_format, swizzle);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline int SelectSampledDepthView(VkFormat image_format, VkFormat view_format,
|
[[nodiscard]] inline bool IsSupportedSampledDepthView(VkFormat image_format, VkFormat view_format,
|
||||||
uint32_t swizzle) noexcept {
|
uint32_t swizzle) noexcept {
|
||||||
if (IsSupportedSampledDepthFormat(image_format, view_format)) {
|
if (!IsSupportedSampledDepthFormat(image_format, view_format)) {
|
||||||
switch (swizzle) {
|
return false;
|
||||||
case DstSel(4, 4, 4, 4): return VulkanImage::VIEW_DEPTH_TEXTURE;
|
}
|
||||||
case DstSel(4, 0, 0, 0): return VulkanImage::VIEW_R000;
|
switch (swizzle) {
|
||||||
case DstSel(4, 0, 0, 1): return VulkanImage::VIEW_R001;
|
case DstSel(4, 4, 4, 4):
|
||||||
default: break;
|
case DstSel(4, 0, 0, 0):
|
||||||
}
|
case DstSel(4, 0, 0, 1): return true;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline uint32_t SelectSampledDepthView(VkFormat image_format, VkFormat view_format,
|
||||||
|
uint32_t swizzle) noexcept {
|
||||||
|
if (IsSupportedSampledDepthView(image_format, view_format, swizzle)) {
|
||||||
|
return swizzle;
|
||||||
}
|
}
|
||||||
EXIT("unsupported sampled depth image view: image_format=%d view_format=%d swizzle=0x%03x\n",
|
EXIT("unsupported sampled depth image view: image_format=%d view_format=%d swizzle=0x%03x\n",
|
||||||
static_cast<int>(image_format), static_cast<int>(view_format), swizzle);
|
static_cast<int>(image_format), static_cast<int>(view_format), swizzle);
|
||||||
@@ -134,8 +160,8 @@ IsSupportedSampledDepthResource(const ShaderRecompiler::IR::ImageResource& resou
|
|||||||
!resource.written && !resource.atomic;
|
!resource.written && !resource.atomic;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline bool IsSupportedSampledDepthUintResource(
|
[[nodiscard]] inline bool
|
||||||
const ShaderRecompiler::IR::ImageResource& resource) noexcept {
|
IsSupportedSampledDepthUintResource(const ShaderRecompiler::IR::ImageResource& resource) noexcept {
|
||||||
return resource.kind == ShaderRecompiler::IR::ResourceKind::ImageUint &&
|
return resource.kind == ShaderRecompiler::IR::ResourceKind::ImageUint &&
|
||||||
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D &&
|
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D &&
|
||||||
resource.mip_mode == ShaderRecompiler::IR::ImageMipMode::None && resource.read &&
|
resource.mip_mode == ShaderRecompiler::IR::ImageMipMode::None && resource.read &&
|
||||||
|
|||||||
@@ -887,32 +887,11 @@ void CreateRenderTargetViews(GraphicContext* ctx, RenderTextureVulkanImage* imag
|
|||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_DEFAULT, VK_COMPONENT_SWIZZLE_IDENTITY,
|
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_DEFAULT, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY);
|
VK_COMPONENT_SWIZZLE_IDENTITY);
|
||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_BGRA, VK_COMPONENT_SWIZZLE_B,
|
|
||||||
VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R,
|
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY);
|
|
||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_R001, VK_COMPONENT_SWIZZLE_R,
|
|
||||||
VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO,
|
|
||||||
VK_COMPONENT_SWIZZLE_ONE);
|
|
||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_RGB1, VK_COMPONENT_SWIZZLE_R,
|
|
||||||
VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B,
|
|
||||||
VK_COMPONENT_SWIZZLE_ONE);
|
|
||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_R000, VK_COMPONENT_SWIZZLE_R,
|
|
||||||
VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO,
|
|
||||||
VK_COMPONENT_SWIZZLE_ZERO);
|
|
||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_RG01, VK_COMPONENT_SWIZZLE_R,
|
|
||||||
VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_ZERO,
|
|
||||||
VK_COMPONENT_SWIZZLE_ONE);
|
|
||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_000R, VK_COMPONENT_SWIZZLE_ZERO,
|
|
||||||
VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO,
|
|
||||||
VK_COMPONENT_SWIZZLE_R);
|
|
||||||
if (image->layers > 1) {
|
if (image->layers > 1) {
|
||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_DEFAULT_ARRAY,
|
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_DEFAULT_ARRAY,
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
VK_IMAGE_VIEW_TYPE_2D_ARRAY);
|
VK_IMAGE_VIEW_TYPE_2D_ARRAY);
|
||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_BGRA_ARRAY, VK_COMPONENT_SWIZZLE_B,
|
|
||||||
VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R,
|
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_IMAGE_VIEW_TYPE_2D_ARRAY);
|
|
||||||
}
|
}
|
||||||
if (FormatSupportsStorage(ctx, image->format)) {
|
if (FormatSupportsStorage(ctx, image->format)) {
|
||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_STORAGE, VK_COMPONENT_SWIZZLE_IDENTITY,
|
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_STORAGE, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
@@ -926,13 +905,6 @@ void CreateRenderTargetViews(GraphicContext* ctx, RenderTextureVulkanImage* imag
|
|||||||
VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_FORMAT_UNDEFINED, 0, 1);
|
VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_FORMAT_UNDEFINED, 0, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto rgba_view_format = BgraToRgbaSampledViewFormat(image->format);
|
|
||||||
if (rgba_view_format != VK_FORMAT_UNDEFINED) {
|
|
||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_BGRA_TO_RGBA, VK_COMPONENT_SWIZZLE_B,
|
|
||||||
VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R,
|
|
||||||
VK_COMPONENT_SWIZZLE_A, VK_IMAGE_VIEW_TYPE_2D, rgba_view_format,
|
|
||||||
VK_IMAGE_USAGE_SAMPLED_BIT);
|
|
||||||
}
|
|
||||||
CreateRenderAttachmentViews(ctx, image);
|
CreateRenderAttachmentViews(ctx, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -940,24 +912,12 @@ void CreateVideoOutViews(GraphicContext* ctx, VideoOutVulkanImage* image) {
|
|||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_DEFAULT, VK_COMPONENT_SWIZZLE_IDENTITY,
|
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_DEFAULT, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY);
|
VK_COMPONENT_SWIZZLE_IDENTITY);
|
||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_BGRA, VK_COMPONENT_SWIZZLE_B,
|
if ((image->format == VK_FORMAT_R8G8B8A8_SRGB || image->format == VK_FORMAT_B8G8R8A8_SRGB) &&
|
||||||
VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R,
|
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY);
|
|
||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_DEFAULT_ARRAY,
|
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
|
||||||
VK_IMAGE_VIEW_TYPE_2D_ARRAY);
|
|
||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_BGRA_ARRAY, VK_COMPONENT_SWIZZLE_B,
|
|
||||||
VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R,
|
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_IMAGE_VIEW_TYPE_2D_ARRAY);
|
|
||||||
if ((image->format == VK_FORMAT_R8G8B8A8_SRGB ||
|
|
||||||
image->format == VK_FORMAT_B8G8R8A8_SRGB) &&
|
|
||||||
FormatSupportsStorage(ctx, VK_FORMAT_R8G8B8A8_UINT)) {
|
FormatSupportsStorage(ctx, VK_FORMAT_R8G8B8A8_UINT)) {
|
||||||
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_STORAGE,
|
CreateRenderTargetView(ctx, image, VulkanImage::VIEW_STORAGE, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
VK_COMPONENT_SWIZZLE_IDENTITY, VK_IMAGE_VIEW_TYPE_2D,
|
||||||
VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UINT,
|
VK_FORMAT_R8G8B8A8_UINT, VK_IMAGE_USAGE_STORAGE_BIT, 1);
|
||||||
VK_IMAGE_USAGE_STORAGE_BIT, 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1074,43 +1034,6 @@ void CreateDepthViews(GraphicContext* ctx, DepthStencilVulkanImage* image) {
|
|||||||
{VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
{VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
|
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
|
||||||
0, 0, 1, 1);
|
0, 0, 1, 1);
|
||||||
UtilCreateImageView(ctx, image, VulkanImage::VIEW_DEPTH_TEXTURE, VK_IMAGE_VIEW_TYPE_2D,
|
|
||||||
VK_IMAGE_ASPECT_DEPTH_BIT,
|
|
||||||
{VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R,
|
|
||||||
VK_COMPONENT_SWIZZLE_R},
|
|
||||||
0, 0, 1, 1);
|
|
||||||
UtilCreateImageView(ctx, image, VulkanImage::VIEW_R000, VK_IMAGE_VIEW_TYPE_2D,
|
|
||||||
VK_IMAGE_ASPECT_DEPTH_BIT,
|
|
||||||
{VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO,
|
|
||||||
VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO},
|
|
||||||
0, 0, 1, 1);
|
|
||||||
UtilCreateImageView(ctx, image, VulkanImage::VIEW_R001, VK_IMAGE_VIEW_TYPE_2D,
|
|
||||||
VK_IMAGE_ASPECT_DEPTH_BIT,
|
|
||||||
{VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO,
|
|
||||||
VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ONE},
|
|
||||||
0, 0, 1, 1);
|
|
||||||
if (image->layers > 1) {
|
|
||||||
UtilCreateImageView(ctx, image, VulkanImage::VIEW_DEFAULT_ARRAY,
|
|
||||||
VK_IMAGE_VIEW_TYPE_2D_ARRAY, DepthAspectMask(image->format),
|
|
||||||
{VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
|
|
||||||
0, 0, image->layers, 1);
|
|
||||||
UtilCreateImageView(ctx, image, VulkanImage::VIEW_DEPTH_TEXTURE_ARRAY,
|
|
||||||
VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_IMAGE_ASPECT_DEPTH_BIT,
|
|
||||||
{VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R,
|
|
||||||
VK_COMPONENT_SWIZZLE_R},
|
|
||||||
0, 0, image->layers, 1);
|
|
||||||
UtilCreateImageView(ctx, image, VulkanImage::VIEW_R000_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY,
|
|
||||||
VK_IMAGE_ASPECT_DEPTH_BIT,
|
|
||||||
{VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO,
|
|
||||||
VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO},
|
|
||||||
0, 0, image->layers, 1);
|
|
||||||
UtilCreateImageView(ctx, image, VulkanImage::VIEW_R001_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY,
|
|
||||||
VK_IMAGE_ASPECT_DEPTH_BIT,
|
|
||||||
{VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO,
|
|
||||||
VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ONE},
|
|
||||||
0, 0, image->layers, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DepthStencilVulkanImage* CreateDepthTarget(GraphicContext* ctx, const DepthTargetInfo& info,
|
DepthStencilVulkanImage* CreateDepthTarget(GraphicContext* ctx, const DepthTargetInfo& info,
|
||||||
@@ -1366,147 +1289,128 @@ VkImageView TextureCache::GetDepthTargetAttachmentView(GraphicContext*
|
|||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageView TextureCache::GetRenderTargetSampledView(GraphicContext* ctx,
|
VkImageView TextureCache::GetImageView(GraphicContext* ctx, VulkanImage* image,
|
||||||
RenderTextureVulkanImage* image,
|
const ImageViewInfo& info) {
|
||||||
VkFormat view_format, int variant,
|
const bool supported_type = info.type == VK_IMAGE_VIEW_TYPE_2D ||
|
||||||
uint32_t base_level, uint32_t level_count,
|
info.type == VK_IMAGE_VIEW_TYPE_2D_ARRAY ||
|
||||||
VkImageViewType type, uint32_t base_layer,
|
info.type == VK_IMAGE_VIEW_TYPE_3D;
|
||||||
uint32_t layer_count) {
|
const bool valid_shape =
|
||||||
if (ctx == nullptr || image == nullptr || image->image == nullptr || base_level >= 16 ||
|
(info.type == VK_IMAGE_VIEW_TYPE_2D && info.layer_count == 1) ||
|
||||||
view_format == VK_FORMAT_UNDEFINED || level_count == 0 ||
|
info.type == VK_IMAGE_VIEW_TYPE_2D_ARRAY ||
|
||||||
base_level + level_count > image->mip_levels || layer_count == 0 ||
|
(info.type == VK_IMAGE_VIEW_TYPE_3D && info.base_layer == 0 && info.layer_count == 1);
|
||||||
base_layer >= image->layers || layer_count > image->layers - base_layer ||
|
if (ctx == nullptr || image == nullptr || image->image == nullptr ||
|
||||||
(type != VK_IMAGE_VIEW_TYPE_2D && type != VK_IMAGE_VIEW_TYPE_2D_ARRAY) ||
|
info.format == VK_FORMAT_UNDEFINED || info.aspect == 0 || info.level_count == 0 ||
|
||||||
(type == VK_IMAGE_VIEW_TYPE_2D && layer_count != 1)) {
|
info.base_level >= (image != nullptr ? image->mip_levels : 0) ||
|
||||||
EXIT("TextureCache: invalid render-target sampled view, image=%p variant=%d"
|
info.level_count > image->mip_levels - info.base_level || info.layer_count == 0 ||
|
||||||
" view_format=%d mip=%u+%u layer=%u+%u type=%d image_levels=%u image_layers=%u\n",
|
info.base_layer >= image->layers || info.layer_count > image->layers - info.base_layer ||
|
||||||
static_cast<const void*>(image), variant, static_cast<int>(view_format), base_level,
|
!supported_type || !valid_shape) {
|
||||||
level_count, base_layer, layer_count, static_cast<int>(type),
|
EXIT("TextureCache: invalid dynamic image view, image=%p format=%d aspect=0x%x"
|
||||||
image != nullptr ? image->mip_levels : 0, image != nullptr ? image->layers : 0);
|
" swizzle=0x%03x mip=%u+%u layer=%u+%u type=%d storage=%d"
|
||||||
}
|
" image_levels=%u image_layers=%u\n",
|
||||||
const bool compatible_variant_format =
|
static_cast<const void*>(image), static_cast<int>(info.format), info.aspect,
|
||||||
view_format == image->format || (variant == VulkanImage::VIEW_BGRA_TO_RGBA &&
|
info.swizzle, info.base_level, info.level_count, info.base_layer, info.layer_count,
|
||||||
IsBgraToRgbaSampledView(image->format, view_format)) ||
|
static_cast<int>(info.type), info.is_storage, image != nullptr ? image->mip_levels : 0,
|
||||||
(variant == VulkanImage::VIEW_DEFAULT &&
|
image != nullptr ? image->layers : 0);
|
||||||
(IsRgba16UintFloatReinterpretation(image->format, view_format) ||
|
|
||||||
IsRgba8UnormUintReinterpretation(image->format, view_format)));
|
|
||||||
if (!compatible_variant_format) {
|
|
||||||
EXIT("TextureCache: incompatible render-target sampled view format, image_format=%d"
|
|
||||||
" view_format=%d variant=%d\n",
|
|
||||||
static_cast<int>(image->format), static_cast<int>(view_format), variant);
|
|
||||||
}
|
|
||||||
const auto default_view_format = variant == VulkanImage::VIEW_BGRA_TO_RGBA
|
|
||||||
? BgraToRgbaSampledViewFormat(image->format)
|
|
||||||
: image->format;
|
|
||||||
int default_variant = variant;
|
|
||||||
if (type == VK_IMAGE_VIEW_TYPE_2D_ARRAY) {
|
|
||||||
switch (variant) {
|
|
||||||
case VulkanImage::VIEW_DEFAULT:
|
|
||||||
default_variant = VulkanImage::VIEW_DEFAULT_ARRAY;
|
|
||||||
break;
|
|
||||||
case VulkanImage::VIEW_BGRA: default_variant = VulkanImage::VIEW_BGRA_ARRAY; break;
|
|
||||||
default: default_variant = VulkanImage::VIEW_MAX; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const bool full_view =
|
|
||||||
base_level == 0 && level_count == image->mip_levels && base_layer == 0 &&
|
|
||||||
layer_count == (type == VK_IMAGE_VIEW_TYPE_2D_ARRAY ? image->layers : 1u);
|
|
||||||
if (view_format == default_view_format && full_view && default_variant >= 0 &&
|
|
||||||
default_variant < VulkanImage::VIEW_MAX && image->image_view[default_variant] != nullptr) {
|
|
||||||
return image->image_view[default_variant];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock(image->sampled_view_mutex);
|
auto& cache = image->view_cache;
|
||||||
for (const auto& cached: image->sampled_views) {
|
std::lock_guard lock(cache.mutex);
|
||||||
if (cached.format == view_format && cached.type == type && cached.variant == variant &&
|
for (const auto& cached: cache.views) {
|
||||||
cached.base_level == base_level && cached.level_count == level_count &&
|
if (cached.info == info) {
|
||||||
cached.base_layer == base_layer && cached.layer_count == layer_count) {
|
|
||||||
return cached.view;
|
return cached.view;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VkComponentMapping components {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY};
|
|
||||||
switch (variant) {
|
|
||||||
case VulkanImage::VIEW_DEFAULT: break;
|
|
||||||
case VulkanImage::VIEW_BGRA:
|
|
||||||
components = {VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R,
|
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY};
|
|
||||||
break;
|
|
||||||
case VulkanImage::VIEW_R001:
|
|
||||||
components = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO,
|
|
||||||
VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ONE};
|
|
||||||
break;
|
|
||||||
case VulkanImage::VIEW_RGB1:
|
|
||||||
components = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B,
|
|
||||||
VK_COMPONENT_SWIZZLE_ONE};
|
|
||||||
break;
|
|
||||||
case VulkanImage::VIEW_R000:
|
|
||||||
components = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO,
|
|
||||||
VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO};
|
|
||||||
break;
|
|
||||||
case VulkanImage::VIEW_RG01:
|
|
||||||
components = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_ZERO,
|
|
||||||
VK_COMPONENT_SWIZZLE_ONE};
|
|
||||||
break;
|
|
||||||
case VulkanImage::VIEW_000R:
|
|
||||||
components = {VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO,
|
|
||||||
VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_R};
|
|
||||||
break;
|
|
||||||
case VulkanImage::VIEW_BGRA_TO_RGBA:
|
|
||||||
if (!IsBgraToRgbaSampledView(image->format, view_format)) {
|
|
||||||
EXIT("TextureCache: incompatible mutable render-target sampled view\n");
|
|
||||||
}
|
|
||||||
components = {VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R,
|
|
||||||
VK_COMPONENT_SWIZZLE_A};
|
|
||||||
break;
|
|
||||||
case VulkanImage::VIEW_ABGR:
|
|
||||||
components = {VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G,
|
|
||||||
VK_COMPONENT_SWIZZLE_R};
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
EXIT("TextureCache: unsupported render-target sampled view variant: %d\n", variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
VkImageViewCreateInfo create {};
|
|
||||||
VkImageViewUsageCreateInfo usage {};
|
VkImageViewUsageCreateInfo usage {};
|
||||||
usage.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO;
|
usage.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO;
|
||||||
usage.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
usage.usage = info.is_storage ? VK_IMAGE_USAGE_STORAGE_BIT : VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
create.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
VkImageViewCreateInfo create {};
|
||||||
create.pNext = &usage;
|
create.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
create.image = image->image;
|
create.pNext = &usage;
|
||||||
create.viewType = type;
|
create.image = image->image;
|
||||||
create.format = view_format;
|
create.viewType = info.type;
|
||||||
create.components = components;
|
create.format = info.format;
|
||||||
create.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
create.components =
|
||||||
create.subresourceRange.baseMipLevel = base_level;
|
info.is_storage ? VkComponentMapping {} : TextureGetComponentMapping(info.swizzle);
|
||||||
create.subresourceRange.levelCount = level_count;
|
create.subresourceRange.aspectMask = info.aspect;
|
||||||
create.subresourceRange.baseArrayLayer = base_layer;
|
create.subresourceRange.baseMipLevel = info.base_level;
|
||||||
create.subresourceRange.layerCount = layer_count;
|
create.subresourceRange.levelCount = info.level_count;
|
||||||
|
create.subresourceRange.baseArrayLayer = info.base_layer;
|
||||||
|
create.subresourceRange.layerCount = info.layer_count;
|
||||||
VkImageView view = nullptr;
|
VkImageView view = nullptr;
|
||||||
const auto result = vkCreateImageView(ctx->device, &create, nullptr, &view);
|
const auto result = vkCreateImageView(ctx->device, &create, nullptr, &view);
|
||||||
if (result != VK_SUCCESS || view == nullptr) {
|
if (result != VK_SUCCESS || view == nullptr) {
|
||||||
EXIT("TextureCache: failed to create render-target sampled subresource view,"
|
EXIT("TextureCache: failed to create dynamic image view, result=%d format=%d"
|
||||||
" result=%d view_format=%d variant=%d mip=%u+%u layer=%u+%u type=%d\n",
|
" aspect=0x%x swizzle=0x%03x mip=%u+%u layer=%u+%u type=%d storage=%d\n",
|
||||||
static_cast<int>(result), static_cast<int>(view_format), variant, base_level,
|
static_cast<int>(result), static_cast<int>(info.format), info.aspect, info.swizzle,
|
||||||
level_count, base_layer, layer_count, static_cast<int>(type));
|
info.base_level, info.level_count, info.base_layer, info.layer_count,
|
||||||
|
static_cast<int>(info.type), info.is_storage);
|
||||||
}
|
}
|
||||||
image->sampled_views.push_back(
|
cache.views.push_back({info, view});
|
||||||
{view_format, type, base_level, level_count, base_layer, layer_count, variant, view});
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkImageView TextureCache::GetDepthTargetSampledView(GraphicContext* ctx,
|
||||||
|
DepthStencilVulkanImage* image,
|
||||||
|
VkFormat view_format, uint32_t swizzle,
|
||||||
|
uint32_t base_level, uint32_t level_count,
|
||||||
|
VkImageViewType type, uint32_t base_layer,
|
||||||
|
uint32_t layer_count) {
|
||||||
|
if (ctx == nullptr || image == nullptr || image->image == nullptr ||
|
||||||
|
view_format == VK_FORMAT_UNDEFINED ||
|
||||||
|
!IsSupportedSampledDepthView(image->format, view_format, swizzle)) {
|
||||||
|
EXIT("TextureCache: invalid sampled depth-target view, image=%p image_format=%d"
|
||||||
|
" view_format=%d swizzle=0x%03x mip=%u+%u layer=%u+%u type=%d"
|
||||||
|
" image_levels=%u image_layers=%u\n",
|
||||||
|
static_cast<const void*>(image),
|
||||||
|
image != nullptr ? static_cast<int>(image->format) : VK_FORMAT_UNDEFINED,
|
||||||
|
static_cast<int>(view_format), swizzle, base_level, level_count, base_layer,
|
||||||
|
layer_count, static_cast<int>(type), image != nullptr ? image->mip_levels : 0,
|
||||||
|
image != nullptr ? image->layers : 0);
|
||||||
|
}
|
||||||
|
return GetImageView(ctx, image,
|
||||||
|
{image->format, type, VK_IMAGE_ASPECT_DEPTH_BIT, base_level, level_count,
|
||||||
|
base_layer, layer_count, swizzle});
|
||||||
|
}
|
||||||
|
|
||||||
|
VkImageView TextureCache::GetSampledColorView(GraphicContext* ctx, VulkanImage* image,
|
||||||
|
VkFormat view_format, uint32_t swizzle,
|
||||||
|
uint32_t base_level, uint32_t level_count,
|
||||||
|
VkImageViewType type, uint32_t base_layer,
|
||||||
|
uint32_t layer_count) {
|
||||||
|
if (ctx == nullptr || image == nullptr || image->image == nullptr ||
|
||||||
|
view_format == VK_FORMAT_UNDEFINED || base_level >= 16 ||
|
||||||
|
(type != VK_IMAGE_VIEW_TYPE_2D && type != VK_IMAGE_VIEW_TYPE_2D_ARRAY) ||
|
||||||
|
!IsSupportedSampledColorView(image->format, view_format, swizzle)) {
|
||||||
|
EXIT("TextureCache: invalid sampled color view, image=%p swizzle=0x%03x"
|
||||||
|
" view_format=%d mip=%u+%u layer=%u+%u type=%d image_levels=%u image_layers=%u\n",
|
||||||
|
static_cast<const void*>(image), swizzle, static_cast<int>(view_format), base_level,
|
||||||
|
level_count, base_layer, layer_count, static_cast<int>(type),
|
||||||
|
image != nullptr ? image->mip_levels : 0, image != nullptr ? image->layers : 0);
|
||||||
|
}
|
||||||
|
const auto precreated_view = type == VK_IMAGE_VIEW_TYPE_2D_ARRAY
|
||||||
|
? VulkanImage::VIEW_DEFAULT_ARRAY
|
||||||
|
: VulkanImage::VIEW_DEFAULT;
|
||||||
|
const bool full_view =
|
||||||
|
base_level == 0 && level_count == image->mip_levels && base_layer == 0 &&
|
||||||
|
layer_count == (type == VK_IMAGE_VIEW_TYPE_2D_ARRAY ? image->layers : 1u);
|
||||||
|
if (view_format == image->format && swizzle == DstSel(4, 5, 6, 7) && full_view &&
|
||||||
|
image->image_view[precreated_view] != nullptr) {
|
||||||
|
return image->image_view[precreated_view];
|
||||||
|
}
|
||||||
|
return GetImageView(ctx, image,
|
||||||
|
{view_format, type, VK_IMAGE_ASPECT_COLOR_BIT, base_level, level_count,
|
||||||
|
base_layer, layer_count, swizzle});
|
||||||
|
}
|
||||||
|
|
||||||
VkImageView TextureCache::GetRenderTargetStorageView(GraphicContext* ctx,
|
VkImageView TextureCache::GetRenderTargetStorageView(GraphicContext* ctx,
|
||||||
RenderTextureVulkanImage* image,
|
RenderTextureVulkanImage* image,
|
||||||
VkFormat view_format, uint32_t base_level,
|
VkFormat view_format, uint32_t base_level,
|
||||||
uint32_t level_count, VkImageViewType type,
|
uint32_t level_count, VkImageViewType type,
|
||||||
uint32_t base_layer, uint32_t layer_count) {
|
uint32_t base_layer, uint32_t layer_count) {
|
||||||
if (ctx == nullptr || image == nullptr || image->image == nullptr ||
|
if (ctx == nullptr || image == nullptr || image->image == nullptr ||
|
||||||
view_format == VK_FORMAT_UNDEFINED || level_count == 0 ||
|
view_format == VK_FORMAT_UNDEFINED ||
|
||||||
base_level + level_count > image->mip_levels || layer_count == 0 ||
|
(type != VK_IMAGE_VIEW_TYPE_2D && type != VK_IMAGE_VIEW_TYPE_2D_ARRAY)) {
|
||||||
base_layer >= image->layers || layer_count > image->layers - base_layer ||
|
|
||||||
(type != VK_IMAGE_VIEW_TYPE_2D && type != VK_IMAGE_VIEW_TYPE_2D_ARRAY) ||
|
|
||||||
(type == VK_IMAGE_VIEW_TYPE_2D && layer_count != 1)) {
|
|
||||||
EXIT("TextureCache: invalid render-target storage view, image=%p view_format=%d"
|
EXIT("TextureCache: invalid render-target storage view, image=%p view_format=%d"
|
||||||
" mip=%u+%u layer=%u+%u type=%d image_levels=%u image_layers=%u\n",
|
" mip=%u+%u layer=%u+%u type=%d image_levels=%u image_layers=%u\n",
|
||||||
static_cast<const void*>(image), static_cast<int>(view_format), base_level,
|
static_cast<const void*>(image), static_cast<int>(view_format), base_level,
|
||||||
@@ -1532,52 +1436,15 @@ VkImageView TextureCache::GetRenderTargetStorageView(GraphicContext* c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock(image->storage_view_mutex);
|
|
||||||
for (const auto& cached: image->storage_views) {
|
|
||||||
if (cached.format == view_format && cached.type == type &&
|
|
||||||
cached.base_level == base_level && cached.level_count == level_count &&
|
|
||||||
cached.base_layer == base_layer && cached.layer_count == layer_count) {
|
|
||||||
return cached.view;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (compatible && !FormatSupportsStorage(ctx, view_format)) {
|
if (compatible && !FormatSupportsStorage(ctx, view_format)) {
|
||||||
EXIT("TextureCache: compatible render-target storage format lacks storage support,"
|
EXIT("TextureCache: compatible render-target storage format lacks storage support,"
|
||||||
" image_format=%d view_format=%d base=%u count=%u\n",
|
" image_format=%d view_format=%d base=%u count=%u\n",
|
||||||
static_cast<int>(image->format), static_cast<int>(view_format), base_level,
|
static_cast<int>(image->format), static_cast<int>(view_format), base_level,
|
||||||
level_count);
|
level_count);
|
||||||
}
|
}
|
||||||
|
return GetImageView(ctx, image,
|
||||||
VkImageViewUsageCreateInfo usage {};
|
{view_format, type, VK_IMAGE_ASPECT_COLOR_BIT, base_level, level_count,
|
||||||
usage.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO;
|
base_layer, layer_count, DstSel(4, 5, 6, 7), true});
|
||||||
usage.usage = VK_IMAGE_USAGE_STORAGE_BIT;
|
|
||||||
VkImageViewCreateInfo create {};
|
|
||||||
create.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
||||||
create.pNext = &usage;
|
|
||||||
create.image = image->image;
|
|
||||||
create.viewType = type;
|
|
||||||
create.format = view_format;
|
|
||||||
create.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY};
|
|
||||||
create.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
create.subresourceRange.baseMipLevel = base_level;
|
|
||||||
create.subresourceRange.levelCount = level_count;
|
|
||||||
create.subresourceRange.baseArrayLayer = base_layer;
|
|
||||||
create.subresourceRange.layerCount = layer_count;
|
|
||||||
VkImageView view = nullptr;
|
|
||||||
const auto result = vkCreateImageView(ctx->device, &create, nullptr, &view);
|
|
||||||
if (result != VK_SUCCESS || view == nullptr) {
|
|
||||||
EXIT("TextureCache: failed to create compatible render-target storage view,"
|
|
||||||
" result=%d image_format=%d view_format=%d base=%u count=%u\n",
|
|
||||||
static_cast<int>(result), static_cast<int>(image->format),
|
|
||||||
static_cast<int>(view_format), base_level, level_count);
|
|
||||||
}
|
|
||||||
image->storage_views.push_back(
|
|
||||||
{view_format, type, base_level, level_count, base_layer, layer_count, view});
|
|
||||||
LOGF("TextureCache: created compatible render-target storage view: image_format=%d"
|
|
||||||
" view_format=%d base=%u count=%u extent=%ux%u\n",
|
|
||||||
static_cast<int>(image->format), static_cast<int>(view_format), base_level, level_count,
|
|
||||||
image->extent.width, image->extent.height);
|
|
||||||
return view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageView TextureCache::GetStorageTextureSampledView(GraphicContext* ctx,
|
VkImageView TextureCache::GetStorageTextureSampledView(GraphicContext* ctx,
|
||||||
@@ -1595,101 +1462,41 @@ VkImageView TextureCache::GetStorageTextureSampledView(GraphicContext*
|
|||||||
info.view_levels, image != nullptr ? image->mip_levels : 0, info.base_array);
|
info.view_levels, image != nullptr ? image->mip_levels : 0, info.base_array);
|
||||||
}
|
}
|
||||||
const auto view_format = TextureGetFormat(info.format, TextureFormatUsage::Sampled);
|
const auto view_format = TextureGetFormat(info.format, TextureFormatUsage::Sampled);
|
||||||
if (view_format != image->format &&
|
if (view_format != image->format && !IsRgba8SrgbReinterpretation(image->format, view_format) &&
|
||||||
!IsRgba8SrgbReinterpretation(image->format, view_format) &&
|
|
||||||
!IsR32UintFloatReinterpretation(image->format, view_format)) {
|
!IsR32UintFloatReinterpretation(image->format, view_format)) {
|
||||||
EXIT("TextureCache: incompatible sampled view of storage texture, image_format=%d"
|
EXIT("TextureCache: incompatible sampled view of storage texture, image_format=%d"
|
||||||
" view_format=%d swizzle=0x%03x\n",
|
" view_format=%d swizzle=0x%03x\n",
|
||||||
static_cast<int>(image->format), static_cast<int>(view_format), info.swizzle);
|
static_cast<int>(image->format), static_cast<int>(view_format), info.swizzle);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock(image->sampled_view_mutex);
|
VkImageViewType type = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
|
||||||
for (const auto& cached: image->sampled_views) {
|
|
||||||
if (cached.format == view_format && cached.swizzle == info.swizzle &&
|
|
||||||
cached.type == info.type && cached.base_level == info.base_level &&
|
|
||||||
cached.level_count == info.view_levels) {
|
|
||||||
return cached.view;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VkImageViewUsageCreateInfo usage {};
|
|
||||||
usage.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO;
|
|
||||||
usage.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
||||||
VkImageViewCreateInfo create {};
|
|
||||||
create.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
||||||
create.pNext = &usage;
|
|
||||||
create.image = image->image;
|
|
||||||
switch (shape) {
|
switch (shape) {
|
||||||
case StorageSampledViewShape::Image2D: create.viewType = VK_IMAGE_VIEW_TYPE_2D; break;
|
case StorageSampledViewShape::Image2D: type = VK_IMAGE_VIEW_TYPE_2D; break;
|
||||||
case StorageSampledViewShape::Image2DArray:
|
case StorageSampledViewShape::Image2DArray: type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; break;
|
||||||
create.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
case StorageSampledViewShape::Image3D: type = VK_IMAGE_VIEW_TYPE_3D; break;
|
||||||
break;
|
|
||||||
case StorageSampledViewShape::Image3D: create.viewType = VK_IMAGE_VIEW_TYPE_3D; break;
|
|
||||||
case StorageSampledViewShape::Unsupported:
|
case StorageSampledViewShape::Unsupported:
|
||||||
EXIT("TextureCache: unsupported sampled storage-image view shape\n");
|
EXIT("TextureCache: unsupported sampled storage-image view shape\n");
|
||||||
}
|
}
|
||||||
create.format = view_format;
|
const auto layer_count = shape == StorageSampledViewShape::Image2DArray ? info.depth : 1u;
|
||||||
create.components = TextureGetComponentMapping(info.swizzle);
|
return GetImageView(ctx, image,
|
||||||
create.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
{view_format, type, VK_IMAGE_ASPECT_COLOR_BIT, info.base_level,
|
||||||
create.subresourceRange.baseMipLevel = info.base_level;
|
info.view_levels, 0, layer_count, info.swizzle});
|
||||||
create.subresourceRange.levelCount = info.view_levels;
|
|
||||||
create.subresourceRange.baseArrayLayer = 0;
|
|
||||||
create.subresourceRange.layerCount =
|
|
||||||
shape == StorageSampledViewShape::Image2DArray ? info.depth : 1;
|
|
||||||
VkImageView view = nullptr;
|
|
||||||
const auto result = vkCreateImageView(ctx->device, &create, nullptr, &view);
|
|
||||||
if (result != VK_SUCCESS || view == nullptr) {
|
|
||||||
EXIT("TextureCache: failed to create sampled view of storage texture, result=%d"
|
|
||||||
" image_format=%d view_format=%d swizzle=0x%03x type=%u base=%u count=%u\n",
|
|
||||||
static_cast<int>(result), static_cast<int>(image->format),
|
|
||||||
static_cast<int>(view_format), info.swizzle, info.type, info.base_level,
|
|
||||||
info.view_levels);
|
|
||||||
}
|
|
||||||
image->sampled_views.push_back(
|
|
||||||
{view_format, info.swizzle, info.type, info.base_level, info.view_levels, view});
|
|
||||||
LOGF("TextureCache: created sampled view of storage texture: image_format=%d"
|
|
||||||
" view_format=%d swizzle=0x%03x type=%u base=%u count=%u\n",
|
|
||||||
static_cast<int>(image->format), static_cast<int>(view_format), info.swizzle, info.type,
|
|
||||||
info.base_level, info.view_levels);
|
|
||||||
return view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageView TextureCache::GetStorageTextureStorageView(GraphicContext* ctx,
|
VkImageView TextureCache::GetStorageTextureStorageView(GraphicContext* ctx,
|
||||||
StorageTextureVulkanImage* image,
|
StorageTextureVulkanImage* image,
|
||||||
uint32_t base_level) {
|
uint32_t base_level) {
|
||||||
if (base_level >= image->mip_levels) {
|
if (ctx == nullptr || image == nullptr || image->image == nullptr ||
|
||||||
|
base_level >= (image != nullptr ? image->mip_levels : 0)) {
|
||||||
EXIT("TextureCache: invalid storage-texture mip view, image=%p level=%u levels=%u\n",
|
EXIT("TextureCache: invalid storage-texture mip view, image=%p level=%u levels=%u\n",
|
||||||
static_cast<const void*>(image), base_level, image != nullptr ? image->mip_levels : 0);
|
static_cast<const void*>(image), base_level, image != nullptr ? image->mip_levels : 0);
|
||||||
}
|
}
|
||||||
if (base_level == 0) {
|
if (base_level == 0) {
|
||||||
return image->image_view[VulkanImage::VIEW_DEFAULT];
|
return image->image_view[VulkanImage::VIEW_DEFAULT];
|
||||||
}
|
}
|
||||||
std::lock_guard lock(image->storage_view_mutex);
|
return GetImageView(ctx, image,
|
||||||
for (const auto& cached: image->storage_views) {
|
{image->format, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
if (cached.base_level == base_level) {
|
base_level, 1, 0, 1, DstSel(4, 5, 6, 7), true});
|
||||||
return cached.view;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
VkImageViewCreateInfo create {};
|
|
||||||
create.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
||||||
create.image = image->image;
|
|
||||||
create.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
|
||||||
create.format = image->format;
|
|
||||||
create.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY};
|
|
||||||
create.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
create.subresourceRange.baseMipLevel = base_level;
|
|
||||||
create.subresourceRange.levelCount = 1;
|
|
||||||
create.subresourceRange.baseArrayLayer = 0;
|
|
||||||
create.subresourceRange.layerCount = 1;
|
|
||||||
VkImageView view = nullptr;
|
|
||||||
const auto result = vkCreateImageView(ctx->device, &create, nullptr, &view);
|
|
||||||
if (result != VK_SUCCESS || view == nullptr) {
|
|
||||||
EXIT("TextureCache: failed to create storage-texture mip view, result=%d level=%u\n",
|
|
||||||
static_cast<int>(result), base_level);
|
|
||||||
}
|
|
||||||
image->storage_views.push_back({base_level, view});
|
|
||||||
return view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::CachedImage* TextureCache::FindGpuReadbackPageCandidateLocked(uint64_t vaddr,
|
TextureCache::CachedImage* TextureCache::FindGpuReadbackPageCandidateLocked(uint64_t vaddr,
|
||||||
@@ -4295,6 +4102,13 @@ void TextureCache::DeleteImageViews(GraphicContext* ctx, VulkanImage* image) {
|
|||||||
EXIT_IF(ctx == nullptr);
|
EXIT_IF(ctx == nullptr);
|
||||||
EXIT_IF(image == nullptr);
|
EXIT_IF(image == nullptr);
|
||||||
|
|
||||||
|
for (auto& cached: image->view_cache.views) {
|
||||||
|
if (cached.view != nullptr) {
|
||||||
|
vkDestroyImageView(ctx->device, cached.view, nullptr);
|
||||||
|
cached.view = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
image->view_cache.views.clear();
|
||||||
for (auto& view: image->image_view) {
|
for (auto& view: image->image_view) {
|
||||||
if (view != nullptr) {
|
if (view != nullptr) {
|
||||||
vkDestroyImageView(ctx->device, view, nullptr);
|
vkDestroyImageView(ctx->device, view, nullptr);
|
||||||
@@ -4310,23 +4124,6 @@ void TextureCache::DeleteGpuTexture(GraphicContext* ctx, GpuTextureVulkanImage*
|
|||||||
EXIT_IF(ctx == nullptr);
|
EXIT_IF(ctx == nullptr);
|
||||||
EXIT_IF(image == nullptr);
|
EXIT_IF(image == nullptr);
|
||||||
|
|
||||||
if (image->type == VulkanImageType::StorageTexture) {
|
|
||||||
auto* storage = static_cast<StorageTextureVulkanImage*>(image);
|
|
||||||
for (auto& cached: storage->sampled_views) {
|
|
||||||
if (cached.view != nullptr) {
|
|
||||||
vkDestroyImageView(ctx->device, cached.view, nullptr);
|
|
||||||
cached.view = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
storage->sampled_views.clear();
|
|
||||||
for (auto& cached: storage->storage_views) {
|
|
||||||
if (cached.view != nullptr) {
|
|
||||||
vkDestroyImageView(ctx->device, cached.view, nullptr);
|
|
||||||
cached.view = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
storage->storage_views.clear();
|
|
||||||
}
|
|
||||||
DeleteImageViews(ctx, image);
|
DeleteImageViews(ctx, image);
|
||||||
VulkanDeleteImage(ctx, image, mem);
|
VulkanDeleteImage(ctx, image, mem);
|
||||||
|
|
||||||
@@ -4360,20 +4157,6 @@ void TextureCache::DeleteRenderTexture(GraphicContext* ctx, RenderTextureVulkanI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
image->attachment_views.clear();
|
image->attachment_views.clear();
|
||||||
for (auto& cached: image->sampled_views) {
|
|
||||||
if (cached.view != nullptr) {
|
|
||||||
vkDestroyImageView(ctx->device, cached.view, nullptr);
|
|
||||||
cached.view = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
image->sampled_views.clear();
|
|
||||||
for (auto& cached: image->storage_views) {
|
|
||||||
if (cached.view != nullptr) {
|
|
||||||
vkDestroyImageView(ctx->device, cached.view, nullptr);
|
|
||||||
cached.view = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
image->storage_views.clear();
|
|
||||||
DeleteImageViews(ctx, image);
|
DeleteImageViews(ctx, image);
|
||||||
VulkanDeleteImage(ctx, image, mem);
|
VulkanDeleteImage(ctx, image, mem);
|
||||||
delete image;
|
delete image;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace Libs::Graphics {
|
|||||||
struct DepthStencilVulkanImage;
|
struct DepthStencilVulkanImage;
|
||||||
struct GpuTextureVulkanImage;
|
struct GpuTextureVulkanImage;
|
||||||
struct GraphicContext;
|
struct GraphicContext;
|
||||||
|
struct ImageViewInfo;
|
||||||
struct RenderTextureVulkanImage;
|
struct RenderTextureVulkanImage;
|
||||||
struct StorageTextureVulkanImage;
|
struct StorageTextureVulkanImage;
|
||||||
struct VideoOutVulkanImage;
|
struct VideoOutVulkanImage;
|
||||||
@@ -69,12 +70,17 @@ public:
|
|||||||
DepthStencilVulkanImage* image,
|
DepthStencilVulkanImage* image,
|
||||||
uint32_t base_layer,
|
uint32_t base_layer,
|
||||||
uint32_t layer_count);
|
uint32_t layer_count);
|
||||||
[[nodiscard]] VkImageView GetRenderTargetSampledView(GraphicContext* ctx,
|
[[nodiscard]] VkImageView GetDepthTargetSampledView(GraphicContext* ctx,
|
||||||
RenderTextureVulkanImage* image,
|
DepthStencilVulkanImage* image,
|
||||||
VkFormat view_format, int variant,
|
VkFormat view_format, uint32_t swizzle,
|
||||||
uint32_t base_level, uint32_t level_count,
|
uint32_t base_level, uint32_t level_count,
|
||||||
VkImageViewType type, uint32_t base_layer,
|
VkImageViewType type, uint32_t base_layer,
|
||||||
uint32_t layer_count);
|
uint32_t layer_count);
|
||||||
|
[[nodiscard]] VkImageView GetSampledColorView(GraphicContext* ctx, VulkanImage* image,
|
||||||
|
VkFormat view_format, uint32_t swizzle,
|
||||||
|
uint32_t base_level, uint32_t level_count,
|
||||||
|
VkImageViewType type, uint32_t base_layer,
|
||||||
|
uint32_t layer_count);
|
||||||
[[nodiscard]] VkImageView GetRenderTargetStorageView(GraphicContext* ctx,
|
[[nodiscard]] VkImageView GetRenderTargetStorageView(GraphicContext* ctx,
|
||||||
RenderTextureVulkanImage* image,
|
RenderTextureVulkanImage* image,
|
||||||
VkFormat view_format, uint32_t base_level,
|
VkFormat view_format, uint32_t base_level,
|
||||||
@@ -83,13 +89,13 @@ public:
|
|||||||
[[nodiscard]] VkImageView GetStorageTextureSampledView(GraphicContext* ctx,
|
[[nodiscard]] VkImageView GetStorageTextureSampledView(GraphicContext* ctx,
|
||||||
StorageTextureVulkanImage* image,
|
StorageTextureVulkanImage* image,
|
||||||
const ImageInfo& info);
|
const ImageInfo& info);
|
||||||
[[nodiscard]] VkImageView GetStorageTextureStorageView(GraphicContext* ctx,
|
[[nodiscard]] VkImageView GetStorageTextureStorageView(GraphicContext* ctx,
|
||||||
StorageTextureVulkanImage* image,
|
StorageTextureVulkanImage* image,
|
||||||
uint32_t base_level);
|
uint32_t base_level);
|
||||||
[[nodiscard]] DepthStencilVulkanImage* FindDepthTargetByRange(uint64_t vaddr, uint64_t size,
|
[[nodiscard]] DepthStencilVulkanImage*
|
||||||
bool allow_containing_sampled = false);
|
FindDepthTargetByRange(uint64_t vaddr, uint64_t size, bool allow_containing_sampled = false);
|
||||||
[[nodiscard]] bool HasPageOverlap(uint64_t vaddr, uint64_t size);
|
[[nodiscard]] bool HasPageOverlap(uint64_t vaddr, uint64_t size);
|
||||||
[[nodiscard]] bool HasRangeOverlap(uint64_t vaddr, uint64_t size);
|
[[nodiscard]] bool HasRangeOverlap(uint64_t vaddr, uint64_t size);
|
||||||
[[nodiscard]] bool HasGpuModifiedRangeOverlap(uint64_t vaddr, uint64_t size);
|
[[nodiscard]] bool HasGpuModifiedRangeOverlap(uint64_t vaddr, uint64_t size);
|
||||||
[[nodiscard]] bool HasGpuTargetPageOverlap(uint64_t vaddr, uint64_t size);
|
[[nodiscard]] bool HasGpuTargetPageOverlap(uint64_t vaddr, uint64_t size);
|
||||||
void RegisterMeta(uint64_t vaddr, uint64_t size, uint32_t layers = 1);
|
void RegisterMeta(uint64_t vaddr, uint64_t size, uint32_t layers = 1);
|
||||||
@@ -126,6 +132,8 @@ private:
|
|||||||
bool gpu_modified = false;
|
bool gpu_modified = false;
|
||||||
};
|
};
|
||||||
static void DeleteImageViews(GraphicContext* ctx, VulkanImage* image);
|
static void DeleteImageViews(GraphicContext* ctx, VulkanImage* image);
|
||||||
|
[[nodiscard]] VkImageView GetImageView(GraphicContext* ctx, VulkanImage* image,
|
||||||
|
const ImageViewInfo& info);
|
||||||
[[nodiscard]] bool HasMetaOverlapLocked(uint64_t vaddr, uint64_t size) const;
|
[[nodiscard]] bool HasMetaOverlapLocked(uint64_t vaddr, uint64_t size) const;
|
||||||
[[nodiscard]] CachedImage* FindGpuReadbackPageCandidateLocked(uint64_t vaddr,
|
[[nodiscard]] CachedImage* FindGpuReadbackPageCandidateLocked(uint64_t vaddr,
|
||||||
uint64_t size) const;
|
uint64_t size) const;
|
||||||
|
|||||||
@@ -154,8 +154,9 @@ static void ConfigurePreparedFrame(PreparedFrame* frame, VkExtent2D extent, VkFo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (dst.image != nullptr) {
|
if (dst.image != nullptr) {
|
||||||
|
EXIT_IF(!dst.view_cache.views.empty());
|
||||||
VulkanDeleteImage(ctx, &dst, &dst.memory);
|
VulkanDeleteImage(ctx, &dst, &dst.memory);
|
||||||
dst = VulkanImage(VulkanImageType::Unknown);
|
dst.memory = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
dst.extent = extent;
|
dst.extent = extent;
|
||||||
|
|||||||
@@ -491,6 +491,11 @@ void Require(const char *shader_name, const char *stage, bool value,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RejectUnexpectedPageFault(void *, PageFaultAccess, uint64_t, uint64_t,
|
||||||
|
PageFaultPhase) noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
struct TestCase {
|
struct TestCase {
|
||||||
const char *name = "";
|
const char *name = "";
|
||||||
std::vector<u32> code;
|
std::vector<u32> code;
|
||||||
@@ -1047,6 +1052,258 @@ public:
|
|||||||
static_cast<int>(view_info.format));
|
static_cast<int>(view_info.format));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckRenderTargetViewCache() {
|
||||||
|
constexpr const char *name = "RenderTargetViewCache";
|
||||||
|
VkImageCreateInfo image_info{};
|
||||||
|
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
|
image_info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
||||||
|
image_info.imageType = VK_IMAGE_TYPE_2D;
|
||||||
|
image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
image_info.extent = {8, 8, 1};
|
||||||
|
image_info.mipLevels = 2;
|
||||||
|
image_info.arrayLayers = 2;
|
||||||
|
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
|
image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
|
||||||
|
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
|
||||||
|
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
|
||||||
|
VkImage image_handle = VK_NULL_HANDLE;
|
||||||
|
RequireVk(name, "image",
|
||||||
|
vkCreateImage(m_device, &image_info, nullptr, &image_handle),
|
||||||
|
"vkCreateImage");
|
||||||
|
VkMemoryRequirements requirements{};
|
||||||
|
vkGetImageMemoryRequirements(m_device, image_handle, &requirements);
|
||||||
|
u32 memory_type = 0;
|
||||||
|
Require(name, "memory",
|
||||||
|
FindMemoryType(requirements.memoryTypeBits,
|
||||||
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memory_type) ||
|
||||||
|
FindMemoryType(requirements.memoryTypeBits, 0, &memory_type),
|
||||||
|
"no memory type for sampled render target");
|
||||||
|
VkMemoryAllocateInfo allocation{};
|
||||||
|
allocation.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
allocation.allocationSize = requirements.size;
|
||||||
|
allocation.memoryTypeIndex = memory_type;
|
||||||
|
VkDeviceMemory memory = VK_NULL_HANDLE;
|
||||||
|
RequireVk(name, "memory",
|
||||||
|
vkAllocateMemory(m_device, &allocation, nullptr, &memory),
|
||||||
|
"vkAllocateMemory");
|
||||||
|
RequireVk(name, "memory",
|
||||||
|
vkBindImageMemory(m_device, image_handle, memory, 0),
|
||||||
|
"vkBindImageMemory");
|
||||||
|
|
||||||
|
GraphicContext context{};
|
||||||
|
context.physical_device = m_physical_device;
|
||||||
|
context.device = m_device;
|
||||||
|
ResourceMutex resource_mutex;
|
||||||
|
PageManager page_manager(RejectUnexpectedPageFault, nullptr);
|
||||||
|
BufferCache buffer_cache(page_manager, resource_mutex);
|
||||||
|
TextureCache texture_cache(page_manager, buffer_cache, resource_mutex);
|
||||||
|
buffer_cache.SetTextureCache(texture_cache);
|
||||||
|
RenderTextureVulkanImage image;
|
||||||
|
image.image = image_handle;
|
||||||
|
image.format = image_info.format;
|
||||||
|
image.extent = {image_info.extent.width, image_info.extent.height};
|
||||||
|
image.layers = 2;
|
||||||
|
image.mip_levels = 2;
|
||||||
|
|
||||||
|
constexpr auto first_swizzle = DstSel(5, 1, 7, 0);
|
||||||
|
constexpr auto second_swizzle = DstSel(7, 4, 0, 1);
|
||||||
|
const auto first = texture_cache.GetSampledColorView(
|
||||||
|
&context, &image, image.format, first_swizzle, 0, 1,
|
||||||
|
VK_IMAGE_VIEW_TYPE_2D, 0, 1);
|
||||||
|
const auto first_again = texture_cache.GetSampledColorView(
|
||||||
|
&context, &image, image.format, first_swizzle, 0, 1,
|
||||||
|
VK_IMAGE_VIEW_TYPE_2D, 0, 1);
|
||||||
|
const auto second = texture_cache.GetSampledColorView(
|
||||||
|
&context, &image, image.format, second_swizzle, 0, 1,
|
||||||
|
VK_IMAGE_VIEW_TYPE_2D, 0, 1);
|
||||||
|
const auto different_mip = texture_cache.GetSampledColorView(
|
||||||
|
&context, &image, image.format, first_swizzle, 1, 1,
|
||||||
|
VK_IMAGE_VIEW_TYPE_2D, 0, 1);
|
||||||
|
const auto different_layer = texture_cache.GetSampledColorView(
|
||||||
|
&context, &image, image.format, first_swizzle, 0, 1,
|
||||||
|
VK_IMAGE_VIEW_TYPE_2D, 1, 1);
|
||||||
|
const auto array_view = texture_cache.GetSampledColorView(
|
||||||
|
&context, &image, image.format, first_swizzle, 0, 1,
|
||||||
|
VK_IMAGE_VIEW_TYPE_2D_ARRAY, 0, 2);
|
||||||
|
constexpr auto identity = DstSel(4, 5, 6, 7);
|
||||||
|
const auto native_format = texture_cache.GetSampledColorView(
|
||||||
|
&context, &image, image.format, identity, 0, 1, VK_IMAGE_VIEW_TYPE_2D,
|
||||||
|
0, 1);
|
||||||
|
const auto reinterpreted_format = texture_cache.GetSampledColorView(
|
||||||
|
&context, &image, VK_FORMAT_R8G8B8A8_UINT, identity, 0, 1,
|
||||||
|
VK_IMAGE_VIEW_TYPE_2D, 0, 1);
|
||||||
|
const auto storage = texture_cache.GetRenderTargetStorageView(
|
||||||
|
&context, &image, image.format, 0, 1, VK_IMAGE_VIEW_TYPE_2D, 0, 1);
|
||||||
|
const auto storage_again = texture_cache.GetRenderTargetStorageView(
|
||||||
|
&context, &image, image.format, 0, 1, VK_IMAGE_VIEW_TYPE_2D, 0, 1);
|
||||||
|
Require(name, "cache identity",
|
||||||
|
first != VK_NULL_HANDLE && first_again == first &&
|
||||||
|
second != VK_NULL_HANDLE && second != first &&
|
||||||
|
different_mip != VK_NULL_HANDLE && different_mip != first &&
|
||||||
|
different_layer != VK_NULL_HANDLE && different_layer != first &&
|
||||||
|
array_view != VK_NULL_HANDLE && array_view != first &&
|
||||||
|
native_format != VK_NULL_HANDLE &&
|
||||||
|
reinterpreted_format != VK_NULL_HANDLE &&
|
||||||
|
reinterpreted_format != native_format &&
|
||||||
|
storage != VK_NULL_HANDLE && storage != native_format &&
|
||||||
|
storage_again == storage && image.view_cache.views.size() == 8,
|
||||||
|
"view cache omitted usage, swizzle, format, type, mip, or layer "
|
||||||
|
"identity");
|
||||||
|
|
||||||
|
for (const auto &view : image.view_cache.views) {
|
||||||
|
vkDestroyImageView(m_device, view.view, nullptr);
|
||||||
|
}
|
||||||
|
image.view_cache.views.clear();
|
||||||
|
vkDestroyImage(m_device, image_handle, nullptr);
|
||||||
|
vkFreeMemory(m_device, memory, nullptr);
|
||||||
|
std::printf("[host] %-32s ok\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckDepthTargetSampledViewCache() {
|
||||||
|
constexpr const char *name = "DepthTargetSampledViewCache";
|
||||||
|
VkImageCreateInfo image_info{};
|
||||||
|
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
|
image_info.imageType = VK_IMAGE_TYPE_2D;
|
||||||
|
image_info.format = VK_FORMAT_D32_SFLOAT;
|
||||||
|
image_info.extent = {8, 8, 1};
|
||||||
|
image_info.mipLevels = 1;
|
||||||
|
image_info.arrayLayers = 2;
|
||||||
|
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
|
image_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
|
||||||
|
VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
|
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
|
||||||
|
VkImage image_handle = VK_NULL_HANDLE;
|
||||||
|
RequireVk(name, "image",
|
||||||
|
vkCreateImage(m_device, &image_info, nullptr, &image_handle),
|
||||||
|
"vkCreateImage");
|
||||||
|
VkMemoryRequirements requirements{};
|
||||||
|
vkGetImageMemoryRequirements(m_device, image_handle, &requirements);
|
||||||
|
u32 memory_type = 0;
|
||||||
|
Require(name, "memory",
|
||||||
|
FindMemoryType(requirements.memoryTypeBits,
|
||||||
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memory_type) ||
|
||||||
|
FindMemoryType(requirements.memoryTypeBits, 0, &memory_type),
|
||||||
|
"no memory type for sampled depth target");
|
||||||
|
VkMemoryAllocateInfo allocation{};
|
||||||
|
allocation.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
allocation.allocationSize = requirements.size;
|
||||||
|
allocation.memoryTypeIndex = memory_type;
|
||||||
|
VkDeviceMemory memory = VK_NULL_HANDLE;
|
||||||
|
RequireVk(name, "memory",
|
||||||
|
vkAllocateMemory(m_device, &allocation, nullptr, &memory),
|
||||||
|
"vkAllocateMemory");
|
||||||
|
RequireVk(name, "memory",
|
||||||
|
vkBindImageMemory(m_device, image_handle, memory, 0),
|
||||||
|
"vkBindImageMemory");
|
||||||
|
|
||||||
|
GraphicContext context{};
|
||||||
|
context.physical_device = m_physical_device;
|
||||||
|
context.device = m_device;
|
||||||
|
ResourceMutex resource_mutex;
|
||||||
|
PageManager page_manager(RejectUnexpectedPageFault, nullptr);
|
||||||
|
BufferCache buffer_cache(page_manager, resource_mutex);
|
||||||
|
TextureCache texture_cache(page_manager, buffer_cache, resource_mutex);
|
||||||
|
buffer_cache.SetTextureCache(texture_cache);
|
||||||
|
DepthStencilVulkanImage image;
|
||||||
|
image.image = image_handle;
|
||||||
|
image.format = image_info.format;
|
||||||
|
image.extent = {image_info.extent.width, image_info.extent.height};
|
||||||
|
image.layers = image_info.arrayLayers;
|
||||||
|
image.mip_levels = image_info.mipLevels;
|
||||||
|
|
||||||
|
constexpr auto replicated = DstSel(4, 4, 4, 4);
|
||||||
|
constexpr auto r001 = DstSel(4, 0, 0, 1);
|
||||||
|
const auto first = texture_cache.GetDepthTargetSampledView(
|
||||||
|
&context, &image, VK_FORMAT_R32_SFLOAT, replicated, 0, 1,
|
||||||
|
VK_IMAGE_VIEW_TYPE_2D, 0, 1);
|
||||||
|
const auto first_again = texture_cache.GetDepthTargetSampledView(
|
||||||
|
&context, &image, VK_FORMAT_R32_SFLOAT, replicated, 0, 1,
|
||||||
|
VK_IMAGE_VIEW_TYPE_2D, 0, 1);
|
||||||
|
const auto different_swizzle = texture_cache.GetDepthTargetSampledView(
|
||||||
|
&context, &image, VK_FORMAT_R32_SFLOAT, r001, 0, 1,
|
||||||
|
VK_IMAGE_VIEW_TYPE_2D, 0, 1);
|
||||||
|
const auto different_layer = texture_cache.GetDepthTargetSampledView(
|
||||||
|
&context, &image, VK_FORMAT_R32_SFLOAT, replicated, 0, 1,
|
||||||
|
VK_IMAGE_VIEW_TYPE_2D, 1, 1);
|
||||||
|
const auto array_view = texture_cache.GetDepthTargetSampledView(
|
||||||
|
&context, &image, VK_FORMAT_R32_SFLOAT, replicated, 0, 1,
|
||||||
|
VK_IMAGE_VIEW_TYPE_2D_ARRAY, 0, 2);
|
||||||
|
Require(name, "cache identity",
|
||||||
|
first != VK_NULL_HANDLE && first_again == first &&
|
||||||
|
different_swizzle != VK_NULL_HANDLE &&
|
||||||
|
different_swizzle != first &&
|
||||||
|
different_layer != VK_NULL_HANDLE && different_layer != first &&
|
||||||
|
array_view != VK_NULL_HANDLE && array_view != first &&
|
||||||
|
image.view_cache.views.size() == 4,
|
||||||
|
"sampled depth cache omitted swizzle, type, or layer identity");
|
||||||
|
|
||||||
|
for (const auto &view : image.view_cache.views) {
|
||||||
|
vkDestroyImageView(m_device, view.view, nullptr);
|
||||||
|
}
|
||||||
|
image.view_cache.views.clear();
|
||||||
|
vkDestroyImage(m_device, image_handle, nullptr);
|
||||||
|
vkFreeMemory(m_device, memory, nullptr);
|
||||||
|
std::printf("[host] %-32s ok\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckVideoOutSampledViewCache() {
|
||||||
|
constexpr const char *name = "VideoOutSampledViewCache";
|
||||||
|
auto backing = CreateImage2D(name, 8, 8, VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
|
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
|
||||||
|
VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
|
{}, 1, VK_IMAGE_LAYOUT_UNDEFINED);
|
||||||
|
|
||||||
|
GraphicContext context{};
|
||||||
|
context.physical_device = m_physical_device;
|
||||||
|
context.device = m_device;
|
||||||
|
ResourceMutex resource_mutex;
|
||||||
|
PageManager page_manager(RejectUnexpectedPageFault, nullptr);
|
||||||
|
BufferCache buffer_cache(page_manager, resource_mutex);
|
||||||
|
TextureCache texture_cache(page_manager, buffer_cache, resource_mutex);
|
||||||
|
buffer_cache.SetTextureCache(texture_cache);
|
||||||
|
VideoOutVulkanImage image;
|
||||||
|
image.image = backing.image;
|
||||||
|
image.format = backing.format;
|
||||||
|
image.extent = {backing.width, backing.height};
|
||||||
|
image.layers = 1;
|
||||||
|
image.mip_levels = 1;
|
||||||
|
image.image_view[VulkanImage::VIEW_DEFAULT] = backing.view;
|
||||||
|
|
||||||
|
constexpr auto identity = DstSel(4, 5, 6, 7);
|
||||||
|
constexpr auto bgra = DstSel(6, 5, 4, 7);
|
||||||
|
constexpr auto uncommon = DstSel(5, 1, 7, 0);
|
||||||
|
const auto default_view = texture_cache.GetSampledColorView(
|
||||||
|
&context, &image, image.format, identity, 0, 1, VK_IMAGE_VIEW_TYPE_2D,
|
||||||
|
0, 1);
|
||||||
|
const auto bgra_view = texture_cache.GetSampledColorView(
|
||||||
|
&context, &image, image.format, bgra, 0, 1, VK_IMAGE_VIEW_TYPE_2D, 0,
|
||||||
|
1);
|
||||||
|
const auto uncommon_view = texture_cache.GetSampledColorView(
|
||||||
|
&context, &image, image.format, uncommon, 0, 1, VK_IMAGE_VIEW_TYPE_2D,
|
||||||
|
0, 1);
|
||||||
|
const auto uncommon_again = texture_cache.GetSampledColorView(
|
||||||
|
&context, &image, image.format, uncommon, 0, 1, VK_IMAGE_VIEW_TYPE_2D,
|
||||||
|
0, 1);
|
||||||
|
Require(name, "cache identity",
|
||||||
|
default_view == backing.view && bgra_view != VK_NULL_HANDLE &&
|
||||||
|
bgra_view != default_view && uncommon_view != VK_NULL_HANDLE &&
|
||||||
|
uncommon_view != bgra_view && uncommon_again == uncommon_view &&
|
||||||
|
image.view_cache.views.size() == 2,
|
||||||
|
"video-out sampled views did not use identity fast path and lazy "
|
||||||
|
"mappings");
|
||||||
|
|
||||||
|
for (const auto &view : image.view_cache.views) {
|
||||||
|
vkDestroyImageView(m_device, view.view, nullptr);
|
||||||
|
}
|
||||||
|
image.view_cache.views.clear();
|
||||||
|
DestroyImage(&backing);
|
||||||
|
std::printf("[host] %-32s ok\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
Buffer CreateStorageBuffer(const char *shader_name,
|
Buffer CreateStorageBuffer(const char *shader_name,
|
||||||
const std::vector<u32> &initial,
|
const std::vector<u32> &initial,
|
||||||
size_t dword_count) {
|
size_t dword_count) {
|
||||||
@@ -8730,7 +8987,7 @@ void CheckReverseRenderTargetFormatContract() {
|
|||||||
if (std::strcmp(kind, "sampled") == 0) {
|
if (std::strcmp(kind, "sampled") == 0) {
|
||||||
(void)SelectSampledColorView(VK_FORMAT_R8G8B8A8_UNORM,
|
(void)SelectSampledColorView(VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
VK_FORMAT_R8G8B8A8_UNORM,
|
VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
DstSel(4, 5, 6, 0));
|
DstSel(4, 5, 6, 2));
|
||||||
} else if (std::strcmp(kind, "sampled-compatible-swizzle") == 0) {
|
} else if (std::strcmp(kind, "sampled-compatible-swizzle") == 0) {
|
||||||
(void)SelectSampledColorView(VK_FORMAT_B8G8R8A8_UNORM,
|
(void)SelectSampledColorView(VK_FORMAT_B8G8R8A8_UNORM,
|
||||||
VK_FORMAT_R8G8B8A8_UNORM,
|
VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
@@ -8759,10 +9016,10 @@ void CheckReverseRenderTargetFormatContract() {
|
|||||||
(void)SelectSampledColorView(VK_FORMAT_A2B10G10R10_UNORM_PACK32,
|
(void)SelectSampledColorView(VK_FORMAT_A2B10G10R10_UNORM_PACK32,
|
||||||
VK_FORMAT_A2R10G10B10_UNORM_PACK32,
|
VK_FORMAT_A2R10G10B10_UNORM_PACK32,
|
||||||
DstSel(6, 5, 4, 7));
|
DstSel(6, 5, 4, 7));
|
||||||
} else if (std::strcmp(kind, "sampled-abgr-format") == 0) {
|
} else if (std::strcmp(kind, "sampled-invalid-high") == 0) {
|
||||||
(void)SelectSampledColorView(VK_FORMAT_R8G8B8A8_UNORM,
|
(void)SelectSampledColorView(VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
VK_FORMAT_R8G8B8A8_UNORM,
|
VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
DstSel(7, 6, 5, 4));
|
DstSel(7, 6, 5, 3));
|
||||||
} else if (std::strcmp(kind, "sampled-depth-format") == 0) {
|
} else if (std::strcmp(kind, "sampled-depth-format") == 0) {
|
||||||
(void)SelectSampledDepthView(VK_FORMAT_D24_UNORM_S8_UINT,
|
(void)SelectSampledDepthView(VK_FORMAT_D24_UNORM_S8_UINT,
|
||||||
VK_FORMAT_R32_SFLOAT, DstSel(4, 4, 4, 4));
|
VK_FORMAT_R32_SFLOAT, DstSel(4, 4, 4, 4));
|
||||||
@@ -8811,95 +9068,135 @@ void CheckSampledColorViews() {
|
|||||||
Require("SampledColorViews", "identity",
|
Require("SampledColorViews", "identity",
|
||||||
SelectSampledColorView(VK_FORMAT_R8G8B8A8_UNORM,
|
SelectSampledColorView(VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
VK_FORMAT_R8G8B8A8_UNORM,
|
VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
DstSel(4, 5, 6, 7)) == VulkanImage::VIEW_DEFAULT,
|
DstSel(4, 5, 6, 7)) == DstSel(4, 5, 6, 7),
|
||||||
"RGBA did not select the identity view");
|
"RGBA did not select the identity view");
|
||||||
|
uint32_t valid_swizzles = 0;
|
||||||
|
for (uint32_t swizzle = 0; swizzle <= 0xfffu; swizzle++) {
|
||||||
|
bool expected = true;
|
||||||
|
for (uint32_t channel = 0; channel < 4; channel++) {
|
||||||
|
const auto selector = GetDstSel(swizzle, channel);
|
||||||
|
if (selector == 2 || selector == 3) {
|
||||||
|
expected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const bool valid = IsValidSampledColorSwizzle(swizzle);
|
||||||
|
const bool supported = IsSupportedSampledColorView(
|
||||||
|
VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, swizzle);
|
||||||
|
Require("SampledColorViews", "exhaustive read swizzle domain",
|
||||||
|
valid == expected && supported == expected,
|
||||||
|
"sampled swizzle validator disagreed with the PS5 selector domain");
|
||||||
|
valid_swizzles += valid;
|
||||||
|
}
|
||||||
|
Require("SampledColorViews", "all PS5 read swizzles",
|
||||||
|
valid_swizzles == 1296 &&
|
||||||
|
!IsValidSampledColorSwizzle(DstSel(4, 5, 6, 2)) &&
|
||||||
|
!IsValidSampledColorSwizzle(DstSel(4, 5, 6, 3)) &&
|
||||||
|
!IsValidSampledColorSwizzle(0x1000),
|
||||||
|
"valid PS5 sampled mappings were rejected or reserved selectors were "
|
||||||
|
"admitted");
|
||||||
|
const auto arbitrary = DstSel(5, 1, 7, 0);
|
||||||
|
const auto components = TextureGetComponentMapping(arbitrary);
|
||||||
|
Require("SampledColorViews", "generic Vulkan component mapping",
|
||||||
|
SelectSampledColorView(VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
|
VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
|
arbitrary) == arbitrary &&
|
||||||
|
components.r == VK_COMPONENT_SWIZZLE_G &&
|
||||||
|
components.g == VK_COMPONENT_SWIZZLE_ONE &&
|
||||||
|
components.b == VK_COMPONENT_SWIZZLE_A &&
|
||||||
|
components.a == VK_COMPONENT_SWIZZLE_ZERO,
|
||||||
|
"arbitrary valid sampled mapping did not use the generic view path");
|
||||||
Require("SampledColorViews", "R8 R001",
|
Require("SampledColorViews", "R8 R001",
|
||||||
SelectSampledColorView(VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM,
|
SelectSampledColorView(VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM,
|
||||||
DstSel(4, 0, 0, 1)) == VulkanImage::VIEW_R001,
|
DstSel(4, 0, 0, 1)) == DstSel(4, 0, 0, 1),
|
||||||
"R8 did not select its R001 view");
|
"R8 did not select its R001 view");
|
||||||
|
Require("SampledColorViews", "R8 000R",
|
||||||
|
SelectSampledColorView(VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM,
|
||||||
|
DstSel(0, 0, 0, 4)) == DstSel(0, 0, 0, 4),
|
||||||
|
"R8 did not select its 000R component-mapped view");
|
||||||
Require("SampledColorViews", "R16G16 RG01",
|
Require("SampledColorViews", "R16G16 RG01",
|
||||||
SelectSampledColorView(VK_FORMAT_R16G16_SFLOAT,
|
SelectSampledColorView(VK_FORMAT_R16G16_SFLOAT,
|
||||||
VK_FORMAT_R16G16_SFLOAT,
|
VK_FORMAT_R16G16_SFLOAT,
|
||||||
DstSel(4, 5, 0, 1)) == VulkanImage::VIEW_RG01,
|
DstSel(4, 5, 0, 1)) == DstSel(4, 5, 0, 1),
|
||||||
"R16G16 did not select its RG01 view");
|
"R16G16 did not select its RG01 view");
|
||||||
Require("SampledColorViews", "alpha one",
|
Require("SampledColorViews", "alpha one",
|
||||||
SelectSampledColorView(VK_FORMAT_R8G8B8A8_UNORM,
|
SelectSampledColorView(VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
VK_FORMAT_R8G8B8A8_UNORM,
|
VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
DstSel(4, 5, 6, 1)) == VulkanImage::VIEW_RGB1,
|
DstSel(4, 5, 6, 1)) == DstSel(4, 5, 6, 1),
|
||||||
"RGB1 did not select the alpha-one view");
|
"RGB1 did not select the alpha-one view");
|
||||||
Require("SampledColorViews", "mutable BGRA target",
|
Require("SampledColorViews", "mutable BGRA target",
|
||||||
SelectSampledColorView(VK_FORMAT_B8G8R8A8_UNORM,
|
SelectSampledColorView(VK_FORMAT_B8G8R8A8_UNORM,
|
||||||
VK_FORMAT_R8G8B8A8_UNORM,
|
VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
DstSel(6, 5, 4, 7)) == VulkanImage::VIEW_BGRA_TO_RGBA,
|
DstSel(6, 5, 4, 7)) == DstSel(6, 5, 4, 7),
|
||||||
"BGRA target did not select the exact RGBA/BGRA mutable view");
|
"BGRA target did not select the exact RGBA/BGRA mutable view");
|
||||||
Require("SampledColorViews", "mutable sRGB view of UNORM BGRA target",
|
Require(
|
||||||
SelectSampledColorView(VK_FORMAT_B8G8R8A8_UNORM,
|
"SampledColorViews", "mutable sRGB view of UNORM BGRA target",
|
||||||
VK_FORMAT_R8G8B8A8_SRGB,
|
SelectSampledColorView(VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB,
|
||||||
DstSel(6, 5, 4, 7)) == VulkanImage::VIEW_BGRA_TO_RGBA,
|
DstSel(6, 5, 4, 7)) == DstSel(6, 5, 4, 7),
|
||||||
"UNORM BGRA target did not select its compatible sRGB RGBA sampled view");
|
"UNORM BGRA target did not select its compatible sRGB RGBA sampled view");
|
||||||
Require("SampledColorViews", "mutable sRGB BGRA target",
|
Require("SampledColorViews", "mutable sRGB BGRA target",
|
||||||
BgraToRgbaSampledViewFormat(VK_FORMAT_B8G8R8A8_SRGB) ==
|
BgraToRgbaSampledViewFormat(VK_FORMAT_B8G8R8A8_SRGB) ==
|
||||||
VK_FORMAT_R8G8B8A8_SRGB &&
|
VK_FORMAT_R8G8B8A8_SRGB &&
|
||||||
SelectSampledColorView(VK_FORMAT_B8G8R8A8_SRGB,
|
SelectSampledColorView(VK_FORMAT_B8G8R8A8_SRGB,
|
||||||
VK_FORMAT_R8G8B8A8_SRGB,
|
VK_FORMAT_R8G8B8A8_SRGB,
|
||||||
DstSel(6, 5, 4, 7)) ==
|
DstSel(6, 5, 4, 7)) == DstSel(6, 5, 4, 7),
|
||||||
VulkanImage::VIEW_BGRA_TO_RGBA,
|
|
||||||
"sRGB BGRA target did not select its matching mutable RGBA view");
|
"sRGB BGRA target did not select its matching mutable RGBA view");
|
||||||
|
constexpr auto colorspace_swizzle = DstSel(5, 1, 7, 0);
|
||||||
|
Require("SampledColorViews", "mutable sRGB/UNORM views",
|
||||||
|
SelectSampledColorView(VK_FORMAT_R8G8B8A8_SRGB,
|
||||||
|
VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
|
DstSel(4, 5, 6, 7)) == DstSel(4, 5, 6, 7) &&
|
||||||
|
SelectSampledColorView(VK_FORMAT_B8G8R8A8_UNORM,
|
||||||
|
VK_FORMAT_B8G8R8A8_SRGB,
|
||||||
|
colorspace_swizzle) == colorspace_swizzle,
|
||||||
|
"same-order mutable sRGB/UNORM sampled views were rejected");
|
||||||
Require("SampledColorViews", "mutable packed RGB10 view",
|
Require("SampledColorViews", "mutable packed RGB10 view",
|
||||||
BgraToRgbaSampledViewFormat(VK_FORMAT_A2R10G10B10_UNORM_PACK32) ==
|
BgraToRgbaSampledViewFormat(VK_FORMAT_A2R10G10B10_UNORM_PACK32) ==
|
||||||
VK_FORMAT_A2B10G10R10_UNORM_PACK32 &&
|
VK_FORMAT_A2B10G10R10_UNORM_PACK32 &&
|
||||||
SelectSampledColorView(VK_FORMAT_A2R10G10B10_UNORM_PACK32,
|
SelectSampledColorView(VK_FORMAT_A2R10G10B10_UNORM_PACK32,
|
||||||
VK_FORMAT_A2B10G10R10_UNORM_PACK32,
|
VK_FORMAT_A2B10G10R10_UNORM_PACK32,
|
||||||
DstSel(6, 5, 4, 7)) ==
|
DstSel(6, 5, 4, 7)) == DstSel(6, 5, 4, 7),
|
||||||
VulkanImage::VIEW_BGRA_TO_RGBA,
|
|
||||||
"packed RGB10 target did not select its matching mutable channel-order view");
|
"packed RGB10 target did not select its matching mutable channel-order view");
|
||||||
Require("SampledColorViews", "reverse RGBA16F sampled view",
|
Require("SampledColorViews", "reverse RGBA16F sampled view",
|
||||||
SelectSampledColorView(VK_FORMAT_R16G16B16A16_SFLOAT,
|
SelectSampledColorView(VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||||
VK_FORMAT_R16G16B16A16_SFLOAT,
|
VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||||
DstSel(7, 6, 5, 4)) == VulkanImage::VIEW_ABGR,
|
DstSel(7, 6, 5, 4)) == DstSel(7, 6, 5, 4),
|
||||||
"reverse RGBA16F target did not select its reciprocal ABGR sampled view");
|
"reverse RGBA16F target did not select its reciprocal ABGR sampled view");
|
||||||
Require("SampledColorViews", "mutable integer-class views",
|
Require("SampledColorViews", "mutable integer-class views",
|
||||||
SelectSampledColorView(VK_FORMAT_R16G16B16A16_SFLOAT,
|
SelectSampledColorView(VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||||
VK_FORMAT_R16G16B16A16_UINT,
|
VK_FORMAT_R16G16B16A16_UINT,
|
||||||
DstSel(4, 5, 6, 7)) == VulkanImage::VIEW_DEFAULT &&
|
DstSel(4, 5, 6, 7)) == DstSel(4, 5, 6, 7) &&
|
||||||
SelectSampledColorView(VK_FORMAT_R8G8B8A8_UNORM,
|
SelectSampledColorView(VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
VK_FORMAT_R8G8B8A8_UINT,
|
VK_FORMAT_R8G8B8A8_UINT,
|
||||||
DstSel(4, 5, 6, 7)) == VulkanImage::VIEW_DEFAULT &&
|
DstSel(4, 5, 6, 7)) == DstSel(4, 5, 6, 7) &&
|
||||||
SelectSampledColorView(VK_FORMAT_R8G8B8A8_UINT,
|
SelectSampledColorView(VK_FORMAT_R8G8B8A8_UINT,
|
||||||
VK_FORMAT_R8G8B8A8_UNORM,
|
VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
DstSel(4, 5, 6, 7)) == VulkanImage::VIEW_DEFAULT,
|
DstSel(4, 5, 6, 7)) == DstSel(4, 5, 6, 7),
|
||||||
"compatible integer render-target sampled view was rejected");
|
"compatible integer render-target sampled view was rejected");
|
||||||
Require("SampledColorViews", "D32 depth target",
|
Require("SampledColorViews", "D32 depth target",
|
||||||
SelectSampledDepthView(VK_FORMAT_D32_SFLOAT_S8_UINT,
|
SelectSampledDepthView(VK_FORMAT_D32_SFLOAT_S8_UINT,
|
||||||
VK_FORMAT_R32_SFLOAT,
|
VK_FORMAT_R32_SFLOAT,
|
||||||
DstSel(4, 4, 4, 4)) ==
|
DstSel(4, 4, 4, 4)) == DstSel(4, 4, 4, 4),
|
||||||
VulkanImage::VIEW_DEPTH_TEXTURE,
|
|
||||||
"D32 depth target did not select its depth-aspect view");
|
"D32 depth target did not select its depth-aspect view");
|
||||||
Require("SampledColorViews", "D16 R000 depth target",
|
Require("SampledColorViews", "D16 R000 depth target",
|
||||||
SelectSampledDepthView(VK_FORMAT_D16_UNORM, VK_FORMAT_R16_UNORM,
|
SelectSampledDepthView(VK_FORMAT_D16_UNORM, VK_FORMAT_R16_UNORM,
|
||||||
DstSel(4, 0, 0, 0)) ==
|
DstSel(4, 0, 0, 0)) == DstSel(4, 0, 0, 0),
|
||||||
VulkanImage::VIEW_R000,
|
|
||||||
"D16 depth target did not select its R000 depth-aspect view");
|
"D16 depth target did not select its R000 depth-aspect view");
|
||||||
Require("SampledColorViews", "D16S8 R001 depth target",
|
Require("SampledColorViews", "D16S8 R001 depth target",
|
||||||
SelectSampledDepthView(VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_R16_UNORM,
|
SelectSampledDepthView(VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_R16_UNORM,
|
||||||
DstSel(4, 0, 0, 1)) ==
|
DstSel(4, 0, 0, 1)) == DstSel(4, 0, 0, 1),
|
||||||
VulkanImage::VIEW_R001,
|
|
||||||
"D16S8 depth target did not select its R001 depth-aspect view");
|
"D16S8 depth target did not select its R001 depth-aspect view");
|
||||||
Require("SampledColorViews", "promoted D24S8 R001 depth target",
|
Require("SampledColorViews", "promoted D24S8 R001 depth target",
|
||||||
SelectSampledDepthView(VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_R16_UNORM,
|
SelectSampledDepthView(VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_R16_UNORM,
|
||||||
DstSel(4, 0, 0, 1)) ==
|
DstSel(4, 0, 0, 1)) == DstSel(4, 0, 0, 1),
|
||||||
VulkanImage::VIEW_R001,
|
|
||||||
"D24S8 host fallback did not preserve the guest R16 depth view");
|
"D24S8 host fallback did not preserve the guest R16 depth view");
|
||||||
Require("SampledColorViews", "promoted D32S8 R001 depth target",
|
Require("SampledColorViews", "promoted D32S8 R001 depth target",
|
||||||
SelectSampledDepthView(VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_R16_UNORM,
|
SelectSampledDepthView(VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_R16_UNORM,
|
||||||
DstSel(4, 0, 0, 1)) ==
|
DstSel(4, 0, 0, 1)) == DstSel(4, 0, 0, 1),
|
||||||
VulkanImage::VIEW_R001,
|
|
||||||
"D32S8 host fallback did not preserve the guest R16 depth view");
|
"D32S8 host fallback did not preserve the guest R16 depth view");
|
||||||
Require("SampledColorViews", "D32S8 R001 depth target",
|
Require("SampledColorViews", "D32S8 R001 depth target",
|
||||||
SelectSampledDepthView(VK_FORMAT_D32_SFLOAT_S8_UINT,
|
SelectSampledDepthView(VK_FORMAT_D32_SFLOAT_S8_UINT,
|
||||||
VK_FORMAT_R32_SFLOAT,
|
VK_FORMAT_R32_SFLOAT,
|
||||||
DstSel(4, 0, 0, 1)) ==
|
DstSel(4, 0, 0, 1)) == DstSel(4, 0, 0, 1),
|
||||||
VulkanImage::VIEW_R001,
|
|
||||||
"D32S8 depth target did not select its R001 depth-aspect view");
|
"D32S8 depth target did not select its R001 depth-aspect view");
|
||||||
Require("SampledColorViews", "storage identity",
|
Require("SampledColorViews", "storage identity",
|
||||||
SelectStorageColorView(VK_FORMAT_R8G8B8A8_UNORM,
|
SelectStorageColorView(VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
@@ -8981,7 +9278,7 @@ void CheckSampledColorViews() {
|
|||||||
{"sampled", "sampled-compatible-swizzle", "sampled-compatible-reverse",
|
{"sampled", "sampled-compatible-swizzle", "sampled-compatible-reverse",
|
||||||
"sampled-compatible-colorspace",
|
"sampled-compatible-colorspace",
|
||||||
"sampled-compatible-snorm", "sampled-rgb10-swizzle",
|
"sampled-compatible-snorm", "sampled-rgb10-swizzle",
|
||||||
"sampled-rgb10-reverse", "sampled-abgr-format", "sampled-depth-format",
|
"sampled-rgb10-reverse", "sampled-invalid-high", "sampled-depth-format",
|
||||||
"sampled-depth-swizzle", "storage", "storage-format",
|
"sampled-depth-swizzle", "storage", "storage-format",
|
||||||
"storage-compatible-swizzle", "storage-abgr", "storage-kind", "storage-no-write",
|
"storage-compatible-swizzle", "storage-abgr", "storage-kind", "storage-no-write",
|
||||||
"storage-atomic", "storage-compare", "storage-mip",
|
"storage-atomic", "storage-compare", "storage-mip",
|
||||||
@@ -9069,6 +9366,50 @@ void CheckSampledDepthResource() {
|
|||||||
std::printf("[host] %-32s ok\n", "SampledDepthResource");
|
std::printf("[host] %-32s ok\n", "SampledDepthResource");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckSampledVideoOutView() {
|
||||||
|
ShaderRecompiler::IR::ImageResource resource{};
|
||||||
|
resource.kind = ShaderRecompiler::IR::ResourceKind::Image;
|
||||||
|
resource.dimension = ShaderRecompiler::Decoder::ImageDimension::Dim2D;
|
||||||
|
resource.read = true;
|
||||||
|
|
||||||
|
ShaderTextureResource descriptor{};
|
||||||
|
descriptor.fields[3] = Prospero::GpuEnumValue(Prospero::ImageType::kColor2D)
|
||||||
|
<< 28u;
|
||||||
|
VulkanImage image{VulkanImageType::VideoOut};
|
||||||
|
image.layers = 1;
|
||||||
|
Require("SampledVideoOutView", "basic 2D",
|
||||||
|
IsSupportedSampledVideoOutView(resource, descriptor, image),
|
||||||
|
"basic 2D video-out view was rejected");
|
||||||
|
|
||||||
|
const auto basic_resource = resource;
|
||||||
|
resource.dimension = ShaderRecompiler::Decoder::ImageDimension::Dim2DArray;
|
||||||
|
const bool rejects_array_resource =
|
||||||
|
!IsSupportedSampledVideoOutView(resource, descriptor, image);
|
||||||
|
resource = basic_resource;
|
||||||
|
descriptor.fields[3] =
|
||||||
|
Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) << 28u;
|
||||||
|
const bool rejects_array_descriptor =
|
||||||
|
!IsSupportedSampledVideoOutView(resource, descriptor, image);
|
||||||
|
descriptor.fields[3] = Prospero::GpuEnumValue(Prospero::ImageType::kColor2D)
|
||||||
|
<< 28u;
|
||||||
|
descriptor.fields[4] = 1u << 16u;
|
||||||
|
const bool rejects_base_layer =
|
||||||
|
!IsSupportedSampledVideoOutView(resource, descriptor, image);
|
||||||
|
descriptor.fields[4] = 1u;
|
||||||
|
const bool rejects_layer_count =
|
||||||
|
!IsSupportedSampledVideoOutView(resource, descriptor, image);
|
||||||
|
descriptor.fields[4] = 0;
|
||||||
|
image.layers = 2;
|
||||||
|
const bool rejects_layered_image =
|
||||||
|
!IsSupportedSampledVideoOutView(resource, descriptor, image);
|
||||||
|
Require("SampledVideoOutView", "array hard failures",
|
||||||
|
rejects_array_resource && rejects_array_descriptor &&
|
||||||
|
rejects_base_layer && rejects_layer_count &&
|
||||||
|
rejects_layered_image,
|
||||||
|
"unsupported layered video-out view was accepted");
|
||||||
|
std::printf("[host] %-32s ok\n", "SampledVideoOutView");
|
||||||
|
}
|
||||||
|
|
||||||
void CheckSampledDepthDescriptor() {
|
void CheckSampledDepthDescriptor() {
|
||||||
ShaderTextureResource descriptor{{0x00eb0900u, 0xc1600000u, 0x00bcc14fu,
|
ShaderTextureResource descriptor{{0x00eb0900u, 0xc1600000u, 0x00bcc14fu,
|
||||||
0x91800924u, 0x00000000u, 0x00700000u,
|
0x91800924u, 0x00000000u, 0x00700000u,
|
||||||
@@ -12358,6 +12699,14 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
if (argc == 2 && std::strcmp(argv[1], "--image-view-only") == 0) {
|
if (argc == 2 && std::strcmp(argv[1], "--image-view-only") == 0) {
|
||||||
CheckSampledColorViews();
|
CheckSampledColorViews();
|
||||||
|
CheckSampledVideoOutView();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (argc == 2 && std::strcmp(argv[1], "--image-view-cache-only") == 0) {
|
||||||
|
VulkanHarness vulkan;
|
||||||
|
vulkan.CheckRenderTargetViewCache();
|
||||||
|
vulkan.CheckDepthTargetSampledViewCache();
|
||||||
|
vulkan.CheckVideoOutSampledViewCache();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (argc == 2 && std::strcmp(argv[1], "--sampled-depth-resource-only") == 0) {
|
if (argc == 2 && std::strcmp(argv[1], "--sampled-depth-resource-only") == 0) {
|
||||||
@@ -12404,7 +12753,8 @@ int main(int argc, char **argv) {
|
|||||||
std::strcmp(argv[1], "--storage-texture-descriptor-death") == 0) {
|
std::strcmp(argv[1], "--storage-texture-descriptor-death") == 0) {
|
||||||
RunStorageTextureDescriptorDeathCase(argv[2]);
|
RunStorageTextureDescriptorDeathCase(argv[2]);
|
||||||
}
|
}
|
||||||
if (argc == 3 && std::strcmp(argv[1], "--storage-texture-access-death") == 0) {
|
if (argc == 3 &&
|
||||||
|
std::strcmp(argv[1], "--storage-texture-access-death") == 0) {
|
||||||
RunStorageTextureAccessDeathCase(argv[2]);
|
RunStorageTextureAccessDeathCase(argv[2]);
|
||||||
}
|
}
|
||||||
if (argc == 3 && std::strcmp(argv[1], "--meta-overlap-death") == 0) {
|
if (argc == 3 && std::strcmp(argv[1], "--meta-overlap-death") == 0) {
|
||||||
@@ -12415,6 +12765,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
CheckReverseRenderTargetFormatContract();
|
CheckReverseRenderTargetFormatContract();
|
||||||
CheckSampledColorViews();
|
CheckSampledColorViews();
|
||||||
|
CheckSampledVideoOutView();
|
||||||
CheckSampledDepthResource();
|
CheckSampledDepthResource();
|
||||||
CheckSampledDepthDescriptor();
|
CheckSampledDepthDescriptor();
|
||||||
CheckBufferCacheRangeMerge();
|
CheckBufferCacheRangeMerge();
|
||||||
@@ -12456,6 +12807,9 @@ int main(int argc, char **argv) {
|
|||||||
VulkanHarness vulkan;
|
VulkanHarness vulkan;
|
||||||
vulkan.CheckMutableStorageSrgbView();
|
vulkan.CheckMutableStorageSrgbView();
|
||||||
vulkan.CheckMutableRenderTargetBgraStorageView();
|
vulkan.CheckMutableRenderTargetBgraStorageView();
|
||||||
|
vulkan.CheckRenderTargetViewCache();
|
||||||
|
vulkan.CheckDepthTargetSampledViewCache();
|
||||||
|
vulkan.CheckVideoOutSampledViewCache();
|
||||||
const auto tests = MakeCases();
|
const auto tests = MakeCases();
|
||||||
const auto graphics_tests = MakeGraphicsCases();
|
const auto graphics_tests = MakeGraphicsCases();
|
||||||
CheckOpcodeCoverage(tests, graphics_tests);
|
CheckOpcodeCoverage(tests, graphics_tests);
|
||||||
|
|||||||
Reference in New Issue
Block a user