mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-23 16:19:44 +00:00
Fix rendering on MacOSX (shader compiler very fussy...). Minor prep for hw transform.
This commit is contained in:
parent
67f9f3f73f
commit
700921deb3
@ -21,7 +21,6 @@
|
||||
#define GLSL_1_3
|
||||
#endif
|
||||
|
||||
|
||||
#include "FragmentShaderGenerator.h"
|
||||
#include "../ge_constants.h"
|
||||
#include "../GPUState.h"
|
||||
@ -77,7 +76,9 @@ char *GenerateFragmentShader()
|
||||
|
||||
int lmode = gstate.lmode & 1;
|
||||
|
||||
if (gstate.textureMapEnable & 1)
|
||||
int doTexture = (gstate.textureMapEnable & 1) && !(gstate.clearmode & 1);
|
||||
|
||||
if (doTexture)
|
||||
WRITE(p, "uniform sampler2D tex;\n");
|
||||
if (gstate.alphaTestEnable & 1)
|
||||
WRITE(p, "uniform vec4 u_alpharef;\n");
|
||||
@ -89,7 +90,8 @@ char *GenerateFragmentShader()
|
||||
WRITE(p, "varying vec4 v_color0;\n");
|
||||
if (lmode)
|
||||
WRITE(p, "varying vec4 v_color1;\n");
|
||||
WRITE(p, "varying vec2 v_texcoord;\n");
|
||||
if (doTexture)
|
||||
WRITE(p, "varying vec2 v_texcoord;\n");
|
||||
if (gstate.isFogEnabled())
|
||||
WRITE(p, "varying float v_depth;\n");
|
||||
|
||||
@ -98,6 +100,7 @@ char *GenerateFragmentShader()
|
||||
|
||||
if (gstate.clearmode & 1)
|
||||
{
|
||||
// Clear mode does not allow any fancy shading.
|
||||
WRITE(p, " v = v_color0;\n");
|
||||
}
|
||||
else
|
||||
@ -156,7 +159,7 @@ char *GenerateFragmentShader()
|
||||
if (gstate.texfunc & 0x10000) {
|
||||
WRITE(p, " v = v * vec4(2.0, 2.0, 2.0, 1.0);");
|
||||
}
|
||||
|
||||
|
||||
if (gstate.alphaTestEnable & 1) {
|
||||
int alphaTestFunc = gstate.alphatest & 7;
|
||||
const char *alphaTestFuncs[] = { "#", "#", " == ", " != ", " < ", " <= ", " > ", " >= " }; // never/always don't make sense
|
||||
@ -169,7 +172,6 @@ char *GenerateFragmentShader()
|
||||
// WRITE(p, " v = mix(v, u_fogcolor, u_fogcoef.x + u_fogcoef.y * v_depth;\n");
|
||||
// WRITE(p, " v.x = v_depth;\n");
|
||||
}
|
||||
// Fogging should be added here - and disabled during clear mode
|
||||
}
|
||||
|
||||
WRITE(p, " gl_FragColor = v;\n");
|
||||
|
@ -46,7 +46,7 @@ Shader::Shader(const char *code, uint32_t shaderType) {
|
||||
ERROR_LOG(G3D, "Info log: %s\n", infoLog);
|
||||
ERROR_LOG(G3D, "Shader source:\n%s\n", (const char *)code);
|
||||
} else {
|
||||
//NOTICE_LOG(G3D, "Compiled shader:\n%s\n", (const char *)code);
|
||||
DEBUG_LOG(G3D, "Compiled shader:\n%s\n", (const char *)code);
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,32 +67,30 @@ LinkedShader::LinkedShader(Shader *vs, Shader *fs)
|
||||
glGetProgramInfoLog(program, bufLength, NULL, buf);
|
||||
ERROR_LOG(G3D, "Could not link program:\n %s", buf);
|
||||
delete [] buf; // we're dead!
|
||||
|
||||
//_dbg_assert_msg_(HLE,0,"Could not link program");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
NOTICE_LOG(G3D, "Linked shader!");
|
||||
INFO_LOG(G3D, "Linked shader: vs %i fs %i", (int)vs->shader, (int)fs->shader);
|
||||
|
||||
u_tex = glGetUniformLocation(program, "tex");
|
||||
u_proj = glGetUniformLocation(program, "u_proj");
|
||||
u_tex = glGetUniformLocation(program, "tex");
|
||||
u_proj = glGetUniformLocation(program, "u_proj");
|
||||
u_proj_through = glGetUniformLocation(program, "u_proj_through");
|
||||
u_texenv = glGetUniformLocation(program, "u_texenv");
|
||||
u_fogcolor = glGetUniformLocation(program, "u_fogcolor");
|
||||
u_fogcoef = glGetUniformLocation(program, "u_fogcoef");
|
||||
u_alpharef = glGetUniformLocation(program, "u_alpharef");
|
||||
|
||||
a_position = glGetAttribLocation(program, "a_position");
|
||||
a_color0 = glGetAttribLocation(program, "a_color0");
|
||||
a_color1 = glGetAttribLocation(program, "a_color1");
|
||||
a_texcoord = glGetAttribLocation(program, "a_texcoord");
|
||||
a_position = glGetAttribLocation(program, "a_position");
|
||||
a_color0 = glGetAttribLocation(program, "a_color0");
|
||||
a_color1 = glGetAttribLocation(program, "a_color1");
|
||||
a_texcoord = glGetAttribLocation(program, "a_texcoord");
|
||||
|
||||
glUseProgram(program);
|
||||
// Default uniform values
|
||||
glUniform1i(u_tex, 0);
|
||||
// The rest, use the "dirty" mechanism.
|
||||
dirtyUniforms = DIRTY_PROJMATRIX | DIRTY_TEXENV | DIRTY_ALPHAREF;
|
||||
dirtyUniforms = DIRTY_PROJMATRIX | DIRTY_PROJTHROUGHMATRIX | DIRTY_TEXENV | DIRTY_ALPHAREF;
|
||||
}
|
||||
|
||||
LinkedShader::~LinkedShader() {
|
||||
@ -100,7 +98,7 @@ LinkedShader::~LinkedShader() {
|
||||
}
|
||||
|
||||
void LinkedShader::use() {
|
||||
glUseProgram(program);
|
||||
glUseProgram(program);
|
||||
glUniform1i(u_tex, 0);
|
||||
// Update any dirty uniforms before we draw
|
||||
if (u_proj != -1 && (dirtyUniforms & DIRTY_PROJMATRIX)) {
|
||||
@ -175,7 +173,7 @@ void ShaderManager::DirtyShader()
|
||||
}
|
||||
|
||||
|
||||
LinkedShader *ShaderManager::ApplyShader()
|
||||
LinkedShader *ShaderManager::ApplyShader(int prim)
|
||||
{
|
||||
if (globalDirty) {
|
||||
// Deferred dirtying! Let's see if we can make this even more clever later.
|
||||
@ -187,7 +185,7 @@ LinkedShader *ShaderManager::ApplyShader()
|
||||
|
||||
VertexShaderID VSID;
|
||||
FragmentShaderID FSID;
|
||||
ComputeVertexShaderID(&VSID);
|
||||
ComputeVertexShaderID(&VSID, prim);
|
||||
ComputeFragmentShaderID(&FSID);
|
||||
|
||||
// Bail quickly in the no-op case. TODO: why does it cause trouble?
|
||||
@ -206,7 +204,7 @@ LinkedShader *ShaderManager::ApplyShader()
|
||||
} else {
|
||||
vs = vsIter->second;
|
||||
}
|
||||
|
||||
|
||||
FSCache::iterator fsIter = fsCache.find(FSID);
|
||||
Shader *fs;
|
||||
if (fsIter == fsCache.end()) {
|
||||
|
@ -53,8 +53,13 @@ struct LinkedShader
|
||||
int u_alpharef;
|
||||
int u_fogcolor;
|
||||
int u_fogcoef;
|
||||
|
||||
// Lighting
|
||||
int u_ambientcolor;
|
||||
int u_light[4]; // each light consist of vec4[3]
|
||||
};
|
||||
|
||||
// Will reach 32 bits soon :P
|
||||
enum
|
||||
{
|
||||
DIRTY_PROJMATRIX = (1 << 0),
|
||||
@ -63,8 +68,29 @@ enum
|
||||
DIRTY_FOGCOEF = (1 << 3),
|
||||
DIRTY_TEXENV = (1 << 4),
|
||||
DIRTY_ALPHAREF = (1 << 5),
|
||||
DIRTY_COLORREF = (1 << 6),
|
||||
|
||||
DIRTY_ALL = (1 << 6) - 1
|
||||
DIRTY_LIGHT0 = (1 << 12),
|
||||
DIRTY_LIGHT1 = (1 << 13),
|
||||
DIRTY_LIGHT2 = (1 << 14),
|
||||
DIRTY_LIGHT3 = (1 << 15),
|
||||
|
||||
DIRTY_GLOBALAMBIENT = (1 << 16),
|
||||
DIRTY_MATERIAL = (1 << 17), // let's set all 4 together (emissive ambient diffuse specular). We hide specular coef in specular.a
|
||||
DIRTY_UVSCALEOFFSET = (1 << 18), // this will be dirtied ALL THE TIME... maybe we'll need to do "last value with this shader compares"
|
||||
|
||||
DIRTY_VIEWMATRIX = (1 << 22), // Maybe we'll fold this into projmatrix eventually
|
||||
DIRTY_TEXMATRIX = (1 << 23),
|
||||
DIRTY_BONEMATRIX0 = (1 << 24),
|
||||
DIRTY_BONEMATRIX1 = (1 << 25),
|
||||
DIRTY_BONEMATRIX2 = (1 << 26),
|
||||
DIRTY_BONEMATRIX3 = (1 << 27),
|
||||
DIRTY_BONEMATRIX4 = (1 << 28),
|
||||
DIRTY_BONEMATRIX5 = (1 << 29),
|
||||
DIRTY_BONEMATRIX6 = (1 << 30),
|
||||
DIRTY_BONEMATRIX7 = (1 << 31),
|
||||
|
||||
DIRTY_ALL = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
// Real public interface
|
||||
@ -84,7 +110,7 @@ public:
|
||||
ShaderManager() : globalDirty(0xFFFFFFFF) {}
|
||||
|
||||
void ClearCache(bool deleteThem); // TODO: deleteThem currently not respected
|
||||
LinkedShader *ApplyShader();
|
||||
LinkedShader *ApplyShader(int prim);
|
||||
void DirtyShader();
|
||||
void DirtyUniform(u32 what);
|
||||
|
||||
|
@ -119,9 +119,9 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[
|
||||
specular = ∈
|
||||
else
|
||||
specular = &materialSpecular;
|
||||
|
||||
|
||||
Color4 lightSum0 = globalAmbient * *ambient + materialEmissive;
|
||||
Color4 lightSum1(0,0,0,0);
|
||||
Color4 lightSum1(0, 0, 0, 0);
|
||||
|
||||
// Try lights.elf - there's something wrong with the lighting
|
||||
|
||||
@ -131,8 +131,8 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[
|
||||
if ((gstate.lightEnable[l] & 1) == 0 && !doShadeMapping_)
|
||||
continue;
|
||||
|
||||
GELightComputation comp = (GELightComputation)(gstate.ltype[l]&3);
|
||||
GELightType type = (GELightType)((gstate.ltype[l]>>8)&3);
|
||||
GELightComputation comp = (GELightComputation)(gstate.ltype[l] & 3);
|
||||
GELightType type = (GELightType)((gstate.ltype[l] >> 8) & 3);
|
||||
Vec3 toLight;
|
||||
|
||||
if (type == GE_LIGHTTYPE_DIRECTIONAL)
|
||||
@ -146,7 +146,7 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[
|
||||
float lightScale = 1.0f;
|
||||
if (type != GE_LIGHTTYPE_DIRECTIONAL)
|
||||
{
|
||||
float distance = toLight.Normalize();
|
||||
float distance = toLight.Normalize();
|
||||
lightScale = 1.0f / (gstate_c.lightatt[l][0] + gstate_c.lightatt[l][1]*distance + gstate_c.lightatt[l][2]*distance*distance);
|
||||
if (lightScale > 1.0f) lightScale = 1.0f;
|
||||
}
|
||||
@ -159,12 +159,12 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[
|
||||
if (poweredDiffuse)
|
||||
dot = powf(dot, specCoef_);
|
||||
|
||||
Color4 diff = (gstate_c.lightColor[1][l] * *diffuse) * (dot * lightScale);
|
||||
Color4 diff = (gstate_c.lightColor[1][l] * *diffuse) * (dot * lightScale);
|
||||
|
||||
// Real PSP specular
|
||||
Vec3 toViewer(0,0,1);
|
||||
// Better specular
|
||||
//Vec3 toViewer = (viewer - pos).Normalized();
|
||||
// Vec3 toViewer = (viewer - pos).Normalized();
|
||||
|
||||
if (doSpecular)
|
||||
{
|
||||
@ -176,7 +176,7 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[
|
||||
if (dot >= 0)
|
||||
{
|
||||
lightSum1 += (gstate_c.lightColor[2][l] * *specular * (powf(dot, specCoef_)*lightScale));
|
||||
}
|
||||
}
|
||||
}
|
||||
dots[l] = dot;
|
||||
if (gstate.lightEnable[l] & 1)
|
||||
@ -203,7 +203,11 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte
|
||||
VertexDecoder dec;
|
||||
dec.SetVertexType(gstate.vertType);
|
||||
dec.DecodeVerts(decoded, verts, inds, prim, vertexCount, &indexLowerBound, &indexUpperBound);
|
||||
|
||||
#if 0
|
||||
for (int i = indexLowerBound; i <= indexUpperBound; i++) {
|
||||
PrintDecodedVertex(decoded[i], gstate.vertType);
|
||||
}
|
||||
#endif
|
||||
bool useTexCoord = false;
|
||||
|
||||
// Check if anything needs updating
|
||||
@ -217,14 +221,14 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte
|
||||
}
|
||||
gpuStats.numDrawCalls++;
|
||||
gpuStats.numVertsTransformed += vertexCount;
|
||||
|
||||
|
||||
if (bytesRead)
|
||||
*bytesRead = vertexCount * dec.VertexSize();
|
||||
|
||||
bool throughmode = (gstate.vertType & GE_VTYPE_THROUGH_MASK) != 0;
|
||||
// Then, transform and draw in one big swoop (urgh!)
|
||||
// need to move this to the shader.
|
||||
|
||||
|
||||
// We're gonna have to keep software transforming RECTANGLES, unless we use a geom shader which we can't on OpenGL ES 2.0.
|
||||
// Usually, though, these primitives don't use lighting etc so it's no biggie performance wise, but it would be nice to get rid of
|
||||
// this code.
|
||||
@ -322,7 +326,7 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte
|
||||
float litColor0[4];
|
||||
float litColor1[4];
|
||||
lighter.Light(litColor0, litColor1, unlitColor, out, norm, dots);
|
||||
|
||||
|
||||
if (gstate.lightingEnable & 1)
|
||||
{
|
||||
// TODO: don't ignore gstate.lmode - we should send two colors in that case
|
||||
@ -459,7 +463,7 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte
|
||||
if (indexType == GE_VTYPE_IDX_8BIT)
|
||||
{
|
||||
index = ((u8*)inds)[i];
|
||||
}
|
||||
}
|
||||
else if (indexType == GE_VTYPE_IDX_16BIT)
|
||||
{
|
||||
index = ((u16*)inds)[i];
|
||||
@ -480,7 +484,7 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte
|
||||
// We have to turn the rectangle into two triangles, so 6 points. Sigh.
|
||||
|
||||
// TODO: there's supposed to be extra magic here to rotate the UV coordinates depending on if upside down etc.
|
||||
|
||||
|
||||
// bottom right
|
||||
*trans = transVtx;
|
||||
trans++;
|
||||
@ -606,17 +610,19 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte
|
||||
glstate.depthTest.set(wantDepthTest);
|
||||
if(wantDepthTest) {
|
||||
// Force GL_ALWAYS if mode clear
|
||||
u8 depthTestFunc = gstate.isModeClear() ? 1 : gstate.getDepthTestFunc();
|
||||
int depthTestFunc = gstate.isModeClear() ? 1 : gstate.getDepthTestFunc();
|
||||
glstate.depthFunc.set(ztests[depthTestFunc]);
|
||||
}
|
||||
|
||||
bool wantDepthWrite = gstate.isModeClear() || gstate.isDepthWriteEnabled();
|
||||
glstate.depthWrite.set(wantDepthWrite ? GL_TRUE : GL_FALSE);
|
||||
|
||||
glstate.depthRange.set(gstate_c.zOff - gstate_c.zScale, gstate_c.zOff + gstate_c.zScale);
|
||||
float depthRangeMin = gstate_c.zOff - gstate_c.zScale;
|
||||
float depthRangeMax = gstate_c.zOff + gstate_c.zScale;
|
||||
glstate.depthRange.set(depthRangeMin, depthRangeMax);
|
||||
|
||||
UpdateViewportAndProjection();
|
||||
LinkedShader *program = shaderManager_->ApplyShader();
|
||||
LinkedShader *program = shaderManager_->ApplyShader(prim);
|
||||
|
||||
// TODO: Make a cache for glEnableVertexAttribArray and glVertexAttribPtr states, these spam the gDebugger log.
|
||||
glEnableVertexAttribArray(program->a_position);
|
||||
@ -625,7 +631,7 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte
|
||||
if (program->a_color1 != -1) glEnableVertexAttribArray(program->a_color1);
|
||||
const int vertexSize = sizeof(transformed[0]);
|
||||
glVertexAttribPointer(program->a_position, 3, GL_FLOAT, GL_FALSE, vertexSize, drawBuffer);
|
||||
if (useTexCoord && program->a_texcoord != -1) glVertexAttribPointer(program->a_texcoord, 2, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 3 * 4);
|
||||
if (useTexCoord && program->a_texcoord != -1) glVertexAttribPointer(program->a_texcoord, 2, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 3 * 4);
|
||||
if (program->a_color0 != -1) glVertexAttribPointer(program->a_color0, 4, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 5 * 4);
|
||||
if (program->a_color1 != -1) glVertexAttribPointer(program->a_color1, 4, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 9 * 4);
|
||||
// NOTICE_LOG(G3D,"DrawPrimitive: %i", numTrans);
|
||||
@ -643,7 +649,7 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte
|
||||
void GLES_GPU::UpdateViewportAndProjection()
|
||||
{
|
||||
bool throughmode = (gstate.vertType & GE_VTYPE_THROUGH_MASK) != 0;
|
||||
|
||||
|
||||
// We can probably use these to simply set scissors? Maybe we need to offset by regionX1/Y1
|
||||
int regionX1 = gstate.region1 & 0x3FF;
|
||||
int regionY1 = (gstate.region1 >> 10) & 0x3FF;
|
||||
@ -654,8 +660,8 @@ void GLES_GPU::UpdateViewportAndProjection()
|
||||
float offsetY = (float)(gstate.offsety & 0xFFFF) / 16.0f;
|
||||
|
||||
if (throughmode) {
|
||||
return;
|
||||
// No viewport transform here. Let's experiment with using region.
|
||||
return;
|
||||
glViewport((0 + regionX1) * renderWidthFactor_, (0 - regionY1) * renderHeightFactor_, (regionX2 - regionX1) * renderWidthFactor_, (regionY2 - regionY1) * renderHeightFactor_);
|
||||
} else {
|
||||
// These we can turn into a glViewport call, offset by offsetX and offsetY. Math after.
|
||||
@ -693,8 +699,8 @@ void GLES_GPU::UpdateViewportAndProjection()
|
||||
|
||||
// Flip vpY0 to match the OpenGL coordinate system.
|
||||
vpY0 = renderHeight_ - (vpY0 + vpHeight);
|
||||
glViewport(vpX0, vpY0, vpWidth, vpHeight);
|
||||
glViewport(vpX0, vpY0, vpWidth, vpHeight);
|
||||
// Sadly, as glViewport takes integers, we will not be able to support sub pixel offsets this way. But meh.
|
||||
shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,15 @@
|
||||
|
||||
#include "VertexDecoder.h"
|
||||
|
||||
void PrintDecodedVertex(const DecodedVertex &vtx, u32 vtype)
|
||||
{
|
||||
if (vtype & GE_VTYPE_NRM_MASK) printf("N: %f %f %f\n", vtx.normal[0], vtx.normal[1], vtx.normal[2]);
|
||||
if (vtype & GE_VTYPE_TC_MASK) printf("TC: %f %f\n", vtx.uv[0], vtx.uv[1]);
|
||||
if (vtype & GE_VTYPE_COL_MASK) printf("C: %02x %02x %02x %02x\n", vtx.color[0], vtx.color[1], vtx.color[2], vtx.color[3]);
|
||||
if (vtype & GE_VTYPE_WEIGHT_MASK) printf("W: TODO\n");
|
||||
printf("P: %f %f %f\n", vtx.pos[0], vtx.pos[1], vtx.pos[2]);
|
||||
}
|
||||
|
||||
const int tcsize[4] = {0,2,4,8}, tcalign[4] = {0,1,2,4};
|
||||
const int colsize[8] = {0,0,0,0,2,2,2,4}, colalign[8] = {0,0,0,0,2,2,2,4};
|
||||
const int nrmsize[4] = {0,3,6,12}, nrmalign[4] = {0,1,2,4};
|
||||
@ -30,7 +39,7 @@ const int wtsize[4] = {0,1,2,4}, wtalign[4] = {0,1,2,4};
|
||||
|
||||
inline int align(int n, int align)
|
||||
{
|
||||
return (n+(align-1)) & ~(align-1);
|
||||
return (n + (align - 1)) & ~(align - 1);
|
||||
}
|
||||
|
||||
void VertexDecoder::SetVertexType(u32 fmt)
|
||||
@ -40,7 +49,7 @@ void VertexDecoder::SetVertexType(u32 fmt)
|
||||
|
||||
int biggest = 0;
|
||||
size = 0;
|
||||
|
||||
|
||||
tc = fmt & 0x3;
|
||||
col = (fmt >> 2) & 0x7;
|
||||
nrm = (fmt >> 5) & 0x3;
|
||||
@ -51,7 +60,7 @@ void VertexDecoder::SetVertexType(u32 fmt)
|
||||
nweights = ((fmt >> 14) & 0x7)+1;
|
||||
|
||||
DEBUG_LOG(G3D,"VTYPE: THRU=%i TC=%i COL=%i POS=%i NRM=%i WT=%i NW=%i IDX=%i MC=%i", (int)throughmode, tc,col,pos,nrm,weighttype,nweights,idx,morphcount);
|
||||
|
||||
|
||||
if (weighttype)
|
||||
{
|
||||
//size = align(size, wtalign[weighttype]); unnecessary
|
||||
|
@ -40,26 +40,27 @@ struct TransformedVertex
|
||||
|
||||
|
||||
|
||||
// Right now
|
||||
// Right now
|
||||
// - only contains computed information
|
||||
// - does decoding in nasty branchfilled loops
|
||||
// Future TODO
|
||||
// - will compile into lighting fast specialized x86
|
||||
// Future TODO
|
||||
// - will compile into lighting fast specialized x86 and ARM
|
||||
// - will not bother translating components that can be read directly
|
||||
// by OpenGL ES. Will still have to translate 565 colors, and things
|
||||
// like that. DecodedVertex will not be a fixed struct. Will have to
|
||||
// do morphing here.
|
||||
//
|
||||
// We want 100% perf on 1Ghz even in vertex complex games!
|
||||
class VertexDecoder
|
||||
class VertexDecoder
|
||||
{
|
||||
public:
|
||||
VertexDecoder() : coloff(0), nrmoff(0), posoff(0) {}
|
||||
~VertexDecoder() {}
|
||||
void SetVertexType(u32 fmt);
|
||||
void SetVertexType(u32 vtype);
|
||||
void DecodeVerts(DecodedVertex *decoded, const void *verts, const void *inds, int prim, int count, int *indexLowerBound, int *indexUpperBound) const;
|
||||
bool hasColor() const { return col != 0; }
|
||||
int VertexSize() const { return size; }
|
||||
|
||||
private:
|
||||
u32 fmt;
|
||||
bool throughmode;
|
||||
@ -81,5 +82,8 @@ private:
|
||||
int idx;
|
||||
int morphcount;
|
||||
int nweights;
|
||||
|
||||
};
|
||||
|
||||
// Debugging utilities
|
||||
void PrintDecodedVertex(const DecodedVertex &vtx, u32 vtype);
|
||||
|
||||
|
@ -38,12 +38,21 @@ static char buffer[16384];
|
||||
|
||||
#define WRITE(x, ...) p+=sprintf(p, x "\n" __VA_ARGS__)
|
||||
|
||||
void ComputeVertexShaderID(VertexShaderID *id)
|
||||
// prim so we can special case for RECTANGLES :(
|
||||
void ComputeVertexShaderID(VertexShaderID *id, int prim)
|
||||
{
|
||||
memset(id->d, 0, sizeof(id->d));
|
||||
id->d[0] = gstate.lmode & 1;
|
||||
id->d[0] |= ((int)gstate.isModeThrough()) << 1;
|
||||
id->d[0] |= ((int)gstate.isFogEnabled()) << 2;
|
||||
|
||||
// Bits that we will need:
|
||||
// lightenable * 4
|
||||
// lighttype * 4
|
||||
// lightcomp * 4
|
||||
// uv gen:
|
||||
// mapping type
|
||||
// texshade light choices (ONLY IF uv mapping type is shade)
|
||||
}
|
||||
|
||||
void WriteLight(char *p, int l) {
|
||||
@ -61,8 +70,11 @@ char *GenerateVertexShader()
|
||||
|
||||
int lmode = gstate.lmode & 1;
|
||||
|
||||
WRITE("attribute vec4 a_position;");
|
||||
WRITE("attribute vec2 a_texcoord;");
|
||||
int doTexture = (gstate.textureMapEnable & 1) && !(gstate.clearmode & 1);
|
||||
|
||||
WRITE("attribute vec3 a_position;");
|
||||
if (doTexture)
|
||||
WRITE("attribute vec2 a_texcoord;");
|
||||
WRITE("attribute vec4 a_color0;");
|
||||
if (lmode)
|
||||
WRITE("attribute vec4 a_color1;");
|
||||
@ -77,18 +89,20 @@ char *GenerateVertexShader()
|
||||
WRITE("varying vec4 v_color0;");
|
||||
if (lmode)
|
||||
WRITE("varying vec4 v_color1;");
|
||||
WRITE("varying vec2 v_texcoord;");
|
||||
if (doTexture)
|
||||
WRITE("varying vec2 v_texcoord;");
|
||||
if (gstate.isFogEnabled())
|
||||
WRITE("varying float v_depth;");
|
||||
WRITE("void main() {");
|
||||
WRITE(" v_color0 = a_color0;");
|
||||
if (lmode)
|
||||
WRITE(" v_color1 = a_color1;");
|
||||
WRITE(" v_texcoord = a_texcoord;");
|
||||
if (doTexture)
|
||||
WRITE(" v_texcoord = a_texcoord;");
|
||||
if (gstate.isModeThrough()) {
|
||||
WRITE(" gl_Position = u_proj_through * a_position;");
|
||||
WRITE(" gl_Position = u_proj_through * vec4(a_position, 1.0);");
|
||||
} else {
|
||||
WRITE(" gl_Position = u_proj * a_position;");
|
||||
WRITE(" gl_Position = u_proj * vec4(a_position, 1.0);");
|
||||
}
|
||||
if (gstate.isFogEnabled()) {
|
||||
WRITE(" v_depth = gl_Position.z;");
|
||||
|
@ -46,7 +46,7 @@ struct VertexShaderID
|
||||
}
|
||||
};
|
||||
|
||||
void ComputeVertexShaderID(VertexShaderID *id);
|
||||
void ComputeVertexShaderID(VertexShaderID *id, int prim);
|
||||
|
||||
// The return value is only valid until the function is called again.
|
||||
char *GenerateVertexShader();
|
||||
|
@ -79,8 +79,8 @@ struct GPUgstate
|
||||
u32 cmdmem[256];
|
||||
struct
|
||||
{
|
||||
int nop;
|
||||
u32 vaddr,
|
||||
u32 nop,
|
||||
vaddr,
|
||||
iaddr,
|
||||
pad00,
|
||||
prim,
|
||||
@ -226,11 +226,9 @@ struct GPUgstate
|
||||
transferstart,
|
||||
transfersrcpos,
|
||||
transferdstpos,
|
||||
transfersize
|
||||
;
|
||||
transfersize;
|
||||
|
||||
u32 pad05[0x63-0x40];
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
0
android/ab.sh
Normal file → Executable file
0
android/ab.sh
Normal file → Executable file
@ -16,6 +16,7 @@
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "gfx_es2/glsl_program.h"
|
||||
#include "gfx_es2/gl_state.h"
|
||||
#include "gfx_es2/fbo.h"
|
||||
|
||||
#include "input/input_state.h"
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "base/NativeApp.h"
|
||||
#include "file/vfs.h"
|
||||
#include "file/zip_read.h"
|
||||
#include "gfx/gl_state.h"
|
||||
#include "gfx_es2/gl_state.h"
|
||||
#include "gfx/gl_lost_manager.h"
|
||||
#include "gfx/texture.h"
|
||||
#include "input/input_state.h"
|
||||
@ -214,7 +214,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_directory, co
|
||||
{
|
||||
LogTypes::LOG_TYPE type = (LogTypes::LOG_TYPE)i;
|
||||
logman->SetEnable(type, true);
|
||||
logman->SetLogLevel(type, logLevel);
|
||||
logman->SetLogLevel(type, gfxLog && i == LogTypes::G3D ? LogTypes::LDEBUG : logLevel);
|
||||
#ifdef ANDROID
|
||||
logman->AddListener(type, logger);
|
||||
#endif
|
||||
@ -268,6 +268,7 @@ void NativeInitGraphics()
|
||||
|
||||
void NativeRender()
|
||||
{
|
||||
glstate.Restore();
|
||||
glViewport(0, 0, pixel_xres, pixel_yres);
|
||||
Matrix4x4 ortho;
|
||||
ortho.setOrtho(0.0f, dp_xres, dp_yres, 0.0f, -1.0f, 1.0f);
|
||||
|
2
native
2
native
@ -1 +1 @@
|
||||
Subproject commit 92bd22ffe5fd90b1441660b9136fc6dc230399ec
|
||||
Subproject commit 7ed5811db38f3547f8eec3d3b577dae38405b1e0
|
Loading…
Reference in New Issue
Block a user