mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
More work on indexed draws. Not combining yet.
This commit is contained in:
parent
2e9daa5f89
commit
3b114eb24a
7 changed files with 115 additions and 33 deletions
|
@ -182,6 +182,7 @@ void hleEnterVblank(u64 userdata, int cyclesLate)
|
|||
sprintf(stats,
|
||||
"Frames: %i\n"
|
||||
"Draw calls: %i\n"
|
||||
"Draw flushes: %i\n"
|
||||
"Vertices Transformed: %i\n"
|
||||
"Textures active: %i\n"
|
||||
"Vertex shaders loaded: %i\n"
|
||||
|
@ -189,6 +190,7 @@ void hleEnterVblank(u64 userdata, int cyclesLate)
|
|||
"Combined shaders loaded: %i\n",
|
||||
gpuStats.numFrames,
|
||||
gpuStats.numDrawCalls,
|
||||
gpuStats.numFlushes,
|
||||
gpuStats.numVertsTransformed,
|
||||
gpuStats.numTextures,
|
||||
gpuStats.numVertexShaders,
|
||||
|
|
|
@ -54,6 +54,7 @@ GLES_GPU::GLES_GPU(int renderWidth, int renderHeight)
|
|||
renderHeightFactor_ = (float)renderHeight / 272.0f;
|
||||
shaderManager_ = &shaderManager;
|
||||
TextureCache_Init();
|
||||
InitTransform();
|
||||
// Sanity check gstate
|
||||
if ((int *)&gstate.transferstart - (int *)&gstate != 0xEA) {
|
||||
ERROR_LOG(G3D, "gstate has drifted out of sync!");
|
||||
|
@ -113,6 +114,7 @@ void GLES_GPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, int format)
|
|||
|
||||
void GLES_GPU::CopyDisplayToOutput()
|
||||
{
|
||||
Flush();
|
||||
if (!g_Config.bBufferedRendering)
|
||||
return;
|
||||
|
||||
|
|
|
@ -22,11 +22,11 @@
|
|||
|
||||
#include "../GPUInterface.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "VertexDecoder.h"
|
||||
#include "gfx_es2/fbo.h"
|
||||
|
||||
class ShaderManager;
|
||||
class LinkedShader;
|
||||
struct DecVtxFormat;
|
||||
|
||||
class GLES_GPU : public GPUInterface
|
||||
{
|
||||
|
@ -52,10 +52,11 @@ public:
|
|||
|
||||
private:
|
||||
// TransformPipeline.cpp
|
||||
void InitTransform();
|
||||
void TransformAndDrawPrim(void *verts, void *inds, int prim, int vertexCount, float *customUV, int forceIndexType, int *bytesRead = 0);
|
||||
//void SoftwareTransformAndDraw(int prim, LinkedShader *program, int forceIndexType, int vertexCount, void *inds, const DecVtxFormat &decVtxFormat, int indexLowerBound, int indexUpperBound, float *customUV);
|
||||
void ApplyDrawState();
|
||||
void Flush(int prim);
|
||||
void Flush();
|
||||
void UpdateViewportAndProjection();
|
||||
void DrawBezier(int ucount, int vcount);
|
||||
void DoBlockTransfer();
|
||||
|
|
|
@ -25,13 +25,14 @@ const u8 indexedPrimitiveType[7] = {
|
|||
GE_PRIM_TRIANGLES,
|
||||
GE_PRIM_TRIANGLES,
|
||||
GE_PRIM_TRIANGLES,
|
||||
GE_PRIM_TRIANGLES,
|
||||
GE_PRIM_RECTANGLES,
|
||||
};
|
||||
|
||||
void IndexGenerator::Reset() {
|
||||
prim_ = -1;
|
||||
inds_ = 0;
|
||||
count_ = 0;
|
||||
index_ = 0;
|
||||
this->inds_ = indsBase_;
|
||||
}
|
||||
|
||||
bool IndexGenerator::PrimCompatible(int prim) {
|
||||
|
@ -40,12 +41,10 @@ bool IndexGenerator::PrimCompatible(int prim) {
|
|||
return indexedPrimitiveType[prim] == indexedPrimitiveType[prim_];
|
||||
}
|
||||
|
||||
void IndexGenerator::Start(u16 *inds, int baseIndex, int prim)
|
||||
void IndexGenerator::Setup(u16 *inds)
|
||||
{
|
||||
count_ = 0;
|
||||
this->inds_ = inds;
|
||||
index_ = baseIndex;
|
||||
prim_ = indexedPrimitiveType[prim];
|
||||
this->indsBase_ = inds;
|
||||
Reset();
|
||||
}
|
||||
|
||||
void IndexGenerator::AddPoints(int numVerts)
|
||||
|
@ -58,6 +57,7 @@ void IndexGenerator::AddPoints(int numVerts)
|
|||
// ignore overflow verts
|
||||
index_ += numVerts;
|
||||
count_ += numVerts;
|
||||
prim_ = GE_PRIM_POINTS;
|
||||
}
|
||||
|
||||
void IndexGenerator::AddList(int numVerts)
|
||||
|
@ -74,6 +74,7 @@ void IndexGenerator::AddList(int numVerts)
|
|||
// ignore overflow verts
|
||||
index_ += numVerts;
|
||||
count_ += numTris * 3;
|
||||
prim_ = GE_PRIM_TRIANGLES;
|
||||
}
|
||||
|
||||
void IndexGenerator::AddStrip(int numVerts)
|
||||
|
@ -89,6 +90,7 @@ void IndexGenerator::AddStrip(int numVerts)
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numTris * 3;
|
||||
prim_ = GE_PRIM_TRIANGLES;
|
||||
}
|
||||
|
||||
void IndexGenerator::AddFan(int numVerts)
|
||||
|
@ -102,6 +104,7 @@ void IndexGenerator::AddFan(int numVerts)
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numTris * 3;
|
||||
prim_ = GE_PRIM_TRIANGLES;
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslatePoints(int numVerts, const u8 *inds, int offset)
|
||||
|
@ -112,6 +115,7 @@ void IndexGenerator::TranslatePoints(int numVerts, const u8 *inds, int offset)
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numVerts;
|
||||
prim_ = GE_PRIM_POINTS;
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslatePoints(int numVerts, const u16 *inds, int offset)
|
||||
|
@ -122,6 +126,7 @@ void IndexGenerator::TranslatePoints(int numVerts, const u16 *inds, int offset)
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numVerts;
|
||||
prim_ = GE_PRIM_POINTS;
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslateList(int numVerts, const u8 *inds, int offset)
|
||||
|
@ -135,6 +140,7 @@ void IndexGenerator::TranslateList(int numVerts, const u8 *inds, int offset)
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numTris * 3;
|
||||
prim_ = GE_PRIM_TRIANGLES;
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslateStrip(int numVerts, const u8 *inds, int offset)
|
||||
|
@ -150,6 +156,7 @@ void IndexGenerator::TranslateStrip(int numVerts, const u8 *inds, int offset)
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numTris * 3;
|
||||
prim_ = GE_PRIM_TRIANGLES;
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslateFan(int numVerts, const u8 *inds, int offset)
|
||||
|
@ -164,6 +171,7 @@ void IndexGenerator::TranslateFan(int numVerts, const u8 *inds, int offset)
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numTris * 3;
|
||||
prim_ = GE_PRIM_TRIANGLES;
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslateList(int numVerts, const u16 *inds, int offset)
|
||||
|
@ -177,6 +185,7 @@ void IndexGenerator::TranslateList(int numVerts, const u16 *inds, int offset)
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numTris * 3;
|
||||
prim_ = GE_PRIM_TRIANGLES;
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslateStrip(int numVerts, const u16 *inds, int offset)
|
||||
|
@ -192,6 +201,7 @@ void IndexGenerator::TranslateStrip(int numVerts, const u16 *inds, int offset)
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numTris * 3;
|
||||
prim_ = GE_PRIM_TRIANGLES;
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslateFan(int numVerts, const u16 *inds, int offset)
|
||||
|
@ -206,6 +216,7 @@ void IndexGenerator::TranslateFan(int numVerts, const u16 *inds, int offset)
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numTris * 3;
|
||||
prim_ = GE_PRIM_TRIANGLES;
|
||||
}
|
||||
|
||||
//Lines
|
||||
|
@ -219,6 +230,7 @@ void IndexGenerator::AddLineList(int numVerts)
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numLines * 2;
|
||||
prim_ = GE_PRIM_LINES;
|
||||
}
|
||||
|
||||
void IndexGenerator::AddLineStrip(int numVerts)
|
||||
|
@ -231,6 +243,20 @@ void IndexGenerator::AddLineStrip(int numVerts)
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numLines * 2;
|
||||
prim_ = GE_PRIM_LINES;
|
||||
}
|
||||
|
||||
void IndexGenerator::AddRectangles(int numVerts)
|
||||
{
|
||||
int numRects = numVerts / 2;
|
||||
for (int i = 0; i < numRects; i++)
|
||||
{
|
||||
*inds_++ = index_ + i*2;
|
||||
*inds_++ = index_ + i*2+1;
|
||||
}
|
||||
index_ += numVerts;
|
||||
count_ += numRects * 2;
|
||||
prim_ = GE_PRIM_RECTANGLES;
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslateLineList(int numVerts, const u8 *inds, int offset)
|
||||
|
@ -243,6 +269,7 @@ void IndexGenerator::TranslateLineList(int numVerts, const u8 *inds, int offset)
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numLines * 2;
|
||||
prim_ = GE_PRIM_LINES;
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslateLineStrip(int numVerts, const u8 *inds, int offset)
|
||||
|
@ -255,6 +282,7 @@ void IndexGenerator::TranslateLineStrip(int numVerts, const u8 *inds, int offset
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numLines * 2;
|
||||
prim_ = GE_PRIM_LINES;
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslateLineList(int numVerts, const u16 *inds, int offset)
|
||||
|
@ -267,6 +295,7 @@ void IndexGenerator::TranslateLineList(int numVerts, const u16 *inds, int offset
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numLines * 2;
|
||||
prim_ = GE_PRIM_LINES;
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslateLineStrip(int numVerts, const u16 *inds, int offset)
|
||||
|
@ -279,4 +308,31 @@ void IndexGenerator::TranslateLineStrip(int numVerts, const u16 *inds, int offse
|
|||
}
|
||||
index_ += numVerts;
|
||||
count_ += numLines * 2;
|
||||
}
|
||||
prim_ = GE_PRIM_LINES;
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslateRectangles(int numVerts, const u8 *inds, int offset)
|
||||
{
|
||||
int numRects = numVerts / 2;
|
||||
for (int i = 0; i < numRects; i++)
|
||||
{
|
||||
*inds_++ = index_ + i*2;
|
||||
*inds_++ = index_ + i*2+1;
|
||||
}
|
||||
index_ += numVerts;
|
||||
count_ += numRects * 2;
|
||||
prim_ = GE_PRIM_RECTANGLES;
|
||||
}
|
||||
|
||||
void IndexGenerator::TranslateRectangles(int numVerts, const u16 *inds, int offset)
|
||||
{
|
||||
int numRects = numVerts / 2;
|
||||
for (int i = 0; i < numRects; i++)
|
||||
{
|
||||
*inds_++ = index_ + i*2;
|
||||
*inds_++ = index_ + i*2+1;
|
||||
}
|
||||
index_ += numVerts;
|
||||
count_ += numRects * 2;
|
||||
prim_ = GE_PRIM_RECTANGLES;
|
||||
}
|
||||
|
|
|
@ -24,9 +24,10 @@
|
|||
class IndexGenerator
|
||||
{
|
||||
public:
|
||||
void Setup(u16 *indexptr);
|
||||
void Reset();
|
||||
void Start(u16 *indexptr, int baseIndex, int prim);
|
||||
bool PrimCompatible(int prim);
|
||||
int Prim() const { return prim_; }
|
||||
|
||||
// Points (why index these? code simplicity)
|
||||
void AddPoints(int numVerts);
|
||||
|
@ -37,15 +38,21 @@ public:
|
|||
// Lines
|
||||
void AddLineList(int numVerts);
|
||||
void AddLineStrip(int numVerts);
|
||||
// Rectangles
|
||||
void AddRectangles(int numVerts);
|
||||
|
||||
void TranslatePoints(int numVerts, const u8 *inds, int offset);
|
||||
void TranslatePoints(int numVerts, const u16 *inds, int offset);
|
||||
// Translates already indexed lists
|
||||
void TranslateLineList(int numVerts, const u8 *inds, int offset);
|
||||
void TranslateLineStrip(int numVerts, const u8 *inds, int offset);
|
||||
void TranslateLineList(int numVerts, const u16 *inds, int offset);
|
||||
void TranslateLineStrip(int numVerts, const u8 *inds, int offset);
|
||||
void TranslateLineStrip(int numVerts, const u16 *inds, int offset);
|
||||
|
||||
void TranslateRectangles(int numVerts, const u8 *inds, int offset);
|
||||
void TranslateRectangles(int numVerts, const u16 *inds, int offset);
|
||||
|
||||
|
||||
void TranslateList(int numVerts, const u8 *inds, int offset);
|
||||
void TranslateStrip(int numVerts, const u8 *inds, int offset);
|
||||
void TranslateFan(int numVerts, const u8 *inds, int offset);
|
||||
|
@ -56,7 +63,10 @@ public:
|
|||
int MaxIndex() { return index_; }
|
||||
int VertexCount() { return count_; }
|
||||
|
||||
bool Empty() { return index_ == 0; }
|
||||
|
||||
private:
|
||||
u16 *indsBase_;
|
||||
u16 *inds_;
|
||||
int index_;
|
||||
int count_;
|
||||
|
|
|
@ -43,7 +43,10 @@ const GLuint glprim[8] = {
|
|||
};
|
||||
|
||||
u8 decoded[65536 * 32];
|
||||
VertexDecoder dec;
|
||||
uint16_t decIndex[65536]; // Unused
|
||||
int numVerts;
|
||||
int numInds;
|
||||
|
||||
IndexGenerator indexGen;
|
||||
|
||||
|
@ -265,7 +268,7 @@ static void DesetupDecFmtForDraw(LinkedShader *program, const DecVtxFormat &decF
|
|||
|
||||
// Actually again, single quads could be drawn more efficiently using GL_TRIANGLE_STRIP, no need to duplicate verts as for
|
||||
// GL_TRIANGLES. Still need to sw transform to compute the extra two corners though.
|
||||
void SoftwareTransformAndDraw(int prim, LinkedShader *program, int vertexCount, void *inds, int indexType, const DecVtxFormat &decVtxFormat, int maxIndex, float *customUV)
|
||||
void SoftwareTransformAndDraw(int prim, LinkedShader *program, int vertexCount, void *inds, int indexType, const DecVtxFormat &decVtxFormat, int maxIndex)
|
||||
{
|
||||
/*
|
||||
DEBUG_LOG(G3D, "View matrix:");
|
||||
|
@ -418,10 +421,7 @@ void SoftwareTransformAndDraw(int prim, LinkedShader *program, int vertexCount,
|
|||
}
|
||||
}
|
||||
|
||||
if (customUV) {
|
||||
uv[0] = customUV[index * 2 + 0]*gstate_c.uScale + gstate_c.uOff;
|
||||
uv[1] = customUV[index * 2 + 1]*gstate_c.vScale + gstate_c.vOff;
|
||||
} else if (reader.hasUV()) {
|
||||
if (reader.hasUV()) {
|
||||
float ruv[2];
|
||||
reader.ReadUV(ruv);
|
||||
// Perform texture coordinate generation after the transform and lighting - one style of UV depends on lights.
|
||||
|
@ -575,22 +575,27 @@ void SoftwareTransformAndDraw(int prim, LinkedShader *program, int vertexCount,
|
|||
if (program->a_color1 != -1) glDisableVertexAttribArray(program->a_color1);
|
||||
}
|
||||
|
||||
void GLES_GPU::InitTransform() {
|
||||
indexGen.Setup(decIndex);
|
||||
}
|
||||
|
||||
void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int vertexCount, float *customUV, int forceIndexType, int *bytesRead)
|
||||
{
|
||||
// For the future
|
||||
if (!indexGen.PrimCompatible(prim))
|
||||
Flush(prim);
|
||||
Flush();
|
||||
|
||||
gpuStats.numDrawCalls++;
|
||||
gpuStats.numVertsTransformed += vertexCount;
|
||||
|
||||
int indexLowerBound, indexUpperBound;
|
||||
// First, decode the verts and apply morphing
|
||||
VertexDecoder dec;
|
||||
dec.SetVertexType(gstate.vertType);
|
||||
dec.DecodeVerts(decoded, verts, inds, prim, vertexCount, &indexLowerBound, &indexUpperBound);
|
||||
|
||||
if (bytesRead)
|
||||
*bytesRead = vertexCount * dec.VertexSize();
|
||||
|
||||
indexGen.Start(decIndex, 0, prim);
|
||||
|
||||
int indexType = (gstate.vertType & GE_VTYPE_IDX_MASK);
|
||||
if (forceIndexType != -1) indexType = forceIndexType;
|
||||
switch (indexType) {
|
||||
|
@ -602,7 +607,7 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte
|
|||
case GE_PRIM_TRIANGLES: indexGen.AddList(vertexCount); break;
|
||||
case GE_PRIM_TRIANGLE_STRIP: indexGen.AddStrip(vertexCount); break;
|
||||
case GE_PRIM_TRIANGLE_FAN: indexGen.AddFan(vertexCount); break;
|
||||
case GE_PRIM_RECTANGLES: indexGen.AddLineList(vertexCount); break; // Same
|
||||
case GE_PRIM_RECTANGLES: indexGen.AddRectangles(vertexCount); break; // Same
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -614,7 +619,7 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte
|
|||
case GE_PRIM_TRIANGLES: indexGen.TranslateList(vertexCount, (const u8 *)inds, -indexLowerBound); break;
|
||||
case GE_PRIM_TRIANGLE_STRIP: indexGen.TranslateStrip(vertexCount, (const u8 *)inds, -indexLowerBound); break;
|
||||
case GE_PRIM_TRIANGLE_FAN: indexGen.TranslateFan(vertexCount, (const u8 *)inds, -indexLowerBound); break;
|
||||
case GE_PRIM_RECTANGLES: indexGen.TranslateLineList(vertexCount, (const u8 *)inds, -indexLowerBound); break; // Same
|
||||
case GE_PRIM_RECTANGLES: indexGen.TranslateRectangles(vertexCount, (const u8 *)inds, -indexLowerBound); break; // Same
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -626,12 +631,18 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte
|
|||
case GE_PRIM_TRIANGLES: indexGen.TranslateList(vertexCount, (const u16 *)inds, -indexLowerBound); break;
|
||||
case GE_PRIM_TRIANGLE_STRIP: indexGen.TranslateStrip(vertexCount, (const u16 *)inds, -indexLowerBound); break;
|
||||
case GE_PRIM_TRIANGLE_FAN: indexGen.TranslateFan(vertexCount, (const u16 *)inds, -indexLowerBound); break;
|
||||
case GE_PRIM_RECTANGLES: indexGen.TranslateLineList(vertexCount, (const u16 *)inds, -indexLowerBound); break; // Same
|
||||
case GE_PRIM_RECTANGLES: indexGen.TranslateRectangles(vertexCount, (const u16 *)inds, -indexLowerBound); break; // Same
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
indexType = GE_VTYPE_IDX_16BIT;
|
||||
Flush();
|
||||
}
|
||||
|
||||
void GLES_GPU::Flush()
|
||||
{
|
||||
if (indexGen.Empty())
|
||||
return;
|
||||
// From here on out, the index type is ALWAYS 16-bit. Deal with it.
|
||||
|
||||
// And here we should return, having collected the morphed but untransformed vertices.
|
||||
|
@ -654,12 +665,13 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte
|
|||
}
|
||||
gstate_c.textureChanged = false;
|
||||
}
|
||||
gpuStats.numDrawCalls++;
|
||||
gpuStats.numVertsTransformed += vertexCount;
|
||||
gpuStats.numFlushes++;
|
||||
|
||||
// TODO: This should not be done on every drawcall, we should collect vertex data
|
||||
// until critical state changes. That's when we draw (flush).
|
||||
|
||||
int prim = indexGen.Prim();
|
||||
|
||||
ApplyDrawState();
|
||||
UpdateViewportAndProjection();
|
||||
|
||||
|
@ -670,11 +682,9 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte
|
|||
glDrawElements(glprim[prim], indexGen.VertexCount(), GL_UNSIGNED_SHORT, (GLvoid *)decIndex);
|
||||
DesetupDecFmtForDraw(program, dec.GetDecVtxFmt());
|
||||
} else {
|
||||
SoftwareTransformAndDraw(prim, program, indexGen.VertexCount(), (void *)decIndex, indexType, dec.GetDecVtxFmt(),
|
||||
indexGen.MaxIndex(), customUV);
|
||||
SoftwareTransformAndDraw(prim, program, indexGen.VertexCount(), (void *)decIndex, GE_VTYPE_IDX_16BIT, dec.GetDecVtxFmt(),
|
||||
indexGen.MaxIndex());
|
||||
}
|
||||
}
|
||||
|
||||
void GLES_GPU::Flush(int prim) {
|
||||
// TODO
|
||||
}
|
||||
indexGen.Reset();
|
||||
}
|
|
@ -263,6 +263,7 @@ struct GPUStatistics
|
|||
|
||||
// Per frame statistics
|
||||
int numDrawCalls;
|
||||
int numFlushes;
|
||||
int numVertsTransformed;
|
||||
int numTextureSwitches;
|
||||
int numShaderSwitches;
|
||||
|
|
Loading…
Add table
Reference in a new issue