From 408c65fcbf696d36bc3e9c8f3de1fa06d618ff27 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 11 May 2021 10:38:17 +0200 Subject: [PATCH] gl4: pack/unpack pixel colors. pack poly params. share GLSL with vk --- core/rend/gl4/abuffer.cpp | 2 +- core/rend/gl4/gl4.h | 127 ++--------------------- core/rend/gl4/gles.cpp | 17 +++- core/rend/gl4/glsl.h | 144 +++++++++++++++++++++++++++ core/rend/vulkan/oit/oit_shaders.cpp | 127 ++--------------------- 5 files changed, 173 insertions(+), 244 deletions(-) create mode 100644 core/rend/gl4/glsl.h diff --git a/core/rend/gl4/abuffer.cpp b/core/rend/gl4/abuffer.cpp index f11ba055e..8543ba583 100644 --- a/core/rend/gl4/abuffer.cpp +++ b/core/rend/gl4/abuffer.cpp @@ -95,7 +95,7 @@ vec4 resolveAlphaBlend(ivec2 coords) { srcColor = secondaryBuffer; else { - srcColor = pixel.color; + srcColor = unpackColors(pixel.color); if (shadowed) srcColor.rgb *= shade_scale_factor; } diff --git a/core/rend/gl4/gl4.h b/core/rend/gl4/gl4.h index c28e1ec85..07f633456 100755 --- a/core/rend/gl4/gl4.h +++ b/core/rend/gl4/gl4.h @@ -18,6 +18,7 @@ */ #pragma once #include "rend/gles/gles.h" +#include "glsl.h" #include void gl4DrawStrips(GLuint output_fbo, int width, int height); @@ -108,27 +109,15 @@ extern GLuint depth_fbo; #define SHADER_HEADER "#version 430 \n\ \n\ layout(r32ui, binding = 4) uniform coherent restrict uimage2D abufferPointerImg; \n\ -struct Pixel { \n\ - vec4 color; \n\ - float depth; \n\ - uint seq_num; \n\ - uint next; \n\ -}; \n\ -#define EOL 0xFFFFFFFFu \n\ +\n\ +layout(binding = 0, offset = 0) uniform atomic_uint buffer_index; \n\ +\n" \ +OIT_POLY_PARAM \ +"\ layout (binding = 0, std430) coherent restrict buffer PixelBuffer { \n\ Pixel pixels[]; \n\ }; \n\ -layout(binding = 0, offset = 0) uniform atomic_uint buffer_index; \n\ \n\ -#define ZERO 0 \n\ -#define ONE 1 \n\ -#define OTHER_COLOR 2 \n\ -#define INVERSE_OTHER_COLOR 3 \n\ -#define SRC_ALPHA 4 \n\ -#define INVERSE_SRC_ALPHA 5 \n\ -#define DST_ALPHA 6 \n\ -#define INVERSE_DST_ALPHA 7 \n\ - \n\ uint getNextPixelIndex() \n\ { \n\ uint index = atomicCounterIncrement(buffer_index); \n\ @@ -139,114 +128,10 @@ uint getNextPixelIndex() \n\ return index; \n\ } \n\ \n\ -void setFragDepth(void) \n\ -{ \n\ - float w = 100000.0 * gl_FragCoord.w; \n\ - gl_FragDepth = log2(1.0 + w) / 34.0; \n\ -} \n\ -struct PolyParam { \n\ - int first; \n\ - int count; \n\ - int texid_low; \n\ - int texid_high; \n\ - int tsp; \n\ - int tcw; \n\ - int pcw; \n\ - int isp; \n\ - float zvZ; \n\ - int tileclip; \n\ - int tsp1; \n\ - int tcw1; \n\ - int texid1_low; \n\ - int texid1_high; \n\ -}; \n\ layout (binding = 1, std430) readonly buffer TrPolyParamBuffer { \n\ PolyParam tr_poly_params[]; \n\ }; \n\ \n\ -#define GET_TSP_FOR_AREA int tsp; if (area1) tsp = pp.tsp1; else tsp = pp.tsp; \n\ - \n\ -int getSrcBlendFunc(const PolyParam pp, bool area1) \n\ -{ \n\ - GET_TSP_FOR_AREA \n\ - return (tsp >> 29) & 7; \n\ -} \n\ -\n\ -int getDstBlendFunc(const PolyParam pp, bool area1) \n\ -{ \n\ - GET_TSP_FOR_AREA \n\ - return (tsp >> 26) & 7; \n\ -} \n\ -\n\ -bool getSrcSelect(const PolyParam pp, bool area1) \n\ -{ \n\ - GET_TSP_FOR_AREA \n\ - return ((tsp >> 25) & 1) != 0; \n\ -} \n\ -\n\ -bool getDstSelect(const PolyParam pp, bool area1) \n\ -{ \n\ - GET_TSP_FOR_AREA \n\ - return ((tsp >> 24) & 1) != 0; \n\ -} \n\ -\n\ -int getFogControl(const PolyParam pp, bool area1) \n\ -{ \n\ - GET_TSP_FOR_AREA \n\ - return (tsp >> 22) & 3; \n\ -} \n\ -\n\ -bool getUseAlpha(const PolyParam pp, bool area1) \n\ -{ \n\ - GET_TSP_FOR_AREA \n\ - return ((tsp >> 20) & 1) != 0; \n\ -} \n\ -\n\ -bool getIgnoreTexAlpha(const PolyParam pp, bool area1) \n\ -{ \n\ - GET_TSP_FOR_AREA \n\ - return ((tsp >> 19) & 1) != 0; \n\ -} \n\ -\n\ -int getShadingInstruction(const PolyParam pp, bool area1) \n\ -{ \n\ - GET_TSP_FOR_AREA \n\ - return (tsp >> 6) & 3; \n\ -} \n\ -\n\ -int getDepthFunc(const PolyParam pp) \n\ -{ \n\ - return (pp.isp >> 29) & 7; \n\ -} \n\ -\n\ -bool getDepthMask(const PolyParam pp) \n\ -{ \n\ - return ((pp.isp >> 26) & 1) != 1; \n\ -} \n\ -\n\ -bool getShadowEnable(const PolyParam pp) \n\ -{ \n\ - return ((pp.pcw >> 7) & 1) != 0; \n\ -} \n\ -\n\ -uint getPolyNumber(const Pixel pixel) \n\ -{ \n\ - return pixel.seq_num & 0x3FFFFFFFu; \n\ -} \n\ -\n\ -#define SHADOW_STENCIL 0x40000000u \n\ -#define SHADOW_ACC 0x80000000u \n\ -\n\ -bool isShadowed(const Pixel pixel) \n\ -{ \n\ - return (pixel.seq_num & SHADOW_ACC) == SHADOW_ACC; \n\ -} \n\ -\n\ -bool isTwoVolumes(const PolyParam pp) \n\ -{ \n\ - return pp.tsp1 != -1 || pp.tcw1 != -1; \n\ -} \n\ - \n\ " void gl4SetupMainVBO(); diff --git a/core/rend/gl4/gles.cpp b/core/rend/gl4/gles.cpp index 26f239d1c..67a2fb5b2 100644 --- a/core/rend/gl4/gles.cpp +++ b/core/rend/gl4/gles.cpp @@ -375,7 +375,7 @@ void main() uint idx = getNextPixelIndex(); Pixel pixel; - pixel.color = color; + pixel.color = packColors(clamp(color, vec4(0.0), vec4(1.0))); pixel.depth = gl_FragDepth; pixel.seq_num = uint(pp_Number); pixel.next = imageAtomicExchange(abufferPointerImg, coords, idx); @@ -740,8 +740,19 @@ static bool RenderFrame(int width, int height) } // TR PolyParam data - glBindBuffer(GL_SHADER_STORAGE_BUFFER, gl4.vbo.tr_poly_params); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(struct PolyParam) * pvrrc.global_param_tr.used(), pvrrc.global_param_tr.head(), GL_STATIC_DRAW); + if (pvrrc.global_param_tr.used() != 0) + { + glBindBuffer(GL_SHADER_STORAGE_BUFFER, gl4.vbo.tr_poly_params); + std::vector trPolyParams(pvrrc.global_param_tr.used() * 2); + const PolyParam *pp_end = pvrrc.global_param_tr.LastPtr(0); + const PolyParam *pp = pvrrc.global_param_tr.head(); + for (int i = 0; pp != pp_end; i += 2, pp++) + { + trPolyParams[i] = (pp->tsp.full & 0xffff00c0) | ((pp->isp.full >> 16) & 0xe400) | ((pp->pcw.full >> 7) & 1); + trPolyParams[i + 1] = pp->tsp1.full; + } + glBufferData(GL_SHADER_STORAGE_BUFFER, trPolyParams.size() * 4, trPolyParams.data(), GL_STATIC_DRAW); + } glCheck(); if (is_rtt || !config::Widescreen || matrices.IsClipped() || config::Rotate90) diff --git a/core/rend/gl4/glsl.h b/core/rend/gl4/glsl.h new file mode 100644 index 000000000..b111caedf --- /dev/null +++ b/core/rend/gl4/glsl.h @@ -0,0 +1,144 @@ +/* + Copyright 2021 flyinghead + + This file is part of Flycast. + + Flycast is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Flycast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Flycast. If not, see . +*/ +#pragma once + +// GLSL code for poly params handling, used by Open GL and Vulkan per-pixel renderers + +#define OIT_POLY_PARAM " \n\ +struct Pixel { \n\ + uint color; \n\ + float depth; \n\ + uint seq_num; \n\ + uint next; \n\ +}; \n\ +#define EOL 0xFFFFFFFFu \n\ +\n\ +#define ZERO 0 \n\ +#define ONE 1 \n\ +#define OTHER_COLOR 2 \n\ +#define INVERSE_OTHER_COLOR 3 \n\ +#define SRC_ALPHA 4 \n\ +#define INVERSE_SRC_ALPHA 5 \n\ +#define DST_ALPHA 6 \n\ +#define INVERSE_DST_ALPHA 7 \n\ + \n\ +void setFragDepth(void) \n\ +{ \n\ + float w = 100000.0 * gl_FragCoord.w; \n\ + gl_FragDepth = log2(1.0 + w) / 34.0; \n\ +} \n\ +\n\ +struct PolyParam { \n\ + int tsp_isp_pcw; \n\ + int tsp1; \n\ +}; \n\ + \n\ +#define GET_TSP_FOR_AREA int tsp = area1 ? pp.tsp1 : pp.tsp_isp_pcw; \n\ + \n\ +int getSrcBlendFunc(const PolyParam pp, bool area1) \n\ +{ \n\ + GET_TSP_FOR_AREA \n\ + return (tsp >> 29) & 7; \n\ +} \n\ + \n\ +int getDstBlendFunc(const PolyParam pp, bool area1) \n\ +{ \n\ + GET_TSP_FOR_AREA \n\ + return (tsp >> 26) & 7; \n\ +} \n\ + \n\ +bool getSrcSelect(const PolyParam pp, bool area1) \n\ +{ \n\ + GET_TSP_FOR_AREA \n\ + return ((tsp >> 25) & 1) != 0; \n\ +} \n\ + \n\ +bool getDstSelect(const PolyParam pp, bool area1) \n\ +{ \n\ + GET_TSP_FOR_AREA \n\ + return ((tsp >> 24) & 1) != 0; \n\ +} \n\ + \n\ +int getFogControl(const PolyParam pp, bool area1) \n\ +{ \n\ + GET_TSP_FOR_AREA \n\ + return (tsp >> 22) & 3; \n\ +} \n\ + \n\ +bool getUseAlpha(const PolyParam pp, bool area1) \n\ +{ \n\ + GET_TSP_FOR_AREA \n\ + return ((tsp >> 20) & 1) != 0; \n\ +} \n\ + \n\ +bool getIgnoreTexAlpha(const PolyParam pp, bool area1) \n\ +{ \n\ + GET_TSP_FOR_AREA \n\ + return ((tsp >> 19) & 1) != 0; \n\ +} \n\ + \n\ +int getShadingInstruction(const PolyParam pp, bool area1) \n\ +{ \n\ + GET_TSP_FOR_AREA \n\ + return (tsp >> 6) & 3; \n\ +} \n\ + \n\ +int getDepthFunc(const PolyParam pp) \n\ +{ \n\ + return (pp.tsp_isp_pcw >> 13) & 7; \n\ +} \n\ + \n\ +bool getDepthMask(const PolyParam pp) \n\ +{ \n\ + return ((pp.tsp_isp_pcw >> 10) & 1) != 1; \n\ +} \n\ + \n\ +bool getShadowEnable(const PolyParam pp) \n\ +{ \n\ + return (pp.tsp_isp_pcw & 1) != 0; \n\ +} \n\ + \n\ +uint getPolyNumber(const Pixel pixel) \n\ +{ \n\ + return pixel.seq_num & 0x3FFFFFFFu; \n\ +} \n\ + \n\ +#define SHADOW_STENCIL 0x40000000u \n\ +#define SHADOW_ACC 0x80000000u \n\ + \n\ +bool isShadowed(const Pixel pixel) \n\ +{ \n\ + return (pixel.seq_num & SHADOW_ACC) == SHADOW_ACC; \n\ +} \n\ + \n\ +bool isTwoVolumes(const PolyParam pp) \n\ +{ \n\ + return pp.tsp1 != -1; \n\ +} \n\ + \n\ +uint packColors(vec4 v) \n\ +{ \n\ + return (uint(round(v.r * 255.0)) << 24) | (uint(round(v.g * 255.0)) << 16) | (uint(round(v.b * 255.0)) << 8) | uint(round(v.a * 255.0)); \n\ +} \n\ + \n\ +vec4 unpackColors(uint u) \n\ +{ \n\ + return vec4(float((u >> 24) & 255) / 255.0, float((u >> 16) & 255) / 255.0, float((u >> 8) & 255) / 255.0, float(u & 255) / 255.0); \n\ +} \n\ +" diff --git a/core/rend/vulkan/oit/oit_shaders.cpp b/core/rend/vulkan/oit/oit_shaders.cpp index 656381e03..350396602 100644 --- a/core/rend/vulkan/oit/oit_shaders.cpp +++ b/core/rend/vulkan/oit/oit_shaders.cpp @@ -20,6 +20,7 @@ */ #include "oit_shaders.h" #include "../compiler.h" +#include "rend/gl4/glsl.h" static const char OITVertexShaderSource[] = R"(#version 450 @@ -81,28 +82,17 @@ layout (std140, set = 0, binding = 1) uniform FragmentShaderUniforms } uniformBuffer; layout(set = 3, binding = 2, r32ui) uniform coherent restrict uimage2D abufferPointerImg; -struct Pixel { - uint color; - float depth; - uint seq_num; - uint next; -}; -#define EOL 0xFFFFFFFFu -layout (set = 3, binding = 0, std430) coherent restrict buffer PixelBuffer_ { - Pixel pixels[]; -} PixelBuffer; + layout(set = 3, binding = 1) buffer PixelCounter_ { uint buffer_index; } PixelCounter; +)" +OIT_POLY_PARAM +R"( -#define ZERO 0 -#define ONE 1 -#define OTHER_COLOR 2 -#define INVERSE_OTHER_COLOR 3 -#define SRC_ALPHA 4 -#define INVERSE_SRC_ALPHA 5 -#define DST_ALPHA 6 -#define INVERSE_DST_ALPHA 7 +layout (set = 3, binding = 0, std430) coherent restrict buffer PixelBuffer_ { + Pixel pixels[]; +} PixelBuffer; uint getNextPixelIndex() { @@ -114,111 +104,10 @@ uint getNextPixelIndex() return index; } -void setFragDepth(void) -{ - float w = 100000.0 * gl_FragCoord.w; - gl_FragDepth = log2(1.0 + w) / 34.0; -} -struct PolyParam { - int tsp_isp_pcw; - int tsp1; -}; layout (set = 0, binding = 3, std430) readonly buffer TrPolyParamBuffer { PolyParam tr_poly_params[]; } TrPolyParam; -#define GET_TSP_FOR_AREA int tsp = area1 ? pp.tsp1 : pp.tsp_isp_pcw; - -int getSrcBlendFunc(const PolyParam pp, bool area1) -{ - GET_TSP_FOR_AREA - return (tsp >> 29) & 7; -} - -int getDstBlendFunc(const PolyParam pp, bool area1) -{ - GET_TSP_FOR_AREA - return (tsp >> 26) & 7; -} - -bool getSrcSelect(const PolyParam pp, bool area1) -{ - GET_TSP_FOR_AREA - return ((tsp >> 25) & 1) != 0; -} - -bool getDstSelect(const PolyParam pp, bool area1) -{ - GET_TSP_FOR_AREA - return ((tsp >> 24) & 1) != 0; -} - -int getFogControl(const PolyParam pp, bool area1) -{ - GET_TSP_FOR_AREA - return (tsp >> 22) & 3; -} - -bool getUseAlpha(const PolyParam pp, bool area1) -{ - GET_TSP_FOR_AREA - return ((tsp >> 20) & 1) != 0; -} - -bool getIgnoreTexAlpha(const PolyParam pp, bool area1) -{ - GET_TSP_FOR_AREA - return ((tsp >> 19) & 1) != 0; -} - -int getShadingInstruction(const PolyParam pp, bool area1) -{ - GET_TSP_FOR_AREA - return (tsp >> 6) & 3; -} - -int getDepthFunc(const PolyParam pp) -{ - return (pp.tsp_isp_pcw >> 13) & 7; -} - -bool getDepthMask(const PolyParam pp) -{ - return ((pp.tsp_isp_pcw >> 10) & 1) != 1; -} - -bool getShadowEnable(const PolyParam pp) -{ - return (pp.tsp_isp_pcw & 1) != 0; -} - -uint getPolyNumber(const Pixel pixel) -{ - return pixel.seq_num & 0x3FFFFFFFu; -} - -#define SHADOW_STENCIL 0x40000000u -#define SHADOW_ACC 0x80000000u - -bool isShadowed(const Pixel pixel) -{ - return (pixel.seq_num & SHADOW_ACC) == SHADOW_ACC; -} - -bool isTwoVolumes(const PolyParam pp) -{ - return pp.tsp1 != -1; -} - -uint packColors(vec4 v) -{ - return (uint(round(v.r * 255.0)) << 24) | (uint(round(v.g * 255.0)) << 16) | (uint(round(v.b * 255.0)) << 8) | uint(round(v.a * 255.0)); -} - -vec4 unpackColors(uint u) -{ - return vec4(float((u >> 24) & 255) / 255.0, float((u >> 16) & 255) / 255.0, float((u >> 8) & 255) / 255.0, float(u & 255) / 255.0); -} )"; static const char OITFragmentShaderSource[] = R"(