mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-03 19:42:45 +01:00
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:
commit
5512d19d4b
@ -46,7 +46,8 @@ std::unique_ptr<DXTexture> DXTexture::Create(const TextureConfig& config, std::s
|
|||||||
bindflags |= D3D11_BIND_UNORDERED_ACCESS;
|
bindflags |= D3D11_BIND_UNORDERED_ACCESS;
|
||||||
|
|
||||||
CD3D11_TEXTURE2D_DESC desc(tex_format, config.width, config.height, config.layers, config.levels,
|
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;
|
ComPtr<ID3D11Texture2D> d3d_texture;
|
||||||
HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, d3d_texture.GetAddressOf());
|
HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, d3d_texture.GetAddressOf());
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
@ -90,6 +91,7 @@ bool DXTexture::CreateSRV()
|
|||||||
{
|
{
|
||||||
const CD3D11_SHADER_RESOURCE_VIEW_DESC desc(
|
const CD3D11_SHADER_RESOURCE_VIEW_DESC desc(
|
||||||
m_texture.Get(),
|
m_texture.Get(),
|
||||||
|
m_config.IsCubeMap() ? D3D11_SRV_DIMENSION_TEXTURECUBE :
|
||||||
m_config.IsMultisampled() ? D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY :
|
m_config.IsMultisampled() ? D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY :
|
||||||
D3D11_SRV_DIMENSION_TEXTURE2DARRAY,
|
D3D11_SRV_DIMENSION_TEXTURE2DARRAY,
|
||||||
D3DCommon::GetSRVFormatForAbstractFormat(m_config.format), 0, m_config.levels, 0,
|
D3DCommon::GetSRVFormatForAbstractFormat(m_config.format), 0, m_config.levels, 0,
|
||||||
|
@ -88,7 +88,8 @@ std::vector<u32> DXContext::GetAAModes(u32 adapter_index)
|
|||||||
|
|
||||||
bool DXContext::SupportsTextureFormat(DXGI_FORMAT format)
|
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};
|
D3D12_FEATURE_DATA_FORMAT_SUPPORT support = {format};
|
||||||
return SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &support,
|
return SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &support,
|
||||||
|
@ -165,19 +165,30 @@ bool DXTexture::CreateSRVDescriptor()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12_SHADER_RESOURCE_VIEW_DESC desc = {D3DCommon::GetSRVFormatForAbstractFormat(m_config.format),
|
D3D12_SHADER_RESOURCE_VIEW_DESC desc = {
|
||||||
m_config.IsMultisampled() ?
|
D3DCommon::GetSRVFormatForAbstractFormat(m_config.format),
|
||||||
D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY :
|
m_config.IsCubeMap() ? D3D12_SRV_DIMENSION_TEXTURECUBE :
|
||||||
D3D12_SRV_DIMENSION_TEXTURE2DARRAY,
|
m_config.IsMultisampled() ? D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY :
|
||||||
D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING};
|
D3D12_SRV_DIMENSION_TEXTURE2DARRAY,
|
||||||
if (m_config.IsMultisampled())
|
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
|
else
|
||||||
{
|
{
|
||||||
desc.Texture2DArray.MipLevels = m_config.levels;
|
if (m_config.IsMultisampled())
|
||||||
desc.Texture2DArray.ArraySize = m_config.layers;
|
{
|
||||||
|
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,
|
g_dx_context->GetDevice()->CreateShaderResourceView(m_resource.Get(), &desc,
|
||||||
m_srv_descriptor.cpu_handle);
|
m_srv_descriptor.cpu_handle);
|
||||||
|
@ -140,7 +140,11 @@ OGLTexture::OGLTexture(const TextureConfig& tex_config, std::string_view name)
|
|||||||
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, m_config.levels - 1);
|
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, m_config.levels - 1);
|
||||||
|
|
||||||
GLenum gl_internal_format = GetGLInternalFormatForTextureFormat(m_config.format, true);
|
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);
|
ASSERT(g_ogl_config.bSupportsMSAA);
|
||||||
if (g_ogl_config.SupportedMultisampleTexStorage != MultisampleTexStorageType::TexStorageNone)
|
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);
|
GLenum gl_internal_format = GetGLInternalFormatForTextureFormat(m_config.format, false);
|
||||||
if (IsCompressedFormat(m_config.format))
|
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,
|
if (g_ogl_config.bSupportsTextureStorage)
|
||||||
static_cast<GLsizei>(buffer_size), buffer);
|
{
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
glCompressedTexImage3D(target, level, gl_internal_format, width, height, 1, 0,
|
if (g_ogl_config.bSupportsTextureStorage)
|
||||||
static_cast<GLsizei>(buffer_size), buffer);
|
{
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
GLenum gl_format = GetGLFormatForTextureFormat(m_config.format);
|
GLenum gl_format = GetGLFormatForTextureFormat(m_config.format);
|
||||||
GLenum gl_type = GetGLTypeForTextureFormat(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
|
else
|
||||||
{
|
{
|
||||||
glTexImage3D(target, level, gl_internal_format, width, height, 1, 0, gl_format, gl_type,
|
if (g_ogl_config.bSupportsTextureStorage)
|
||||||
buffer);
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,9 @@ public:
|
|||||||
GLuint GetGLTextureId() const { return m_texId; }
|
GLuint GetGLTextureId() const { return m_texId; }
|
||||||
GLenum GetGLTarget() const
|
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);
|
static GLenum GetGLInternalFormatForTextureFormat(AbstractTextureFormat format, bool storage);
|
||||||
GLenum GetGLFormatForImageTexture() const;
|
GLenum GetGLFormatForImageTexture() const;
|
||||||
|
@ -70,7 +70,8 @@ std::unique_ptr<VKTexture> VKTexture::Create(const TextureConfig& tex_config, st
|
|||||||
|
|
||||||
VkImageCreateInfo image_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
VkImageCreateInfo image_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||||
nullptr,
|
nullptr,
|
||||||
0,
|
tex_config.IsCubeMap() ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT :
|
||||||
|
static_cast<VkImageCreateFlags>(0),
|
||||||
VK_IMAGE_TYPE_2D,
|
VK_IMAGE_TYPE_2D,
|
||||||
GetVkFormatForHostTextureFormat(tex_config.format),
|
GetVkFormatForHostTextureFormat(tex_config.format),
|
||||||
{tex_config.width, tex_config.height, 1},
|
{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>(
|
std::unique_ptr<VKTexture> texture = std::make_unique<VKTexture>(
|
||||||
tex_config, alloc, image, name, VK_IMAGE_LAYOUT_UNDEFINED, ComputeImageLayout::Undefined);
|
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 nullptr;
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
|
@ -39,6 +39,7 @@ enum AbstractTextureFlag : u32
|
|||||||
{
|
{
|
||||||
AbstractTextureFlag_RenderTarget = (1 << 0), // Texture is used as a framebuffer.
|
AbstractTextureFlag_RenderTarget = (1 << 0), // Texture is used as a framebuffer.
|
||||||
AbstractTextureFlag_ComputeImage = (1 << 1), // Texture is used as a compute image.
|
AbstractTextureFlag_ComputeImage = (1 << 1), // Texture is used as a compute image.
|
||||||
|
AbstractTextureFlag_CubeMap = (1 << 2), // Texture is used as a cube map.
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextureConfig
|
struct TextureConfig
|
||||||
@ -61,6 +62,7 @@ struct TextureConfig
|
|||||||
bool IsMultisampled() const { return samples > 1; }
|
bool IsMultisampled() const { return samples > 1; }
|
||||||
bool IsRenderTarget() const { return (flags & AbstractTextureFlag_RenderTarget) != 0; }
|
bool IsRenderTarget() const { return (flags & AbstractTextureFlag_RenderTarget) != 0; }
|
||||||
bool IsComputeImage() const { return (flags & AbstractTextureFlag_ComputeImage) != 0; }
|
bool IsComputeImage() const { return (flags & AbstractTextureFlag_ComputeImage) != 0; }
|
||||||
|
bool IsCubeMap() const { return (flags & AbstractTextureFlag_CubeMap) != 0; }
|
||||||
|
|
||||||
u32 width = 0;
|
u32 width = 0;
|
||||||
u32 height = 0;
|
u32 height = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user