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

@ -170,6 +170,41 @@ 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;
if (throughmode) {
for (int index = 0; index < maxIndex; index++) {
// Do not touch the coordinates or the colors. No lighting.
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_8888(vert.color0);
} else {
vert.color0_32 = gstate.getMaterialAmbientRGBA();
}
if (reader.hasUV()) {
reader.ReadUV(vert.uv);
vert.u *= uscale;
vert.v *= vscale;
}
else
{
vert.u = 0.0f;
vert.v = 0.0f;
}
// Scale UV?
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);
@ -179,25 +214,6 @@ void SoftwareTransform(
float uv[3] = {0, 0, 1};
float fogCoef = 1.0f;
if (throughmode) {
// Do not touch the coordinates or the colors. No lighting.
reader.ReadPos(v);
if (reader.hasColor0()) {
reader.ReadColor0(&c0.x);
// c1 is already 0.
} else {
c0 = Vec4f::FromRGBA(gstate.getMaterialAmbientRGBA());
}
if (reader.hasUV()) {
reader.ReadUV(uv);
uv[0] *= uscale;
uv[1] *= vscale;
}
fogCoef = 1.0f;
// Scale UV?
} else {
// We do software T&L for now
float out[3];
float pos[3];
@ -369,7 +385,6 @@ 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));
@ -381,6 +396,7 @@ void SoftwareTransform(
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
// replace them with real clears. This can provide a speedup on certain mobile chips.

View file

@ -75,8 +75,18 @@ struct DecVtxFormat {
// This struct too.
struct TransformedVertex
{
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,9 +232,6 @@ 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");
}
if (hasColor) {
@ -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");
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
if (lmode) {
WRITE(p, " float4 color1 : COLOR1;\n");
}
WRITE(p, "};\n");
}
@ -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) {
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,8 +362,12 @@ void GenerateVertexShader(int prim, u32 vertType, char *buffer, bool useHWTransf
if (!useHWTransform) {
// Simple pass-through of vertex data to fragment shader
if (doTexture) {
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");
if (lmode)