Split code from GLES_GPU to TransformDrawEngine, cleanup

This commit is contained in:
Henrik Rydgård 2012-12-25 13:47:59 +01:00
parent b5b13256b6
commit d21647bbb9
8 changed files with 180 additions and 201 deletions

View File

@ -33,17 +33,11 @@
#include "../../Core/HLE/sceKernelThread.h"
#include "../../Core/HLE/sceKernelInterrupt.h"
inline void glEnDis(GLuint cmd, int value)
{
(value ? glEnable : glDisable)(cmd);
}
ShaderManager shaderManager;
extern u32 curTextureWidth;
extern u32 curTextureHeight;
bool *flushBeforeCommand = 0;
const int flushBeforeCommandList[] = {
GE_CMD_BEZIER,
GE_CMD_SPLINE,
@ -54,10 +48,10 @@ const int flushBeforeCommandList[] = {
GE_CMD_OFFSETADDR,
GE_CMD_REGION1,
GE_CMD_REGION2,
GE_CMD_CULLFACEENABLE,
GE_CMD_TEXTUREMAPENABLE,
GE_CMD_CULLFACEENABLE,
GE_CMD_TEXTUREMAPENABLE,
GE_CMD_LIGHTINGENABLE,
GE_CMD_FOGENABLE,
GE_CMD_FOGENABLE,
GE_CMD_TEXSCALEU,
GE_CMD_TEXSCALEV,
GE_CMD_TEXOFFSETU,
@ -163,43 +157,38 @@ GLES_GPU::GLES_GPU(int renderWidth, int renderHeight)
displayFramebufPtr_(0),
renderWidth_(renderWidth),
renderHeight_(renderHeight),
dlIdGenerator(1)
{
dlIdGenerator(1),
transformDraw_(&shaderManager) {
renderWidthFactor_ = (float)renderWidth / 480.0f;
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!");
}
flushBeforeCommand = new bool[256];
memset(flushBeforeCommand, 0, 256 * sizeof(bool));
flushBeforeCommand_ = new bool[256];
memset(flushBeforeCommand_, 0, 256 * sizeof(bool));
for (int i = 0; i < ARRAY_SIZE(flushBeforeCommandList); i++) {
flushBeforeCommand[flushBeforeCommandList[i]] = true;
flushBeforeCommand_[flushBeforeCommandList[i]] = true;
}
flushBeforeCommand[1] = false;
flushBeforeCommand_[1] = false;
}
GLES_GPU::~GLES_GPU()
{
GLES_GPU::~GLES_GPU() {
TextureCache_Shutdown();
for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter)
{
for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) {
fbo_destroy((*iter)->fbo);
delete (*iter);
}
vfbs_.clear();
delete flushBeforeCommand;
delete [] flushBeforeCommand_;
}
void GLES_GPU::InitClear()
{
if (!g_Config.bBufferedRendering)
{
void GLES_GPU::InitClear() {
if (!g_Config.bBufferedRendering) {
glClearColor(0,0,0,1);
// glClearColor(1,0,1,1);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
@ -207,13 +196,11 @@ void GLES_GPU::InitClear()
glViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
}
void GLES_GPU::BeginFrame()
{
void GLES_GPU::BeginFrame() {
TextureCache_Decimate();
// NOTE - this is all wrong. At the beginning of the frame is a TERRIBLE time to draw the fb.
if (g_Config.bDisplayFramebuffer && displayFramebufPtr_)
{
if (g_Config.bDisplayFramebuffer && displayFramebufPtr_) {
INFO_LOG(HLE, "Drawing the framebuffer");
const u8 *pspframebuf = Memory::GetPointer((0x44000000) | (displayFramebufPtr_ & 0x1FFFFF)); // TODO - check
glstate.cullFace.disable();
@ -225,8 +212,7 @@ void GLES_GPU::BeginFrame()
currentRenderVfb_ = 0;
}
void GLES_GPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, int format)
{
void GLES_GPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, int format) {
if (framebuf & 0x04000000) {
DEBUG_LOG(G3D, "Switch display framebuffer %08x", framebuf);
displayFramebufPtr_ = framebuf;
@ -237,9 +223,8 @@ void GLES_GPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, int format)
}
}
void GLES_GPU::CopyDisplayToOutput()
{
Flush();
void GLES_GPU::CopyDisplayToOutput() {
transformDraw_.Flush();
if (!g_Config.bBufferedRendering)
return;
@ -271,17 +256,15 @@ void GLES_GPU::CopyDisplayToOutput()
// These are in the output display coordinates
framebufferManager.DrawActiveTexture(480, 272, true);
shaderManager.DirtyShader();
shaderManager.DirtyUniform(DIRTY_ALL);
shaderManager_->DirtyShader();
shaderManager_->DirtyUniform(DIRTY_ALL);
gstate_c.textureChanged = true;
BeginDebugDraw();
}
GLES_GPU::VirtualFramebuffer *GLES_GPU::GetDisplayFBO()
{
for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter)
{
GLES_GPU::VirtualFramebuffer *GLES_GPU::GetDisplayFBO() {
for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) {
if (((*iter)->fb_address & 0x3FFFFFF) == (displayFramebufPtr_ & 0x3FFFFFF)) {
// Could check w to but whatever
return *iter;
@ -291,8 +274,7 @@ GLES_GPU::VirtualFramebuffer *GLES_GPU::GetDisplayFBO()
return 0;
}
void GLES_GPU::SetRenderFrameBuffer()
{
void GLES_GPU::SetRenderFrameBuffer() {
if (!g_Config.bBufferedRendering)
return;
// Get parameters
@ -301,7 +283,7 @@ void GLES_GPU::SetRenderFrameBuffer()
u32 z_address = (gstate.zbptr & 0xFFE000) | ((gstate.zbwidth & 0xFF0000) << 8);
int z_stride = gstate.zbwidth & 0x3C0;
// Yeah this is not completely right. but it'll do for now.
int drawing_width = ((gstate.region2) & 0x3FF) + 1;
int drawing_height = ((gstate.region2 >> 10) & 0x3FF) + 1;
@ -310,8 +292,7 @@ void GLES_GPU::SetRenderFrameBuffer()
// Find a matching framebuffer
VirtualFramebuffer *vfb = 0;
for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter)
{
for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) {
VirtualFramebuffer *v = *iter;
if (v->fb_address == fb_address) {
// Let's not be so picky for now. Let's say this is the one.
@ -324,7 +305,7 @@ void GLES_GPU::SetRenderFrameBuffer()
// None found? Create one.
if (!vfb) {
Flush();
transformDraw_.Flush();
gstate_c.textureChanged = true;
vfb = new VirtualFramebuffer;
vfb->fb_address = fb_address;
@ -344,9 +325,8 @@ void GLES_GPU::SetRenderFrameBuffer()
return;
}
if (vfb != currentRenderVfb_)
{
Flush();
if (vfb != currentRenderVfb_) {
transformDraw_.Flush();
// Use it as a render target.
DEBUG_LOG(HLE, "Switching render target to FBO for %08x", vfb->fb_address);
gstate_c.textureChanged = true;
@ -356,8 +336,7 @@ void GLES_GPU::SetRenderFrameBuffer()
}
}
void GLES_GPU::BeginDebugDraw()
{
void GLES_GPU::BeginDebugDraw() {
if (g_Config.bDrawWireframe) {
#ifndef USING_GLES2
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@ -373,23 +352,18 @@ void GLES_GPU::EndDebugDraw() {
// Render queue
bool GLES_GPU::ProcessDLQueue()
{
bool GLES_GPU::ProcessDLQueue() {
std::vector<DisplayList>::iterator iter = dlQueue.begin();
while (!(iter == dlQueue.end()))
{
while (!(iter == dlQueue.end())) {
DisplayList &l = *iter;
dcontext.pc = l.listpc;
dcontext.stallAddr = l.stall;
// DEBUG_LOG(G3D,"Okay, starting DL execution at %08 - stall = %08x", context.pc, stallAddr);
if (!InterpretList())
{
if (!InterpretList()) {
l.listpc = dcontext.pc;
l.stall = dcontext.stallAddr;
return false;
}
else
{
} else {
//At the end, we can remove it from the queue and continue
dlQueue.erase(iter);
//this invalidated the iterator, let's fix it
@ -399,8 +373,7 @@ bool GLES_GPU::ProcessDLQueue()
return true; //no more lists!
}
u32 GLES_GPU::EnqueueList(u32 listpc, u32 stall)
{
u32 GLES_GPU::EnqueueList(u32 listpc, u32 stall) {
DisplayList dl;
dl.id = dlIdGenerator++;
dl.listpc = listpc & 0xFFFFFFF;
@ -412,8 +385,7 @@ u32 GLES_GPU::EnqueueList(u32 listpc, u32 stall)
return 0;
}
void GLES_GPU::UpdateStall(int listid, u32 newstall)
{
void GLES_GPU::UpdateStall(int listid, u32 newstall) {
// this needs improvement....
for (std::vector<DisplayList>::iterator iter = dlQueue.begin(); iter != dlQueue.end(); iter++)
{
@ -423,55 +395,23 @@ void GLES_GPU::UpdateStall(int listid, u32 newstall)
l.stall = newstall & 0xFFFFFFF;
}
}
ProcessDLQueue();
}
void GLES_GPU::DrawSync(int mode)
{
Flush();
void GLES_GPU::DrawSync(int mode) {
transformDraw_.Flush();
}
void GLES_GPU::Continue()
{
void GLES_GPU::Continue() {
}
void GLES_GPU::Break()
{
void GLES_GPU::Break() {
}
// Just to get something on the screen, we'll just not subdivide correctly.
void GLES_GPU::DrawBezier(int ucount, int vcount)
{
u16 indices[3 * 3 * 6];
float customUV[32];
int c = 0;
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
indices[c++] = y * 4 + x;
indices[c++] = y * 4 + x + 1;
indices[c++] = (y + 1) * 4 + x + 1;
indices[c++] = (y + 1) * 4 + x + 1;
indices[c++] = (y + 1) * 4 + x;
indices[c++] = y * 4 + x;
}
}
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
customUV[(y * 4 + x) * 2 + 0] = (float)x/3.0f;
customUV[(y * 4 + x) * 2 + 1] = (float)y/3.0f;
}
}
TransformAndDrawPrim(Memory::GetPointer(gstate_c.vertexAddr), &indices[0], GE_PRIM_TRIANGLES, 3 * 3 * 6, customUV, GE_VTYPE_IDX_16BIT);
}
void EnterClearMode(u32 data)
{
static void EnterClearMode(u32 data) {
bool colMask = (data >> 8) & 1;
bool alphaMask = (data >> 9) & 1;
bool updateZ = (data >> 10) & 1;
@ -479,8 +419,7 @@ void EnterClearMode(u32 data)
glstate.depthWrite.set(updateZ ? GL_TRUE : GL_FALSE);
}
void LeaveClearMode()
{
static void LeaveClearMode() {
// We have to reset the following state as per the state of the command registers:
// Back face culling
// Texture map enable (meh)
@ -492,8 +431,7 @@ void LeaveClearMode()
// dirtyshader?
}
void GLES_GPU::ExecuteOp(u32 op, u32 diff)
{
void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
u32 cmd = op >> 24;
u32 data = op & 0xFFFFFF;
@ -553,7 +491,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
// Seems we have to advance the vertex addr, at least in some cases.
// Question: Should we also advance the index addr?
int bytesRead;
TransformAndDrawPrim(verts, inds, type, count, 0, -1, &bytesRead);
transformDraw_.SubmitPrim(verts, inds, type, count, 0, -1, &bytesRead);
gstate_c.vertexAddr += bytesRead;
}
break;
@ -563,7 +501,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
{
int bz_ucount = data & 0xFF;
int bz_vcount = (data >> 8) & 0xFF;
DrawBezier(bz_ucount, bz_vcount);
transformDraw_.DrawBezier(bz_ucount, bz_vcount);
DEBUG_LOG(G3D,"DL DRAW BEZIER: %i x %i", bz_ucount, bz_vcount);
}
break;
@ -690,7 +628,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
DEBUG_LOG(G3D,"DL SetVertexType: %06x", data);
if (diff & GE_VTYPE_THROUGH) {
// Throughmode changed, let's make the proj matrix dirty.
shaderManager.DirtyUniform(DIRTY_PROJMATRIX);
shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
}
// This sets through-mode or not, as well.
break;
@ -755,25 +693,25 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
case GE_CMD_TEXSCALEU:
gstate_c.uScale = getFloat24(data);
DEBUG_LOG(G3D, "DL Texture U Scale: %f", gstate_c.uScale);
shaderManager.DirtyUniform(DIRTY_UVSCALEOFFSET);
shaderManager_->DirtyUniform(DIRTY_UVSCALEOFFSET);
break;
case GE_CMD_TEXSCALEV:
gstate_c.vScale = getFloat24(data);
DEBUG_LOG(G3D, "DL Texture V Scale: %f", gstate_c.vScale);
shaderManager.DirtyUniform(DIRTY_UVSCALEOFFSET);
shaderManager_->DirtyUniform(DIRTY_UVSCALEOFFSET);
break;
case GE_CMD_TEXOFFSETU:
gstate_c.uOff = getFloat24(data);
DEBUG_LOG(G3D, "DL Texture U Offset: %f", gstate_c.uOff);
shaderManager.DirtyUniform(DIRTY_UVSCALEOFFSET);
shaderManager_->DirtyUniform(DIRTY_UVSCALEOFFSET);
break;
case GE_CMD_TEXOFFSETV:
gstate_c.vOff = getFloat24(data);
DEBUG_LOG(G3D, "DL Texture V Offset: %f", gstate_c.vOff);
shaderManager.DirtyUniform(DIRTY_UVSCALEOFFSET);
shaderManager_->DirtyUniform(DIRTY_UVSCALEOFFSET);
break;
case GE_CMD_SCISSOR1:
@ -985,37 +923,37 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
case GE_CMD_MATERIALAMBIENT:
DEBUG_LOG(G3D,"DL Material Ambient Color: %06x", data);
if (diff)
shaderManager.DirtyUniform(DIRTY_MATAMBIENTALPHA);
shaderManager_->DirtyUniform(DIRTY_MATAMBIENTALPHA);
break;
case GE_CMD_MATERIALDIFFUSE:
DEBUG_LOG(G3D,"DL Material Diffuse Color: %06x", data);
if (diff)
shaderManager.DirtyUniform(DIRTY_MATDIFFUSE);
shaderManager_->DirtyUniform(DIRTY_MATDIFFUSE);
break;
case GE_CMD_MATERIALEMISSIVE:
DEBUG_LOG(G3D,"DL Material Emissive Color: %06x", data);
if (diff)
shaderManager.DirtyUniform(DIRTY_MATEMISSIVE);
shaderManager_->DirtyUniform(DIRTY_MATEMISSIVE);
break;
case GE_CMD_MATERIALSPECULAR:
DEBUG_LOG(G3D,"DL Material Specular Color: %06x", data);
if (diff)
shaderManager.DirtyUniform(DIRTY_MATSPECULAR);
shaderManager_->DirtyUniform(DIRTY_MATSPECULAR);
break;
case GE_CMD_MATERIALALPHA:
DEBUG_LOG(G3D,"DL Material Alpha Color: %06x", data);
if (diff)
shaderManager.DirtyUniform(DIRTY_MATAMBIENTALPHA);
shaderManager_->DirtyUniform(DIRTY_MATAMBIENTALPHA);
break;
case GE_CMD_MATERIALSPECULARCOEF:
DEBUG_LOG(G3D,"DL Material specular coef: %f", getFloat24(data));
if (diff)
shaderManager.DirtyUniform(DIRTY_MATSPECULAR);
shaderManager_->DirtyUniform(DIRTY_MATSPECULAR);
break;
case GE_CMD_LIGHTTYPE0:
@ -1037,7 +975,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
DEBUG_LOG(G3D,"DL Light %i %c pos: %f", l, c+'X', val);
gstate_c.lightpos[l][c] = val;
if (diff)
shaderManager.DirtyUniform(DIRTY_LIGHT0 << l);
shaderManager_->DirtyUniform(DIRTY_LIGHT0 << l);
}
break;
@ -1053,7 +991,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
DEBUG_LOG(G3D,"DL Light %i %c dir: %f", l, c+'X', val);
gstate_c.lightdir[l][c] = val;
if (diff)
shaderManager.DirtyUniform(DIRTY_LIGHT0 << l);
shaderManager_->DirtyUniform(DIRTY_LIGHT0 << l);
}
break;
@ -1069,7 +1007,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
DEBUG_LOG(G3D,"DL Light %i %c att: %f", l, c+'X', val);
gstate_c.lightatt[l][c] = val;
if (diff)
shaderManager.DirtyUniform(DIRTY_LIGHT0 << l);
shaderManager_->DirtyUniform(DIRTY_LIGHT0 << l);
}
break;
@ -1089,7 +1027,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
gstate_c.lightColor[t][l][1] = g;
gstate_c.lightColor[t][l][2] = b;
if (diff)
shaderManager.DirtyUniform(DIRTY_LIGHT0 << l);
shaderManager_->DirtyUniform(DIRTY_LIGHT0 << l);
}
break;
@ -1171,7 +1109,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
case GE_CMD_ALPHATEST:
DEBUG_LOG(G3D,"DL Alpha test settings");
shaderManager.DirtyUniform(DIRTY_ALPHACOLORREF);
shaderManager_->DirtyUniform(DIRTY_ALPHACOLORREF);
break;
case GE_CMD_TEXFUNC:
@ -1211,7 +1149,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
case GE_CMD_TEXENVCOLOR:
DEBUG_LOG(G3D,"DL TexEnvColor %06x", data);
if (diff)
shaderManager.DirtyUniform(DIRTY_TEXENV);
shaderManager_->DirtyUniform(DIRTY_TEXENV);
break;
case GE_CMD_TEXMODE:
DEBUG_LOG(G3D,"DL TexMode %08x", data);
@ -1278,7 +1216,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
if (num < 12)
gstate.worldMatrix[num++] = getFloat24(data);
gstate.worldmtxnum = (gstate.worldmtxnum & 0xFF000000) | (num & 0xF);
shaderManager.DirtyUniform(DIRTY_WORLDMATRIX);
shaderManager_->DirtyUniform(DIRTY_WORLDMATRIX);
}
break;
@ -1294,7 +1232,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
if (num < 12)
gstate.viewMatrix[num++] = getFloat24(data);
gstate.viewmtxnum = (gstate.viewmtxnum & 0xFF000000) | (num & 0xF);
shaderManager.DirtyUniform(DIRTY_VIEWMATRIX);
shaderManager_->DirtyUniform(DIRTY_VIEWMATRIX);
}
break;
@ -1310,7 +1248,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
gstate.projMatrix[num++] = getFloat24(data);
gstate.projmtxnum = (gstate.projmtxnum & 0xFF000000) | (num & 0xF);
}
shaderManager.DirtyUniform(DIRTY_PROJMATRIX);
shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
break;
case GE_CMD_TGENMATRIXNUMBER:
@ -1326,7 +1264,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
gstate.tgenMatrix[num++] = getFloat24(data);
gstate.texmtxnum = (gstate.texmtxnum & 0xFF000000) | (num & 0xF);
}
shaderManager.DirtyUniform(DIRTY_TEXMATRIX);
shaderManager_->DirtyUniform(DIRTY_TEXMATRIX);
break;
case GE_CMD_BONEMATRIXNUMBER:
@ -1338,7 +1276,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
DEBUG_LOG(G3D,"DL BONE data #%i %f", gstate.boneMatrixNumber & 0x7f, getFloat24(data));
{
int num = gstate.boneMatrixNumber & 0x7F;
shaderManager.DirtyUniform(DIRTY_BONEMATRIX0 << (num / 12));
shaderManager_->DirtyUniform(DIRTY_BONEMATRIX0 << (num / 12));
if (num < 96) {
gstate.boneMatrix[num++] = getFloat24(data);
}
@ -1373,8 +1311,8 @@ bool GLES_GPU::InterpretList()
op = Memory::ReadUnchecked_U32(dcontext.pc); //read from memory
u32 cmd = op >> 24;
u32 diff = op ^ gstate.cmdmem[cmd];
if (flushBeforeCommand[cmd])
Flush();
if (flushBeforeCommand_[cmd])
transformDraw_.Flush();
gstate.cmdmem[cmd] = op;
ExecuteOp(op, diff);
@ -1387,9 +1325,9 @@ bool GLES_GPU::InterpretList()
void GLES_GPU::UpdateStats()
{
gpuStats.numVertexShaders = shaderManager.NumVertexShaders();
gpuStats.numFragmentShaders = shaderManager.NumFragmentShaders();
gpuStats.numShaders = shaderManager.NumPrograms();
gpuStats.numVertexShaders = shaderManager_->NumVertexShaders();
gpuStats.numFragmentShaders = shaderManager_->NumFragmentShaders();
gpuStats.numShaders = shaderManager_->NumPrograms();
gpuStats.numTextures = TextureCache_NumLoadedTextures();
}
@ -1443,3 +1381,7 @@ void GLES_GPU::InvalidateCache(u32 addr, int size)
else
TextureCache_Clear(true);
}
void GLES_GPU::Flush() {
transformDraw_.Flush();
}

View File

@ -23,6 +23,7 @@
#include "../GPUInterface.h"
#include "Framebuffer.h"
#include "VertexDecoder.h"
#include "TransformPipeline.h"
#include "gfx_es2/fbo.h"
class ShaderManager;
@ -51,15 +52,8 @@ public:
virtual void UpdateStats();
virtual void InvalidateCache(u32 addr, int size);
virtual void Flush();
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();
void UpdateViewportAndProjection();
void DrawBezier(int ucount, int vcount);
void DoBlockTransfer();
bool ProcessDLQueue();
@ -68,8 +62,9 @@ private:
void EndDebugDraw();
FramebufferManager framebufferManager;
TransformDrawEngine transformDraw_;
ShaderManager *shaderManager_;
bool *flushBeforeCommand_;
bool interruptsEnabled_;
u32 displayFramebufPtr_;
@ -82,8 +77,7 @@ private:
float renderWidthFactor_;
float renderHeightFactor_;
struct CmdProcessorState
{
struct CmdProcessorState {
u32 pc;
u32 stallAddr;
};
@ -92,8 +86,7 @@ private:
int dlIdGenerator;
struct DisplayList
{
struct DisplayList {
int id;
u32 listpc;
u32 stall;

View File

@ -3,6 +3,7 @@
#include "../Math3D.h"
#include "../GPUState.h"
#include "../../Core/System.h"
#include "../ge_constants.h"
#include "DisplayListInterpreter.h"
#include "ShaderManager.h"
@ -59,7 +60,7 @@ const GLuint ztests[] =
GL_LESS, GL_LEQUAL, GL_GREATER, GL_GEQUAL,
};
void GLES_GPU::ApplyDrawState()
void ApplyDrawState()
{
// TODO: All this setup is soon so expensive that we'll need dirty flags, or simply do it in the command writes where we detect dirty by xoring. Silly to do all this work on every drawcall.
@ -71,7 +72,7 @@ void GLES_GPU::ApplyDrawState()
bool wantCull = !gstate.isModeClear() && !gstate.isModeThrough() && gstate.isCullEnabled();
glstate.cullFace.set(wantCull);
if(wantCull) {
if (wantCull) {
u8 cullMode = gstate.getCullMode();
glstate.cullFaceMode.set(cullingMode[cullMode]);
}
@ -162,8 +163,11 @@ void GLES_GPU::ApplyDrawState()
glstate.depthRange.set(depthRangeMin, depthRangeMax);
}
void GLES_GPU::UpdateViewportAndProjection()
{
void UpdateViewportAndProjection() {
int renderWidth = PSP_CoreParameter().renderWidth;
int renderHeight = PSP_CoreParameter().renderHeight;
float renderWidthFactor = (float)renderWidth / 480.0f;
float renderHeightFactor = (float)renderHeight / 272.0f;
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
@ -178,7 +182,7 @@ void GLES_GPU::UpdateViewportAndProjection()
if (throughmode) {
// No viewport transform here. Let's experiment with using region.
return;
glViewport((0 + regionX1) * renderWidthFactor_, (0 - regionY1) * renderHeightFactor_, (regionX2 - regionX1) * renderWidthFactor_, (regionY2 - regionY1) * renderHeightFactor_);
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.
float vpXa = getFloat24(gstate.viewportx1);
@ -208,15 +212,15 @@ void GLES_GPU::UpdateViewportAndProjection()
float vpZ0 = (vpZb - vpZa) / 65536.0f;
float vpZ1 = (vpZa * 2) / 65536.0f;
vpX0 *= renderWidthFactor_;
vpY0 *= renderHeightFactor_;
vpWidth *= renderWidthFactor_;
vpHeight *= renderHeightFactor_;
vpX0 *= renderWidthFactor;
vpY0 *= renderHeightFactor;
vpWidth *= renderWidthFactor;
vpHeight *= renderHeightFactor;
// Flip vpY0 to match the OpenGL coordinate system.
vpY0 = renderHeight_ - (vpY0 + vpHeight);
vpY0 = renderHeight - (vpY0 + 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);
// shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
}
}

View File

@ -5,3 +5,8 @@ extern const GLint bLookup[];
extern const GLint eqLookup[];
extern const GLint cullingMode[];
extern const GLuint ztests[];
void ApplyDrawState();
void UpdateViewportAndProjection();

View File

@ -30,7 +30,6 @@
#include "VertexDecoder.h"
#include "ShaderManager.h"
#include "DisplayListInterpreter.h"
#include "IndexGenerator.h"
const GLuint glprim[8] = {
GL_POINTS,
@ -45,15 +44,44 @@ const GLuint glprim[8] = {
u8 decoded[65536 * 32];
VertexDecoder dec;
uint16_t decIndex[65536];
int numVerts;
IndexGenerator indexGen;
TransformedVertex transformed[65536];
TransformedVertex transformedExpanded[65536];
TransformDrawEngine::TransformDrawEngine(ShaderManager *shaderManager)
: numVerts(0),
shaderManager_(shaderManager) {
indexGen.Setup(decIndex);
}
// TODO: This should really return 2 colors, one for specular and one for diffuse.
TransformDrawEngine::~TransformDrawEngine() {
}
// Just to get something on the screen, we'll just not subdivide correctly.
void TransformDrawEngine::DrawBezier(int ucount, int vcount) {
u16 indices[3 * 3 * 6];
float customUV[32];
int c = 0;
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
indices[c++] = y * 4 + x;
indices[c++] = y * 4 + x + 1;
indices[c++] = (y + 1) * 4 + x + 1;
indices[c++] = (y + 1) * 4 + x + 1;
indices[c++] = (y + 1) * 4 + x;
indices[c++] = y * 4 + x;
}
}
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
customUV[(y * 4 + x) * 2 + 0] = (float)x/3.0f;
customUV[(y * 4 + x) * 2 + 1] = (float)y/3.0f;
}
}
SubmitPrim(Memory::GetPointer(gstate_c.vertexAddr), &indices[0], GE_PRIM_TRIANGLES, 3 * 3 * 6, customUV, GE_VTYPE_IDX_16BIT, 0);
}
// Convenient way to do precomputation to save the parts of the lighting calculation
// that's common between the many vertices of a draw call.
@ -295,7 +323,7 @@ void SoftwareTransformAndDraw(int prim, LinkedShader *program, int vertexCount,
VertexReader reader(decoded, decVtxFormat);
for (int index = 0; index < maxIndex; index++)
{
{
reader.Goto(index);
float v[3] = {0, 0, 0};
@ -365,7 +393,7 @@ void SoftwareTransformAndDraw(int prim, LinkedShader *program, int vertexCount,
}
}
}
// Yes, we really must multiply by the world matrix too.
Vec3ByMatrix43(out, psum.v, gstate.worldMatrix);
if (reader.hasNormal()) {
@ -574,12 +602,7 @@ void SoftwareTransformAndDraw(int prim, LinkedShader *program, int vertexCount,
if (program->a_color1 != -1) glDisableVertexAttribArray(program->a_color1);
}
void GLES_GPU::InitTransform() {
indexGen.Setup(decIndex);
numVerts = 0;
}
void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int vertexCount, float *customUV, int forceIndexType, int *bytesRead)
void TransformDrawEngine::SubmitPrim(void *verts, void *inds, int prim, int vertexCount, float *customUV, int forceIndexType, int *bytesRead)
{
// For the future
if (!indexGen.PrimCompatible(prim))
@ -642,8 +665,7 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte
}
}
void GLES_GPU::Flush()
{
void TransformDrawEngine::Flush() {
if (indexGen.Empty())
return;
// From here on out, the index type is ALWAYS 16-bit. Deal with it.
@ -660,10 +682,8 @@ void GLES_GPU::Flush()
}
#endif
// Check if anything needs updating
if (gstate_c.textureChanged)
{
if ((gstate.textureMapEnable & 1) && !gstate.isModeClear())
{
if (gstate_c.textureChanged) {
if ((gstate.textureMapEnable & 1) && !gstate.isModeClear()) {
PSPSetTexture();
}
gstate_c.textureChanged = false;

View File

@ -17,52 +17,68 @@
#pragma once
#include "IndexGenerator.h"
class LinkedShader;
class ShaderManager;
struct DecVtxFormat;
// Handles transform, lighting and drawing.
class TransformDrawEngine {
public:
TransformDrawEngine(ShaderManager *shaderManager);
~TransformDrawEngine();
void SubmitPrim(void *verts, void *inds, int prim, int vertexCount, float *customUV, int forceIndexType, int *bytesRead);
void DrawBezier(int ucount, int vcount);
void Flush();
private:
// Vertex collector state
IndexGenerator indexGen;
int numVerts;
// Vertex collector buffers
// Other
ShaderManager *shaderManager_;
};
// void SoftwareTransformAndDraw(int prim, LinkedShader *program, int vertexCount, void *inds, int indexType, const DecVtxFormat &decVtxFormat, int maxIndex, float *customUV);
// Only used by SW transform
struct Color4
{
float r,g,b,a;
struct Color4 {
float r, g, b, a;
Color4() : r(0), g(0), b(0), a(0) { }
Color4(float _r, float _g, float _b, float _a=1.0f)
{
r=_r; g=_g; b=_b; a=_a;
: r(_r), g(_g), b(_b), a(_a) {
}
Color4(const float in[4]) {r=in[0];g=in[1];b=in[2];a=in[3];}
Color4(const float in[3], float alpha) {r=in[0];g=in[1];b=in[2];a=alpha;}
const float &operator [](int i) const {return *(&r + i);}
Color4 operator *(float f) const
{
Color4 operator *(float f) const {
return Color4(f*r,f*g,f*b,f*a);
}
Color4 operator *(const Color4 &c) const
{
Color4 operator *(const Color4 &c) const {
return Color4(r*c.r,g*c.g,b*c.b,a*c.a);
}
Color4 operator +(const Color4 &c) const
{
Color4 operator +(const Color4 &c) const {
return Color4(r+c.r,g+c.g,b+c.b,a+c.a);
}
void operator +=(const Color4 &c)
{
void operator +=(const Color4 &c) {
r+=c.r;
g+=c.g;
b+=c.b;
a+=c.a;
}
void GetFromRGB(u32 col)
{
void GetFromRGB(u32 col) {
r = ((col>>16) & 0xff)/255.0f;
g = ((col>>8) & 0xff)/255.0f;
b = ((col>>0) & 0xff)/255.0f;
}
void GetFromA(u32 col)
{
void GetFromA(u32 col) {
a = (col&0xff)/255.0f;
}
};
// void SoftwareTransformAndDraw(int prim, LinkedShader *program, int vertexCount, void *inds, int indexType, const DecVtxFormat &decVtxFormat, int maxIndex, float *customUV);

View File

@ -33,7 +33,7 @@ public:
virtual void UpdateStall(int listid, u32 newstall) = 0;
virtual void DrawSync(int mode) = 0;
virtual void Continue() = 0;
virtual void ExecuteOp(u32 op, u32 diff) = 0;
virtual bool InterpretList() = 0;

View File

@ -37,7 +37,7 @@ void InitGfxState()
gstate.lightingEnable = 0x17000001;
static const float identity4x3[12] =
static const float identity4x3[12] =
{1,0,0,
0,1,0,
0,0,1,
@ -78,7 +78,6 @@ void ReapplyGfxState()
{
if (!gpu)
return;
gpu->Flush();
// ShaderManager_DirtyShader();
// The commands are embedded in the command memory so we can just reexecute the words. Convenient.
// To be safe we pass 0xFFFFFFF as the diff.
@ -96,9 +95,9 @@ void ReapplyGfxState()
for (int i = GE_CMD_VERTEXTYPE; i < GE_CMD_BONEMATRIXNUMBER; i++)
{
gpu->ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF);
gpu->ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF);
}
// Can't write to bonematrixnumber here
for (int i = GE_CMD_MORPHWEIGHT0; i < GE_CMD_PATCHFACING; i++)