AbstractTexture: Add support for depth textures/formats

This commit is contained in:
Stenzek 2018-01-21 23:59:19 +10:00
parent 6374a4c4a8
commit 2a6d9e4713
7 changed files with 155 additions and 16 deletions

View File

@ -43,19 +43,71 @@ DXGI_FORMAT GetDXGIFormatForHostFormat(AbstractTextureFormat format)
return DXGI_FORMAT_R8G8B8A8_UNORM;
case AbstractTextureFormat::BGRA8:
return DXGI_FORMAT_B8G8R8A8_UNORM;
case AbstractTextureFormat::R16:
return DXGI_FORMAT_R16_UNORM;
case AbstractTextureFormat::R32F:
return DXGI_FORMAT_R32_FLOAT;
case AbstractTextureFormat::D16:
return DXGI_FORMAT_R16_TYPELESS;
case AbstractTextureFormat::D32F:
return DXGI_FORMAT_R32_TYPELESS;
case AbstractTextureFormat::D32F_S8:
return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
default:
PanicAlert("Unhandled texture format.");
return DXGI_FORMAT_R8G8B8A8_UNORM;
}
}
DXGI_FORMAT GetSRVFormatForHostFormat(AbstractTextureFormat format)
{
switch (format)
{
case AbstractTextureFormat::D16:
return DXGI_FORMAT_R16_UNORM;
case AbstractTextureFormat::D32F:
return DXGI_FORMAT_R32_FLOAT;
case AbstractTextureFormat::D32F_S8:
return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
default:
return GetDXGIFormatForHostFormat(format);
}
}
DXGI_FORMAT GetDSVFormatForHostFormat(AbstractTextureFormat format)
{
switch (format)
{
case AbstractTextureFormat::D16:
return DXGI_FORMAT_D16_UNORM;
case AbstractTextureFormat::D32F:
return DXGI_FORMAT_D32_FLOAT;
case AbstractTextureFormat::D32F_S8:
return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
default:
return GetDXGIFormatForHostFormat(format);
}
}
} // Anonymous namespace
DXTexture::DXTexture(const TextureConfig& tex_config) : AbstractTexture(tex_config)
{
DXGI_FORMAT tex_format = GetDXGIFormatForHostFormat(m_config.format);
DXGI_FORMAT srv_format = GetSRVFormatForHostFormat(m_config.format);
DXGI_FORMAT rtv_format = DXGI_FORMAT_UNKNOWN;
DXGI_FORMAT dsv_format = DXGI_FORMAT_UNKNOWN;
UINT bind_flags = D3D11_BIND_SHADER_RESOURCE;
if (tex_config.rendertarget)
bind_flags |= D3D11_BIND_RENDER_TARGET;
{
if (IsDepthFormat(tex_config.format))
{
bind_flags |= D3D11_BIND_DEPTH_STENCIL;
dsv_format = GetDSVFormatForHostFormat(m_config.format);
}
else
{
bind_flags |= D3D11_BIND_RENDER_TARGET;
rtv_format = tex_format;
}
}
CD3D11_TEXTURE2D_DESC texdesc(tex_format, tex_config.width, tex_config.height, tex_config.layers,
tex_config.levels, bind_flags, D3D11_USAGE_DEFAULT, 0,
@ -65,13 +117,8 @@ DXTexture::DXTexture(const TextureConfig& tex_config) : AbstractTexture(tex_conf
HRESULT hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &pTexture);
CHECK(SUCCEEDED(hr), "Create backing DXTexture");
m_texture = new D3DTexture2D(
pTexture, static_cast<D3D11_BIND_FLAG>(bind_flags), tex_format, DXGI_FORMAT_UNKNOWN,
tex_config.rendertarget ? tex_format : DXGI_FORMAT_UNKNOWN, tex_config.samples > 1);
D3D::SetDebugObjectName(m_texture->GetTex(), "a texture of the TextureCache");
D3D::SetDebugObjectName(m_texture->GetSRV(),
"shader resource view of a texture of the TextureCache");
m_texture = new D3DTexture2D(pTexture, static_cast<D3D11_BIND_FLAG>(bind_flags), srv_format,
dsv_format, rtv_format, tex_config.samples > 1);
SAFE_RELEASE(pTexture);
}

View File

@ -35,6 +35,16 @@ GLenum GetGLInternalFormatForTextureFormat(AbstractTextureFormat format, bool st
return storage ? GL_RGBA8 : GL_RGBA;
case AbstractTextureFormat::BGRA8:
return storage ? GL_RGBA8 : GL_BGRA;
case AbstractTextureFormat::R16:
return GL_R16;
case AbstractTextureFormat::R32F:
return GL_R32F;
case AbstractTextureFormat::D16:
return GL_DEPTH_COMPONENT16;
case AbstractTextureFormat::D32F:
return GL_DEPTH_COMPONENT32F;
case AbstractTextureFormat::D32F_S8:
return GL_DEPTH32F_STENCIL8;
default:
PanicAlert("Unhandled texture format.");
return storage ? GL_RGBA8 : GL_RGBA;
@ -49,6 +59,14 @@ GLenum GetGLFormatForTextureFormat(AbstractTextureFormat format)
return GL_RGBA;
case AbstractTextureFormat::BGRA8:
return GL_BGRA;
case AbstractTextureFormat::R16:
case AbstractTextureFormat::R32F:
return GL_RED;
case AbstractTextureFormat::D16:
case AbstractTextureFormat::D32F:
return GL_DEPTH_COMPONENT;
case AbstractTextureFormat::D32F_S8:
return GL_DEPTH_STENCIL;
// Compressed texture formats don't use this parameter.
default:
return GL_UNSIGNED_BYTE;
@ -62,6 +80,16 @@ GLenum GetGLTypeForTextureFormat(AbstractTextureFormat format)
case AbstractTextureFormat::RGBA8:
case AbstractTextureFormat::BGRA8:
return GL_UNSIGNED_BYTE;
case AbstractTextureFormat::R16:
return GL_UNSIGNED_SHORT;
case AbstractTextureFormat::R32F:
return GL_FLOAT;
case AbstractTextureFormat::D16:
return GL_UNSIGNED_SHORT;
case AbstractTextureFormat::D32F:
return GL_FLOAT;
case AbstractTextureFormat::D32F_S8:
return GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
// Compressed texture formats don't use this parameter.
default:
return GL_UNSIGNED_BYTE;

View File

@ -112,6 +112,21 @@ VkFormat GetVkFormatForHostTextureFormat(AbstractTextureFormat format)
case AbstractTextureFormat::BGRA8:
return VK_FORMAT_B8G8R8A8_UNORM;
case AbstractTextureFormat::R16:
return VK_FORMAT_R16_UNORM;
case AbstractTextureFormat::D16:
return VK_FORMAT_D16_UNORM;
case AbstractTextureFormat::R32F:
return VK_FORMAT_R32_SFLOAT;
case AbstractTextureFormat::D32F:
return VK_FORMAT_D32_SFLOAT;
case AbstractTextureFormat::D32F_S8:
return VK_FORMAT_D32_SFLOAT_S8_UINT;
default:
PanicAlert("Unhandled texture format.");
return VK_FORMAT_R8G8B8A8_UNORM;

View File

@ -79,14 +79,29 @@ std::unique_ptr<VKTexture> VKTexture::Create(const TextureConfig& tex_config)
return nullptr;
}
// Clear render targets before use to prevent reading uninitialized memory.
VkClearColorValue clear_value = {{0.0f, 0.0f, 0.0f, 1.0f}};
VkImageSubresourceRange clear_range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, tex_config.levels, 0,
tex_config.layers};
texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentInitCommandBuffer(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
vkCmdClearColorImage(g_command_buffer_mgr->GetCurrentInitCommandBuffer(), texture->GetImage(),
texture->GetLayout(), &clear_value, 1, &clear_range);
if (!IsDepthFormat(tex_config.format))
{
// Clear render targets before use to prevent reading uninitialized memory.
VkClearColorValue clear_value = {{0.0f, 0.0f, 0.0f, 1.0f}};
VkImageSubresourceRange clear_range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, tex_config.levels, 0,
tex_config.layers};
texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentInitCommandBuffer(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
vkCmdClearColorImage(g_command_buffer_mgr->GetCurrentInitCommandBuffer(), texture->GetImage(),
texture->GetLayout(), &clear_value, 1, &clear_range);
}
else
{
// Clear render targets before use to prevent reading uninitialized memory.
VkClearDepthStencilValue clear_value = {0.0f, 0};
VkImageSubresourceRange clear_range = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, tex_config.levels, 0,
tex_config.layers};
texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentInitCommandBuffer(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
vkCmdClearDepthStencilImage(g_command_buffer_mgr->GetCurrentInitCommandBuffer(),
texture->GetImage(), texture->GetLayout(), &clear_value, 1,
&clear_range);
}
}
return std::unique_ptr<VKTexture>(new VKTexture(tex_config, std::move(texture), framebuffer));

View File

@ -64,6 +64,20 @@ bool AbstractTexture::IsCompressedFormat(AbstractTextureFormat format)
}
}
bool AbstractTexture::IsDepthFormat(AbstractTextureFormat format)
{
switch (format)
{
case AbstractTextureFormat::D16:
case AbstractTextureFormat::D32F:
case AbstractTextureFormat::D32F_S8:
return true;
default:
return false;
}
}
size_t AbstractTexture::CalculateStrideForFormat(AbstractTextureFormat format, u32 row_length)
{
switch (format)
@ -74,9 +88,16 @@ size_t AbstractTexture::CalculateStrideForFormat(AbstractTextureFormat format, u
case AbstractTextureFormat::DXT5:
case AbstractTextureFormat::BPTC:
return static_cast<size_t>(std::max(1u, row_length / 4)) * 16;
case AbstractTextureFormat::R16:
case AbstractTextureFormat::D16:
return static_cast<size_t>(row_length) * 2;
case AbstractTextureFormat::RGBA8:
case AbstractTextureFormat::BGRA8:
case AbstractTextureFormat::R32F:
case AbstractTextureFormat::D32F:
return static_cast<size_t>(row_length) * 4;
case AbstractTextureFormat::D32F_S8:
return static_cast<size_t>(row_length) * 8;
default:
PanicAlert("Unhandled texture format.");
return 0;
@ -93,9 +114,16 @@ size_t AbstractTexture::GetTexelSizeForFormat(AbstractTextureFormat format)
case AbstractTextureFormat::DXT5:
case AbstractTextureFormat::BPTC:
return 16;
case AbstractTextureFormat::R16:
case AbstractTextureFormat::D16:
return 2;
case AbstractTextureFormat::RGBA8:
case AbstractTextureFormat::BGRA8:
case AbstractTextureFormat::R32F:
case AbstractTextureFormat::D32F:
return 4;
case AbstractTextureFormat::D32F_S8:
return 8;
default:
PanicAlert("Unhandled texture format.");
return 0;

View File

@ -39,6 +39,7 @@ public:
bool Save(const std::string& filename, unsigned int level);
static bool IsCompressedFormat(AbstractTextureFormat format);
static bool IsDepthFormat(AbstractTextureFormat format);
static size_t CalculateStrideForFormat(AbstractTextureFormat format, u32 row_length);
static size_t GetTexelSizeForFormat(AbstractTextureFormat format);

View File

@ -18,6 +18,11 @@ enum class AbstractTextureFormat : u32
DXT3,
DXT5,
BPTC,
R16,
D16,
R32F,
D32F,
D32F_S8,
Undefined
};