Merge pull request #12061 from iwubcode/cubemap_backends_only

VideoBackends: add support for cube maps for OGL, Vulkan, and D3D
This commit is contained in:
JMC47 2023-08-10 18:36:48 -04:00 committed by GitHub
commit 5512d19d4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 81 additions and 24 deletions

View File

@ -46,7 +46,8 @@ std::unique_ptr<DXTexture> DXTexture::Create(const TextureConfig& config, std::s
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, 0);
bindflags, D3D11_USAGE_DEFAULT, 0, config.samples, 0,
config.IsCubeMap() ? D3D11_RESOURCE_MISC_TEXTURECUBE : 0);
ComPtr<ID3D11Texture2D> d3d_texture;
HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, d3d_texture.GetAddressOf());
if (FAILED(hr))
@ -90,6 +91,7 @@ bool DXTexture::CreateSRV()
{
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,

View File

@ -88,7 +88,8 @@ std::vector<u32> DXContext::GetAAModes(u32 adapter_index)
bool DXContext::SupportsTextureFormat(DXGI_FORMAT format)
{
constexpr u32 required = D3D12_FORMAT_SUPPORT1_TEXTURE2D | D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE;
constexpr u32 required = D3D12_FORMAT_SUPPORT1_TEXTURE2D | D3D12_FORMAT_SUPPORT1_TEXTURECUBE |
D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE;
D3D12_FEATURE_DATA_FORMAT_SUPPORT support = {format};
return SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &support,

View File

@ -165,19 +165,30 @@ bool DXTexture::CreateSRVDescriptor()
return false;
}
D3D12_SHADER_RESOURCE_VIEW_DESC desc = {D3DCommon::GetSRVFormatForAbstractFormat(m_config.format),
m_config.IsMultisampled() ?
D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY :
D3D12_SRV_DIMENSION_TEXTURE2DARRAY,
D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING};
if (m_config.IsMultisampled())
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};
if (m_config.IsCubeMap())
{
desc.Texture2DMSArray.ArraySize = m_config.layers;
desc.TextureCube.MostDetailedMip = 0;
desc.TextureCube.MipLevels = m_config.levels;
desc.TextureCube.ResourceMinLODClamp = 0.0f;
}
else
{
desc.Texture2DArray.MipLevels = m_config.levels;
desc.Texture2DArray.ArraySize = m_config.layers;
if (m_config.IsMultisampled())
{
desc.Texture2DMSArray.ArraySize = m_config.layers;
}
else
{
desc.Texture2DArray.MipLevels = m_config.levels;
desc.Texture2DArray.ArraySize = m_config.layers;
}
}
g_dx_context->GetDevice()->CreateShaderResourceView(m_resource.Get(), &desc,
m_srv_descriptor.cpu_handle);

View File

@ -140,7 +140,11 @@ 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 (tex_config.IsMultisampled())
if (g_ogl_config.bSupportsTextureStorage && m_config.IsCubeMap())
{
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)
@ -267,29 +271,62 @@ 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 (g_ogl_config.bSupportsTextureStorage)
if (m_config.IsCubeMap())
{
glCompressedTexSubImage3D(target, level, 0, 0, layer, width, height, 1, gl_internal_format,
static_cast<GLsizei>(buffer_size), buffer);
if (g_ogl_config.bSupportsTextureStorage)
{
glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer, level, 0, 0, width,
height, gl_internal_format, static_cast<GLsizei>(buffer_size),
buffer);
}
else
{
glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer, level, gl_internal_format,
width, height, 0, static_cast<GLsizei>(buffer_size), buffer);
}
}
else
{
glCompressedTexImage3D(target, level, gl_internal_format, width, height, 1, 0,
static_cast<GLsizei>(buffer_size), buffer);
if (g_ogl_config.bSupportsTextureStorage)
{
glCompressedTexSubImage3D(target, level, 0, 0, layer, width, height, 1, gl_internal_format,
static_cast<GLsizei>(buffer_size), buffer);
}
else
{
glCompressedTexImage3D(target, level, gl_internal_format, width, height, 1, 0,
static_cast<GLsizei>(buffer_size), buffer);
}
}
}
else
{
GLenum gl_format = GetGLFormatForTextureFormat(m_config.format);
GLenum gl_type = GetGLTypeForTextureFormat(m_config.format);
if (g_ogl_config.bSupportsTextureStorage)
if (m_config.IsCubeMap())
{
glTexSubImage3D(target, level, 0, 0, layer, width, height, 1, gl_format, gl_type, buffer);
if (g_ogl_config.bSupportsTextureStorage)
{
glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer, level, 0, 0, width, height,
gl_format, gl_type, buffer);
}
else
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer, level, gl_internal_format, width,
height, 0, gl_format, gl_type, buffer);
}
}
else
{
glTexImage3D(target, level, gl_internal_format, width, height, 1, 0, gl_format, gl_type,
buffer);
if (g_ogl_config.bSupportsTextureStorage)
{
glTexSubImage3D(target, level, 0, 0, layer, width, height, 1, gl_format, gl_type, buffer);
}
else
{
glTexImage3D(target, level, gl_internal_format, width, height, 1, 0, gl_format, gl_type,
buffer);
}
}
}

View File

@ -34,7 +34,9 @@ public:
GLuint GetGLTextureId() const { return m_texId; }
GLenum GetGLTarget() const
{
return IsMultisampled() ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : GL_TEXTURE_2D_ARRAY;
return m_config.IsCubeMap() ? GL_TEXTURE_CUBE_MAP :
IsMultisampled() ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY :
GL_TEXTURE_2D_ARRAY;
}
static GLenum GetGLInternalFormatForTextureFormat(AbstractTextureFormat format, bool storage);
GLenum GetGLFormatForImageTexture() const;

View File

@ -70,7 +70,8 @@ std::unique_ptr<VKTexture> VKTexture::Create(const TextureConfig& tex_config, st
VkImageCreateInfo image_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
nullptr,
0,
tex_config.IsCubeMap() ? 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},
@ -106,7 +107,8 @@ 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(VK_IMAGE_VIEW_TYPE_2D_ARRAY))
if (!texture->CreateView(tex_config.IsCubeMap() ? VK_IMAGE_VIEW_TYPE_CUBE :
VK_IMAGE_VIEW_TYPE_2D_ARRAY))
return nullptr;
return texture;

View File

@ -39,6 +39,7 @@ enum AbstractTextureFlag : u32
{
AbstractTextureFlag_RenderTarget = (1 << 0), // Texture is used as a framebuffer.
AbstractTextureFlag_ComputeImage = (1 << 1), // Texture is used as a compute image.
AbstractTextureFlag_CubeMap = (1 << 2), // Texture is used as a cube map.
};
struct TextureConfig
@ -61,6 +62,7 @@ struct TextureConfig
bool IsMultisampled() const { return samples > 1; }
bool IsRenderTarget() const { return (flags & AbstractTextureFlag_RenderTarget) != 0; }
bool IsComputeImage() const { return (flags & AbstractTextureFlag_ComputeImage) != 0; }
bool IsCubeMap() const { return (flags & AbstractTextureFlag_CubeMap) != 0; }
u32 width = 0;
u32 height = 0;