mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-15 10:40:01 +01:00
Merge remote-tracking branch 'remotes/origin/guardband-culling'
This commit is contained in:
commit
6dc089c57f
13 files changed
+149
-35
No files matched your search
@@ -136,6 +136,7 @@ bool IsColorTestTriviallyTrue() {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Pack into 16-bit integer.
|
||||
const bool nonAlphaSrcFactors[16] = {
|
||||
true, // GE_SRCBLEND_DSTCOLOR,
|
||||
true, // GE_SRCBLEND_INVDSTCOLOR,
|
||||
|
||||
@@ -76,6 +76,8 @@ enum : uint64_t {
|
||||
DIRTY_TEXCLAMP = 1ULL << 19,
|
||||
DIRTY_DEPTHRANGE = 1ULL << 19,
|
||||
|
||||
DIRTY_GUARDBAND = 1ULL << 20,
|
||||
|
||||
DIRTY_WORLDMATRIX = 1ULL << 21,
|
||||
DIRTY_VIEWMATRIX = 1ULL << 22,
|
||||
DIRTY_TEXMATRIX = 1ULL << 23,
|
||||
|
||||
@@ -23,6 +23,25 @@ static void ConvertProjMatrixToD3D11(Matrix4x4 &in) {
|
||||
in.translateAndScale(trans, scale);
|
||||
}
|
||||
|
||||
void ComputeGuardband(float gb[4], float zmin) {
|
||||
float vpWidth = fabsf(gstate_c.vpWidth);
|
||||
float vpHeight = fabsf(gstate_c.vpHeight);
|
||||
// Avoid bad values during initialization. Doubt these are really needed.
|
||||
if (vpWidth == 0.0)
|
||||
vpWidth = 480;
|
||||
if (vpHeight == 0.0)
|
||||
vpHeight = 272;
|
||||
|
||||
// We assume a symmetric guardband, even though it's not entirely correct to do so - but nearly everything does it
|
||||
// this way and we have space for the NAN in the uniform.
|
||||
// We also assume that everything behind the near clipping plane gets clipped and will thus not in reality
|
||||
// exceed the guardband. This is a bit rough but should be ok.
|
||||
gb[0] = (2048.0f / (vpWidth*0.5f));
|
||||
gb[1] = (2048.0f / (vpHeight*0.5f));
|
||||
gb[2] = zmin;
|
||||
gb[3] = NAN;
|
||||
}
|
||||
|
||||
void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipViewport) {
|
||||
if (dirtyUniforms & DIRTY_TEXENV) {
|
||||
Uint8x3ToFloat4(ub->texEnvColor, gstate.texenvcolor);
|
||||
@@ -56,7 +75,11 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
|
||||
ub->texClampOffset[0] = gstate_c.curTextureXOffset * invW;
|
||||
ub->texClampOffset[1] = gstate_c.curTextureYOffset * invH;
|
||||
}
|
||||
|
||||
if (dirtyUniforms & DIRTY_GUARDBAND) {
|
||||
float gb[4];
|
||||
ComputeGuardband(gb, 0.0f);
|
||||
memcpy(ub->guardband, gb, sizeof(float) * 4);
|
||||
}
|
||||
if (dirtyUniforms & DIRTY_PROJMATRIX) {
|
||||
Matrix4x4 flippedMatrix;
|
||||
memcpy(&flippedMatrix, gstate.projMatrix, 16 * sizeof(float));
|
||||
@@ -98,6 +121,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
|
||||
if (g_Config.iRenderingMode == 0 && g_display_rotation != DisplayRotation::ROTATE_0) {
|
||||
proj_through = proj_through * g_display_rot_matrix;
|
||||
}
|
||||
// proj_through.translateAndScale(Vec3(0, 0, 0), Vec3(1.0f / debugscale, 1.0f / debugscale, 0));
|
||||
CopyMatrix4x4(ub->proj_through, proj_through.getReadPtr());
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
enum : uint64_t {
|
||||
DIRTY_BASE_UNIFORMS =
|
||||
DIRTY_WORLDMATRIX | DIRTY_PROJTHROUGHMATRIX | DIRTY_VIEWMATRIX | DIRTY_TEXMATRIX | DIRTY_ALPHACOLORREF |
|
||||
DIRTY_PROJMATRIX | DIRTY_FOGCOLOR | DIRTY_FOGCOEF | DIRTY_TEXENV | DIRTY_STENCILREPLACEVALUE |
|
||||
DIRTY_PROJMATRIX | DIRTY_FOGCOLOR | DIRTY_FOGCOEF | DIRTY_TEXENV | DIRTY_STENCILREPLACEVALUE | DIRTY_GUARDBAND |
|
||||
DIRTY_ALPHACOLORMASK | DIRTY_SHADERBLEND | DIRTY_UVSCALEOFFSET | DIRTY_TEXCLAMP | DIRTY_DEPTHRANGE | DIRTY_MATAMBIENTALPHA |
|
||||
DIRTY_BEZIERSPLINE,
|
||||
DIRTY_LIGHT_UNIFORMS =
|
||||
@@ -34,6 +34,7 @@ struct UB_VS_FS_Base {
|
||||
int spline_count_v;
|
||||
int spline_type_u;
|
||||
int spline_type_v;
|
||||
float guardband[4];
|
||||
// Fragment data
|
||||
float fogColor[4];
|
||||
float texEnvColor[4];
|
||||
@@ -59,6 +60,8 @@ R"( mat4 proj_mtx;
|
||||
int spline_count_v;
|
||||
int spline_type_u;
|
||||
int spline_type_v;
|
||||
vec4 guardband;
|
||||
// Fragment
|
||||
vec3 fogcolor;
|
||||
vec3 texenv;
|
||||
ivec4 alphacolorref;
|
||||
@@ -84,6 +87,8 @@ R"( float4x4 u_proj;
|
||||
int u_spline_count_v;
|
||||
int u_spline_type_u;
|
||||
int u_spline_type_v;
|
||||
float4 u_guardband;
|
||||
// Fragment
|
||||
float3 u_fogcolor;
|
||||
float3 u_texenv;
|
||||
uint4 u_alphacolorref;
|
||||
@@ -184,3 +189,5 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
|
||||
void LightUpdateUniforms(UB_VS_Lights *ub, uint64_t dirtyUniforms);
|
||||
void BoneUpdateUniforms(UB_VS_Bones *ub, uint64_t dirtyUniforms);
|
||||
|
||||
// Shared helper functions
|
||||
void ComputeGuardband(float gb[4], float zmin);
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "GPU/Math3D.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/Common/ShaderUniforms.h"
|
||||
#include "GPU/Directx9/ShaderManagerDX9.h"
|
||||
#include "GPU/Directx9/DrawEngineDX9.h"
|
||||
#include "GPU/Directx9/FramebufferDX9.h"
|
||||
@@ -378,6 +379,11 @@ void ShaderManagerDX9::VSUpdateUniforms(u64 dirtyUniforms) {
|
||||
#endif
|
||||
VSSetFloatArray(CONST_VS_FOGCOEF, fogcoef, 2);
|
||||
}
|
||||
if (dirtyUniforms & DIRTY_GUARDBAND) {
|
||||
float gb[4];
|
||||
ComputeGuardband(gb, 0.0f);
|
||||
VSSetFloatUniform4(CONST_VS_GUARDBAND, gb);
|
||||
}
|
||||
// TODO: Could even set all bones in one go if they're all dirty.
|
||||
#ifdef USE_BONE_ARRAY
|
||||
if (u_bone != 0) {
|
||||
|
||||
@@ -38,6 +38,13 @@
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
// The PSP does not have a proper triangle clipper on the sides. It does have on for the front plane.
|
||||
// It has a guard band though and can rasterize rather large
|
||||
// triangles that go outside the viewport. However, there are limits, and it will drop triangles that are very
|
||||
// large. Some games appear to draw broken geometry, probably game bugs that were never discovered because the PSP
|
||||
// would drop the geometry, including Parappa The Rapper in an obscure case and Outrun. Try to get rid of those
|
||||
// triangles by setting the W of one of the vertices to NaN if they are discovered.
|
||||
|
||||
static const char * const boneWeightAttrDecl[9] = {
|
||||
"#ERROR#",
|
||||
"float a_w1:TEXCOORD1;\n",
|
||||
@@ -56,6 +63,26 @@ enum DoLightComputation {
|
||||
LIGHT_FULL,
|
||||
};
|
||||
|
||||
// #define COLORGUARDBAND
|
||||
|
||||
#ifdef COLORGUARDBAND
|
||||
// Coloring debug version
|
||||
static void WriteGuardBand(char *&p) {
|
||||
WRITE(p, " if (outPos.w >= 0.0) {\n");
|
||||
WRITE(p, " float3 projPos = outPos.xyz / outPos.w; \n");
|
||||
WRITE(p, " if (projPos.z >= 0.0 && projPos.z <= 1.0 && (abs(projPos.x) > u_guardband.x || projPos.y > u_guardband.y)) colorOverride.g = 0.0;\n");//outPos.w = u_guardband.w;\n");
|
||||
WRITE(p, " } else { colorOverride.b = 0.0; } \n");
|
||||
}
|
||||
#else
|
||||
// NOTE: We are skipping the bottom check. This fixes TOCA but I am dubious about it...
|
||||
static void WriteGuardBand(char *&p) {
|
||||
WRITE(p, " if (outPos.w >= 0.0) {\n");
|
||||
WRITE(p, " float3 projPos = outPos.xyz / outPos.w; \n");
|
||||
WRITE(p, " if (projPos.z >= 0.0 && projPos.z <= 1.0 && (abs(projPos.x) > u_guardband.x || abs(projPos.y) > u_guardband.y)) outPos.w = u_guardband.w;\n");
|
||||
WRITE(p, " }\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void GenerateVertexShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage lang) {
|
||||
char *p = buffer;
|
||||
const u32 vertType = gstate.vertType;
|
||||
@@ -119,6 +146,7 @@ void GenerateVertexShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage l
|
||||
WRITE(p, "float4x4 u_proj : register(c%i);\n", CONST_VS_PROJ);
|
||||
// Add all the uniforms we'll need to transform properly.
|
||||
}
|
||||
WRITE(p, "float4 u_guardband : register(c%i);\n", CONST_VS_GUARDBAND);
|
||||
|
||||
if (enableFog) {
|
||||
WRITE(p, "float2 u_fogcoef : register(c%i);\n", CONST_VS_FOGCOEF);
|
||||
@@ -350,6 +378,9 @@ void GenerateVertexShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage l
|
||||
|
||||
WRITE(p, "VS_OUT main(VS_IN In) {\n");
|
||||
WRITE(p, " VS_OUT Out;\n");
|
||||
#ifdef COLORGUARDBAND
|
||||
WRITE(p, " float4 colorOverride = float4(1.0, 1.0, 1.0, 1.0);\n");
|
||||
#endif
|
||||
if (!useHWTransform) {
|
||||
// Simple pass-through of vertex data to fragment shader
|
||||
if (doTexture) {
|
||||
@@ -373,26 +404,30 @@ void GenerateVertexShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage l
|
||||
}
|
||||
if (lang == HLSL_D3D11 || lang == HLSL_D3D11_LEVEL9) {
|
||||
if (gstate.isModeThrough()) {
|
||||
WRITE(p, " Out.gl_Position = mul(u_proj_through, float4(In.position.xyz, 1.0));\n");
|
||||
WRITE(p, " float4 outPos = mul(u_proj_through, float4(In.position.xyz, 1.0));\n");
|
||||
} else {
|
||||
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, " Out.gl_Position = depthRoundZVP(mul(u_proj, float4(In.position.xyz, 1.0)));\n");
|
||||
WRITE(p, " float4 outPos = depthRoundZVP(mul(u_proj, float4(In.position.xyz, 1.0)));\n");
|
||||
} else {
|
||||
WRITE(p, " Out.gl_Position = mul(u_proj, float4(In.position.xyz, 1.0));\n");
|
||||
WRITE(p, " float4 outPos = mul(u_proj, float4(In.position.xyz, 1.0));\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (gstate.isModeThrough()) {
|
||||
WRITE(p, " Out.gl_Position = mul(float4(In.position.xyz, 1.0), u_proj_through);\n");
|
||||
WRITE(p, " float4 outPos = mul(float4(In.position.xyz, 1.0), u_proj_through);\n");
|
||||
} else {
|
||||
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, " Out.gl_Position = depthRoundZVP(mul(float4(In.position.xyz, 1.0), u_proj));\n");
|
||||
WRITE(p, " float4 outPos = depthRoundZVP(mul(float4(In.position.xyz, 1.0), u_proj));\n");
|
||||
} else {
|
||||
WRITE(p, " Out.gl_Position = mul(float4(In.position.xyz, 1.0), u_proj);\n");
|
||||
WRITE(p, " float4 outPos = mul(float4(In.position.xyz, 1.0), u_proj);\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (lang != HLSL_DX9) {
|
||||
WriteGuardBand(p);
|
||||
}
|
||||
WRITE(p, " Out.gl_Position = outPos;\n");
|
||||
} else {
|
||||
// Step 1: World Transform / Skinning
|
||||
if (!enableBones) {
|
||||
// Hardware tessellation
|
||||
@@ -578,18 +613,20 @@ void GenerateVertexShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage l
|
||||
if (lang == HLSL_D3D11 || lang == HLSL_D3D11_LEVEL9) {
|
||||
// Final view and projection transforms.
|
||||
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, " Out.gl_Position = depthRoundZVP(mul(u_proj, viewPos));\n");
|
||||
WRITE(p, " float4 outPos = depthRoundZVP(mul(u_proj, viewPos));\n");
|
||||
} else {
|
||||
WRITE(p, " Out.gl_Position = mul(u_proj, viewPos);\n");
|
||||
WRITE(p, " float4 outPos = mul(u_proj, viewPos);\n");
|
||||
}
|
||||
} else {
|
||||
// Final view and projection transforms.
|
||||
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, " Out.gl_Position = depthRoundZVP(mul(viewPos, u_proj));\n");
|
||||
WRITE(p, " float4 outPos = depthRoundZVP(mul(viewPos, u_proj));\n");
|
||||
} else {
|
||||
WRITE(p, " Out.gl_Position = mul(viewPos, u_proj);\n");
|
||||
WRITE(p, " float4 outPos = mul(viewPos, u_proj);\n");
|
||||
}
|
||||
}
|
||||
WriteGuardBand(p);
|
||||
WRITE(p, " Out.gl_Position = outPos;\n");
|
||||
|
||||
// TODO: Declare variables for dots for shade mapping if needed.
|
||||
|
||||
@@ -807,6 +844,9 @@ void GenerateVertexShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage l
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef COLORGUARDBAND
|
||||
WRITE(p, " Out.v_color0 *= colorOverride;\n");
|
||||
#endif
|
||||
WRITE(p, " return Out;\n");
|
||||
WRITE(p, "}\n");
|
||||
}
|
||||
|
||||
@@ -55,5 +55,6 @@ namespace DX9 {
|
||||
#define CONST_VS_LIGHTSPECULAR 75
|
||||
#define CONST_VS_LIGHTAMBIENT 79
|
||||
#define CONST_VS_DEPTHRANGE 83
|
||||
#define CONST_VS_GUARDBAND 84
|
||||
|
||||
};
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "ext/native/gfx/GLStateCache.h"
|
||||
#include "GPU/GLES/ShaderManagerGLES.h"
|
||||
#include "GPU/GLES/DrawEngineGLES.h"
|
||||
#include "GPU/Common/ShaderUniforms.h"
|
||||
#include "FramebufferManagerGLES.h"
|
||||
|
||||
Shader::Shader(const char *code, uint32_t glShaderType, bool useHWTransform)
|
||||
@@ -210,6 +211,7 @@ LinkedShader::LinkedShader(ShaderID VSID, Shader *vs, ShaderID FSID, Shader *fs,
|
||||
u_uvscaleoffset = glGetUniformLocation(program, "u_uvscaleoffset");
|
||||
u_texclamp = glGetUniformLocation(program, "u_texclamp");
|
||||
u_texclampoff = glGetUniformLocation(program, "u_texclampoff");
|
||||
u_guardband = glGetUniformLocation(program, "u_guardband");
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
char temp[64];
|
||||
@@ -268,7 +270,8 @@ LinkedShader::LinkedShader(ShaderID VSID, Shader *vs, ShaderID FSID, Shader *fs,
|
||||
if (u_blendFixA != -1 || u_blendFixB != -1 || u_fbotexSize != -1) availableUniforms |= DIRTY_SHADERBLEND;
|
||||
if (u_depthRange != -1)
|
||||
availableUniforms |= DIRTY_DEPTHRANGE;
|
||||
|
||||
if (u_guardband != -1)
|
||||
availableUniforms |= DIRTY_GUARDBAND;
|
||||
// Looping up to numBones lets us avoid checking u_bone[i]
|
||||
#ifdef USE_BONE_ARRAY
|
||||
if (u_bone != -1) {
|
||||
@@ -601,6 +604,13 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid) {
|
||||
if (dirty & DIRTY_TEXMATRIX) {
|
||||
SetMatrix4x3(u_texmtx, gstate.tgenMatrix);
|
||||
}
|
||||
|
||||
if (dirty & DIRTY_GUARDBAND) {
|
||||
float gb[4];
|
||||
ComputeGuardband(gb, 0.0f);
|
||||
SetFloatUniform4(u_guardband, gb);
|
||||
}
|
||||
|
||||
if ((dirty & DIRTY_DEPTHRANGE) && u_depthRange != -1) {
|
||||
// Since depth is [-1, 1] mapping to [minz, maxz], this is easyish.
|
||||
float vpZScale = gstate.getViewportZScale();
|
||||
|
||||
@@ -96,6 +96,9 @@ public:
|
||||
int u_texclamp;
|
||||
int u_texclampoff;
|
||||
|
||||
// Clipping
|
||||
int u_guardband;
|
||||
|
||||
// Lighting
|
||||
int u_ambient;
|
||||
int u_matambientalpha;
|
||||
|
||||
@@ -69,6 +69,12 @@ enum DoLightComputation {
|
||||
LIGHT_FULL,
|
||||
};
|
||||
|
||||
static void WriteGuardBand(char *&p) {
|
||||
WRITE(p, " vec3 projPos = outPos.xyz / outPos.w; \n");
|
||||
WRITE(p, " if (outPos.w >= u_guardband.z) {\n");
|
||||
WRITE(p, " if (abs(projPos.x) > u_guardband.x || projPos.y < -u_guardband.y) outPos.w = u_guardband.w;\n");
|
||||
WRITE(p, " }\n");
|
||||
}
|
||||
|
||||
// Depth range and viewport
|
||||
//
|
||||
@@ -95,6 +101,7 @@ enum DoLightComputation {
|
||||
// TODO: Skip all this if we can actually get a 16-bit depth buffer along with stencil, which
|
||||
// is a bit of a rare configuration, although quite common on mobile.
|
||||
|
||||
// NOTE: We are skipping the bottom check. This fixes TOCA but I am dubious about it...
|
||||
|
||||
void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
||||
char *p = buffer;
|
||||
@@ -247,6 +254,7 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
||||
WRITE(p, "uniform mat4 u_proj;\n");
|
||||
// Add all the uniforms we'll need to transform properly.
|
||||
}
|
||||
WRITE(p, "uniform vec4 u_guardband;\n");
|
||||
|
||||
bool scaleUV = !throughmode && (uvGenMode == GE_TEXMAP_TEXTURE_COORDS || uvGenMode == GE_TEXMAP_UNKNOWN);
|
||||
|
||||
@@ -452,15 +460,17 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
||||
WRITE(p, " v_fogdepth = position.w;\n");
|
||||
}
|
||||
if (isModeThrough) {
|
||||
WRITE(p, " gl_Position = u_proj_through * vec4(position.xyz, 1.0);\n");
|
||||
WRITE(p, " vec4 outPos = u_proj_through * vec4(position.xyz, 1.0);\n");
|
||||
} else {
|
||||
// The viewport is used in this case, so need to compensate for that.
|
||||
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, " gl_Position = depthRoundZVP(u_proj * vec4(position.xyz, 1.0));\n");
|
||||
WRITE(p, " vec4 outPos = depthRoundZVP(u_proj * vec4(position.xyz, 1.0));\n");
|
||||
} else {
|
||||
WRITE(p, " gl_Position = u_proj * vec4(position.xyz, 1.0);\n");
|
||||
WRITE(p, " vec4 outPos = u_proj * vec4(position.xyz, 1.0);\n");
|
||||
}
|
||||
}
|
||||
WriteGuardBand(p);
|
||||
WRITE(p, " gl_Position = outPos;\n");
|
||||
} else {
|
||||
// Step 1: World Transform / Skinning
|
||||
if (!enableBones) {
|
||||
@@ -652,10 +662,12 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
||||
|
||||
// Final view and projection transforms.
|
||||
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, " gl_Position = depthRoundZVP(u_proj * viewPos);\n");
|
||||
WRITE(p, " vec4 outPos = depthRoundZVP(u_proj * viewPos);\n");
|
||||
} else {
|
||||
WRITE(p, " gl_Position = u_proj * viewPos;\n");
|
||||
WRITE(p, " vec4 outPos = u_proj * viewPos;\n");
|
||||
}
|
||||
WriteGuardBand(p);
|
||||
WRITE(p, " gl_Position = outPos;\n");
|
||||
|
||||
// TODO: Declare variables for dots for shade mapping if needed.
|
||||
|
||||
|
||||
+6
-6
@@ -172,12 +172,12 @@ const CommonCommandTableEntry commonCommandTable[] = {
|
||||
{ GE_CMD_ANTIALIASENABLE, FLAG_FLUSHBEFOREONCHANGE },
|
||||
|
||||
// Viewport.
|
||||
{ GE_CMD_OFFSETX, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VIEWPORTSCISSOR_STATE },
|
||||
{ GE_CMD_OFFSETY, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VIEWPORTSCISSOR_STATE },
|
||||
{ GE_CMD_VIEWPORTXSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_VIEWPORTSCISSOR_STATE },
|
||||
{ GE_CMD_VIEWPORTYSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_VIEWPORTSCISSOR_STATE },
|
||||
{ GE_CMD_VIEWPORTXCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_VIEWPORTSCISSOR_STATE },
|
||||
{ GE_CMD_VIEWPORTYCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_VIEWPORTSCISSOR_STATE },
|
||||
{ GE_CMD_OFFSETX, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_GUARDBAND},
|
||||
{ GE_CMD_OFFSETY, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_GUARDBAND},
|
||||
{ GE_CMD_VIEWPORTXSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_GUARDBAND},
|
||||
{ GE_CMD_VIEWPORTYSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_GUARDBAND},
|
||||
{ GE_CMD_VIEWPORTXCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_GUARDBAND},
|
||||
{ GE_CMD_VIEWPORTYCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_GUARDBAND},
|
||||
{ GE_CMD_VIEWPORTZSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_DEPTHRANGE | DIRTY_PROJMATRIX | DIRTY_VIEWPORTSCISSOR_STATE },
|
||||
{ GE_CMD_VIEWPORTZCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_DEPTHRANGE | DIRTY_PROJMATRIX | DIRTY_VIEWPORTSCISSOR_STATE },
|
||||
{ GE_CMD_CLIPENABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VIEWPORTSCISSOR_STATE },
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <map>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/stringutil.h"
|
||||
#include "math/lin/matrix4x4.h"
|
||||
#include "math/math_util.h"
|
||||
#include "math/dataconv.h"
|
||||
@@ -64,7 +65,7 @@ VulkanFragmentShader::VulkanFragmentShader(VulkanContext *vulkan, ShaderID id, c
|
||||
#ifdef SHADERLOG
|
||||
OutputDebugStringA("Messages:\n");
|
||||
OutputDebugStringA(errorMessage.c_str());
|
||||
OutputDebugStringA(code);
|
||||
OutputDebugStringA(LineNumberString(code).c_str());
|
||||
#endif
|
||||
Reporting::ReportMessage("Vulkan error in shader compilation: info: %s / code: %s", errorMessage.c_str(), code);
|
||||
} else {
|
||||
|
||||
@@ -47,11 +47,7 @@ static const char *vulkan_glsl_preamble =
|
||||
// texcoord = 2
|
||||
// fog = 3
|
||||
|
||||
|
||||
|
||||
|
||||
#undef WRITE
|
||||
|
||||
#define WRITE p+=sprintf
|
||||
|
||||
static const char * const boneWeightDecl[9] = {
|
||||
@@ -72,6 +68,13 @@ enum DoLightComputation {
|
||||
LIGHT_FULL,
|
||||
};
|
||||
|
||||
static void WriteGuardBand(char *&p) {
|
||||
WRITE(p, " vec3 projPos = outPos.xyz / outPos.w; \n");
|
||||
WRITE(p, " if (outPos.w >= base.guardband.z) {\n");
|
||||
WRITE(p, " if (abs(projPos.x) > base.guardband.x || projPos.y < -base.guardband.y) outPos.w = base.guardband.w;\n");
|
||||
WRITE(p, " }\n");
|
||||
}
|
||||
|
||||
// Depth range and viewport
|
||||
//
|
||||
// After the multiplication with the projection matrix, we have a 4D vector in clip space.
|
||||
@@ -317,15 +320,17 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer, bool *uses
|
||||
WRITE(p, " v_fogdepth = position.w;\n");
|
||||
}
|
||||
if (isModeThrough) {
|
||||
WRITE(p, " gl_Position = base.proj_through_mtx * vec4(position.xyz, 1.0);\n");
|
||||
WRITE(p, " vec4 outPos = base.proj_through_mtx * vec4(position.xyz, 1.0);\n");
|
||||
} else {
|
||||
// The viewport is used in this case, so need to compensate for that.
|
||||
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, " gl_Position = depthRoundZVP(base.proj_mtx * vec4(position.xyz, 1.0));\n");
|
||||
WRITE(p, " vec4 outPos = depthRoundZVP(base.proj_mtx * vec4(position.xyz, 1.0));\n");
|
||||
} else {
|
||||
WRITE(p, " gl_Position = base.proj_mtx * vec4(position.xyz, 1.0);\n");
|
||||
WRITE(p, " vec4 outPos = base.proj_mtx * vec4(position.xyz, 1.0);\n");
|
||||
}
|
||||
}
|
||||
WriteGuardBand(p);
|
||||
WRITE(p, " gl_Position = outPos;\n");
|
||||
} else {
|
||||
// Step 1: World Transform / Skinning
|
||||
if (!enableBones) {
|
||||
@@ -469,10 +474,12 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer, bool *uses
|
||||
|
||||
// Final view and projection transforms.
|
||||
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, " gl_Position = depthRoundZVP(base.proj_mtx * viewPos);\n");
|
||||
WRITE(p, " vec4 outPos = depthRoundZVP(base.proj_mtx * viewPos);\n");
|
||||
} else {
|
||||
WRITE(p, " gl_Position = base.proj_mtx * viewPos;\n");
|
||||
WRITE(p, " vec4 outPos = base.proj_mtx * viewPos;\n");
|
||||
}
|
||||
WriteGuardBand(p);
|
||||
WRITE(p, " gl_Position = outPos;\n");
|
||||
|
||||
// TODO: Declare variables for dots for shade mapping if needed.
|
||||
|
||||
|
||||
Reference in new issue
Block a user