Skip to content

Commit

Permalink
VideoBackends / VideoCommon: add type enum to dictate whether a textu…
Browse files Browse the repository at this point in the history
…re is a 2D texture, a texture array, or a cube map; support 2D texture type across backends

Co-authored-by: TellowKrinkle <tellowkrinkle@gmail.com>
  • Loading branch information
iwubcode and TellowKrinkle committed Dec 10, 2023
1 parent bec4c77 commit 2ef4317
Show file tree
Hide file tree
Showing 16 changed files with 232 additions and 80 deletions.
37 changes: 27 additions & 10 deletions Source/Core/VideoBackends/D3D/DXTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ std::unique_ptr<DXTexture> DXTexture::Create(const TextureConfig& config, std::s
if (config.IsComputeImage())
bindflags |= D3D11_BIND_UNORDERED_ACCESS;

CD3D11_TEXTURE2D_DESC desc(tex_format, config.width, config.height, config.layers, config.levels,
bindflags, D3D11_USAGE_DEFAULT, 0, config.samples, 0,
config.IsCubeMap() ? D3D11_RESOURCE_MISC_TEXTURECUBE : 0);
CD3D11_TEXTURE2D_DESC desc(
tex_format, config.width, config.height, config.layers, config.levels, bindflags,
D3D11_USAGE_DEFAULT, 0, config.samples, 0,
config.type == AbstractTextureType::Texture_CubeMap ? D3D11_RESOURCE_MISC_TEXTURECUBE : 0);
ComPtr<ID3D11Texture2D> d3d_texture;
HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, d3d_texture.GetAddressOf());
if (FAILED(hr))
Expand All @@ -72,7 +73,8 @@ std::unique_ptr<DXTexture> DXTexture::CreateAdopted(ComPtr<ID3D11Texture2D> text
// Convert to our texture config format.
TextureConfig config(desc.Width, desc.Height, desc.MipLevels, desc.ArraySize,
desc.SampleDesc.Count,
D3DCommon::GetAbstractFormatForDXGIFormat(desc.Format), 0);
D3DCommon::GetAbstractFormatForDXGIFormat(desc.Format), 0,
AbstractTextureType::Texture_2DArray);
if (desc.BindFlags & D3D11_BIND_RENDER_TARGET)
config.flags |= AbstractTextureFlag_RenderTarget;
if (desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS)
Expand All @@ -89,13 +91,28 @@ std::unique_ptr<DXTexture> DXTexture::CreateAdopted(ComPtr<ID3D11Texture2D> text

bool DXTexture::CreateSRV()
{
D3D_SRV_DIMENSION dimension = D3D_SRV_DIMENSION_TEXTURE2DARRAY;
if (m_config.type == AbstractTextureType::Texture_2DArray)
{
if (m_config.IsMultisampled())
dimension = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY;
else
dimension = D3D_SRV_DIMENSION_TEXTURE2DARRAY;
}
else if (m_config.type == AbstractTextureType::Texture_2D)
{
if (m_config.IsMultisampled())
dimension = D3D_SRV_DIMENSION_TEXTURE2DMS;
else
dimension = D3D_SRV_DIMENSION_TEXTURE2D;
}
else if (m_config.type == AbstractTextureType::Texture_CubeMap)
{
dimension = D3D_SRV_DIMENSION_TEXTURECUBE;
}
const CD3D11_SHADER_RESOURCE_VIEW_DESC desc(
m_texture.Get(),
m_config.IsCubeMap() ? D3D11_SRV_DIMENSION_TEXTURECUBE :
m_config.IsMultisampled() ? D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY :
D3D11_SRV_DIMENSION_TEXTURE2DARRAY,
D3DCommon::GetSRVFormatForAbstractFormat(m_config.format), 0, m_config.levels, 0,
m_config.layers);
m_texture.Get(), dimension, D3DCommon::GetSRVFormatForAbstractFormat(m_config.format), 0,
m_config.levels, 0, m_config.layers);
DEBUG_ASSERT(!m_srv);
HRESULT hr = D3D::device->CreateShaderResourceView(m_texture.Get(), &desc, m_srv.GetAddressOf());
if (FAILED(hr))
Expand Down
32 changes: 24 additions & 8 deletions Source/Core/VideoBackends/D3D12/DX12Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ std::unique_ptr<DXTexture> DXTexture::CreateAdopted(ID3D12Resource* resource)
}

