From 555a93057c07f045cc71c4652c54eebb990021b7 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Mon, 26 Jul 2021 11:20:04 -0700 Subject: [PATCH] VideoCommon: Allow BitfieldExtract in specialized shaders --- Source/Core/VideoCommon/PixelShaderGen.cpp | 1 + Source/Core/VideoCommon/ShaderGenCommon.cpp | 18 ++++++++++++++++++ Source/Core/VideoCommon/ShaderGenCommon.h | 12 ++++++++++++ Source/Core/VideoCommon/UberShaderCommon.cpp | 18 ------------------ Source/Core/VideoCommon/UberShaderCommon.h | 19 ------------------- Source/Core/VideoCommon/UberShaderPixel.cpp | 2 +- Source/Core/VideoCommon/UberShaderVertex.cpp | 2 +- 7 files changed, 33 insertions(+), 39 deletions(-) diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index a380937ae2..97adb46a97 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -565,6 +565,7 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos uid_data->genMode_numtexgens, uid_data->genMode_numindstages); // Stuff that is shared between ubershaders and pixelgen. + WriteBitfieldExtractHeader(out, api_type, host_config); WritePixelShaderCommonHeader(out, api_type, host_config, uid_data->bounding_box); if (uid_data->forced_early_z && g_ActiveConfig.backend_info.bSupportsEarlyZ) diff --git a/Source/Core/VideoCommon/ShaderGenCommon.cpp b/Source/Core/VideoCommon/ShaderGenCommon.cpp index c5cd3ef30d..cbc17f0772 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.cpp +++ b/Source/Core/VideoCommon/ShaderGenCommon.cpp @@ -105,6 +105,24 @@ void WriteIsNanHeader(ShaderCode& out, APIType api_type) } } +void WriteBitfieldExtractHeader(ShaderCode& out, APIType api_type, + const ShaderHostConfig& host_config) +{ + // ============================================== + // BitfieldExtract for APIs which don't have it + // ============================================== + if (!host_config.backend_bitfield) + { + out.Write("uint bitfieldExtract(uint val, int off, int size) {{\n" + " // This built-in function is only supported in OpenGL 4.0+ and ES 3.1+\n" + " // Microsoft's HLSL compiler automatically optimises this to a bitfield extract " + "instruction.\n" + " uint mask = uint((1 << size) - 1);\n" + " return uint(val >> off) & mask;\n" + "}}\n\n"); + } +} + static void DefineOutputMember(ShaderCode& object, APIType api_type, std::string_view qualifier, std::string_view type, std::string_view name, int var_index, std::string_view semantic = {}, int semantic_index = -1) diff --git a/Source/Core/VideoCommon/ShaderGenCommon.h b/Source/Core/VideoCommon/ShaderGenCommon.h index 3c1e7f38f8..f7f27b3073 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/ShaderGenCommon.h @@ -14,6 +14,7 @@ #include "Common/BitField.h" #include "Common/CommonTypes.h" #include "Common/StringUtil.h" +#include "Common/TypeUtils.h" enum class APIType; @@ -177,6 +178,8 @@ std::string GetDiskShaderCacheFileName(APIType api_type, const char* type, bool bool include_host_config, bool include_api = true); void WriteIsNanHeader(ShaderCode& out, APIType api_type); +void WriteBitfieldExtractHeader(ShaderCode& out, APIType api_type, + const ShaderHostConfig& host_config); void GenerateVSOutputMembers(ShaderCode& object, APIType api_type, u32 texgens, const ShaderHostConfig& host_config, std::string_view qualifier); @@ -195,6 +198,15 @@ void AssignVSOutputMembers(ShaderCode& object, std::string_view a, std::string_v const char* GetInterpolationQualifier(bool msaa, bool ssaa, bool in_glsl_interface_block = false, bool in = false); +// bitfieldExtract generator for BitField types +template +std::string BitfieldExtract(std::string_view source) +{ + using BitFieldT = Common::MemberType; + return fmt::format("bitfieldExtract({}, {}, {})", source, static_cast(BitFieldT::StartBit()), + static_cast(BitFieldT::NumBits())); +} + // Constant variable names #define I_COLORS "color" #define I_KCOLORS "k" diff --git a/Source/Core/VideoCommon/UberShaderCommon.cpp b/Source/Core/VideoCommon/UberShaderCommon.cpp index 8b013fc91b..283d11ffdd 100644 --- a/Source/Core/VideoCommon/UberShaderCommon.cpp +++ b/Source/Core/VideoCommon/UberShaderCommon.cpp @@ -9,24 +9,6 @@ namespace UberShader { -void WriteUberShaderCommonHeader(ShaderCode& out, APIType api_type, - const ShaderHostConfig& host_config) -{ - // ============================================== - // BitfieldExtract for APIs which don't have it - // ============================================== - if (!host_config.backend_bitfield) - { - out.Write("uint bitfieldExtract(uint val, int off, int size) {{\n" - " // This built-in function is only support in OpenGL 4.0+ and ES 3.1+\n" - " // Microsoft's HLSL compiler automatically optimises this to a bitfield extract " - "instruction.\n" - " uint mask = uint((1 << size) - 1);\n" - " return uint(val >> off) & mask;\n" - "}}\n\n"); - } -} - void WriteLightingFunction(ShaderCode& out) { // ============================================== diff --git a/Source/Core/VideoCommon/UberShaderCommon.h b/Source/Core/VideoCommon/UberShaderCommon.h index d1a736ae47..4e3b0ff2a9 100644 --- a/Source/Core/VideoCommon/UberShaderCommon.h +++ b/Source/Core/VideoCommon/UberShaderCommon.h @@ -3,37 +3,18 @@ #pragma once -#include #include -#include - -#include "Common/CommonTypes.h" -#include "Common/TypeUtils.h" - class ShaderCode; enum class APIType; union ShaderHostConfig; namespace UberShader { -// Common functions across all ubershaders -void WriteUberShaderCommonHeader(ShaderCode& out, APIType api_type, - const ShaderHostConfig& host_config); - // Vertex lighting void WriteLightingFunction(ShaderCode& out); void WriteVertexLighting(ShaderCode& out, APIType api_type, std::string_view world_pos_var, std::string_view normal_var, std::string_view in_color_0_var, std::string_view in_color_1_var, std::string_view out_color_0_var, std::string_view out_color_1_var); - -// bitfieldExtract generator for BitField types -template -std::string BitfieldExtract(std::string_view source) -{ - using BitFieldT = Common::MemberType; - return fmt::format("bitfieldExtract({}, {}, {})", source, static_cast(BitFieldT::StartBit()), - static_cast(BitFieldT::NumBits())); -} } // namespace UberShader diff --git a/Source/Core/VideoCommon/UberShaderPixel.cpp b/Source/Core/VideoCommon/UberShaderPixel.cpp index 4541f15b10..c124a0b5db 100644 --- a/Source/Core/VideoCommon/UberShaderPixel.cpp +++ b/Source/Core/VideoCommon/UberShaderPixel.cpp @@ -63,8 +63,8 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, out.Write("// Pixel UberShader for {} texgens{}{}\n", numTexgen, early_depth ? ", early-depth" : "", per_pixel_depth ? ", per-pixel depth" : ""); + WriteBitfieldExtractHeader(out, api_type, host_config); WritePixelShaderCommonHeader(out, api_type, host_config, bounding_box); - WriteUberShaderCommonHeader(out, api_type, host_config); if (per_pixel_lighting) WriteLightingFunction(out); diff --git a/Source/Core/VideoCommon/UberShaderVertex.cpp b/Source/Core/VideoCommon/UberShaderVertex.cpp index 8d3b128688..68915351d1 100644 --- a/Source/Core/VideoCommon/UberShaderVertex.cpp +++ b/Source/Core/VideoCommon/UberShaderVertex.cpp @@ -49,8 +49,8 @@ ShaderCode GenVertexShader(APIType api_type, const ShaderHostConfig& host_config GenerateVSOutputMembers(out, api_type, num_texgen, host_config, ""); out.Write("}};\n\n"); - WriteUberShaderCommonHeader(out, api_type, host_config); WriteIsNanHeader(out, api_type); + WriteBitfieldExtractHeader(out, api_type, host_config); WriteLightingFunction(out); if (api_type == APIType::OpenGL || api_type == APIType::Vulkan)