From 717e0665ae75ea8a2f36289f4d0084a56d20d313 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 19 Dec 2023 01:40:45 +1000 Subject: [PATCH] GPUDevice: Support R16I/R16U textures --- src/util/d3d_common.cpp | 2 ++ src/util/gpu_texture.cpp | 41 ++++++++++++++++++++++--------------- src/util/gpu_texture.h | 2 ++ src/util/metal_device.mm | 2 ++ src/util/opengl_device.cpp | 4 ++-- src/util/opengl_texture.cpp | 16 +++++++++------ src/util/shadergen.cpp | 11 +++++++--- src/util/shadergen.h | 3 ++- src/util/vulkan_device.cpp | 2 ++ 9 files changed, 55 insertions(+), 28 deletions(-) diff --git a/src/util/d3d_common.cpp b/src/util/d3d_common.cpp index abca6fddf..7031a144b 100644 --- a/src/util/d3d_common.cpp +++ b/src/util/d3d_common.cpp @@ -440,6 +440,8 @@ static constexpr std::array(GPUTe {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_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_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 diff --git a/src/util/gpu_texture.cpp b/src/util/gpu_texture.cpp index d1b10a146..9994524f5 100644 --- a/src/util/gpu_texture.cpp +++ b/src/util/gpu_texture.cpp @@ -67,23 +67,32 @@ std::array GPUTexture::GetUNormClearColor() const u32 GPUTexture::GetPixelSize(GPUTexture::Format format) { - switch (format) - { - case Format::RGBA8: - case Format::BGRA8: - return 4; + static constexpr std::array(Format::MaxCount)> sizes = {{ + 0, // Unknown + 4, // RGBA8 + 4, // BGRA8 + 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: - case Format::RGB565: - case Format::D16: - return 2; - - case Format::R8: - return 1; - - default: - return 0; - } + return sizes[static_cast(format)]; } bool GPUTexture::IsDepthFormat(Format format) diff --git a/src/util/gpu_texture.h b/src/util/gpu_texture.h index 8fbc22ed0..566dc55fd 100644 --- a/src/util/gpu_texture.h +++ b/src/util/gpu_texture.h @@ -42,6 +42,8 @@ public: R8, D16, R16, + R16I, + R16U, R16F, R32I, R32U, diff --git a/src/util/metal_device.mm b/src/util/metal_device.mm index 12618553f..b9a144d9f 100644 --- a/src/util/metal_device.mm +++ b/src/util/metal_device.mm @@ -39,6 +39,8 @@ static constexpr std::array(GPUTexture::Format: MTLPixelFormatR8Unorm, // R8 MTLPixelFormatDepth16Unorm, // D16 MTLPixelFormatR16Unorm, // R16 + MTLPixelFormatR16Sint, // R16I + MTLPixelFormatR16Uint, // R16U MTLPixelFormatR16Float, // R16F MTLPixelFormatR32Sint, // R32I MTLPixelFormatR32Uint, // R32U diff --git a/src/util/opengl_device.cpp b/src/util/opengl_device.cpp index 845e90850..56827b2c6 100644 --- a/src/util/opengl_device.cpp +++ b/src/util/opengl_device.cpp @@ -470,7 +470,7 @@ bool OpenGLDevice::CheckFeatures(bool* buggy_pbo, FeatureMask disabled_features) } #endif - if (!m_features.supports_texture_buffers) + if (!m_features.supports_texture_buffers && !(disabled_features & FEATURE_MASK_TEXTURE_BUFFERS)) { // Try SSBOs. 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(1024 * 512 * sizeof(u16))); 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; } else diff --git a/src/util/opengl_texture.cpp b/src/util/opengl_texture.cpp index 6e18b7f1e..c2e0248b6 100644 --- a/src/util/opengl_texture.cpp +++ b/src/util/opengl_texture.cpp @@ -36,12 +36,14 @@ const std::tuple& OpenGLTexture::GetPixelFormatMapping(G {GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8 {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_SHORT}, // D16 {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_R32I, GL_RED, GL_INT}, // R32I - {GL_R32UI, GL_RED, GL_UNSIGNED_INT}, // R32U + {GL_R32I, GL_RED_INTEGER, GL_INT}, // R32I + {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, // R32U {GL_R32F, GL_RED, GL_FLOAT}, // R32F - {GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // RG8 - {GL_RG16, GL_RG, GL_UNSIGNED_SHORT}, // RG16 + {GL_RG8, GL_RG_INTEGER, GL_UNSIGNED_BYTE}, // RG8 + {GL_RG16F, GL_RG, GL_UNSIGNED_SHORT}, // RG16 {GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16F {GL_RG32F, GL_RG, GL_FLOAT}, // RG32F {GL_RGBA16, GL_RGBA, GL_UNSIGNED_BYTE}, // RGBA16 @@ -61,9 +63,11 @@ const std::tuple& OpenGLTexture::GetPixelFormatMapping(G {GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8 {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_SHORT}, // D16 {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_R32I, GL_RED, GL_INT}, // R32I - {GL_R32UI, GL_RED, GL_UNSIGNED_INT}, // R32U + {GL_R32I, GL_RED_INTEGER, GL_INT}, // R32I + {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, // R32U {GL_R32F, GL_RED, GL_FLOAT}, // R32F {GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // RG8 {GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16 diff --git a/src/util/shadergen.cpp b/src/util/shadergen.cpp index 445b390e1..777ff5471 100644 --- a/src/util/shadergen.cpp +++ b/src/util/shadergen.cpp @@ -181,6 +181,8 @@ void ShaderGen::WriteHeader(std::stringstream& ss) ss << "precision highp float;\n"; ss << "precision highp int;\n"; ss << "precision highp sampler2D;\n"; + ss << "precision highp isampler2D;\n"; + ss << "precision highp usampler2D;\n"; if (GLAD_GL_ES_VERSION_3_1) ss << "precision highp sampler2DMS;\n"; @@ -332,7 +334,8 @@ void ShaderGen::DeclareUniformBuffer(std::stringstream& ss, const std::initializ 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) { @@ -341,11 +344,13 @@ void ShaderGen::DeclareTexture(std::stringstream& ss, const char* name, u32 inde else if (m_use_glsl_binding_layout) 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 { - ss << (multisampled ? "Texture2DMS " : "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"; } } diff --git a/src/util/shadergen.h b/src/util/shadergen.h index 8cd4f119f..0e88b0c6f 100644 --- a/src/util/shadergen.h +++ b/src/util/shadergen.h @@ -41,7 +41,8 @@ protected: void WriteUniformBufferDeclaration(std::stringstream& ss, bool push_constant_on_vulkan); void DeclareUniformBuffer(std::stringstream& ss, const std::initializer_list& members, 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 DeclareVertexEntryPoint(std::stringstream& ss, const std::initializer_list& attributes, u32 num_color_outputs, u32 num_texcoord_outputs, diff --git a/src/util/vulkan_device.cpp b/src/util/vulkan_device.cpp index 7cb7f4f48..49d4cf233 100644 --- a/src/util/vulkan_device.cpp +++ b/src/util/vulkan_device.cpp @@ -76,6 +76,8 @@ const std::array(GPUTexture::Format::MaxCount)> Vulka VK_FORMAT_R8_UNORM, // R8 VK_FORMAT_D16_UNORM, // D16 VK_FORMAT_R16_UNORM, // R16 + VK_FORMAT_R16_SINT, // R16I + VK_FORMAT_R16_UINT, // R16U VK_FORMAT_R16_SFLOAT, // R16F VK_FORMAT_R32_SINT, // R32I VK_FORMAT_R32_UINT, // R32U