TextureConfig config(static_cast<u32>(desc.Width), desc.Height, desc.MipLevels,
desc.DepthOrArraySize, desc.SampleDesc.Count, format, 0);
desc.DepthOrArraySize, desc.SampleDesc.Count, format, 0,
AbstractTextureType::Texture_2DArray);
if (desc.Flags &
(D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL))
{
Expand All @@ -165,14 +166,29 @@ bool DXTexture::CreateSRVDescriptor()
return false;
}

D3D12_SHADER_RESOURCE_VIEW_DESC desc = {
D3DCommon::GetSRVFormatForAbstractFormat(m_config.format),
m_config.IsCubeMap() ? D3D12_SRV_DIMENSION_TEXTURECUBE :
m_config.IsMultisampled() ? D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY :
D3D12_SRV_DIMENSION_TEXTURE2DARRAY,
D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING};
D3D12_SRV_DIMENSION dimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
if (m_config.type == AbstractTextureType::Texture_2DArray)
{
if (m_config.IsMultisampled())
dimension = D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY;
else
dimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
}
else if (m_config.type == AbstractTextureType::Texture_2D)
{
if (m_config.IsMultisampled())
dimension = D3D12_SRV_DIMENSION_TEXTURE2DMS;
else
dimension = D3D12_SRV_DIMENSION_TEXTURE2D;
}
else if (m_config.type == AbstractTextureType::Texture_CubeMap)
{
dimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
}
D3D12_SHADER_RESOURCE_VIEW_DESC desc = {D3DCommon::GetSRVFormatForAbstractFormat(m_config.format),
dimension, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING};

