gl4: pack/unpack pixel colors. pack poly params. share GLSL with vk

This commit is contained in:
Flyinghead 2021-05-11 10:38:17 +02:00
parent b27fa63aea
commit 408c65fcbf
5 changed files with 173 additions and 244 deletions

View File

@ -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;
}

View File

@ -18,6 +18,7 @@
*/
#pragma once
#include "rend/gles/gles.h"
#include "glsl.h"
#include <unordered_map>
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();

View File

@ -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<u32> 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)

144
core/rend/gl4/glsl.h Normal file
View File

@ -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 <https://www.gnu.org/licenses/>.
*/
#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\
"

View File

@ -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"(