Add IndexGenerator.cpp/h which will later be used to combine small draw calls into large indexed draw calls, for better performance.

This commit is contained in:
Henrik Rydgard 2012-12-21 17:50:22 +01:00
parent b486ca1620
commit ea07c14c4c
8 changed files with 301 additions and 5 deletions

View File

@ -786,6 +786,8 @@ add_library(GPU OBJECT
GPU/GLES/FragmentShaderGenerator.h
GPU/GLES/Framebuffer.cpp
GPU/GLES/Framebuffer.h
GPU/GLES/IndexGenerator.cpp
GPU/GLES/IndexGenerator.h
GPU/GLES/ShaderManager.cpp
GPU/GLES/ShaderManager.h
GPU/GLES/StateMapping.cpp

View File

@ -4,6 +4,7 @@ set(SRCS
GLES/DisplayListInterpreter.cpp
GLES/FragmentShaderGenerator.cpp
GLES/Framebuffer.cpp
GLES/IndexGenerator.cpp
GLES/ShaderManager.cpp
GLES/StateMapping.cpp
GLES/TextureCache.cpp

232
GPU/GLES/IndexGenerator.cpp Normal file
View File

@ -0,0 +1,232 @@
// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "IndexGenerator.h"
// Points don't need indexing...
const u8 indexedPrimitiveType[7] = {
GE_PRIM_POINTS,
GE_PRIM_LINES,
GE_PRIM_LINES,
GE_PRIM_TRIANGLES,
GE_PRIM_TRIANGLES,
GE_PRIM_TRIANGLES,
GE_PRIM_TRIANGLES,
};
void IndexGenerator::Reset() {
prim_ = -1;
inds_ = 0;
}
bool IndexGenerator::PrimCompatible(int prim) {
if (prim_ == -1)
return true;
return indexedPrimitiveType[prim] == indexedPrimitiveType[prim_];
}
void IndexGenerator::Start(u16 *inds, int baseIndex, int prim)
{
this->inds_ = inds;
index_ = baseIndex;
}
void IndexGenerator::AddList(int numVerts)
{
//if we have no vertices return
int numTris = numVerts / 3;
for (int i = 0; i < numTris; i++)
{
*inds_++ = index_ + i*3;
*inds_++ = index_ + i*3 + 1;
*inds_++ = index_ + i*3 + 2;
}
// ignore overflow verts
index_ += numVerts;
}
void IndexGenerator::AddStrip(int numVerts)
{
bool wind = false;
int numTris = numVerts - 2;
for (int i = 0; i < numTris; i++)
{
*inds_++ = index_ + i;
*inds_++ = index_ + i+(wind?2:1);
*inds_++ = index_ + i+(wind?1:2);
wind = !wind;
}
index_ += numVerts;
}
void IndexGenerator::AddFan(int numVerts)
{
int numTris = numVerts - 2;
for (int i = 0; i < numTris; i++)
{
*inds_++ = index_;
*inds_++ = index_ + i + 1;
*inds_++ = index_ + i + 2;
}
index_ += numVerts;
}
void IndexGenerator::TranslateList(int numVerts, const u8 *inds, int offset)
{
int numTris = numVerts / 3;
for (int i = 0; i < numTris; i++)
{
*inds_++ = index_ + offset + inds[i*3];
*inds_++ = index_ + offset + inds[i*3 + 1];
*inds_++ = index_ + offset + inds[i*3 + 2];
}
index_ += numVerts;
}
void IndexGenerator::TranslateStrip(int numVerts, const u8 *inds, int offset)
{
bool wind = false;
int numTris = numVerts - 2;
for (int i = 0; i < numTris; i++)
{
*inds_++ = index_ + offset + inds[i];
*inds_++ = index_ + offset + inds[i + (wind?2:1)];
*inds_++ = index_ + offset + inds[i + (wind?1:2)];
wind = !wind;
}
index_ += numVerts;
}
void IndexGenerator::TranslateFan(int numVerts, const u8 *inds, int offset)
{
if (numVerts <= 0) return;
int numTris = numVerts - 2;
for (int i = 0; i < numTris; i++)
{
*inds_++ = index_ + offset + inds[i];
*inds_++ = index_ + offset + inds[i + 1];
*inds_++ = index_ + offset + inds[i + 2];
}
index_ += numVerts;
}
void IndexGenerator::TranslateList(int numVerts, const u16 *inds, int offset)
{
int numTris = numVerts / 3;
for (int i = 0; i < numTris; i++)
{
*inds_++ = index_ + offset + inds[i*3];
*inds_++ = index_ + offset + inds[i*3 + 1];
*inds_++ = index_ + offset + inds[i*3 + 2];
}
index_ += numVerts;
}
void IndexGenerator::TranslateStrip(int numVerts, const u16 *inds, int offset)
{
bool wind = false;
int numTris = numVerts - 2;
for (int i = 0; i < numTris; i++)
{
*inds_++ = index_ + offset + inds[i];
*inds_++ = index_ + offset + inds[i + (wind?2:1)];
*inds_++ = index_ + offset + inds[i + (wind?1:2)];
wind = !wind;
}
index_ += numVerts;
}
void IndexGenerator::TranslateFan(int numVerts, const u16 *inds, int offset)
{
if (numVerts <= 0) return;
int numTris = numVerts - 2;
for (int i = 0; i < numTris; i++)
{
*inds_++ = index_ + offset + inds[i];
*inds_++ = index_ + offset + inds[i + 1];
*inds_++ = index_ + offset + inds[i + 2];
}
index_ += numVerts;
}
//Lines
void IndexGenerator::AddLineList(int numVerts)
{
int numLines = numVerts / 2;
for (int i = 0; i < numLines; i++)
{
*inds_++ = index_ + i*2;
*inds_++ = index_ + i*2+1;
}
index_ += numVerts;
}
void IndexGenerator::AddLineStrip(int numVerts)
{
int numLines = numVerts - 1;
for (int i = 0; i < numLines; i++)
{
*inds_++ = index_ + i;
*inds_++ = index_ + i + 1;
}
index_ += numVerts;
}
void IndexGenerator::TranslateLineList(int numVerts, const u8 *inds, int offset)
{
int numLines = numVerts / 2;
for (int i = 0; i < numLines; i++)
{
*inds_++ = index_ + i*2;
*inds_++ = index_ + i*2+1;
}
index_ += numVerts;
}
void IndexGenerator::TranslateLineStrip(int numVerts, const u8 *inds, int offset)
{
int numLines = numVerts - 1;
for (int i = 0; i < numLines; i++)
{
*inds_++ = index_ + i;
*inds_++ = index_ + i + 1;
}
index_ += numVerts;
}
void IndexGenerator::TranslateLineList(int numVerts, const u16 *inds, int offset)
{
int numLines = numVerts / 2;
for (int i = 0; i < numLines; i++)
{
*inds_++ = index_ + i*2;
*inds_++ = index_ + i*2+1;
}
index_ += numVerts;
}
void IndexGenerator::TranslateLineStrip(int numVerts, const u16 *inds, int offset)
{
int numLines = numVerts - 1;
for (int i = 0; i < numLines; i++)
{
*inds_++ = index_ + i;
*inds_++ = index_ + i + 1;
}
index_ += numVerts;
}

57
GPU/GLES/IndexGenerator.h Normal file
View File

@ -0,0 +1,57 @@
// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#pragma once
#include "CommonTypes.h"
#include "../ge_constants.h"
class IndexGenerator
{
public:
void Reset();
void Start(u16 *indexptr, int baseIndex, int prim);
bool PrimCompatible(int prim);
// Triangles
void AddList(int numVerts);
void AddStrip(int numVerts);
void AddFan(int numVerts);
// Lines
void AddLineList(int numVerts);
void AddLineStrip(int numVerts);
// 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 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);
void TranslateList(int numVerts, const u16 *inds, int offset);
void TranslateStrip(int numVerts, const u16 *inds, int offset);
void TranslateFan(int numVerts, const u16 *inds, int offset);
private:
u16 *inds_;
int index_;
int prim_;
};

View File

@ -15,10 +15,6 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
// TODO: We should transition from doing the transform in software, as seen in TransformPipeline.cpp,
// into doing the transform in the vertex shader - except for Rectangles, there we really need to do
// the transforms ourselves.
#include <stdio.h>
#if defined(_WIN32) && defined(_DEBUG)
#include <windows.h>
@ -42,7 +38,6 @@ static char buffer[16384];
#define WRITE p+=sprintf
bool CanUseHardwareTransform(int prim)
{
if (!g_Config.bHardwareTransform)

View File

@ -120,6 +120,7 @@
<ClInclude Include="GLES\DisplayListInterpreter.h" />
<ClInclude Include="GLES\FragmentShaderGenerator.h" />
<ClInclude Include="GLES\Framebuffer.h" />
<ClInclude Include="GLES\IndexGenerator.h" />
<ClInclude Include="GLES\ShaderManager.h" />
<ClInclude Include="GLES\StateMapping.h" />
<ClInclude Include="GLES\TextureCache.h" />
@ -135,6 +136,7 @@
<ClCompile Include="GLES\DisplayListInterpreter.cpp" />
<ClCompile Include="GLES\FragmentShaderGenerator.cpp" />
<ClCompile Include="GLES\Framebuffer.cpp" />
<ClCompile Include="GLES\IndexGenerator.cpp" />
<ClCompile Include="GLES\ShaderManager.cpp" />
<ClCompile Include="GLES\StateMapping.cpp" />
<ClCompile Include="GLES\TextureCache.cpp" />

View File

@ -57,6 +57,9 @@
<ClInclude Include="GLES\StateMapping.h">
<Filter>GLES</Filter>
</ClInclude>
<ClInclude Include="GLES\IndexGenerator.h">
<Filter>GLES</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Math3D.cpp">
@ -95,6 +98,9 @@
<ClCompile Include="GLES\StateMapping.cpp">
<Filter>GLES</Filter>
</ClCompile>
<ClCompile Include="GLES\IndexGenerator.cpp">
<Filter>GLES</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />

View File

@ -72,6 +72,7 @@ LOCAL_SRC_FILES := \
$(SRC)/GPU/GLES/Framebuffer.cpp \
$(SRC)/GPU/GLES/DisplayListInterpreter.cpp \
$(SRC)/GPU/GLES/TextureCache.cpp \
$(SRC)/GPU/GLES/IndexGenerator.cpp \
$(SRC)/GPU/GLES/TransformPipeline.cpp \
$(SRC)/GPU/GLES/StateMapping.cpp \
$(SRC)/GPU/GLES/VertexDecoder.cpp \