Merge pull request #7573 from unknownbrackets/gpu-minor

Small optimizations to software transform
This commit is contained in:
Henrik Rydgård 2015-03-09 09:59:45 +01:00
commit 9db4c5f34d
9 changed files with 91 additions and 51 deletions

View file

@ -158,7 +158,7 @@ void SoftwareTransform(
// not really sure what a sensible value might be.
fog_slope = fog_slope < 0.0f ? -10000.0f : 10000.0f;
}
if (my_isnan(fog_slope)) {
if (my_isnan(fog_slope)) {
// 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
@ -170,34 +170,50 @@ void SoftwareTransform(
VertexReader reader(decoded, decVtxFormat, vertType);
// We flip in the fragment shader for GE_TEXMAP_TEXTURE_MATRIX.
const bool flipV = gstate_c.flipTexture && gstate.getUVGenMode() != GE_TEXMAP_TEXTURE_MATRIX;
for (int index = 0; index < maxIndex; index++) {
reader.Goto(index);
float v[3] = {0, 0, 0};
Vec4f c0 = Vec4f(1, 1, 1, 1);
Vec4f c1 = Vec4f(0, 0, 0, 0);
float uv[3] = {0, 0, 1};
float fogCoef = 1.0f;
if (throughmode) {
if (throughmode) {
for (int index = 0; index < maxIndex; index++) {
// Do not touch the coordinates or the colors. No lighting.
reader.ReadPos(v);
reader.Goto(index);
// TODO: Write to a flexible buffer, we don't always need all four components.
TransformedVertex &vert = transformed[index];
reader.ReadPos(vert.pos);
if (reader.hasColor0()) {
reader.ReadColor0(&c0.x);
// c1 is already 0.
reader.ReadColor0_8888(vert.color0);
} else {
c0 = Vec4f::FromRGBA(gstate.getMaterialAmbientRGBA());
vert.color0_32 = gstate.getMaterialAmbientRGBA();
}
if (reader.hasUV()) {
reader.ReadUV(uv);
reader.ReadUV(vert.uv);
uv[0] *= uscale;
uv[1] *= vscale;
vert.u *= uscale;
vert.v *= vscale;
}
else
{
vert.u = 0.0f;
vert.v = 0.0f;
}
fogCoef = 1.0f;
// Scale UV?
} else {
if (flipV) {
vert.v = 1.0f - vert.v;
}
// Ignore color1 and fog, never used in throughmode anyway.
// The w of uv is also never used (hardcoded to 1.0.)
}
} else {
for (int index = 0; index < maxIndex; index++) {
reader.Goto(index);
float v[3] = {0, 0, 0};
Vec4f c0 = Vec4f(1, 1, 1, 1);
Vec4f c1 = Vec4f(0, 0, 0, 0);
float uv[3] = {0, 0, 1};
float fogCoef = 1.0f;
// We do software T&L for now
float out[3];
float pos[3];
@ -369,17 +385,17 @@ void SoftwareTransform(
// Transform the coord by the view matrix.
Vec3ByMatrix43(v, out, gstate.viewMatrix);
fogCoef = (v[2] + fog_end) * fog_slope;
}
// TODO: Write to a flexible buffer, we don't always need all four components.
memcpy(&transformed[index].x, v, 3 * sizeof(float));
transformed[index].fog = fogCoef;
memcpy(&transformed[index].u, uv, 3 * sizeof(float));
if (flipV) {
transformed[index].v = 1.0f - transformed[index].v;
// TODO: Write to a flexible buffer, we don't always need all four components.
memcpy(&transformed[index].x, v, 3 * sizeof(float));
transformed[index].fog = fogCoef;
memcpy(&transformed[index].u, uv, 3 * sizeof(float));
if (flipV) {
transformed[index].v = 1.0f - transformed[index].v;
}
transformed[index].color0_32 = c0.ToRGBA();
transformed[index].color1_32 = c1.ToRGBA();
}
transformed[index].color0_32 = c0.ToRGBA();
transformed[index].color1_32 = c1.ToRGBA();
}
// Here's the best opportunity to try to detect rectangles used to clear the screen, and

View file

@ -75,8 +75,18 @@ struct DecVtxFormat {
// This struct too.
struct TransformedVertex
{
float x, y, z, fog; // in case of morph, preblend during decode
float u; float v; float w; // scaled by uscale, vscale, if there
union {
struct {
float x, y, z, fog; // in case of morph, preblend during decode
};
float pos[4];
};
union {
struct {
float u; float v; float w; // scaled by uscale, vscale, if there
};
float uv[3];
};
union {
u8 color0[4]; // prelit
u32 color0_32;

View file

@ -416,7 +416,7 @@ void ComputeFragmentShaderIDDX9(FragmentShaderIDDX9 *id) {
// We only need one clear shader, so let's ignore the rest of the bits.
id0 = 1;
} else {
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled();
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled() && !gstate.isModeThrough();
bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough();
bool enableAlphaTest = gstate.isAlphaTestEnabled() && !IsAlphaTestTriviallyTrue() && !g_Config.bDisableAlphaTest;
bool enableColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue();
@ -504,7 +504,7 @@ void ComputeFragmentShaderIDDX9(FragmentShaderIDDX9 *id) {
void GenerateFragmentShaderDX9(char *buffer) {
char *p = buffer;
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled();
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled() && !gstate.isModeThrough();
bool doTexture = gstate.isTextureMapEnabled() && !gstate.isModeClear();
bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough() && !gstate.isModeClear();
bool enableAlphaTest = gstate.isAlphaTestEnabled() && !IsAlphaTestTriviallyTrue() && !gstate.isModeClear() && !g_Config.bDisableAlphaTest;

View file

@ -133,7 +133,7 @@ void GenerateVertexShaderDX9(int prim, char *buffer, bool useHWTransform) {
char *p = buffer;
const u32 vertType = gstate.vertType;
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled();
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled() && !gstate.isModeThrough();
bool doTexture = gstate.isTextureMapEnabled() && !gstate.isModeClear();
bool doTextureProjection = gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_MATRIX;
bool doShadeMapping = gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP;
@ -232,10 +232,7 @@ void GenerateVertexShaderDX9(int prim, char *buffer, bool useHWTransform) {
WRITE(p, "%s", boneWeightAttrDecl[TranslateNumBones(vertTypeGetNumBoneWeights(vertType))]);
}
if (doTexture && hasTexcoord) {
if (doTextureProjection)
WRITE(p, " float3 texcoord : TEXCOORD0;\n");
else
WRITE(p, " float2 texcoord : TEXCOORD0;\n");
WRITE(p, " float2 texcoord : TEXCOORD0;\n");
}
if (hasColor) {
WRITE(p, " float4 color0 : COLOR0;\n");
@ -249,10 +246,19 @@ void GenerateVertexShaderDX9(int prim, char *buffer, bool useHWTransform) {
} else {
WRITE(p, "struct VS_IN {\n");
WRITE(p, " float4 position : POSITION;\n");
WRITE(p, " float3 texcoord : TEXCOORD0;\n");
WRITE(p, " float4 color0 : COLOR0;\n");
if (doTexture && hasTexcoord) {
if (doTextureProjection && !throughmode)
WRITE(p, " float3 texcoord : TEXCOORD0;\n");
else
WRITE(p, " float2 texcoord : TEXCOORD0;\n");
}
if (hasColor) {
WRITE(p, " float4 color0 : COLOR0;\n");
}
// only software transform supplies color1 as vertex data
WRITE(p, " float4 color1 : COLOR1;\n");
if (lmode) {
WRITE(p, " float4 color1 : COLOR1;\n");
}
WRITE(p, "};\n");
}
@ -265,7 +271,7 @@ void GenerateVertexShaderDX9(int prim, char *buffer, bool useHWTransform) {
WRITE(p, " float2 v_texcoord: TEXCOORD0;\n");
}
WRITE(p, " float4 v_color0 : COLOR0;\n");
if (lmode)
if (lmode)
WRITE(p, " float3 v_color1 : COLOR1;\n");
if (enableFog) {
@ -279,7 +285,11 @@ void GenerateVertexShaderDX9(int prim, char *buffer, bool useHWTransform) {
// Simple pass-through of vertex data to fragment shader
if (doTexture) {
if (doTextureProjection) {
WRITE(p, " Out.v_texcoord = In.texcoord;\n");
if (throughmode) {
WRITE(p, " Out.v_texcoord = float3(In.texcoord.x, In.texcoord.y, 1.0);\n");
} else {
WRITE(p, " Out.v_texcoord = In.texcoord;\n");
}
} else {
WRITE(p, " Out.v_texcoord = In.texcoord.xy;\n");
}

View file

@ -209,7 +209,7 @@ GLuint DepalShaderCache::GetDepalettizeShader(GEBufferFormat pixelFormat) {
GLint u_pal = glGetUniformLocation(program, "pal");
glUniform1i(u_tex, 0);
glUniform1i(u_pal, 1);
glUniform1i(u_pal, 3);
GLint linkStatus = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);

View file

@ -398,7 +398,7 @@ void ComputeFragmentShaderID(ShaderID *id) {
// We only need one clear shader, so let's ignore the rest of the bits.
id0 = 1;
} else {
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled();
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled() && !gstate.isModeThrough();
bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough();
bool enableAlphaTest = gstate.isAlphaTestEnabled() && !IsAlphaTestTriviallyTrue() && !g_Config.bDisableAlphaTest;
bool enableColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue();
@ -571,7 +571,7 @@ void GenerateFragmentShader(char *buffer) {
varying = "in";
}
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled();
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled() && !gstate.isModeThrough();
bool doTexture = gstate.isTextureMapEnabled() && !gstate.isModeClear();
bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough() && !gstate.isModeClear();
bool enableAlphaTest = gstate.isAlphaTestEnabled() && !IsAlphaTestTriviallyTrue() && !gstate.isModeClear() && !g_Config.bDisableAlphaTest;

View file

@ -979,7 +979,7 @@ void FramebufferManager::BindFramebufferColor(int stage, VirtualFramebuffer *fra
fbo_bind_color_as_texture(framebuffer->fbo, 0);
}
if (stage != GL_TEXTURE1) {
if (stage != GL_TEXTURE0) {
glActiveTexture(stage);
}
}

View file

@ -1109,7 +1109,7 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffe
glEnableVertexAttribArray(a_position);
glEnableVertexAttribArray(a_texcoord0);
glActiveTexture(GL_TEXTURE1);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, clutTexture);
glActiveTexture(GL_TEXTURE0);

View file

@ -214,7 +214,7 @@ void GenerateVertexShader(int prim, u32 vertType, char *buffer, bool useHWTransf
boneWeightDecl = boneWeightInDecl;
}
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled();
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled() && !gstate.isModeThrough();
bool doTexture = gstate.isTextureMapEnabled() && !gstate.isModeClear();
bool doTextureProjection = gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_MATRIX;
bool doShadeMapping = gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP;
@ -257,7 +257,7 @@ void GenerateVertexShader(int prim, u32 vertType, char *buffer, bool useHWTransf
WRITE(p, "%s mediump vec3 normal;\n", attribute);
if (doTexture && hasTexcoord) {
if (!useHWTransform && doTextureProjection)
if (!useHWTransform && doTextureProjection && !throughmode)
WRITE(p, "%s vec3 texcoord;\n", attribute);
else
WRITE(p, "%s vec2 texcoord;\n", attribute);
@ -362,7 +362,11 @@ void GenerateVertexShader(int prim, u32 vertType, char *buffer, bool useHWTransf
if (!useHWTransform) {
// Simple pass-through of vertex data to fragment shader
if (doTexture) {
WRITE(p, " v_texcoord = texcoord;\n");
if (throughmode && doTextureProjection) {
WRITE(p, " v_texcoord = vec3(texcoord, 1.0);\n");
} else {
WRITE(p, " v_texcoord = texcoord;\n");
}
}
if (hasColor) {
WRITE(p, " v_color0 = color0;\n");