mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-12 17:19:28 +01:00
Merge pull request #16112 from hrydgard/dynamic-matupdate
Fold the "materialUpdate" flag into the light-ubershader
This commit is contained in:
8 files changed
+48
-26
No files matched your search
@@ -93,4 +93,3 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugUtilsCallback(
|
||||
// keep that behavior here.
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -174,9 +174,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
WRITE(p, "layout (location = 1) %s in lowp vec4 v_color0;\n", shading);
|
||||
if (lmode)
|
||||
WRITE(p, "layout (location = 2) %s in lowp vec3 v_color1;\n", shading);
|
||||
if (enableFog) {
|
||||
WRITE(p, "layout (location = 3) in highp float v_fogdepth;\n");
|
||||
}
|
||||
WRITE(p, "layout (location = 3) in highp float v_fogdepth;\n");
|
||||
if (doTexture) {
|
||||
WRITE(p, "layout (location = 0) in highp vec3 v_texcoord;\n");
|
||||
}
|
||||
@@ -279,9 +277,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
if (lmode) {
|
||||
WRITE(p, " vec3 v_color1: COLOR1;\n");
|
||||
}
|
||||
if (enableFog) {
|
||||
WRITE(p, " float v_fogdepth: TEXCOORD1;\n");
|
||||
}
|
||||
WRITE(p, " float v_fogdepth: TEXCOORD1;\n");
|
||||
if (needFragCoord) {
|
||||
if (compat.shaderLanguage == HLSL_D3D11) {
|
||||
WRITE(p, " vec4 pixelPos : SV_POSITION;\n");
|
||||
@@ -394,8 +390,8 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
if (enableFog) {
|
||||
*uniformMask |= DIRTY_FOGCOLOR;
|
||||
WRITE(p, "uniform vec3 u_fogcolor;\n");
|
||||
WRITE(p, "%s %s float v_fogdepth;\n", compat.varying_fs, highpFog ? "highp" : "mediump");
|
||||
}
|
||||
WRITE(p, "%s %s float v_fogdepth;\n", compat.varying_fs, highpFog ? "highp" : "mediump");
|
||||
if (doTexture) {
|
||||
WRITE(p, "%s %s vec3 v_texcoord;\n", compat.varying_fs, highpTexcoord ? "highp" : "mediump");
|
||||
}
|
||||
|
||||
@@ -123,11 +123,11 @@ void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform,
|
||||
|
||||
if (gstate.isLightingEnabled()) {
|
||||
// doShadeMapping is stored as UVGenMode, and light type doesn't matter for shade mapping.
|
||||
id.SetBits(VS_BIT_MATERIAL_UPDATE, 3, gstate.getMaterialUpdate());
|
||||
id.SetBit(VS_BIT_LIGHTING_ENABLE);
|
||||
if (gstate_c.Supports(GPU_USE_LIGHT_UBERSHADER)) {
|
||||
id.SetBit(VS_BIT_LIGHT_UBERSHADER);
|
||||
} else {
|
||||
id.SetBits(VS_BIT_MATERIAL_UPDATE, 3, gstate.getMaterialUpdate());
|
||||
// Light bits
|
||||
for (int i = 0; i < 4; i++) {
|
||||
bool chanEnabled = gstate.isLightChanEnabled(i) != 0;
|
||||
@@ -248,6 +248,9 @@ std::string FragmentShaderDesc(const FShaderID &id) {
|
||||
else if (id.Bit(FS_BIT_ALPHA_TEST)) desc << "AlphaTest " << alphaTestFuncs[id.Bits(FS_BIT_ALPHA_TEST_FUNC, 3)] << " ";
|
||||
if (id.Bit(FS_BIT_COLOR_AGAINST_ZERO)) desc << "ColorTest0 " << alphaTestFuncs[id.Bits(FS_BIT_COLOR_TEST_FUNC, 2)] << " "; // first 4 match;
|
||||
else if (id.Bit(FS_BIT_COLOR_TEST)) desc << "ColorTest " << alphaTestFuncs[id.Bits(FS_BIT_COLOR_TEST_FUNC, 2)] << " "; // first 4 match
|
||||
if (id.Bit(FS_BIT_TEST_DISCARD_TO_ZERO)) desc << "TestDiscardToZero ";
|
||||
if (id.Bit(FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL)) desc << "StencilDiscardWorkaround ";
|
||||
if (id.Bits(FS_BIT_REPLACE_LOGIC_OP, 4) != GE_LOGIC_COPY) desc << "ReplaceLogic ";
|
||||
|
||||
return desc.str();
|
||||
}
|
||||
|
||||
@@ -271,6 +271,8 @@ uint32_t PackLightControlBits() {
|
||||
// Bit organization
|
||||
// Bottom 4 bits are enable bits for each light.
|
||||
// Then, for each light, comes 2 bits for "comp" and 2 bits for "type".
|
||||
// At the end, at bit 20, we put the three material update bits.
|
||||
|
||||
uint32_t lightControl = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (gstate.isLightChanEnabled(i)) {
|
||||
@@ -282,6 +284,9 @@ uint32_t PackLightControlBits() {
|
||||
lightControl |= computation << (4 + i * 4);
|
||||
lightControl |= type << (4 + i * 4 + 2);
|
||||
}
|
||||
|
||||
lightControl |= gstate.getMaterialUpdate() << 20;
|
||||
|
||||
return lightControl;
|
||||
}
|
||||
|
||||
|
||||
@@ -552,7 +552,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
if (enableLighting) {
|
||||
WRITE(p, "uniform lowp vec4 u_ambient;\n");
|
||||
*uniformMask |= DIRTY_AMBIENT;
|
||||
if ((matUpdate & 2) == 0 || !hasColor) {
|
||||
if (lightUberShader || (matUpdate & 2) == 0 || !hasColor) {
|
||||
WRITE(p, "uniform lowp vec3 u_matdiffuse;\n");
|
||||
*uniformMask |= DIRTY_MATDIFFUSE;
|
||||
}
|
||||
@@ -949,14 +949,25 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
|
||||
// TODO: Declare variables for dots for shade mapping if needed.
|
||||
|
||||
const char *ambientStr = (matUpdate & 1) && hasColor ? "color0" : "u_matambientalpha";
|
||||
const char *diffuseStr = (matUpdate & 2) && hasColor ? "color0.rgb" : "u_matdiffuse";
|
||||
const char *specularStr = (matUpdate & 4) && hasColor ? "color0.rgb" : "u_matspecular.rgb";
|
||||
const char *srcCol = "color0";
|
||||
if (doBezier || doSpline) {
|
||||
// TODO: Probably, should use hasColorTess but FF4 has a problem with drawing the background.
|
||||
ambientStr = (matUpdate & 1) && hasColor ? "tess.col" : "u_matambientalpha";
|
||||
diffuseStr = (matUpdate & 2) && hasColor ? "tess.col.rgb" : "u_matdiffuse";
|
||||
specularStr = (matUpdate & 4) && hasColor ? "tess.col.rgb" : "u_matspecular.rgb";
|
||||
srcCol = "tess.col";
|
||||
}
|
||||
|
||||
if (lightUberShader && hasColor) {
|
||||
p.F(" vec4 ambientColor = ((u_lightControl & (1u << 20u)) != 0u) ? %s : u_matambientalpha;\n", srcCol);
|
||||
if (enableLighting) {
|
||||
p.F(" vec3 diffuseColor = ((u_lightControl & (1u << 21u)) != 0u) ? %s.rgb : u_matdiffuse;\n", srcCol);
|
||||
p.F(" vec3 specularColor = ((u_lightControl & (1u << 22u)) != 0u) ? %s.rgb : u_matspecular.rgb;\n", srcCol);
|
||||
}
|
||||
} else {
|
||||
// This path also takes care of the lightUberShader && !hasColor path, because all comparisons fail.
|
||||
p.F(" vec4 ambientColor = %s;\n", (matUpdate & 1) && hasColor ? srcCol : "u_matambientalpha");
|
||||
if (enableLighting) {
|
||||
p.F(" vec3 diffuseColor = %s.rgb;\n", (matUpdate & 2) && hasColor ? srcCol : "u_matdiffuse");
|
||||
p.F(" vec3 specularColor = %s.rgb;\n", (matUpdate & 4) && hasColor ? srcCol : "u_matspecular");
|
||||
}
|
||||
}
|
||||
|
||||
bool diffuseIsZero = true;
|
||||
@@ -964,7 +975,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
bool distanceNeeded = false;
|
||||
bool anySpots = false;
|
||||
if (enableLighting) {
|
||||
WRITE(p, " lowp vec4 lightSum0 = u_ambient * %s + vec4(u_matemissive, 0.0);\n", ambientStr);
|
||||
p.C(" lowp vec4 lightSum0 = u_ambient * ambientColor + vec4(u_matemissive, 0.0);\n");
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
GELightType type = static_cast<GELightType>(id.Bits(VS_BIT_LIGHT0_TYPE + 4*i, 2));
|
||||
@@ -1043,7 +1054,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
p.C(" lightScale = 1.0;\n");
|
||||
p.C(" break;\n");
|
||||
p.C(" }\n");
|
||||
p.F(" diffuse = (u_lightdiffuse%i * %s) * max(ldot, 0.0);\n", i, diffuseStr);
|
||||
p.F(" diffuse = (u_lightdiffuse%i * diffuseColor) * max(ldot, 0.0);\n", i);
|
||||
p.C(" if (comp == 1u) {\n"); // do specular
|
||||
p.C(" if (ldot >= 0.0) {\n");
|
||||
p.C(" ldot = dot(normalize(toLight + vec3(0.0, 0.0, 1.0)), worldnormal);\n");
|
||||
@@ -1053,10 +1064,10 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
p.C(" ldot = pow(max(ldot, 0.0), u_matspecular.a);\n");
|
||||
p.C(" }\n");
|
||||
p.C(" if (ldot > 0.0)\n");
|
||||
p.F(" lightSum1 += u_lightspecular%i * %s * ldot * lightScale;\n", i, specularStr);
|
||||
p.F(" lightSum1 += u_lightspecular%i * specularColor * ldot * lightScale;\n", i);
|
||||
p.C(" }\n");
|
||||
p.C(" }\n");
|
||||
p.F(" lightSum0.rgb += (u_lightambient%i * %s.rgb + diffuse) * lightScale;\n", i, ambientStr);
|
||||
p.F(" lightSum0.rgb += (u_lightambient%i * ambientColor.rgb + diffuse) * lightScale;\n", i);
|
||||
p.C(" }\n");
|
||||
}
|
||||
} else {
|
||||
@@ -1116,7 +1127,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
break;
|
||||
}
|
||||
|
||||
p.F(" diffuse = (u_lightdiffuse%i * %s) * max(ldot, 0.0);\n", i, diffuseStr);
|
||||
p.F(" diffuse = (u_lightdiffuse%i * diffuseColor) * max(ldot, 0.0);\n", i);
|
||||
if (doSpecular) {
|
||||
p.C(" if (ldot >= 0.0) {\n");
|
||||
p.C(" ldot = dot(normalize(toLight + vec3(0.0, 0.0, 1.0)), worldnormal);\n");
|
||||
@@ -1126,10 +1137,10 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
p.C(" ldot = pow(max(ldot, 0.0), u_matspecular.a);\n");
|
||||
p.C(" }\n");
|
||||
p.C(" if (ldot > 0.0)\n");
|
||||
p.F(" lightSum1 += u_lightspecular%i * %s * ldot %s;\n", i, specularStr, timesLightScale);
|
||||
p.F(" lightSum1 += u_lightspecular%i * specularColor * ldot %s;\n", i, timesLightScale);
|
||||
p.C(" }\n");
|
||||
}
|
||||
p.F(" lightSum0.rgb += (u_lightambient%i * %s.rgb + diffuse)%s;\n", i, ambientStr, timesLightScale);
|
||||
p.F(" lightSum0.rgb += (u_lightambient%i * ambientColor.rgb + diffuse)%s;\n", i, timesLightScale);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-1
@@ -111,7 +111,7 @@ const CommonCommandTableEntry commonCommandTable[] = {
|
||||
{ GE_CMD_LIGHTTYPE1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE | DIRTY_LIGHT1 },
|
||||
{ GE_CMD_LIGHTTYPE2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE | DIRTY_LIGHT2 },
|
||||
{ GE_CMD_LIGHTTYPE3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE | DIRTY_LIGHT3 },
|
||||
{ GE_CMD_MATERIALUPDATE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE }, // TODO: This should not need to dirty the fragment shader?
|
||||
{ GE_CMD_MATERIALUPDATE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE },
|
||||
|
||||
// These change both shaders so need flushing.
|
||||
{ GE_CMD_LIGHTMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE },
|
||||
@@ -465,6 +465,14 @@ void GPUCommon::UpdateCmdInfo() {
|
||||
cmdInfo_[GE_CMD_LIGHTTYPE0 + i].AddDirty(DIRTY_VERTEXSHADER_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
if (gstate_c.Supports(GPU_USE_LIGHT_UBERSHADER)) {
|
||||
cmdInfo_[GE_CMD_MATERIALUPDATE].RemoveDirty(DIRTY_VERTEXSHADER_STATE);
|
||||
cmdInfo_[GE_CMD_MATERIALUPDATE].AddDirty(DIRTY_LIGHT_CONTROL);
|
||||
} else {
|
||||
cmdInfo_[GE_CMD_MATERIALUPDATE].RemoveDirty(DIRTY_LIGHT_CONTROL);
|
||||
cmdInfo_[GE_CMD_MATERIALUPDATE].AddDirty(DIRTY_VERTEXSHADER_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
void GPUCommon::BeginHostFrame() {
|
||||
|
||||
@@ -376,7 +376,7 @@ VulkanFragmentShader *ShaderManagerVulkan::GetFragmentShaderFromModule(VkShaderM
|
||||
// instantaneous.
|
||||
|
||||
#define CACHE_HEADER_MAGIC 0xff51f420
|
||||
#define CACHE_VERSION 27
|
||||
#define CACHE_VERSION 28
|
||||
struct VulkanCacheHeader {
|
||||
uint32_t magic;
|
||||
uint32_t version;
|
||||
|
||||
@@ -447,7 +447,7 @@ void FormatStateRow(wchar_t *dest, const TabStateRow &info, u32 value, bool enab
|
||||
swprintf(dest, 255, L"%S", texformats[value]);
|
||||
}
|
||||
else if ((value & 0xF) < (u32)ARRAY_SIZE(texformats)) {
|
||||
swprintf(dest, 255, L"%S (extra bits %06x)", texformats[value & 0xF], value);
|
||||
swprintf(dest, 255, L"%S (extra bits %06x)", texformats[value & 0xF], value & ~0xF);
|
||||
}
|
||||
else {
|
||||
swprintf(dest, 255, L"%06x", value);
|
||||
|
||||
Reference in new issue
Block a user