d3d9: Update some not-yet-used ps uniforms.

This commit is contained in:
Unknown W. Brackets 2014-09-21 10:41:44 -07:00
parent 9355322824
commit e3d6f19a2e
4 changed files with 108 additions and 21 deletions

View File

@ -57,8 +57,14 @@ bool IsColorTestTriviallyTrue();
#define CONST_PS_ALPHACOLORREF 1
#define CONST_PS_ALPHACOLORMASK 2
#define CONST_PS_FOGCOLOR 3
#define CONST_PS_STENCILREPLACE 4
#define CONST_PS_BLENDFIXA 5
#define CONST_PS_BLENDFIXB 6
#define CONST_PS_FBOTEXSIZE 7
#define CONST_PS_TEXCLAMP 8
#define CONST_PS_TEXCLAMPOFF 9
// For stencil upload
#define CONST_PS_STENCILVALUE 4
#define CONST_PS_STENCILVALUE 10
};

View File

@ -26,6 +26,7 @@
#include "util/text/utf8.h"
#include "Common/Common.h"
#include "Core/Config.h"
#include "Core/Reporting.h"
#include "GPU/Math3D.h"
#include "GPU/GPUState.h"
@ -137,6 +138,19 @@ void ShaderManagerDX9::PSSetColorUniform3Alpha255(int creg, u32 color, u8 alpha)
pD3Ddevice->SetPixelShaderConstantF(creg, col, 1);
}
void ShaderManagerDX9::PSSetFloat(int creg, float value) {
const float f[4] = { value, 0.0f, 0.0f, 0.0f };
pD3Ddevice->SetPixelShaderConstantF(creg, f, 1);
}
void ShaderManagerDX9::PSSetFloatArray(int creg, const float *value, int count) {
float f[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
for (int i = 0; i < count; i++) {
f[i] = value[i];
}
pD3Ddevice->SetPixelShaderConstantF(creg, f, 1);
}
void ShaderManagerDX9::VSSetFloat(int creg, float value) {
const float f[4] = { value, 0.0f, 0.0f, 0.0f };
pD3Ddevice->SetVertexShaderConstantF(creg, f, 1);
@ -231,6 +245,43 @@ void ShaderManagerDX9::PSUpdateUniforms(int dirtyUniforms) {
if (dirtyUniforms & DIRTY_FOGCOLOR) {
PSSetColorUniform3(CONST_PS_FOGCOLOR, gstate.fogcolor);
}
if (dirtyUniforms & DIRTY_STENCILREPLACEVALUE) {
PSSetFloat(CONST_PS_STENCILREPLACE, (float)gstate.getStencilTestRef() * (1.0f / 255.0f));
}
if (dirtyUniforms & DIRTY_SHADERBLEND) {
PSSetColorUniform3(CONST_PS_BLENDFIXA, gstate.getFixA());
PSSetColorUniform3(CONST_PS_BLENDFIXB, gstate.getFixB());
const float fbotexSize[2] = {
1.0f / (float)gstate_c.curRTRenderWidth,
1.0f / (float)gstate_c.curRTRenderHeight,
};
PSSetFloatArray(CONST_PS_FBOTEXSIZE, fbotexSize, 2);
}
if (dirtyUniforms & DIRTY_TEXCLAMP) {
const float invW = 1.0f / (float)gstate_c.curTextureWidth;
const float invH = 1.0f / (float)gstate_c.curTextureHeight;
const int w = gstate.getTextureWidth(0);
const int h = gstate.getTextureHeight(0);
const float widthFactor = (float)w * invW;
const float heightFactor = (float)h * invH;
// First wrap xy, then half texel xy (for clamp.)
const float texclamp[4] = {
widthFactor,
heightFactor,
invW * 0.5f,
invH * 0.5f,
};
const float texclampoff[2] = {
gstate_c.curTextureXOffset * invW,
gstate_c.curTextureYOffset * invH,
};
PSSetFloatArray(CONST_PS_TEXCLAMP, texclamp, 4);
PSSetFloatArray(CONST_PS_TEXCLAMPOFF, texclampoff, 2);
}
}
void ShaderManagerDX9::VSUpdateUniforms(int dirtyUniforms) {
@ -278,6 +329,7 @@ void ShaderManagerDX9::VSUpdateUniforms(int dirtyUniforms) {
getFloat24(gstate.fog1),
getFloat24(gstate.fog2),
};
// TODO: Handle NAN/INF?
VSSetFloatArray(CONST_VS_FOGCOEF, fogcoef, 2);
}
// TODO: Could even set all bones in one go if they're all dirty.
@ -315,31 +367,58 @@ void ShaderManagerDX9::VSUpdateUniforms(int dirtyUniforms) {
// Texturing
if (dirtyUniforms & DIRTY_UVSCALEOFFSET) {
const float invW = 1.0f / (float)gstate_c.curTextureWidth;
const float invH = 1.0f / (float)gstate_c.curTextureHeight;
const int w = gstate.getTextureWidth(0);
const int h = gstate.getTextureHeight(0);
const float widthFactor = (float)w * invW;
const float heightFactor = (float)h * invH;
float uvscaleoff[4];
if (gstate.isModeThrough()) {
// We never get here because we don't use HW transform with through mode.
// Although - why don't we?
uvscaleoff[0] = gstate_c.uv.uScale / gstate_c.curTextureWidth;
uvscaleoff[1] = gstate_c.uv.vScale / gstate_c.curTextureHeight;
uvscaleoff[2] = gstate_c.uv.uOff / gstate_c.curTextureWidth;
uvscaleoff[3] = gstate_c.uv.vOff / gstate_c.curTextureHeight;
} else {
int w = gstate.getTextureWidth(0);
int h = gstate.getTextureHeight(0);
float widthFactor = (float)w / (float)gstate_c.curTextureWidth;
float heightFactor = (float)h / (float)gstate_c.curTextureHeight;
switch (gstate.getUVGenMode()) {
case GE_TEXMAP_TEXTURE_COORDS:
// Not sure what GE_TEXMAP_UNKNOWN is, but seen in Riviera. Treating the same as GE_TEXMAP_TEXTURE_COORDS works.
if (gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_COORDS || gstate.getUVGenMode() == GE_TEXMAP_UNKNOWN) {
uvscaleoff[0] = gstate_c.uv.uScale * widthFactor;
uvscaleoff[1] = gstate_c.uv.vScale * heightFactor;
uvscaleoff[2] = gstate_c.uv.uOff * widthFactor;
uvscaleoff[3] = gstate_c.uv.vOff * heightFactor;
} else {
case GE_TEXMAP_UNKNOWN:
if (g_Config.bPrescaleUV) {
// Shouldn't even get here as we won't use the uniform in the shader.
// We are here but are prescaling UV in the decoder? Let's do the same as in the other case
// except consider *Scale and *Off to be 1 and 0.
uvscaleoff[0] = widthFactor;
uvscaleoff[1] = heightFactor;
uvscaleoff[2] = 0.0f;
uvscaleoff[3] = 0.0f;
} else {
uvscaleoff[0] = gstate_c.uv.uScale * widthFactor;
uvscaleoff[1] = gstate_c.uv.vScale * heightFactor;
uvscaleoff[2] = gstate_c.uv.uOff * widthFactor;
uvscaleoff[3] = gstate_c.uv.vOff * heightFactor;
}
break;
// These two work the same whether or not we prescale UV.
case GE_TEXMAP_TEXTURE_MATRIX:
// We cannot bake the UV coord scale factor in here, as we apply a matrix multiplication
// before this is applied, and the matrix multiplication may contain translation. In this case
// the translation will be scaled which breaks faces in Hexyz Force for example.
// So I've gone back to applying the scale factor in the shader.
uvscaleoff[0] = widthFactor;
uvscaleoff[1] = heightFactor;
uvscaleoff[2] = 0.0f;
uvscaleoff[3] = 0.0f;
break;
case GE_TEXMAP_ENVIRONMENT_MAP:
// In this mode we only use uvscaleoff to scale to the texture size.
uvscaleoff[0] = widthFactor;
uvscaleoff[1] = heightFactor;
uvscaleoff[2] = 0.0f;
uvscaleoff[3] = 0.0f;
break;
default:
ERROR_LOG_REPORT(G3D, "Unexpected UV gen mode: %d", gstate.getUVGenMode());
}
VSSetFloatArray(CONST_VS_UVSCALEOFFSET, uvscaleoff, 4);
}

View File

@ -53,7 +53,7 @@ enum {
DIRTY_MATEMISSIVE = (1 << 14),
DIRTY_AMBIENT = (1 << 15),
DIRTY_MATAMBIENTALPHA = (1 << 16),
DIRTY_MATERIAL = (1 << 17), // let's set all 4 together (emissive ambient diffuse specular). We hide specular coef in specular.a
DIRTY_SHADERBLEND = (1 << 17), // Used only for in-shader blending.
DIRTY_UVSCALEOFFSET = (1 << 18), // this will be dirtied ALL THE TIME... maybe we'll need to do "last value with this shader compares"
DIRTY_TEXCLAMP = (1 << 19),
@ -131,6 +131,8 @@ private:
void VSUpdateUniforms(int dirtyUniforms);
void PSSetColorUniform3Alpha255(int creg, u32 color, u8 alpha);
void PSSetColorUniform3(int creg, u32 color);
void PSSetFloat(int creg, float value);
void PSSetFloatArray(int creg, const float *value, int count);
void VSSetMatrix4x3(int creg, const float *m4x3);
void VSSetMatrix4x3_3(int creg, const float *m4x3);

View File

@ -416,7 +416,7 @@ void LinkedShader::UpdateUniforms(u32 vertType) {
if (my_isinf(fogcoef[1])) {
// not really sure what a sensible value might be.
fogcoef[1] = fogcoef[1] < 0.0f ? -10000.0f : 10000.0f;
} else if (my_isnan(fogcoef[1])) {
} else if (my_isnan(fogcoef[1])) {
// Workaround for https://github.com/hrydgard/ppsspp/issues/5384#issuecomment-38365988
// Just put the fog far away at a large finite distance.
// Infinities and NaNs are rather unpredictable in shaders on many GPUs