Fragment shader generator: Move the framebuffer fetch bit to the shader ID.

Will resolve a future issue in the multisampling PR, where the
GPU_USE_FRAMEBUFFER_FETCH flag changes at runtime if you switch between no AA and MSAA.

Just figured I'd get it in separately for safety.
This commit is contained in:
Henrik Rydgård 2022-11-29 15:29:31 +01:00
parent 0682b7ba54
commit d72ad3b3f4
4 changed files with 18 additions and 3 deletions

View file

@ -169,8 +169,13 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
bool needFramebufferRead = replaceBlend == REPLACE_BLEND_READ_FRAMEBUFFER || colorWriteMask || replaceLogicOp; bool needFramebufferRead = replaceBlend == REPLACE_BLEND_READ_FRAMEBUFFER || colorWriteMask || replaceLogicOp;
bool fetchFramebuffer = needFramebufferRead && gstate_c.Use(GPU_USE_FRAMEBUFFER_FETCH); bool fetchFramebuffer = needFramebufferRead && id.Bit(FS_BIT_USE_FRAMEBUFFER_FETCH);
bool readFramebufferTex = needFramebufferRead && !gstate_c.Use(GPU_USE_FRAMEBUFFER_FETCH); bool readFramebufferTex = needFramebufferRead && !id.Bit(FS_BIT_USE_FRAMEBUFFER_FETCH);
if (fetchFramebuffer && (compat.shaderLanguage != GLSL_VULKAN || compat.shaderLanguage != GLSL_3xx)) {
*errorString = "framebuffer fetch requires GLSL: vulkan or 3xx";
return false;
}
bool needFragCoord = readFramebufferTex || gstate_c.Use(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT); bool needFragCoord = readFramebufferTex || gstate_c.Use(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT);
bool writeDepth = gstate_c.Use(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT); bool writeDepth = gstate_c.Use(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT);

View file

@ -259,6 +259,7 @@ std::string FragmentShaderDesc(const FShaderID &id) {
if ((id.Bits(FS_BIT_REPLACE_LOGIC_OP, 4) != GE_LOGIC_COPY) && !id.Bit(FS_BIT_CLEARMODE)) desc << "ReplaceLogic "; if ((id.Bits(FS_BIT_REPLACE_LOGIC_OP, 4) != GE_LOGIC_COPY) && !id.Bit(FS_BIT_CLEARMODE)) desc << "ReplaceLogic ";
if (id.Bit(FS_BIT_SAMPLE_ARRAY_TEXTURE)) desc << "TexArray "; if (id.Bit(FS_BIT_SAMPLE_ARRAY_TEXTURE)) desc << "TexArray ";
if (id.Bit(FS_BIT_STEREO)) desc << "Stereo "; if (id.Bit(FS_BIT_STEREO)) desc << "Stereo ";
if (id.Bit(FS_BIT_USE_FRAMEBUFFER_FETCH)) desc << "(fetch)";
return desc.str(); return desc.str();
} }
@ -384,6 +385,14 @@ void ComputeFragmentShaderID(FShaderID *id_out, const ComputedPipelineState &pip
id.SetBit(FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL, stencilWithoutDepth); id.SetBit(FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL, stencilWithoutDepth);
} }
} }
// In case the USE flag changes (for example, in multisampling we might disable input attachments),
// we don't want to accidentally use the wrong cached shader here. So moved it to a bit.
if (FragmentIdNeedsFramebufferRead(id)) {
if (gstate_c.Use(GPU_USE_FRAMEBUFFER_FETCH)) {
id.SetBit(FS_BIT_USE_FRAMEBUFFER_FETCH);
}
}
} }
*id_out = id; *id_out = id;

View file

@ -100,6 +100,7 @@ enum FShaderBit : uint8_t {
FS_BIT_SHADER_DEPAL_MODE = 55, // 2 bits (ShaderDepalMode) FS_BIT_SHADER_DEPAL_MODE = 55, // 2 bits (ShaderDepalMode)
FS_BIT_SAMPLE_ARRAY_TEXTURE = 57, // For multiview, framebuffers are array textures and we need to sample the two layers correctly. FS_BIT_SAMPLE_ARRAY_TEXTURE = 57, // For multiview, framebuffers are array textures and we need to sample the two layers correctly.
FS_BIT_STEREO = 58, FS_BIT_STEREO = 58,
FS_BIT_USE_FRAMEBUFFER_FETCH = 59,
}; };
static inline FShaderBit operator +(FShaderBit bit, int i) { static inline FShaderBit operator +(FShaderBit bit, int i) {

View file

@ -484,7 +484,7 @@ VulkanGeometryShader *ShaderManagerVulkan::GetGeometryShaderFromModule(VkShaderM
// instantaneous. // instantaneous.
#define CACHE_HEADER_MAGIC 0xff51f420 #define CACHE_HEADER_MAGIC 0xff51f420
#define CACHE_VERSION 30 #define CACHE_VERSION 31
struct VulkanCacheHeader { struct VulkanCacheHeader {
uint32_t magic; uint32_t magic;
uint32_t version; uint32_t version;