if (m_config.IsCubeMap())
if (m_config.type == AbstractTextureType::Texture_CubeMap)
{
desc.TextureCube.MostDetailedMip = 0;
desc.TextureCube.MipLevels = m_config.levels;
Expand Down
20 changes: 16 additions & 4 deletions Source/Core/VideoBackends/Metal/MTLGfx.mm
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,26 @@

// MARK: Texture Creation

static MTLTextureType FromAbstract(AbstractTextureType type, bool multisample)
{
switch (type)
{
case AbstractTextureType::Texture_2D:
return multisample ? MTLTextureType2DMultisample : MTLTextureType2D;
case AbstractTextureType::Texture_2DArray:
return multisample ? MTLTextureType2DMultisampleArray : MTLTextureType2DArray;
case AbstractTextureType::Texture_CubeMap:
return MTLTextureTypeCube;
}
}

std::unique_ptr<AbstractTexture> Metal::Gfx::CreateTexture(const TextureConfig& config,
std::string_view name)
{
@autoreleasepool
{
MRCOwned<MTLTextureDescriptor*> desc = MRCTransfer([MTLTextureDescriptor new]);
[desc setTextureType:config.samples > 1 ? MTLTextureType2DMultisampleArray :
MTLTextureType2DArray];
[desc setTextureType:FromAbstract(config.type, config.samples > 1)];
[desc setPixelFormat:Util::FromAbstract(config.format)];
[desc setWidth:config.width];
[desc setHeight:config.height];
Expand Down Expand Up @@ -490,8 +502,8 @@

[m_layer setDrawableSize:{static_cast<double>(info.width), static_cast<double>(info.height)}];

TextureConfig cfg(info.width, info.height, 1, 1, 1, info.format,
AbstractTextureFlag_RenderTarget);
TextureConfig cfg(info.width, info.height, 1, 1, 1, info.format, AbstractTextureFlag_RenderTarget,
AbstractTextureType::Texture_2DArray);
m_bb_texture = std::make_unique<Texture>(nullptr, cfg);
m_backbuffer = std::make_unique<Framebuffer>(
m_bb_texture.get(), nullptr, std::vector<AbstractTexture*>{}, info.width, info.height, 1, 1);
Expand Down
71 changes: 60 additions & 11 deletions Source/Core/VideoBackends/OGL/OGLTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,29 +140,53 @@ OGLTexture::OGLTexture(const TextureConfig& tex_config, std::string_view name)
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, m_config.levels - 1);

GLenum gl_internal_format = GetGLInternalFormatForTextureFormat(m_config.format, true);
if (g_ogl_config.bSupportsTextureStorage && m_config.IsCubeMap())
if (g_ogl_config.bSupportsTextureStorage && m_config.type == AbstractTextureType::Texture_CubeMap)
{
glTexStorage2D(target, m_config.levels, gl_internal_format, m_config.width, m_config.height);
}
else if (tex_config.IsMultisampled())
{
ASSERT(g_ogl_config.bSupportsMSAA);
if (g_ogl_config.SupportedMultisampleTexStorage != MultisampleTexStorageType::TexStorageNone)
if (m_config.type == AbstractTextureType::Texture_2DArray)
{
glTexStorage3DMultisample(target, tex_config.samples, gl_internal_format, m_config.width,
if (g_ogl_config.SupportedMultisampleTexStorage != MultisampleTexStorageType::TexStorageNone)
{
glTexStorage3DMultisample(target, tex_config.samples, gl_internal_format, m_config.width,
m_config.height, m_config.layers, GL_FALSE);
}
else
{
ASSERT(!g_ogl_config.bIsES);
glTexImage3DMultisample(target, tex_config.samples, gl_internal_format, m_config.width,
m_config.height, m_config.layers, GL_FALSE);
}
}
else
else if (m_config.type == AbstractTextureType::Texture_2D)
{
ASSERT(!g_ogl_config.bIsES);
glTexImage3DMultisample(target, tex_config.samples, gl_internal_format, m_config.width,
m_config.height, m_config.layers, GL_FALSE);
if (g_ogl_config.SupportedMultisampleTexStorage != MultisampleTexStorageType::TexStorageNone)
{
glTexStorage2DMultisample(target, tex_config.samples, gl_internal_format, m_config.width,
m_config.height, GL_FALSE);
}
else
{
ASSERT(!g_ogl_config.bIsES);
glTexImage2DMultisample(target, tex_config.samples, gl_internal_format, m_config.width,
m_config.height, GL_FALSE);
}
}
}
else if (g_ogl_config.bSupportsTextureStorage)
{
glTexStorage3D(target, m_config.levels, gl_internal_format, m_config.width, m_config.height,
m_config.layers);
if (m_config.type == AbstractTextureType::Texture_2DArray)
{
glTexStorage3D(target, m_config.levels, gl_internal_format, m_config.width, m_config.height,
m_config.layers);
}
else if (m_config.type == AbstractTextureType::Texture_2D)
{
glTexStorage2D(target, m_config.levels, gl_internal_format, m_config.width, m_config.height);
}
}

if (m_config.IsRenderTarget())
Expand Down Expand Up @@ -271,7 +295,7 @@ void OGLTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8
GLenum gl_internal_format = GetGLInternalFormatForTextureFormat(m_config.format, false);
if (IsCompressedFormat(m_config.format))
{
if (m_config.IsCubeMap())
if (m_config.type == AbstractTextureType::Texture_CubeMap)
{
if (g_ogl_config.bSupportsTextureStorage)
{
Expand All @@ -285,6 +309,19 @@ void OGLTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8
width, height, 0, static_cast<GLsizei>(buffer_size), buffer);
}
}
else if (m_config.type == AbstractTextureType::Texture_2D)
{
if (g_ogl_config.bSupportsTextureStorage)
{
glCompressedTexSubImage2D(target, level, 0, 0, width, height, gl_internal_format,
static_cast<GLsizei>(buffer_size), buffer);
}
else
{
glCompressedTexImage2D(target, level, gl_internal_format, width, height, 0,
static_cast<GLsizei>(buffer_size), buffer);
}
}
else
{
if (g_ogl_config.bSupportsTextureStorage)
Expand All @@ -303,7 +340,7 @@ void OGLTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8
{
GLenum gl_format = GetGLFormatForTextureFormat(m_config.format);
GLenum gl_type = GetGLTypeForTextureFormat(m_config.format);
if (m_config.IsCubeMap())
if (m_config.type == AbstractTextureType::Texture_CubeMap)
{
if (g_ogl_config.bSupportsTextureStorage)
{
Expand All @@ -316,6 +353,18 @@ void OGLTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8
height, 0, gl_format, gl_type, buffer);
}
}
else if (m_config.type == AbstractTextureType::Texture_2D)
{
if (g_ogl_config.bSupportsTextureStorage)
{
glTexSubImage2D(target, level, 0, 0, width, height, gl_format, gl_type, buffer);
}
else
{
glTexImage2D(target, level, gl_internal_format, width, height, 0, gl_format, gl_type,
buffer);
}
}
else
{
if (g_ogl_config.bSupportsTextureStorage)
Expand Down
23 changes: 20 additions & 3 deletions Source/Core/VideoBackends/OGL/OGLTexture.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,26 @@ class OGLTexture final : public AbstractTexture
GLuint GetGLTextureId() const { return m_texId; }
GLenum GetGLTarget() const
{
return m_config.IsCubeMap() ? GL_TEXTURE_CUBE_MAP :
IsMultisampled() ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY :
GL_TEXTURE_2D_ARRAY;
if (m_config.type == AbstractTextureType::Texture_2DArray)
{
if (m_config.IsMultisampled())
return GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
else
return GL_TEXTURE_2D_ARRAY;
}
else if (m_config.type == AbstractTextureType::Texture_2D)
{
if (m_config.IsMultisampled())
return GL_TEXTURE_2D_MULTISAMPLE;
else
return GL_TEXTURE_2D;
}
else if (m_config.type == AbstractTextureType::Texture_CubeMap)
{
return GL_TEXTURE_CUBE_MAP;
}

return GL_TEXTURE_2D_ARRAY;
}
static GLenum GetGLInternalFormatForTextureFormat(AbstractTextureFormat format, bool storage);
GLenum GetGLFormatForImageTexture() const;
Expand Down
8 changes: 5 additions & 3 deletions Source/Core/VideoBackends/Vulkan/StateTracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,17 @@ void StateTracker::DestroyInstance()
bool StateTracker::Initialize()
{
// Create a dummy texture which can be used in place of a real binding.
m_dummy_texture =
VKTexture::Create(TextureConfig(1, 1, 1, 1, 1, AbstractTextureFormat::RGBA8, 0), "");
m_dummy_texture = VKTexture::Create(TextureConfig(1, 1, 1, 1, 1, AbstractTextureFormat::RGBA8, 0,
AbstractTextureType::Texture_2DArray),
"");
if (!m_dummy_texture)
return false;
m_dummy_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentInitCommandBuffer(),
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
// Create a dummy compute texture which can be used in place of a real binding
m_dummy_compute_texture = VKTexture::Create(
TextureConfig(1, 1, 1, 1, 1, AbstractTextureFormat::RGBA8, AbstractTextureFlag_ComputeImage),
TextureConfig(1, 1, 1, 1, 1, AbstractTextureFormat::RGBA8, AbstractTextureFlag_ComputeImage,
AbstractTextureType::Texture_2DArray),
"");
if (!m_dummy_compute_texture)
return false;
Expand Down
5 changes: 3 additions & 2 deletions Source/Core/VideoBackends/Vulkan/VKSwapChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,8 +428,9 @@ bool SwapChain::SetupSwapChainImages()
images.data());
ASSERT(res == VK_SUCCESS);

const TextureConfig texture_config(TextureConfig(
m_width, m_height, 1, m_layers, 1, m_texture_format, AbstractTextureFlag_RenderTarget));
const TextureConfig texture_config(
TextureConfig(m_width, m_height, 1, m_layers, 1, m_texture_format,
AbstractTextureFlag_RenderTarget, AbstractTextureType::Texture_2DArray));
const VkRenderPass load_render_pass = g_object_cache->GetRenderPass(
m_surface_format.format, VK_FORMAT_UNDEFINED, 1, VK_ATTACHMENT_LOAD_OP_LOAD);
const VkRenderPass clear_render_pass = g_object_cache->GetRenderPass(
Expand Down
18 changes: 14 additions & 4 deletions Source/Core/VideoBackends/Vulkan/VKTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,9 @@ std::unique_ptr<VKTexture> VKTexture::Create(const TextureConfig& tex_config, st

VkImageCreateInfo image_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
nullptr,
tex_config.IsCubeMap() ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT :
static_cast<VkImageCreateFlags>(0),
tex_config.type == AbstractTextureType::Texture_CubeMap ?
VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT :
static_cast<VkImageCreateFlags>(0),
VK_IMAGE_TYPE_2D,
GetVkFormatForHostTextureFormat(tex_config.format),
{tex_config.width, tex_config.height, 1},
Expand Down Expand Up @@ -107,8 +108,17 @@ std::unique_ptr<VKTexture> VKTexture::Create(const TextureConfig& tex_config, st

std::unique_ptr<VKTexture> texture = std::make_unique<VKTexture>(
tex_config, alloc, image, name, VK_IMAGE_LAYOUT_UNDEFINED, ComputeImageLayout::Undefined);
if (!texture->CreateView(tex_config.IsCubeMap() ? VK_IMAGE_VIEW_TYPE_CUBE :
VK_IMAGE_VIEW_TYPE_2D_ARRAY))

VkImageViewType image_view_type = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
if (tex_config.type == AbstractTextureType::Texture_CubeMap)
{
image_view_type = VK_IMAGE_VIEW_TYPE_CUBE;
}
else if (tex_config.type == AbstractTextureType::Texture_2D)
{
image_view_type = VK_IMAGE_VIEW_TYPE_2D;
}
if (!texture->CreateView(image_view_type))
return nullptr;

return texture;
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/VideoCommon/AbstractTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ bool AbstractTexture::Save(const std::string& filename, unsigned int level, int
// Use a temporary staging texture for the download. Certainly not optimal,
// but this is not a frequently-executed code path..
TextureConfig readback_texture_config(level_width, level_height, 1, 1, 1,
AbstractTextureFormat::RGBA8, 0);
AbstractTextureFormat::RGBA8, 0,
AbstractTextureType::Texture_2DArray);
auto readback_texture =
g_gfx->CreateStagingTexture(StagingTextureType::Readback, readback_texture_config);
if (!readback_texture)
Expand Down
9 changes: 5 additions & 4 deletions Source/Core/VideoCommon/FrameDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ bool FrameDumper::CheckFrameDumpRenderTexture(u32 target_width, u32 target_heigh
m_frame_dump_render_texture.reset();
m_frame_dump_render_texture = g_gfx->CreateTexture(
TextureConfig(target_width, target_height, 1, 1, 1, AbstractTextureFormat::RGBA8,
AbstractTextureFlag_RenderTarget),
AbstractTextureFlag_RenderTarget, AbstractTextureType::Texture_2DArray),
"Frame dump render texture");
if (!m_frame_dump_render_texture)
{
Expand All @@ -102,9 +102,10 @@ bool FrameDumper::CheckFrameDumpReadbackTexture(u32 target_width, u32 target_hei
return true;

rbtex.reset();
rbtex = g_gfx->CreateStagingTexture(
StagingTextureType::Readback,
TextureConfig(target_width, target_height, 1, 1, 1, AbstractTextureFormat::RGBA8, 0));
rbtex = g_gfx->CreateStagingTexture(StagingTextureType::Readback,
TextureConfig(target_width, target_height, 1, 1, 1,
AbstractTextureFormat::RGBA8, 0,
AbstractTextureType::Texture_2DArray));
if (!rbtex)
return false;

Expand Down

0 comments on commit 2ef4317

Please sign in to comment.