[GPU] 3d-to-d2 texture implementation

Adds vulkan version of mode 1 and 2 and fixes related crashes by keeping
the 2d texture views from the texture cache.
This commit is contained in:
Herman S.
2026-01-13 21:33:49 +09:00
parent 7c9b5af236
commit 90c48e1d21
11 changed files with 389 additions and 43 deletions

View File

@@ -92,7 +92,7 @@ class VulkanTextureCache final : public TextureCache {
VkImageView GetActiveBindingOrNullImageView(uint32_t fetch_constant_index,
xenos::FetchOpDimension dimension,
bool is_signed) const;
bool is_signed);
SamplerParameters GetSamplerParameters(
const VulkanShader::SamplerBinding& binding) const;
@@ -254,9 +254,10 @@ class VulkanTextureCache final : public TextureCache {
};
// Takes ownership of the image and its memory.
// track_usage: if false, texture won't participate in LRU cache eviction.
explicit VulkanTexture(VulkanTextureCache& texture_cache,
const TextureKey& key, VkImage image,
VmaAllocation allocation);
VmaAllocation allocation, bool track_usage = true);
~VulkanTexture();
VkImage image() const { return image_; }
@@ -271,6 +272,10 @@ class VulkanTextureCache final : public TextureCache {
VkImageView GetView(bool is_signed, uint32_t host_swizzle,
bool is_array = true);
// For 3D textures sampled as 2D - creates a 2D copy of slice 0.
VkImageView GetOrCreate3DAs2DImageView(bool is_signed,
uint32_t host_swizzle);
private:
union ViewKey {
uint32_t key;
@@ -331,6 +336,14 @@ class VulkanTextureCache final : public TextureCache {
Usage usage_ = Usage::kUndefined;
std::unordered_map<ViewKey, VkImageView, ViewKey::Hasher> views_;
// For 3D textures sampled as 2D - cached 2D copy of slice 0.
// This is a wrapper around the 2D image with a modified key (depth=1).
// For Mode 1 (GPU copy), the wrapper is created after the copy.
// For Mode 2 (CPU re-upload), LoadTextureData is called on the wrapper.
std::unique_ptr<VulkanTexture> texture_3d_as_2d_;
VkImageView image_view_3d_as_2d_unsigned_ = VK_NULL_HANDLE;
VkImageView image_view_3d_as_2d_signed_ = VK_NULL_HANDLE;
};
struct VulkanTextureBinding {
@@ -359,7 +372,8 @@ class VulkanTextureCache final : public TextureCache {
case xenos::FetchOpDimension::k1D:
case xenos::FetchOpDimension::k2D:
return resource_dimension == xenos::DataDimension::k1D ||
resource_dimension == xenos::DataDimension::k2DOrStacked;
resource_dimension == xenos::DataDimension::k2DOrStacked ||
resource_dimension == xenos::DataDimension::k3D;
case xenos::FetchOpDimension::k3DOrStacked:
return resource_dimension == xenos::DataDimension::k3D;
case xenos::FetchOpDimension::kCube: