GPUDevice: Support R16I/R16U textures

This commit is contained in:
Stenzek 2023-12-19 01:40:45 +10:00
parent f5ddd7ba32
commit 717e0665ae
No known key found for this signature in database
9 changed files with 55 additions and 28 deletions

View file

@ -440,6 +440,8 @@ static constexpr std::array<D3DCommon::DXGIFormatMapping, static_cast<int>(GPUTe
{DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_UNKNOWN }, // R8 {DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_UNKNOWN }, // R8
{DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D16_UNORM }, // D16 {DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D16_UNORM }, // D16
{DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN }, // R16 {DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN }, // R16
{DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_UNKNOWN }, // R16I
{DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_UNKNOWN }, // R16U
{DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_UNKNOWN }, // R16F {DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_UNKNOWN }, // R16F
{DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_UNKNOWN }, // R32I {DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_UNKNOWN }, // R32I
{DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN }, // R32U {DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN }, // R32U

View file

@ -67,23 +67,32 @@ std::array<float, 4> GPUTexture::GetUNormClearColor() const
u32 GPUTexture::GetPixelSize(GPUTexture::Format format) u32 GPUTexture::GetPixelSize(GPUTexture::Format format)
{ {
switch (format) static constexpr std::array<u8, static_cast<size_t>(Format::MaxCount)> sizes = {{
{ 0, // Unknown
case Format::RGBA8: 4, // RGBA8
case Format::BGRA8: 4, // BGRA8
return 4; 2, // RGB565
2, // RGBA5551
1, // R8
2, // D16
2, // R16
2, // R16I
2, // R16U
2, // R16F
4, // R32I
4, // R32U
4, // R32F
2, // RG8
2, // RG16
2, // RG16F
8, // RG32F
8, // RGBA16
8, // RGBA16F
16, // RGBA32F
4, // RGB10A2
}};
case Format::RGBA5551: return sizes[static_cast<size_t>(format)];
case Format::RGB565:
case Format::D16:
return 2;
case Format::R8:
return 1;
default:
return 0;
}
} }
bool GPUTexture::IsDepthFormat(Format format) bool GPUTexture::IsDepthFormat(Format format)

View file

@ -42,6 +42,8 @@ public:
R8, R8,
D16, D16,
R16, R16,
R16I,
R16U,
R16F, R16F,
R32I, R32I,
R32U, R32U,

View file

@ -39,6 +39,8 @@ static constexpr std::array<MTLPixelFormat, static_cast<u32>(GPUTexture::Format:
MTLPixelFormatR8Unorm, // R8 MTLPixelFormatR8Unorm, // R8
MTLPixelFormatDepth16Unorm, // D16 MTLPixelFormatDepth16Unorm, // D16
MTLPixelFormatR16Unorm, // R16 MTLPixelFormatR16Unorm, // R16
MTLPixelFormatR16Sint, // R16I
MTLPixelFormatR16Uint, // R16U
MTLPixelFormatR16Float, // R16F MTLPixelFormatR16Float, // R16F
MTLPixelFormatR32Sint, // R32I MTLPixelFormatR32Sint, // R32I
MTLPixelFormatR32Uint, // R32U MTLPixelFormatR32Uint, // R32U

View file

@ -470,7 +470,7 @@ bool OpenGLDevice::CheckFeatures(bool* buggy_pbo, FeatureMask disabled_features)
} }
#endif #endif
if (!m_features.supports_texture_buffers) if (!m_features.supports_texture_buffers && !(disabled_features & FEATURE_MASK_TEXTURE_BUFFERS))
{ {
// Try SSBOs. // Try SSBOs.
GLint max_fragment_storage_blocks = 0; GLint max_fragment_storage_blocks = 0;
@ -487,7 +487,7 @@ bool OpenGLDevice::CheckFeatures(bool* buggy_pbo, FeatureMask disabled_features)
(max_fragment_storage_blocks > 0 && max_ssbo_size >= static_cast<GLint64>(1024 * 512 * sizeof(u16))); (max_fragment_storage_blocks > 0 && max_ssbo_size >= static_cast<GLint64>(1024 * 512 * sizeof(u16)));
if (m_features.texture_buffers_emulated_with_ssbo) if (m_features.texture_buffers_emulated_with_ssbo)
{ {
Log_InfoPrintf("Using shader storage buffers for VRAM writes."); Log_InfoPrint("Using shader storage buffers for VRAM writes.");
m_features.supports_texture_buffers = true; m_features.supports_texture_buffers = true;
} }
else else

View file

@ -36,12 +36,14 @@ const std::tuple<GLenum, GLenum, GLenum>& OpenGLTexture::GetPixelFormatMapping(G
{GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8 {GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8
{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_SHORT}, // D16 {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_SHORT}, // D16
{GL_R16, GL_RED, GL_UNSIGNED_SHORT}, // R16 {GL_R16, GL_RED, GL_UNSIGNED_SHORT}, // R16
{GL_R16I, GL_RED_INTEGER, GL_SHORT}, // R16I
{GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT}, // R16U
{GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16F {GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16F
{GL_R32I, GL_RED, GL_INT}, // R32I {GL_R32I, GL_RED_INTEGER, GL_INT}, // R32I
{GL_R32UI, GL_RED, GL_UNSIGNED_INT}, // R32U {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, // R32U
{GL_R32F, GL_RED, GL_FLOAT}, // R32F {GL_R32F, GL_RED, GL_FLOAT}, // R32F
{GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // RG8 {GL_RG8, GL_RG_INTEGER, GL_UNSIGNED_BYTE}, // RG8
{GL_RG16, GL_RG, GL_UNSIGNED_SHORT}, // RG16 {GL_RG16F, GL_RG, GL_UNSIGNED_SHORT}, // RG16
{GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16F {GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16F
{GL_RG32F, GL_RG, GL_FLOAT}, // RG32F {GL_RG32F, GL_RG, GL_FLOAT}, // RG32F
{GL_RGBA16, GL_RGBA, GL_UNSIGNED_BYTE}, // RGBA16 {GL_RGBA16, GL_RGBA, GL_UNSIGNED_BYTE}, // RGBA16
@ -61,9 +63,11 @@ const std::tuple<GLenum, GLenum, GLenum>& OpenGLTexture::GetPixelFormatMapping(G
{GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8 {GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8
{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_SHORT}, // D16 {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_SHORT}, // D16
{GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16 {GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16
{GL_R16I, GL_RED_INTEGER, GL_SHORT}, // R16I
{GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT}, // R16U
{GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16F {GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16F
{GL_R32I, GL_RED, GL_INT}, // R32I {GL_R32I, GL_RED_INTEGER, GL_INT}, // R32I
{GL_R32UI, GL_RED, GL_UNSIGNED_INT}, // R32U {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, // R32U
{GL_R32F, GL_RED, GL_FLOAT}, // R32F {GL_R32F, GL_RED, GL_FLOAT}, // R32F
{GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // RG8 {GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // RG8
{GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16 {GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16

View file

@ -181,6 +181,8 @@ void ShaderGen::WriteHeader(std::stringstream& ss)
ss << "precision highp float;\n"; ss << "precision highp float;\n";
ss << "precision highp int;\n"; ss << "precision highp int;\n";
ss << "precision highp sampler2D;\n"; ss << "precision highp sampler2D;\n";
ss << "precision highp isampler2D;\n";
ss << "precision highp usampler2D;\n";
if (GLAD_GL_ES_VERSION_3_1) if (GLAD_GL_ES_VERSION_3_1)
ss << "precision highp sampler2DMS;\n"; ss << "precision highp sampler2DMS;\n";
@ -332,7 +334,8 @@ void ShaderGen::DeclareUniformBuffer(std::stringstream& ss, const std::initializ
ss << "};\n\n"; ss << "};\n\n";
} }
void ShaderGen::DeclareTexture(std::stringstream& ss, const char* name, u32 index, bool multisampled /* = false */) void ShaderGen::DeclareTexture(std::stringstream& ss, const char* name, u32 index, bool multisampled /* = false */,
bool is_int /* = false */, bool is_unsigned /* = false */)
{ {
if (m_glsl) if (m_glsl)
{ {
@ -341,11 +344,13 @@ void ShaderGen::DeclareTexture(std::stringstream& ss, const char* name, u32 inde
else if (m_use_glsl_binding_layout) else if (m_use_glsl_binding_layout)
ss << "layout(binding = " << index << ") "; ss << "layout(binding = " << index << ") ";
ss << "uniform " << (multisampled ? "sampler2DMS " : "sampler2D ") << name << ";\n"; ss << "uniform " << (is_int ? (is_unsigned ? "u" : "i") : "") << (multisampled ? "sampler2DMS " : "sampler2D ")
<< name << ";\n";
} }
else else
{ {
ss << (multisampled ? "Texture2DMS<float4> " : "Texture2D ") << name << " : register(t" << index << ");\n"; ss << (multisampled ? "Texture2DMS<" : "Texture2D<") << (is_int ? (is_unsigned ? "uint4" : "int4") : "float4")
<< "> " << name << " : register(t" << index << ");\n";
ss << "SamplerState " << name << "_ss : register(s" << index << ");\n"; ss << "SamplerState " << name << "_ss : register(s" << index << ");\n";
} }
} }

View file

@ -41,7 +41,8 @@ protected:
void WriteUniformBufferDeclaration(std::stringstream& ss, bool push_constant_on_vulkan); void WriteUniformBufferDeclaration(std::stringstream& ss, bool push_constant_on_vulkan);
void DeclareUniformBuffer(std::stringstream& ss, const std::initializer_list<const char*>& members, void DeclareUniformBuffer(std::stringstream& ss, const std::initializer_list<const char*>& members,
bool push_constant_on_vulkan); bool push_constant_on_vulkan);
void DeclareTexture(std::stringstream& ss, const char* name, u32 index, bool multisampled = false); void DeclareTexture(std::stringstream& ss, const char* name, u32 index, bool multisampled = false,
bool is_int = false, bool is_unsigned = false);
void DeclareTextureBuffer(std::stringstream& ss, const char* name, u32 index, bool is_int, bool is_unsigned); void DeclareTextureBuffer(std::stringstream& ss, const char* name, u32 index, bool is_int, bool is_unsigned);
void DeclareVertexEntryPoint(std::stringstream& ss, const std::initializer_list<const char*>& attributes, void DeclareVertexEntryPoint(std::stringstream& ss, const std::initializer_list<const char*>& attributes,
u32 num_color_outputs, u32 num_texcoord_outputs, u32 num_color_outputs, u32 num_texcoord_outputs,

View file

@ -76,6 +76,8 @@ const std::array<VkFormat, static_cast<u32>(GPUTexture::Format::MaxCount)> Vulka
VK_FORMAT_R8_UNORM, // R8 VK_FORMAT_R8_UNORM, // R8
VK_FORMAT_D16_UNORM, // D16 VK_FORMAT_D16_UNORM, // D16
VK_FORMAT_R16_UNORM, // R16 VK_FORMAT_R16_UNORM, // R16
VK_FORMAT_R16_SINT, // R16I
VK_FORMAT_R16_UINT, // R16U
VK_FORMAT_R16_SFLOAT, // R16F VK_FORMAT_R16_SFLOAT, // R16F
VK_FORMAT_R32_SINT, // R32I VK_FORMAT_R32_SINT, // R32I
VK_FORMAT_R32_UINT, // R32U VK_FORMAT_R32_UINT, // R32U