Aligned all vertex components to 4 byte boundaries - maybe ATI likes that? Renamed and reorganized misc things.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@981 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2008-10-27 21:38:30 +00:00
parent d35fb4e2b0
commit 5129341a9c
33 changed files with 437 additions and 524 deletions

View File

@ -75,7 +75,6 @@ public:
// TODO: move these in under private:
int m_VBVertexStride; // PC-side vertex stride
int m_VBStridePad;
u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present.
};

View File

@ -284,15 +284,15 @@ inline void decodebytesARGB8_4(u32 *dst, const u16 *src, const u16 *src2)
inline u32 makecol(int r, int g, int b, int a)
{
return ((a&255)<<24)|((r&255)<<16)|((g&255)<<8)|((b&255));
return (a<<24)|(r<<16)|(g<<8)|b;
}
void decodeDXTBlock(u32 *dst, const DXTBlock *src, int pitch)
{
u16 c1 = Common::swap16(src->color1);
u16 c2 = Common::swap16(src->color2);
int blue1 = lut5to8[c1&0x1F];
int blue2 = lut5to8[c2&0x1F];
int blue1 = lut5to8[c1 & 0x1F];
int blue2 = lut5to8[c2 & 0x1F];
int green1 = lut6to8[(c1>>5) & 0x3F];
int green2 = lut6to8[(c2>>5) & 0x3F];
int red1 = lut5to8[(c1>>11) & 0x1F];
@ -320,7 +320,7 @@ void decodeDXTBlock(u32 *dst, const DXTBlock *src, int pitch)
int val = src->lines[y];
for (int x = 0; x < 4; x++)
{
dst[x] = colors[(val>>6) & 3];
dst[x] = colors[(val >> 6) & 3];
val <<= 2;
}
dst += pitch;
@ -515,11 +515,12 @@ PC_TexFormat TexDecoder_Decode(u8 *dst, const u8 *src, int width, int height, in
}
}
return PC_TEX_FMT_BGRA32;
case GX_TF_CMPR:
case GX_TF_CMPR: // speed critical
{
// TODO: Shuffle to PC S3TC (DXTC) format instead of converting
// 11111111 22222222 55555555 66666666
// 33333333 44444444 77777777 88888888
// The metroid games use this format almost exclusively.
for (int y = 0; y < height; y += 8)
for (int x = 0; x < width; x += 8)
{

View File

@ -19,4 +19,4 @@
// STATE_TO_SAVE
XFRegisters xfregs;
u32 xfmem[XFMEM_SIZE];
u32 xfmem[XFMEM_SIZE];

View File

@ -173,6 +173,8 @@ struct XFRegisters
ColorChannel colChans[2]; //C0A0 C1A1
TexCoordInfo texcoords[8];
bool bEnableDualTexTransform;
float rawViewport[6];
float rawProjection[7];
};
#define XFMEM_SIZE 0x8000

View File

@ -1205,14 +1205,6 @@
RelativePath=".\Src\OpcodeDecoding.cpp"
>
</File>
<File
RelativePath=".\Src\VertexHandler.cpp"
>
</File>
<File
RelativePath=".\Src\VertexHandler.h"
>
</File>
<File
RelativePath=".\Src\VertexLoader.cpp"
>
@ -1245,6 +1237,14 @@
RelativePath=".\Src\VertexLoader_TextCoord.h"
>
</File>
<File
RelativePath=".\Src\VertexManager.cpp"
>
</File>
<File
RelativePath=".\Src\VertexManager.h"
>
</File>
<File
RelativePath=".\Src\XFStructs.cpp"
>

View File

@ -24,7 +24,7 @@
#include "OpcodeDecoding.h"
#include "TextureCache.h"
#include "TextureDecoder.h"
#include "VertexHandler.h"
#include "VertexManager.h"
#include "PixelShader.h"
#include "Utils.h"
@ -112,7 +112,7 @@ void BPWritten(int addr, int changes, int newval)
case BPMEM_GENMODE:
if (changes)
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
// dev->SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]);
@ -146,7 +146,7 @@ void BPWritten(int addr, int changes, int newval)
case BPMEM_IND_MTX+7:
case BPMEM_IND_MTX+8:
if (changes) {
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
// PixelShaderMngr::SetIndMatrixChanged((addr-BPMEM_IND_MTX)/3);
}
@ -154,7 +154,7 @@ void BPWritten(int addr, int changes, int newval)
case BPMEM_RAS1_SS0:
case BPMEM_RAS1_SS1:
if (changes) {
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
// PixelShaderMngr::SetIndTexScaleChanged();
}
@ -163,7 +163,7 @@ void BPWritten(int addr, int changes, int newval)
case BPMEM_ZMODE:
if (changes)
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
if (bpmem.zmode.testenable)
{
@ -190,7 +190,7 @@ void BPWritten(int addr, int changes, int newval)
case BPMEM_ALPHACOMPARE:
if (changes)
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
float f[4] =
{
@ -217,7 +217,7 @@ void BPWritten(int addr, int changes, int newval)
case BPMEM_CONSTANTALPHA:
if (changes)
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
float f[4] = {
bpmem.dstalpha.alpha/255.0f,0,0,0
@ -238,7 +238,7 @@ void BPWritten(int addr, int changes, int newval)
case 0x43:
if (changes) {
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
@ -246,7 +246,7 @@ void BPWritten(int addr, int changes, int newval)
case BPMEM_BLENDMODE:
if (changes & 0xFFFF)
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
if (changes & 1)
{
@ -328,7 +328,7 @@ void BPWritten(int addr, int changes, int newval)
{
// u32 fogATemp = bpmem.fog.a<<12;
// float fogA = *(float*)(&fogATemp);
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
@ -336,7 +336,7 @@ void BPWritten(int addr, int changes, int newval)
case BPMEM_FOGBEXPONENT:
case BPMEM_FOGBMAGNITUDE:
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
@ -345,7 +345,7 @@ void BPWritten(int addr, int changes, int newval)
//fog settings
if(changes) {
static bool bFog = false;
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
if(!renderFog)
@ -393,7 +393,7 @@ void BPWritten(int addr, int changes, int newval)
case BPMEM_FOGCOLOR:
if(changes) {
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
if(!renderFog)
@ -412,7 +412,7 @@ void BPWritten(int addr, int changes, int newval)
case BPMEM_SCISSOROFFSET: //TODO: investigate
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
@ -420,7 +420,7 @@ void BPWritten(int addr, int changes, int newval)
case BPMEM_SCISSORTL:
case BPMEM_SCISSORBR:
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
int xoff = bpmem.scissorOffset.x*2-342;
int yoff = bpmem.scissorOffset.y*2-342;
@ -445,7 +445,7 @@ void BPWritten(int addr, int changes, int newval)
break;
case BPMEM_ZTEX1:
if (changes) {
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
//PRIM_LOG("ztex bias=0x%x\n", bpmem.ztex1.bias);
//PixelShaderMngr::SetZTextureBias(bpmem.ztex1.bias);
@ -453,7 +453,7 @@ void BPWritten(int addr, int changes, int newval)
break;
case BPMEM_ZTEX2:
if (changes) {
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
#ifdef _DEBUG
const char* pzop[] = {"DISABLE", "ADD", "REPLACE", "?"};
@ -473,7 +473,7 @@ void BPWritten(int addr, int changes, int newval)
case 0xfd: // ksel7
if (changes)
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
// PixelShaderMngr::SetTevKSelChanged(addr-0xf6);
}
@ -486,7 +486,7 @@ void BPWritten(int addr, int changes, int newval)
case 0xA0:
if (changes)
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
FourTexUnits &tex = bpmem.tex[(addr&0xE0)==0xA0];
int stage = (addr&3);//(addr>>4)&2;
@ -534,7 +534,7 @@ void BPWritten(int addr, int changes, int newval)
if (changes)
{
textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
CVertexHandler::Flush();
VertexManager::Flush();
}
break;
case 0x8C://TEX IMAGE 1
@ -542,7 +542,7 @@ void BPWritten(int addr, int changes, int newval)
if (changes)
{
textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
CVertexHandler::Flush();
VertexManager::Flush();
}
break;
case 0x90://TEX IMAGE 2
@ -550,7 +550,7 @@ void BPWritten(int addr, int changes, int newval)
if (changes)
{
textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
CVertexHandler::Flush();
VertexManager::Flush();
}
break;
case 0x94://TEX IMAGE 3
@ -558,7 +558,7 @@ void BPWritten(int addr, int changes, int newval)
if (changes)
{
textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
CVertexHandler::Flush();
VertexManager::Flush();
}
break;
case 0x98://TEX TLUT
@ -566,7 +566,7 @@ void BPWritten(int addr, int changes, int newval)
if (changes)
{
textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
CVertexHandler::Flush();
VertexManager::Flush();
}
break;
case 0x9C://TEX UNKNOWN
@ -588,7 +588,7 @@ void BPWritten(int addr, int changes, int newval)
case 0xD0:
if (changes)
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
// PixelShaderMngr::SetTevCombinerChanged((addr&0x1f)/2);
}
@ -599,7 +599,7 @@ void BPWritten(int addr, int changes, int newval)
{
if (addr&1)
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
static int lastRGBA[2][4] = {
{0xEEEEEEEE, 0xEEEEEEEE, 0xEEEEEEEE, 0xEEEEEEEE},
@ -616,7 +616,7 @@ void BPWritten(int addr, int changes, int newval)
int rgba = ((a<<24) | (r << 16) | (g << 8) | b) & 0xFCFCFCFC; //let's not detect minimal changes
if (rgba != lastRGBA[type][num])
{
CVertexHandler::Flush();
VertexManager::Flush();
lastRGBA[type][num] = rgba;
float temp[4] = {
r/255.0f, g/255.0f, b/255.0f, a/255.0f
@ -634,7 +634,7 @@ void BPWritten(int addr, int changes, int newval)
default:
if (changes)
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
@ -665,7 +665,7 @@ void LoadBPReg(u32 value0)
switch (opcode)
{
case 0x45: //GXSetDrawDone
CVertexHandler::Flush();
VertexManager::Flush();
switch (value0 & 0xFF)
{
case 0x02:
@ -694,7 +694,7 @@ void LoadBPReg(u32 value0)
case 0x52:
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[opcode] = newval;
RECT rc = {
@ -778,7 +778,7 @@ void LoadBPReg(u32 value0)
case 0x65: //GXLoadTlut
{
CVertexHandler::Flush();
VertexManager::Flush();
((u32*)&bpmem)[opcode] = newval;
u32 tlutTMemAddr = (value0&0x3FF)<<9;

View File

@ -20,7 +20,7 @@
#include "CPStructs.h"
#include "XFStructs.h"
#include "TransformEngine.h"
#include "VertexHandler.h"
#include "VertexManager.h"
#include "VertexLoader.h"
// PROBLEM - matrix switching within vbuffers may be stateful!
@ -59,8 +59,12 @@ void LoadCPReg(u32 SubCmd, u32 Value)
CPUpdateMatricesB();
break;
case 0x50: CVertexHandler::Flush(); VertexLoader::SetVtxDesc_Lo(Value); break;
case 0x60: CVertexHandler::Flush(); VertexLoader::SetVtxDesc_Hi(Value); break;
case 0x50:
VertexManager::Flush(); VertexLoader::SetVtxDesc_Lo(Value);
break;
case 0x60:
VertexManager::Flush(); VertexLoader::SetVtxDesc_Hi(Value);
break;
case 0x70: g_VertexLoaders[SubCmd & 7].SetVAT_group0(Value); _assert_((SubCmd & 0x0F) < 8); break;
case 0x80: g_VertexLoaders[SubCmd & 7].SetVAT_group1(Value); _assert_((SubCmd & 0x0F) < 8); break;

View File

@ -1,3 +1,20 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _CPSTRUCTS_H
#define _CPSTRUCTS_H

View File

@ -29,7 +29,7 @@
#include "Common.h"
#include "Statistics.h"
#include "Profiler.h"
#include "VertexHandler.h"
#include "VertexManager.h"
#include "TransformEngine.h"
#include "OpcodeDecoding.h"
#include "TextureCache.h"
@ -288,9 +288,9 @@ static void Decode(void)
int vsize = vtxLoader.GetVertexSize();
vtxLoader.RunVertices(numVertices);
// draw vertices
// add vertices
int primitive = (Cmd & GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT;
CVertexHandler::DrawVertices(primitive, numVertices, &tempvarray);
VertexManager::AddVertices(primitive, numVertices, &tempvarray);
}
else
{

View File

@ -22,7 +22,7 @@
#include "Config.h"
#include "main.h"
#include "VertexHandler.h"
#include "VertexManager.h"
#include "Render.h"
#include "OpcodeDecoding.h"
#include "BPStructs.h"
@ -105,7 +105,7 @@ void Renderer::Initialize(void)
Postprocess::Initialize();
Postprocess::BeginFrame();
D3D::BeginFrame(true, 0);
CVertexHandler::BeginFrame();
VertexManager::BeginFrame();
}
void Renderer::AddMessage(const std::string &message, u32 ms)
@ -274,7 +274,7 @@ void Renderer::SwapBuffers(void)
// D3D::EnableAlphaToCoverage();
Postprocess::BeginFrame();
CVertexHandler::BeginFrame();
VertexManager::BeginFrame();
if (g_Config.bOldCard)
D3D::font.SetRenderStates(); //compatibility with low end cards

View File

@ -22,7 +22,7 @@
// #include "Globals.h"
#include "Vec3.h"
#include "TransformEngine.h"
#include "VertexHandler.h"
#include "VertexManager.h"
#include "VertexLoader.h"
#include "BPStructs.h"

View File

@ -22,7 +22,7 @@
//as much work as possible will be delegated to vertex shaders later
//to take full advantage of current PC HW
#include "VertexHandler.h"
#include "VertexManager.h"
#include "DecodedVArray.h"
class CTransformEngine

View File

@ -22,7 +22,7 @@
#include "Common.h"
#include "LookUpTables.h"
#include "Profiler.h"
#include "VertexHandler.h"
#include "VertexManager.h"
#include "VertexLoader.h"
#include "XFStructs.h"
#include "BPStructs.h"
@ -207,15 +207,6 @@ void VertexLoader::Setup()
m_VtxAttr.texCoord[i].Format,
m_VtxAttr.texCoord[i].Elements,
m_VtxAttr.texCoord[i].Frac);
Compile();
//RET();
/*
char temp[256];
sprintf(temp,"Size: %08x Pos: %i Norm:%i Col0: %i Col1: %i",m_VertexSize,m_VtxDesc.Position,m_VtxDesc.Normal,m_VtxDesc.Color0,m_VtxDesc.Color1);
g_VideoInitialize.pLog(temp);
sprintf(temp,"Pos: %i Norm:%i Col0: %i Col1: %i",_VtxAttr.PosFormat,_VtxAttr.NormalFormat,_VtxAttr.color[0].Comp,_VtxAttr.color[1].Comp);
g_VideoInitialize.pLog(temp);*/
}
void VertexLoader::SetupColor(int num, int mode, int format, int elements)
@ -280,14 +271,14 @@ void VertexLoader::SetupTexCoord(int num, int mode, int format, int elements, in
int sizePro=0;
switch (format)
{
case FORMAT_UBYTE: sizePro=1; WriteCall(TexCoord_ReadDirect_UByte); break;
case FORMAT_BYTE: sizePro=1; WriteCall(TexCoord_ReadDirect_Byte); break;
case FORMAT_USHORT: sizePro=2; WriteCall(TexCoord_ReadDirect_UShort); break;
case FORMAT_SHORT: sizePro=2; WriteCall(TexCoord_ReadDirect_Short); break;
case FORMAT_FLOAT: sizePro=4; WriteCall(TexCoord_ReadDirect_Float); break;
case FORMAT_UBYTE: sizePro = 1; WriteCall(TexCoord_ReadDirect_UByte); break;
case FORMAT_BYTE: sizePro = 1; WriteCall(TexCoord_ReadDirect_Byte); break;
case FORMAT_USHORT: sizePro = 2; WriteCall(TexCoord_ReadDirect_UShort); break;
case FORMAT_SHORT: sizePro = 2; WriteCall(TexCoord_ReadDirect_Short); break;
case FORMAT_FLOAT: sizePro = 4; WriteCall(TexCoord_ReadDirect_Float); break;
default: _assert_(0); break;
}
m_VertexSize += sizePro * (elements?2:1);
m_VertexSize += sizePro * (elements ? 2 : 1);
}
break;
case INDEX8:
@ -324,37 +315,6 @@ void VertexLoader::WriteCall(TPipelineFunction func)
using namespace Gen;
// See comment in RunVertices
void VertexLoader::Compile()
{
return;
/* Gen::SetCodePtr(m_compiledCode);
//INT3();
Gen::Util::EmitPrologue(0);
const u8 *loopStart = Gen::GetCodePtr();
MOV(32, M(&tcIndex), Imm32(0));
MOV(32, M(&colIndex), Imm32(0));
for (int i = 0; i < m_numPipelineStates; i++)
{
ABI_AlignStack(1 * 4);
PUSH(32, Imm32((u32)&m_VtxAttr));
CALL(m_PipelineStates[i]);
ABI_RestoreStack(1 * 4);
}
ADD(32, M(&varray->count), Imm8(1));
SUB(32, M(&this->m_counter), Imm8(1));
J_CC(CC_NZ, loopStart, true);
// Epilogue
Gen::Util::EmitEpilogue(0);
if (Gen::GetCodePtr()-(u8*)m_compiledCode > sizeof(m_compiledCode))
{
Crash();
}*/
}
void VertexLoader::PrepareRun()
{
posScale = shiftLookup[m_VtxAttr.PosFrac];

View File

@ -18,29 +18,6 @@
#ifndef _VERTEXLOADER_H
#define _VERTEXLOADER_H
/*
Ideas for new intermediate vertex format
Produce a mask specifying with components are present.
Decoder always produces a canonical format for all components:
Ubyte4 for matrix indices (x,y,z,w) and colors
FloatN for all others, texcoords are always XY at this stage
The decoders will write a continuous stream of vertices, to take maximum
advantage of write combining hardware
a map<mask, vdecl> will keep track of vertex declarations
this time, we are going to minimize transfers to the gfx card
it turns out that with PS2.0 we can easily do all the pipeline in hardware.
The decision will be how granular to be with the number of shaders and lighting settin
*/
int ComputeVertexSize(u32 components);
#include "CPStructs.h"
@ -97,7 +74,6 @@ private:
int m_numPipelineStates;
int m_VertexSize;
int m_counter;
u8 m_compiledCode[1024];
u32 m_components;
@ -106,7 +82,6 @@ private:
UVAT_group2 m_group2;
bool m_AttrDirty;
TVtxAttr m_VtxAttr; //Decoded into easy format
//common for all loaders
@ -124,7 +99,6 @@ public:
// run the pipeline
static void SetVArray(DecodedVArray *_varray);
void Setup();
void Compile();
void PrepareRun();
void RunVertices(int count);
void WriteCall(TPipelineFunction func);

View File

@ -21,7 +21,7 @@
#include "Statistics.h"
#include "Profiler.h"
#include "VertexHandler.h"
#include "VertexManager.h"
#include "OpcodeDecoding.h"
#include "TransformEngine.h"
#include "IndexGenerator.h"
@ -32,13 +32,17 @@
using namespace D3D;
IndexGenerator indexGen;
Collection CVertexHandler::collection;
LPDIRECT3DVERTEXDECLARATION9 vDecl;
namespace VertexManager
{
D3DVertex *fakeVBuffer;
u16 *fakeIBuffer;
static IndexGenerator indexGen;
static Collection collection;
static LPDIRECT3DVERTEXDECLARATION9 vDecl;
static D3DVertex *fakeVBuffer;
static u16 *fakeIBuffer;
#define MAXVBUFFERSIZE 65536*3
#define MAXIBUFFERSIZE 65536*3
@ -60,23 +64,24 @@ const D3DVERTEXELEMENT9 decl[] =
D3DDECL_END()
};
void CVertexHandler::Init()
bool Init()
{
collection = C_NOTHING;
fakeVBuffer = new D3DVertex[65536];
fakeIBuffer = new u16[65536];
CreateDeviceObjects();
return true;
}
void CVertexHandler::Shutdown()
void Shutdown()
{
DestroyDeviceObjects();
delete [] fakeVBuffer;
delete [] fakeIBuffer;
}
void CVertexHandler::CreateDeviceObjects()
void CreateDeviceObjects()
{
HRESULT hr;
if (FAILED(hr = D3D::dev->CreateVertexDeclaration(decl, &vDecl)))
@ -86,13 +91,13 @@ void CVertexHandler::CreateDeviceObjects()
}
}
void CVertexHandler::BeginFrame()
void BeginFrame()
{
D3D::dev->SetVertexDeclaration(vDecl);
//D3D::dev->SetStreamSource(0,vBuffer,0,sizeof(D3DVertex));
}
void CVertexHandler::DestroyDeviceObjects()
void DestroyDeviceObjects()
{
if (vDecl)
vDecl->Release();
@ -100,7 +105,7 @@ void CVertexHandler::DestroyDeviceObjects()
}
void CVertexHandler::AddIndices(int _primitive, int _numVertices)
void AddIndices(int _primitive, int _numVertices)
{
switch(_primitive) {
case GX_DRAW_QUADS: indexGen.AddQuads(_numVertices); return;
@ -127,7 +132,7 @@ const Collection collectionTypeLUT[8] =
D3DVertex *vbufferwrite;
void CVertexHandler::DrawVertices(int _primitive, int _numVertices, const DecodedVArray *varray)
void AddVertices(int _primitive, int _numVertices, const DecodedVArray *varray)
{
if (_numVertices <= 0) //This check is pretty stupid...
return;
@ -163,7 +168,7 @@ void CVertexHandler::DrawVertices(int _primitive, int _numVertices, const Decode
if (_numVertices >= MAXVBUFFERSIZE)
MessageBox(NULL, "To much vertices for the buffer", "Video.DLL", MB_OK);
CTransformEngine::TransformVertices(_numVertices,varray,vbufferwrite);
CTransformEngine::TransformVertices(_numVertices, varray, vbufferwrite);
}
else //We are collecting the right type, keep going
{
@ -171,11 +176,11 @@ void CVertexHandler::DrawVertices(int _primitive, int _numVertices, const Decode
INCSTAT(stats.numJoins);
//Success, keep adding to unlocked buffer
int last=indexGen.GetNumVerts();
AddIndices(_primitive,_numVertices);
AddIndices(_primitive, _numVertices);
if (_numVertices >= MAXVBUFFERSIZE)
MessageBox(NULL, "Too many vertices for the buffer", "Video.DLL", MB_OK);
CTransformEngine::TransformVertices(_numVertices,varray,vbufferwrite + last);
CTransformEngine::TransformVertices(_numVertices, varray, vbufferwrite + last);
}
}
@ -186,7 +191,7 @@ const D3DPRIMITIVETYPE pts[3] =
D3DPT_LINELIST,
};
void CVertexHandler::Flush()
void Flush()
{
DVSTARTPROFILE();
@ -226,46 +231,4 @@ void CVertexHandler::Flush()
}
}
/*
char szTmp[256];
sprintf(szTmp, "Batch size : %i",_numVertices);
g_VideoInitialize.pLog(szTmp);
char szTemp[256];
sprintf(szTemp, "count: %i", count);
SendMessage(g_VideoInitialize.hStatusBar, SB_SETTEXT,0,(LPARAM)szTemp);
static bool bWaitStep = false;
if (count == 24800)
{
bWaitStep = true;
Renderer::Flush();
}
if (GetAsyncKeyState('J'))
bWaitStep = true;
if (GetAsyncKeyState('U'))
bWaitStep = false;
if (bWaitStep)
{
static bool bKey = false;
while (GetAsyncKeyState('H') == 0)
{
if (GetAsyncKeyState(VK_SPACE))
_asm int 3;
if (GetAsyncKeyState('U'))
{
bWaitStep = false;
break;
}
}
Renderer::Flush();
// wait for key release
while (GetAsyncKeyState ('H')){
};
}
}
*/
// old = bpmem.combiners[0].colorC.hex;
} // namespace

View File

@ -41,26 +41,21 @@ enum Collection
C_LINES=2,
C_POINTS=3
};
namespace VertexManager
{
extern const Collection collectionTypeLUT[8];
class CVertexHandler
{
private:
static Collection collection;
// Pipeline
bool Init();
void Shutdown();
static void PrepareRender();
static void AddIndices(int _primitive, int _numVertices);
void BeginFrame();
public:
static void Init();
static void Shutdown();
void CreateDeviceObjects();
void DestroyDeviceObjects();
static void BeginFrame();
static void CreateDeviceObjects();
static void DestroyDeviceObjects();
void AddVertices(int _primitive, int _numVertices, const DecodedVArray *varray);
void Flush();
static void DrawVertices(int _primitive, int _numVertices, const DecodedVArray *varray);
static void Flush();
};
} // namespace

View File

@ -20,18 +20,15 @@
#include "XFStructs.h"
#include "Render.h"
#include "main.h"
#include "VertexHandler.h"
#include "VertexManager.h"
#include "Utils.h"
float rawViewPort[6];
float rawProjection[7];
// LoadXFReg 0x10
void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
{
DVSTARTPROFILE();
u32 address = baseAddress;
for (int i=0; i<(int)transferSize; i++)
for (int i = 0; i < (int)transferSize; i++)
{
address = baseAddress + i;
@ -68,15 +65,15 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
break;
case 0x101a:
CVertexHandler::Flush();
memcpy(rawViewPort, &pData[i], sizeof(rawViewPort));
VertexManager::Flush();
memcpy(xfregs.rawViewport, &pData[i], sizeof(xfregs.rawViewport));
XFUpdateVP();
i += 6;
break;
case 0x1020:
CVertexHandler::Flush();
memcpy(rawProjection, &pData[i], sizeof(rawProjection));
VertexManager::Flush();
memcpy(xfregs.rawProjection, &pData[i], sizeof(xfregs.rawProjection));
XFUpdatePJ();
i += 7;
return;
@ -130,10 +127,10 @@ void LoadIndexedXF(u32 val, int array)
void XFUpdateVP()
{
Renderer::SetViewport(rawViewPort);
Renderer::SetViewport(xfregs.rawViewport);
}
void XFUpdatePJ()
{
Renderer::SetProjection(rawProjection, 0);
Renderer::SetProjection(xfregs.rawProjection, 0);
}

View File

@ -22,15 +22,9 @@
#include "Vec3.h"
#include "XFMemory.h"
extern float rawViewPort[6];
extern float rawProjection[7];
void XFUpdateVP();
void XFUpdatePJ();
void LoadXFReg(u32 transferSize, u32 address, u32 *pData);
void LoadIndexedXF(u32 val, int array);
#pragma pack()
#endif

View File

@ -29,7 +29,7 @@
#include "OpcodeDecoding.h"
#include "TextureCache.h"
#include "BPStructs.h"
#include "VertexHandler.h"
#include "VertexManager.h"
#include "TransformEngine.h"
#include "DlgSettings.h"
#include "D3DPostprocess.h"
@ -213,7 +213,7 @@ void Video_Prepare(void)
TextureCache::Init();
BPInit();
CVertexHandler::Init();
VertexManager::Init();
Fifo_Init();
OpcodeDecoder_Init();
}
@ -221,7 +221,7 @@ void Video_Prepare(void)
void Video_Shutdown(void)
{
Fifo_Shutdown();
CVertexHandler::Shutdown();
VertexManager::Shutdown();
TextureCache::Shutdown();
Renderer::Shutdown();
OpcodeDecoder_Shutdown();

View File

@ -52,13 +52,17 @@ static const GLenum glSrcFactors[8] =
static const GLenum glDestFactors[8] = {
GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR,
GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA };
GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA
};
static const GLenum glCmpFuncs[8] = { GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS };
static const GLenum glCmpFuncs[8] = {
GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS
};
static const GLenum glLogicOpCodes[16] = {
GL_CLEAR, GL_SET, GL_COPY, GL_COPY_INVERTED, GL_NOOP, GL_INVERT, GL_AND, GL_NAND,
GL_OR, GL_NOR, GL_XOR, GL_EQUIV, GL_AND_REVERSE, GL_AND_INVERTED, GL_OR_REVERSE, GL_OR_INVERTED };
GL_OR, GL_NOR, GL_XOR, GL_EQUIV, GL_AND_REVERSE, GL_AND_INVERTED, GL_OR_REVERSE, GL_OR_INVERTED
};
void BPInit()
{
@ -88,7 +92,7 @@ void BPWritten(int addr, int changes, int newval)
// none, ccw, cw, ccw
if (bpmem.genMode.cullmode>0) {
glEnable(GL_CULL_FACE);
glFrontFace(bpmem.genMode.cullmode==2?GL_CCW:GL_CW);
glFrontFace(bpmem.genMode.cullmode == 2 ? GL_CCW : GL_CW);
}
else glDisable(GL_CULL_FACE);
@ -256,7 +260,7 @@ void BPWritten(int addr, int changes, int newval)
glBlendFunc(glSrcFactors[bpmem.blendmode.srcfactor], glDestFactors[bpmem.blendmode.dstfactor]);
}
if (changes & 0x800) {
glBlendEquation(bpmem.blendmode.subtract?GL_FUNC_REVERSE_SUBTRACT:GL_FUNC_ADD);
glBlendEquation(bpmem.blendmode.subtract ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD);
if (bpmem.blendmode.subtract)
glBlendFunc(GL_ONE, GL_ONE);
else
@ -269,7 +273,7 @@ void BPWritten(int addr, int changes, int newval)
break;
case BPMEM_FOGRANGE:
if(changes) {
if (changes) {
// TODO(XK): Fog range format
//glFogi(GL_FOG_START, ...
//glFogi(GL_FOG_END, ...
@ -474,25 +478,25 @@ void BPWritten(int addr, int changes, int newval)
VertexShaderMngr::SetViewportChanged();
// since clear operations use the source rectangle, have to do regular renders (glClear clears the entire buffer)
if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate || bpmem.zmode.updateenable) {
// Since clear operations use the source rectangle, we have to do
// regular renders (glClear clears the entire buffer)
if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate || bpmem.zmode.updateenable)
{
GLbitfield bits = 0;
if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate) {
u32 clearColor = (bpmem.clearcolorAR<<16)|bpmem.clearcolorGB;
glClearColor(((clearColor>>16)&0xff)*(1/255.0f),((clearColor>>8)&0xff)*(1/255.0f),
((clearColor>>0)&0xff)*(1/255.0f),((clearColor>>24)&0xff)*(1/255.0f));
u32 clearColor = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
glClearColor(((clearColor>>16) & 0xff)*(1/255.0f),
((clearColor>>8 ) & 0xff)*(1/255.0f),
((clearColor>>0 ) & 0xff)*(1/255.0f),
((clearColor>>24) & 0xff)*(1/255.0f));
bits |= GL_COLOR_BUFFER_BIT;
}
if (bpmem.zmode.updateenable) {
glClearDepth((float)(bpmem.clearZValue&0xFFFFFF) / float(0xFFFFFF));
bits |= GL_DEPTH_BUFFER_BIT;
}
if (nRestoreZBufferTarget )
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); // don't clear ztarget here
glClear(bits);
}
@ -500,12 +504,12 @@ void BPWritten(int addr, int changes, int newval)
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
GL_REPORT_ERRORD();
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
// red should probably be the LSB
glClearColor(((bpmem.clearZValue>>0)&0xff)*(1/255.0f),((bpmem.clearZValue>>8)&0xff)*(1/255.0f),
((bpmem.clearZValue>>16)&0xff)*(1/255.0f), 0);
glClearColor(((bpmem.clearZValue>>0)&0xff)*(1/255.0f),
((bpmem.clearZValue>>8)&0xff)*(1/255.0f),
((bpmem.clearZValue>>16)&0xff)*(1/255.0f), 0);
glClear(GL_COLOR_BUFFER_BIT);
SetColorMask();
GL_REPORT_ERRORD();
@ -547,7 +551,7 @@ void BPWritten(int addr, int changes, int newval)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PixelShaderMngr::SetTevOrderChanged(addr-0x28);
PixelShaderMngr::SetTevOrderChanged(addr - 0x28);
}
break;

View File

@ -75,9 +75,8 @@ void NativeVertexFormat::Initialize(const TVtxDesc &vtx_desc, const TVtxAttr &vt
DVSTARTPROFILE();
if (m_VBVertexStride & 3) {
// make sure all strides are at least divisible by 4 (some gfx cards experience a 3x speed boost)
m_VBStridePad = 4 - (m_VBVertexStride & 3);
m_VBVertexStride += m_VBStridePad;
// We will not allow vertex components causing uneven strides.
PanicAlert("Uneven vertex stride: %i", m_VBVertexStride);
}
// compile the pointer set function - why?
@ -86,9 +85,9 @@ void NativeVertexFormat::Initialize(const TVtxDesc &vtx_desc, const TVtxAttr &vt
Util::EmitPrologue(6);
int offset = 0;
// Position
// Position, part 1
if (vtx_desc.Position != NOT_PRESENT) { // TODO: Why the check? Always present, AFAIK!
CallCdeclFunction4_I(glVertexPointer, 3, GL_FLOAT, m_VBVertexStride, offset);
CallCdeclFunction4_I(glVertexPointer, 3, GL_FLOAT, m_VBVertexStride, 0);
offset += 12;
}
@ -97,18 +96,18 @@ void NativeVertexFormat::Initialize(const TVtxDesc &vtx_desc, const TVtxAttr &vt
switch (vtx_attr.NormalFormat) {
case FORMAT_UBYTE:
case FORMAT_BYTE:
CallCdeclFunction3_I(glNormalPointer, GL_BYTE, m_VBVertexStride, offset); offset += 3;
CallCdeclFunction3_I(glNormalPointer, GL_BYTE, m_VBVertexStride, offset); offset += 4;
if (vtx_attr.NormalElements) {
CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM1_ATTRIB, 3, GL_BYTE, GL_TRUE, m_VBVertexStride, offset); offset += 3;
CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM2_ATTRIB, 3, GL_BYTE, GL_TRUE, m_VBVertexStride, offset); offset += 3;
CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM1_ATTRIB, 4, GL_BYTE, GL_TRUE, m_VBVertexStride, offset); offset += 4;
CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM2_ATTRIB, 4, GL_BYTE, GL_TRUE, m_VBVertexStride, offset); offset += 4;
}
break;
case FORMAT_USHORT:
case FORMAT_SHORT:
CallCdeclFunction3_I(glNormalPointer, GL_SHORT, m_VBVertexStride, offset); offset += 6;
CallCdeclFunction3_I(glNormalPointer, GL_SHORT, m_VBVertexStride, offset); offset += 8;
if (vtx_attr.NormalElements) {
CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM1_ATTRIB, 3, GL_SHORT, GL_TRUE, m_VBVertexStride, offset); offset += 6;
CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM2_ATTRIB, 3, GL_SHORT, GL_TRUE, m_VBVertexStride, offset); offset += 6;
CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM1_ATTRIB, 4, GL_SHORT, GL_TRUE, m_VBVertexStride, offset); offset += 8;
CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM2_ATTRIB, 4, GL_SHORT, GL_TRUE, m_VBVertexStride, offset); offset += 8;
}
break;
case FORMAT_FLOAT:
@ -164,19 +163,19 @@ void NativeVertexFormat::Initialize(const TVtxDesc &vtx_desc, const TVtxAttr &vt
}
else {
CallCdeclFunction4_I(glTexCoordPointer, 3, GL_SHORT, m_VBVertexStride, offset);
offset += 6;
offset += 8;
}
}
else {
CallCdeclFunction4_I(glTexCoordPointer, vtx_attr.texCoord[i].Elements ? 2 : 1, GL_FLOAT, m_VBVertexStride, offset);
offset += 4 * (vtx_attr.texCoord[i].Elements?2:1);
offset += 4 * (vtx_attr.texCoord[i].Elements ? 2 : 1);
}
}
}
if (vtx_desc.PosMatIdx) {
CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_POSMTX_ATTRIB, 1, GL_UNSIGNED_BYTE, GL_FALSE, m_VBVertexStride, offset);
offset += 1;
CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, m_VBVertexStride, offset);
offset += 4;
}
_assert_(offset + m_VBStridePad == m_VBVertexStride);

View File

@ -224,22 +224,22 @@ static void Decode()
static u32 pData[16];
for (int i = 0; i < dwTransferSize; i++)
pData[i] = DataReadU32();
VertexShaderMngr::LoadXFReg(dwTransferSize, dwAddress, pData);
LoadXFReg(dwTransferSize, dwAddress, pData);
INCSTAT(stats.thisFrame.numXFLoads);
}
break;
case GX_LOAD_INDX_A: //used for position matrices
VertexShaderMngr::LoadIndexedXF(DataReadU32(), 0xC);
LoadIndexedXF(DataReadU32(), 0xC);
break;
case GX_LOAD_INDX_B: //used for normal matrices
VertexShaderMngr::LoadIndexedXF(DataReadU32(), 0xD);
LoadIndexedXF(DataReadU32(), 0xD);
break;
case GX_LOAD_INDX_C: //used for postmatrices
VertexShaderMngr::LoadIndexedXF(DataReadU32(), 0xE);
LoadIndexedXF(DataReadU32(), 0xE);
break;
case GX_LOAD_INDX_D: //used for lights
VertexShaderMngr::LoadIndexedXF(DataReadU32(), 0xF);
LoadIndexedXF(DataReadU32(), 0xF);
break;
case GX_CMD_CALL_DL:

View File

@ -67,28 +67,32 @@ const GLint c_MinLinearFilter[8] = {
const GLint c_WrapSettings[4] = { GL_CLAMP_TO_EDGE, GL_REPEAT, GL_MIRRORED_REPEAT, GL_REPEAT };
void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0& newmode)
void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0 &newmode)
{
mode = newmode;
if( isNonPow2 ) {
if (isNonPow2) {
// very limited!
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, (newmode.mag_filter||g_Config.bForceFiltering)?GL_LINEAR:GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, (g_Config.bForceFiltering||newmode.min_filter>=4)?GL_LINEAR:GL_NEAREST);
if( newmode.wrap_s == 2 || newmode.wrap_t == 2 ) {
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
(newmode.mag_filter || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
(g_Config.bForceFiltering || newmode.min_filter >= 4) ? GL_LINEAR : GL_NEAREST);
if (newmode.wrap_s == 2 || newmode.wrap_t == 2) {
DEBUG_LOG("cannot support mirrorred repeat mode\n");
}
}
else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (newmode.mag_filter||g_Config.bForceFiltering)?GL_LINEAR:GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
(newmode.mag_filter || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST);
if( bHaveMipMaps ) {
if (bHaveMipMaps) {
int filt = newmode.min_filter;
if( g_Config.bForceFiltering && newmode.min_filter < 4 )
if (g_Config.bForceFiltering && newmode.min_filter < 4)
newmode.min_filter += 4; // take equivalent forced linear
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c_MinLinearFilter[filt]);
}
else
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (g_Config.bForceFiltering||newmode.min_filter>=4)?GL_LINEAR:GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
(g_Config.bForceFiltering || newmode.min_filter >= 4) ? GL_LINEAR : GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, c_WrapSettings[newmode.wrap_s]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, c_WrapSettings[newmode.wrap_t]);
@ -195,7 +199,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
return NULL;
TexCache::iterator iter = textures.find(address);
TexMode0 &tm0 = bpmem.tex[texstage>3].texMode0[texstage&3];
TexMode0 &tm0 = bpmem.tex[texstage > 3].texMode0[texstage & 3];
u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address);
int palSize = TexDecoder_GetPaletteSize(format);
@ -248,9 +252,9 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
}
}
int bs = TexDecoder_GetBlockWidthInTexels(format)-1; //TexelSizeInNibbles(format)*width*height/16;
int expandedWidth = (width+bs) & (~bs);
PC_TexFormat dfmt = TexDecoder_Decode(temp,ptr,expandedWidth,height,format, tlutaddr, tlutfmt);
int bs = TexDecoder_GetBlockWidthInTexels(format) - 1; //TexelSizeInNibbles(format)*width*height/16;
int expandedWidth = (width + bs) & (~bs);
PC_TexFormat dfmt = TexDecoder_Decode(temp, ptr, expandedWidth, height, format, tlutaddr, tlutfmt);
//Make an entry in the table
TCacheEntry& entry = textures[address];
@ -283,7 +287,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
gl_type = GL_UNSIGNED_BYTE;
break;
}
if( !entry.isNonPow2 && ((tm0.min_filter&3)==1||(tm0.min_filter&3)==2) ) {
if (!entry.isNonPow2 && ((tm0.min_filter & 3) == 1 || (tm0.min_filter & 3) == 2)) {
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, width, height, gl_format, gl_type, temp);
entry.bHaveMipMaps = true;
}
@ -294,9 +298,9 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
entry.frameCount = frameCount;
entry.w=width;
entry.h=height;
entry.fmt=format;
entry.w = width;
entry.h = height;
entry.fmt = format;
entry.SetTextureParameters(tm0);
if (g_Config.bDumpTextures) { // dump texture to file
@ -346,7 +350,7 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
GL_REPORT_ERRORD();
if( !bIsInit ) {
if (!bIsInit) {
glGenTextures(1, (GLuint *)&entry.texture);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
@ -356,16 +360,16 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
_assert_(entry.texture);
bool bReInit = true;
if( entry.w == w && entry.h == h ) {
if (entry.w == w && entry.h == h) {
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture);
// for some reason mario sunshine errors here...
GLenum err = GL_NO_ERROR;
GL_REPORT_ERROR();
if( err == GL_NO_ERROR )
if (err == GL_NO_ERROR )
bReInit = false;
}
if( bReInit ) {
if (bReInit) {
// necessary, for some reason opengl gives errors when texture isn't deleted
glDeleteTextures(1,(GLuint *)&entry.texture);
glGenTextures(1, (GLuint *)&entry.texture);
@ -375,13 +379,13 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
}
}
if( !bIsInit || !entry.isRenderTarget ) {
if (!bIsInit || !entry.isRenderTarget) {
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if( glGetError() != GL_NO_ERROR) {
if (glGetError() != GL_NO_ERROR) {
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
GL_REPORT_ERRORD();
@ -390,14 +394,14 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
entry.w = w;
entry.h = h;
entry.isRenderTarget=true;
entry.isRenderTarget = true;
entry.fmt = copyfmt;
float colmat[16];
float fConstAdd[4] = {0};
memset(colmat, 0, sizeof(colmat));
if( bFromZBuffer ) {
if (bFromZBuffer) {
switch(copyfmt) {
case 0: // Z4
case 1: // Z8
@ -428,18 +432,19 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
break;
}
}
else if( bIsIntensityFmt ) {
else if (bIsIntensityFmt) {
fConstAdd[0] = fConstAdd[1] = fConstAdd[2] = 16.0f/255.0f;
switch(copyfmt) {
case 0: // I4
case 1: // I8
case 2: // IA4
case 3: // IA8
// TODO - verify these coefficients
colmat[0] = 0.257f; colmat[1] = 0.504f; colmat[2] = 0.098f;
colmat[4] = 0.257f; colmat[5] = 0.504f; colmat[6] = 0.098f;
colmat[8] = 0.257f; colmat[9] = 0.504f; colmat[10] = 0.098f;
if( copyfmt < 2 ) {
fConstAdd[3] = 16.0f/255.0f;
if (copyfmt < 2) {
fConstAdd[3] = 16.0f / 255.0f;
colmat[12] = 0.257f; colmat[13] = 0.504f; colmat[14] = 0.098f;
}
else { // alpha
@ -453,7 +458,7 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
}
}
else {
switch(copyfmt) {
switch (copyfmt) {
case 0: // R4
case 8: // R8
colmat[0] = colmat[4] = colmat[8] = colmat[12] = 1;
@ -495,7 +500,7 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
}
}
// if( bCopyToTarget ) {
// if (bCopyToTarget) {
// _assert_( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT );
// glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
// GL_REPORT_ERRORD();
@ -512,7 +517,7 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
Renderer::ResetGLState(); // reset any game specific settings
if( s_TempFramebuffer == 0 )
if (s_TempFramebuffer == 0 )
glGenFramebuffersEXT( 1, (GLuint *)&s_TempFramebuffer);
Renderer::SetFramebuffer(s_TempFramebuffer);
@ -525,7 +530,7 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
if (itdepth == mapDepthTargets.end()) {
DEPTHTARGET& depth = mapDepthTargets[(h << 16) | w];
depth.framecount = frameCount;
glGenRenderbuffersEXT( 1, &depth.targ);
glGenRenderbuffersEXT(1, &depth.targ);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth.targ);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT/*GL_DEPTH24_STENCIL8_EXT*/, w, h);
GL_REPORT_ERRORD();
@ -565,7 +570,7 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
TextureMngr::DisableStage(0);
if( bFromZBuffer )
if (bFromZBuffer )
Renderer::SetZBufferRender(); // notify for future settings
GL_REPORT_ERRORD();
@ -575,11 +580,11 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
void TextureMngr::EnableTex2D(int stage)
{
if( !(nTex2DEnabled & (1<<stage)) ) {
if (!(nTex2DEnabled & (1<<stage))) {
nTex2DEnabled |= (1<<stage);
glEnable(GL_TEXTURE_2D);
}
if( nTexRECTEnabled & (1<<stage) ) {
if (nTexRECTEnabled & (1<<stage)) {
nTexRECTEnabled &= ~(1<<stage);
glDisable(GL_TEXTURE_RECTANGLE_ARB);
}
@ -587,12 +592,12 @@ void TextureMngr::EnableTex2D(int stage)
void TextureMngr::EnableTexRECT(int stage)
{
if( (nTex2DEnabled & (1<<stage)) ) {
nTex2DEnabled &= ~(1<<stage);
if ((nTex2DEnabled & (1 << stage))) {
nTex2DEnabled &= ~(1 << stage);
glDisable(GL_TEXTURE_2D);
}
if( !(nTexRECTEnabled & (1<<stage)) ) {
nTexRECTEnabled |= (1<<stage);
if (!(nTexRECTEnabled & (1 << stage))) {
nTexRECTEnabled |= (1 << stage);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
}
}
@ -600,15 +605,16 @@ void TextureMngr::EnableTexRECT(int stage)
void TextureMngr::DisableStage(int stage)
{
bool bset = false;
if( nTex2DEnabled & (1<<stage) ) {
nTex2DEnabled &= ~(1<<stage);
glActiveTexture(GL_TEXTURE0+stage);
if (nTex2DEnabled & (1 << stage)) {
nTex2DEnabled &= ~(1 << stage);
glActiveTexture(GL_TEXTURE0 + stage);
glDisable(GL_TEXTURE_2D);
bset = true;
}
if( nTexRECTEnabled & (1<<stage) ) {
nTexRECTEnabled &= ~(1<<stage);
if( !bset ) glActiveTexture(GL_TEXTURE0+stage);
if (nTexRECTEnabled & (1<<stage)) {
nTexRECTEnabled &= ~(1 << stage);
if (!bset)
glActiveTexture(GL_TEXTURE0 + stage);
glDisable(GL_TEXTURE_RECTANGLE_ARB);
}
}

View File

@ -59,9 +59,9 @@ void LOADERDECL PosMtx_ReadDirect_UByte(const void *_p)
void LOADERDECL PosMtx_Write(const void *_p)
{
*VertexManager::s_pCurBufferPointer++ = s_curposmtx;
//*VertexManager::s_pCurBufferPointer++ = 0;
//*VertexManager::s_pCurBufferPointer++ = 0;
//*VertexManager::s_pCurBufferPointer++ = 0;
*VertexManager::s_pCurBufferPointer++ = 0;
*VertexManager::s_pCurBufferPointer++ = 0;
*VertexManager::s_pCurBufferPointer++ = 0;
}
void LOADERDECL TexMtx_ReadDirect_UByte(const void *_p)
@ -89,7 +89,7 @@ void LOADERDECL TexMtx_Write_Short3(const void *_p)
((s16*)VertexManager::s_pCurBufferPointer)[0] = 0;
((s16*)VertexManager::s_pCurBufferPointer)[1] = 0;
((s16*)VertexManager::s_pCurBufferPointer)[2] = s_curtexmtx[s_texmtxwrite++];
VertexManager::s_pCurBufferPointer += 6;
VertexManager::s_pCurBufferPointer += 8;
}
#include "VertexLoader_Position.h"
@ -101,6 +101,7 @@ VertexLoader::VertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr)
{
m_VertexSize = 0;
m_numPipelineStages = 0;
m_NativeFmt = new NativeVertexFormat();
VertexLoader_Normal::Init();
m_VtxDesc = vtx_desc;
@ -112,6 +113,7 @@ VertexLoader::VertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr)
VertexLoader::~VertexLoader()
{
delete m_NativeFmt;
}
int VertexLoader::ComputeVertexSize()
@ -227,30 +229,29 @@ void VertexLoader::CompileVertexTranslator()
m_numPipelineStages = 0;
// It's a bit ugly that we poke inside m_NativeFmt in this function. Planning to fix this.
m_NativeFmt.m_VBStridePad = 0;
m_NativeFmt.m_VBVertexStride = 0;
m_NativeFmt.m_components = 0;
m_NativeFmt->m_VBVertexStride = 0;
m_NativeFmt->m_components = 0;
// m_VBVertexStride for texmtx and posmtx is computed later when writing.
// Position Matrix Index
if (m_VtxDesc.PosMatIdx) {
m_PipelineStages[m_numPipelineStages++] = PosMtx_ReadDirect_UByte;
m_NativeFmt.m_components |= VB_HAS_POSMTXIDX;
m_NativeFmt->m_components |= VB_HAS_POSMTXIDX;
}
if (m_VtxDesc.Tex0MatIdx) {m_NativeFmt.m_components |= VB_HAS_TEXMTXIDX0; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex1MatIdx) {m_NativeFmt.m_components |= VB_HAS_TEXMTXIDX1; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex2MatIdx) {m_NativeFmt.m_components |= VB_HAS_TEXMTXIDX2; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex3MatIdx) {m_NativeFmt.m_components |= VB_HAS_TEXMTXIDX3; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex4MatIdx) {m_NativeFmt.m_components |= VB_HAS_TEXMTXIDX4; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex5MatIdx) {m_NativeFmt.m_components |= VB_HAS_TEXMTXIDX5; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex6MatIdx) {m_NativeFmt.m_components |= VB_HAS_TEXMTXIDX6; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex7MatIdx) {m_NativeFmt.m_components |= VB_HAS_TEXMTXIDX7; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex0MatIdx) {m_NativeFmt->m_components |= VB_HAS_TEXMTXIDX0; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex1MatIdx) {m_NativeFmt->m_components |= VB_HAS_TEXMTXIDX1; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex2MatIdx) {m_NativeFmt->m_components |= VB_HAS_TEXMTXIDX2; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex3MatIdx) {m_NativeFmt->m_components |= VB_HAS_TEXMTXIDX3; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex4MatIdx) {m_NativeFmt->m_components |= VB_HAS_TEXMTXIDX4; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex5MatIdx) {m_NativeFmt->m_components |= VB_HAS_TEXMTXIDX5; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex6MatIdx) {m_NativeFmt->m_components |= VB_HAS_TEXMTXIDX6; WriteCall(TexMtx_ReadDirect_UByte); }
if (m_VtxDesc.Tex7MatIdx) {m_NativeFmt->m_components |= VB_HAS_TEXMTXIDX7; WriteCall(TexMtx_ReadDirect_UByte); }
// Position
if (m_VtxDesc.Position != NOT_PRESENT)
m_NativeFmt.m_VBVertexStride += 12;
m_NativeFmt->m_VBVertexStride += 12;
switch (m_VtxDesc.Position) {
case NOT_PRESENT: {_assert_msg_(0, "Vertex descriptor without position!", "WTF?");} break;
@ -303,19 +304,19 @@ void VertexLoader::CompileVertexTranslator()
int sizePro = 0;
switch (m_VtxAttr.NormalFormat)
{
case FORMAT_UBYTE: sizePro=1; break;
case FORMAT_BYTE: sizePro=1; break;
case FORMAT_USHORT: sizePro=2; break;
case FORMAT_SHORT: sizePro=2; break;
case FORMAT_FLOAT: sizePro=4; break;
case FORMAT_UBYTE: sizePro = 1*4; break;
case FORMAT_BYTE: sizePro = 1*4; break;
case FORMAT_USHORT: sizePro = 2*4; break;
case FORMAT_SHORT: sizePro = 2*4; break;
case FORMAT_FLOAT: sizePro = 4*3; break;
default: _assert_(0); break;
}
m_NativeFmt.m_VBVertexStride += sizePro * 3 * (m_VtxAttr.NormalElements?3:1);
m_NativeFmt->m_VBVertexStride += sizePro * (m_VtxAttr.NormalElements?3:1);
int numNormals = (m_VtxAttr.NormalElements == 1) ? NRM_THREE : NRM_ONE;
m_NativeFmt.m_components |= VB_HAS_NRM0;
m_NativeFmt->m_components |= VB_HAS_NRM0;
if (numNormals == NRM_THREE)
m_NativeFmt.m_components |= VB_HAS_NRM1 | VB_HAS_NRM2;
m_NativeFmt->m_components |= VB_HAS_NRM1 | VB_HAS_NRM2;
}
// Colors
@ -324,7 +325,7 @@ void VertexLoader::CompileVertexTranslator()
SetupColor(i, col[i], m_VtxAttr.color[i].Comp, m_VtxAttr.color[i].Elements);
if (col[i] != NOT_PRESENT)
m_NativeFmt.m_VBVertexStride += 4;
m_NativeFmt->m_VBVertexStride += 4;
}
// TextureCoord
@ -336,21 +337,21 @@ void VertexLoader::CompileVertexTranslator()
// Texture matrix indices (remove if corresponding texture coordinate isn't enabled)
for (int i = 0; i < 8; i++) {
SetupTexCoord(i, tc[i], m_VtxAttr.texCoord[i].Format, m_VtxAttr.texCoord[i].Elements, m_VtxAttr.texCoord[i].Frac);
if (m_NativeFmt.m_components & (VB_HAS_TEXMTXIDX0 << i)) {
if (m_NativeFmt->m_components & (VB_HAS_TEXMTXIDX0 << i)) {
if (tc[i] != NOT_PRESENT) {
// if texmtx is included, texcoord will always be 3 floats, z will be the texmtx index
WriteCall(m_VtxAttr.texCoord[i].Elements ? TexMtx_Write_Float : TexMtx_Write_Float2);
m_NativeFmt.m_VBVertexStride += 12;
m_NativeFmt->m_VBVertexStride += 12;
}
else {
WriteCall(TexMtx_Write_Short3);
m_NativeFmt.m_VBVertexStride += 6; // still include the texture coordinate, but this time as 6 bytes
m_NativeFmt.m_components |= VB_HAS_UV0 << i; // have to include since using now
m_NativeFmt->m_VBVertexStride += 8; // still include the texture coordinate, but this time as 6 bytes
m_NativeFmt->m_components |= VB_HAS_UV0 << i; // have to include since using now
}
}
else {
if (tc[i] != NOT_PRESENT)
m_NativeFmt.m_VBVertexStride += 4 * (m_VtxAttr.texCoord[i].Elements ? 2 : 1);
m_NativeFmt->m_VBVertexStride += 4 * (m_VtxAttr.texCoord[i].Elements ? 2 : 1);
}
if (tc[i] == NOT_PRESENT) {
@ -362,30 +363,30 @@ void VertexLoader::CompileVertexTranslator()
break;
}
}
if (j == 8 && !((m_NativeFmt.m_components&VB_HAS_TEXMTXIDXALL) & (VB_HAS_TEXMTXIDXALL<<(i+1)))) // no more tex coords and tex matrices, so exit loop
if (j == 8 && !((m_NativeFmt->m_components&VB_HAS_TEXMTXIDXALL) & (VB_HAS_TEXMTXIDXALL<<(i+1)))) // no more tex coords and tex matrices, so exit loop
break;
}
}
if (m_VtxDesc.PosMatIdx) {
WriteCall(PosMtx_Write);
m_NativeFmt.m_VBVertexStride += 1;
m_NativeFmt->m_VBVertexStride += 4;
}
m_NativeFmt.Initialize(m_VtxDesc, m_VtxAttr);
m_NativeFmt->Initialize(m_VtxDesc, m_VtxAttr);
}
void VertexLoader::SetupColor(int num, int mode, int format, int elements)
{
// if COL0 not present, then embed COL1 into COL0
if (num == 1 && !(m_NativeFmt.m_components & VB_HAS_COL0))
if (num == 1 && !(m_NativeFmt->m_components & VB_HAS_COL0))
num = 0;
m_NativeFmt.m_components |= VB_HAS_COL0 << num;
m_NativeFmt->m_components |= VB_HAS_COL0 << num;
switch (mode)
{
case NOT_PRESENT:
m_NativeFmt.m_components &= ~(VB_HAS_COL0 << num);
m_NativeFmt->m_components &= ~(VB_HAS_COL0 << num);
break;
case DIRECT:
switch (format)
@ -428,12 +429,12 @@ void VertexLoader::SetupColor(int num, int mode, int format, int elements)
void VertexLoader::SetupTexCoord(int num, int mode, int format, int elements, int _iFrac)
{
m_NativeFmt.m_components |= VB_HAS_UV0 << num;
m_NativeFmt->m_components |= VB_HAS_UV0 << num;
switch (mode)
{
case NOT_PRESENT:
m_NativeFmt.m_components &= ~(VB_HAS_UV0 << num);
m_NativeFmt->m_components &= ~(VB_HAS_UV0 << num);
break;
case DIRECT:
switch (format)
@ -481,12 +482,12 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count)
DVSTARTPROFILE();
// Flush if our vertex format is different from the currently set.
if (g_nativeVertexFmt != NULL && g_nativeVertexFmt != &m_NativeFmt)
if (g_nativeVertexFmt != NULL && g_nativeVertexFmt != m_NativeFmt)
{
VertexManager::Flush();
// Also move the Set() here?
}
g_nativeVertexFmt = &m_NativeFmt;
g_nativeVertexFmt = m_NativeFmt;
if (bpmem.genMode.cullmode == 3 && primitive < 5)
{
@ -495,7 +496,7 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count)
return;
}
VertexManager::EnableComponents(m_NativeFmt.m_components);
VertexManager::EnableComponents(m_NativeFmt->m_components);
// Load position and texcoord scale factors.
// TODO - figure out if we should leave these independent, or compile them into
@ -511,7 +512,7 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count)
m_VtxAttr.texCoord[7].Frac = g_VtxAttr[vtx_attr_group].g2.Tex7Frac;
posScale = shiftLookup[m_VtxAttr.PosFrac];
if (m_NativeFmt.m_components & VB_HAS_UVALL) {
if (m_NativeFmt->m_components & VB_HAS_UVALL) {
for (int i = 0; i < 8; i++) {
tcScaleU[i] = shiftLookup[m_VtxAttr.texCoord[i].Frac];
tcScaleV[i] = shiftLookup[m_VtxAttr.texCoord[i].Frac];
@ -525,11 +526,11 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count)
switch (primitive) {
case 3: // strip
case 4: // fan
if (VertexManager::GetRemainingSize() < 3 * m_NativeFmt.m_VBVertexStride)
if (VertexManager::GetRemainingSize() < 3 * m_NativeFmt->m_VBVertexStride)
VertexManager::Flush();
break;
case 6: // line strip
if (VertexManager::GetRemainingSize() < 2 * m_NativeFmt.m_VBVertexStride)
if (VertexManager::GetRemainingSize() < 2 * m_NativeFmt->m_VBVertexStride)
VertexManager::Flush();
break;
case 0: // quads
@ -544,11 +545,12 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count)
}
int startv = 0, extraverts = 0;
for (int v = 0; v < count; v++)
{
if ((v % granularity) == 0)
{
if (VertexManager::GetRemainingSize() < granularity*m_NativeFmt.m_VBVertexStride) {
if (VertexManager::GetRemainingSize() < granularity*m_NativeFmt->m_VBVertexStride) {
// This buffer full - break current primitive and flush, to switch to the next buffer.
u8* plastptr = VertexManager::s_pCurBufferPointer;
if (v - startv > 0)
@ -559,27 +561,27 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count)
case 3: // triangle strip, copy last two vertices
// a little trick since we have to keep track of signs
if (v & 1) {
memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-2*m_NativeFmt.m_VBVertexStride, m_NativeFmt.m_VBVertexStride);
memcpy_gc(VertexManager::s_pCurBufferPointer+m_NativeFmt.m_VBVertexStride, plastptr-m_NativeFmt.m_VBVertexStride*2, 2*m_NativeFmt.m_VBVertexStride);
VertexManager::s_pCurBufferPointer += m_NativeFmt.m_VBVertexStride*3;
memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-2*m_NativeFmt->m_VBVertexStride, m_NativeFmt->m_VBVertexStride);
memcpy_gc(VertexManager::s_pCurBufferPointer+m_NativeFmt->m_VBVertexStride, plastptr-m_NativeFmt->m_VBVertexStride*2, 2*m_NativeFmt->m_VBVertexStride);
VertexManager::s_pCurBufferPointer += m_NativeFmt->m_VBVertexStride*3;
extraverts = 3;
}
else {
memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-m_NativeFmt.m_VBVertexStride*2, m_NativeFmt.m_VBVertexStride*2);
VertexManager::s_pCurBufferPointer += m_NativeFmt.m_VBVertexStride*2;
memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-m_NativeFmt->m_VBVertexStride*2, m_NativeFmt->m_VBVertexStride*2);
VertexManager::s_pCurBufferPointer += m_NativeFmt->m_VBVertexStride*2;
extraverts = 2;
}
break;
case 4: // tri fan, copy first and last vert
memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-m_NativeFmt.m_VBVertexStride*(v-startv+extraverts), m_NativeFmt.m_VBVertexStride);
VertexManager::s_pCurBufferPointer += m_NativeFmt.m_VBVertexStride;
memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-m_NativeFmt.m_VBVertexStride, m_NativeFmt.m_VBVertexStride);
VertexManager::s_pCurBufferPointer += m_NativeFmt.m_VBVertexStride;
memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-m_NativeFmt->m_VBVertexStride*(v-startv+extraverts), m_NativeFmt->m_VBVertexStride);
VertexManager::s_pCurBufferPointer += m_NativeFmt->m_VBVertexStride;
memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-m_NativeFmt->m_VBVertexStride, m_NativeFmt->m_VBVertexStride);
VertexManager::s_pCurBufferPointer += m_NativeFmt->m_VBVertexStride;
extraverts = 2;
break;
case 6: // line strip
memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-m_NativeFmt.m_VBVertexStride, m_NativeFmt.m_VBVertexStride);
VertexManager::s_pCurBufferPointer += m_NativeFmt.m_VBVertexStride;
memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-m_NativeFmt->m_VBVertexStride, m_NativeFmt->m_VBVertexStride);
VertexManager::s_pCurBufferPointer += m_NativeFmt->m_VBVertexStride;
extraverts = 1;
break;
default:
@ -596,7 +598,6 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count)
for (int i = 0; i < m_numPipelineStages; i++)
m_PipelineStages[i](&m_VtxAttr);
VertexManager::s_pCurBufferPointer += m_NativeFmt.m_VBStridePad;
PRIM_LOG("\n");
}

View File

@ -74,7 +74,7 @@ private:
TVtxDesc m_VtxDesc; // Not really used currently - or well it is, but could be easily avoided.
// PC vertex format
NativeVertexFormat m_NativeFmt;
NativeVertexFormat *m_NativeFmt;
// Pipeline. To be JIT compiled in the future.
TPipelineFunction m_PipelineStages[32]; // TODO - figure out real max. it's lower.

View File

@ -37,6 +37,8 @@ static VertexLoaderMap g_VertexLoaderMap;
void Init()
{
MarkAllDirty();
for (int i = 0; i < 8; i++)
g_VertexLoaders[i] = NULL;
}
void Shutdown()
@ -53,9 +55,9 @@ void MarkAllDirty()
s_attr_dirty = 0xff;
}
void RefreshLoader(int vtx_attr_group)
static void RefreshLoader(int vtx_attr_group)
{
if (((s_attr_dirty >> vtx_attr_group) & 1) || !g_VertexLoaders[vtx_attr_group])
if ((s_attr_dirty >> vtx_attr_group) & 1)
{
VertexLoaderUID uid;
uid.InitFromCurrentState(vtx_attr_group);

View File

@ -123,7 +123,8 @@ void LOADERDECL VertexLoader_Normal::Normal_DirectByte(const void *_p)
*VertexManager::s_pCurBufferPointer++ = DataReadU8();
*VertexManager::s_pCurBufferPointer++ = DataReadU8();
*VertexManager::s_pCurBufferPointer++ = DataReadU8();
LOG_NORM8();
VertexManager::s_pCurBufferPointer++;
LOG_NORM8();
// ((float*)VertexManager::s_pCurBufferPointer)[0] = ((float)(signed char)DataReadU8()+0.5f) / 127.5f;
}
@ -132,7 +133,7 @@ void LOADERDECL VertexLoader_Normal::Normal_DirectShort(const void *_p)
((u16*)VertexManager::s_pCurBufferPointer)[0] = DataReadU16();
((u16*)VertexManager::s_pCurBufferPointer)[1] = DataReadU16();
((u16*)VertexManager::s_pCurBufferPointer)[2] = DataReadU16();
VertexManager::s_pCurBufferPointer += 6;
VertexManager::s_pCurBufferPointer += 8;
LOG_NORM16()
// ((float*)VertexManager::s_pCurBufferPointer)[0] = ((float)(signed short)DataReadU16()+0.5f) / 32767.5f;
// ((float*)VertexManager::s_pCurBufferPointer)[1] = ((float)(signed short)DataReadU16()+0.5f) / 32767.5f;
@ -150,30 +151,31 @@ void LOADERDECL VertexLoader_Normal::Normal_DirectFloat(const void *_p)
void LOADERDECL VertexLoader_Normal::Normal_DirectByte3(const void *_p)
{
for (int i=0; i<3; i++)
for (int i = 0; i < 3; i++)
{
*VertexManager::s_pCurBufferPointer++ = DataReadU8();
*VertexManager::s_pCurBufferPointer++ = DataReadU8();
*VertexManager::s_pCurBufferPointer++ = DataReadU8();
VertexManager::s_pCurBufferPointer++;
LOG_NORM8();
}
}
void LOADERDECL VertexLoader_Normal::Normal_DirectShort3(const void *_p)
{
for (int i=0; i<3; i++)
for (int i = 0; i < 3; i++)
{
((u16*)VertexManager::s_pCurBufferPointer)[0] = DataReadU16();
((u16*)VertexManager::s_pCurBufferPointer)[1] = DataReadU16();
((u16*)VertexManager::s_pCurBufferPointer)[2] = DataReadU16();
VertexManager::s_pCurBufferPointer += 6;
VertexManager::s_pCurBufferPointer += 8;
LOG_NORM16();
}
}
void LOADERDECL VertexLoader_Normal::Normal_DirectFloat3(const void *_p)
{
for (int i=0; i<3; i++)
for (int i = 0; i < 3; i++)
{
((float*)VertexManager::s_pCurBufferPointer)[0] = DataReadF32();
((float*)VertexManager::s_pCurBufferPointer)[1] = DataReadF32();
@ -193,6 +195,7 @@ void LOADERDECL VertexLoader_Normal::Normal_Index8_Byte(const void *_p)
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress);
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress+1);
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress+2);
VertexManager::s_pCurBufferPointer++;
// ((float*)VertexManager::s_pCurBufferPointer)[0] = ((float)(signed char)Memory_Read_U8(iAddress)+0.5f) / 127.5f;
// ((float*)VertexManager::s_pCurBufferPointer)[1] = ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f;
// ((float*)VertexManager::s_pCurBufferPointer)[2] = ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f;
@ -207,7 +210,7 @@ void LOADERDECL VertexLoader_Normal::Normal_Index8_Short(const void *_p)
((u16*)VertexManager::s_pCurBufferPointer)[0] = Memory_Read_U16(iAddress);
((u16*)VertexManager::s_pCurBufferPointer)[1] = Memory_Read_U16(iAddress+2);
((u16*)VertexManager::s_pCurBufferPointer)[2] = Memory_Read_U16(iAddress+4);
VertexManager::s_pCurBufferPointer += 6;
VertexManager::s_pCurBufferPointer += 8;
LOG_NORM16();
}
@ -225,22 +228,24 @@ void LOADERDECL VertexLoader_Normal::Normal_Index8_Float(const void *_p)
void LOADERDECL VertexLoader_Normal::Normal_Index8_Byte3(const void *_p)
{
if (index3) {
for (int i=0; i<3; i++) {
for (int i = 0; i < 3; i++) {
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i;
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress);
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress+1);
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress+2);
*VertexManager::s_pCurBufferPointer++;
LOG_NORM8();
}
}
else {
u8 Index = DataReadU8();
for (int i=0; i<3; i++) {
for (int i = 0; i < 3; i++) {
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i;
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress);
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress+1);
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress+2);
VertexManager::s_pCurBufferPointer++;
LOG_NORM8();
}
}
@ -249,24 +254,24 @@ void LOADERDECL VertexLoader_Normal::Normal_Index8_Byte3(const void *_p)
void LOADERDECL VertexLoader_Normal::Normal_Index8_Short3(const void *_p)
{
if (index3) {
for (int i=0; i<3; i++) {
for (int i = 0; i < 3; i++) {
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i;
((u16*)VertexManager::s_pCurBufferPointer)[0] = Memory_Read_U16(iAddress);
((u16*)VertexManager::s_pCurBufferPointer)[1] = Memory_Read_U16(iAddress+2);
((u16*)VertexManager::s_pCurBufferPointer)[2] = Memory_Read_U16(iAddress+4);
VertexManager::s_pCurBufferPointer += 6;
VertexManager::s_pCurBufferPointer += 8;
LOG_NORM16();
}
}
else {
u8 Index = DataReadU8();
for (int i=0; i<3; i++) {
for (int i = 0; i < 3; i++) {
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i;
((u16*)VertexManager::s_pCurBufferPointer)[0] = Memory_Read_U16(iAddress);
((u16*)VertexManager::s_pCurBufferPointer)[1] = Memory_Read_U16(iAddress+2);
((u16*)VertexManager::s_pCurBufferPointer)[2] = Memory_Read_U16(iAddress+4);
VertexManager::s_pCurBufferPointer += 6;
VertexManager::s_pCurBufferPointer += 8;
LOG_NORM16();
}
}
@ -275,7 +280,7 @@ void LOADERDECL VertexLoader_Normal::Normal_Index8_Short3(const void *_p)
void LOADERDECL VertexLoader_Normal::Normal_Index8_Float3(const void *_p)
{
if (index3) {
for (int i=0; i<3; i++) {
for (int i = 0; i < 3; i++) {
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i;
((float*)VertexManager::s_pCurBufferPointer)[0] = Memory_Read_Float(iAddress);
@ -287,7 +292,7 @@ void LOADERDECL VertexLoader_Normal::Normal_Index8_Float3(const void *_p)
}
else {
u8 Index = DataReadU8();
for (int i=0; i<3; i++) {
for (int i = 0; i < 3; i++) {
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i;
((float*)VertexManager::s_pCurBufferPointer)[0] = Memory_Read_Float(iAddress);
((float*)VertexManager::s_pCurBufferPointer)[1] = Memory_Read_Float(iAddress+4);
@ -309,6 +314,7 @@ void LOADERDECL VertexLoader_Normal::Normal_Index16_Byte(const void *_p)
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress);
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress+1);
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress+2);
VertexManager::s_pCurBufferPointer++;
LOG_NORM8();
}
@ -319,7 +325,7 @@ void LOADERDECL VertexLoader_Normal::Normal_Index16_Short(const void *_p)
((u16*)VertexManager::s_pCurBufferPointer)[0] = Memory_Read_U16(iAddress);
((u16*)VertexManager::s_pCurBufferPointer)[1] = Memory_Read_U16(iAddress+2);
((u16*)VertexManager::s_pCurBufferPointer)[2] = Memory_Read_U16(iAddress+4);
VertexManager::s_pCurBufferPointer += 6;
VertexManager::s_pCurBufferPointer += 8;
LOG_NORM16();
}
@ -337,22 +343,24 @@ void LOADERDECL VertexLoader_Normal::Normal_Index16_Float(const void *_p)
void LOADERDECL VertexLoader_Normal::Normal_Index16_Byte3(const void *_p)
{
if (index3) {
for (int i=0; i<3; i++) {
for (int i = 0; i < 3; i++) {
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i;
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress);
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress+1);
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress+2);
VertexManager::s_pCurBufferPointer++;
LOG_NORM8();
}
}
else {
u16 Index = DataReadU16();
for (int i=0; i<3; i++) {
for (int i = 0; i < 3; i++) {
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i;
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress);
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress+1);
*VertexManager::s_pCurBufferPointer++ = Memory_Read_U8(iAddress+2);
VertexManager::s_pCurBufferPointer++;
LOG_NORM8();
}
}
@ -362,27 +370,27 @@ void LOADERDECL VertexLoader_Normal::Normal_Index16_Short3(const void *_p)
{
if (index3)
{
for (int i=0; i<3; i++)
for (int i = 0; i < 3; i++)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i;
((u16*)VertexManager::s_pCurBufferPointer)[0] = Memory_Read_U16(iAddress);
((u16*)VertexManager::s_pCurBufferPointer)[1] = Memory_Read_U16(iAddress+2);
((u16*)VertexManager::s_pCurBufferPointer)[2] = Memory_Read_U16(iAddress+4);
VertexManager::s_pCurBufferPointer += 6;
VertexManager::s_pCurBufferPointer += 8;
LOG_NORM16();
}
}
else
{
u16 Index = DataReadU16();
for (int i=0; i<3; i++)
for (int i = 0; i < 3; i++)
{
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i;
((u16*)VertexManager::s_pCurBufferPointer)[0] = Memory_Read_U16(iAddress);
((u16*)VertexManager::s_pCurBufferPointer)[1] = Memory_Read_U16(iAddress+2);
((u16*)VertexManager::s_pCurBufferPointer)[2] = Memory_Read_U16(iAddress+4);
VertexManager::s_pCurBufferPointer += 6;
VertexManager::s_pCurBufferPointer += 8;
LOG_NORM16();
}
}
@ -392,7 +400,7 @@ void LOADERDECL VertexLoader_Normal::Normal_Index16_Float3(const void *_p)
{
if (index3)
{
for (int i=0; i<3; i++)
for (int i = 0; i < 3; i++)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i;
@ -406,7 +414,7 @@ void LOADERDECL VertexLoader_Normal::Normal_Index16_Float3(const void *_p)
else
{
u16 Index = DataReadU16();
for (int i=0; i<3; i++)
for (int i = 0; i < 3; i++)
{
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i;
((float*)VertexManager::s_pCurBufferPointer)[0] = Memory_Read_Float(iAddress);

View File

@ -48,8 +48,6 @@ static const GLenum c_primitiveType[8] =
bool Init()
{
Destroy();
s_prevcomponents = 0;
s_pBaseBufferPointer = (u8*)AllocateMemoryPages(MAX_BUFFER_SIZE);
s_pCurBufferPointer = s_pBaseBufferPointer;
@ -69,7 +67,7 @@ bool Init()
return true;
}
void Destroy()
void Shutdown()
{
FreeMemoryPages(s_pBaseBufferPointer, MAX_BUFFER_SIZE); s_pBaseBufferPointer = s_pCurBufferPointer = NULL;
glDeleteBuffers(ARRAYSIZE(s_vboBuffers), s_vboBuffers);

View File

@ -25,21 +25,23 @@
// Other functionality is moving out.
namespace VertexManager
{
bool Init();
void Destroy();
void ResetBuffer();
void ResetComponents();
bool Init();
void Shutdown();
void AddVertices(int primitive, int numvertices);
void Flush(); // flushes the current buffer
void ResetBuffer();
void ResetComponents();
int GetRemainingSize(); // remaining space in the current buffer.
void AddVertices(int primitive, int numvertices);
void Flush(); // flushes the current buffer
void EnableComponents(u32 components); // very implementation specific - D3D9 won't need this one.
int GetRemainingSize(); // remaining space in the current buffer.
void EnableComponents(u32 components); // very implementation specific - D3D9 won't need this one.
// TODO: move, rename.
extern u8* s_pCurBufferPointer;
// TODO: move, rename.
extern u8* s_pCurBufferPointer;
};
#endif // _VERTEXMANAGER_H

View File

@ -49,8 +49,6 @@ extern int nBackbufferWidth, nBackbufferHeight;
static int s_nMaxVertexInstructions;
static float s_fMaterials[16];
static float rawViewport[6] = {0};
static float rawProjection[7] = {0};
// track changes
static bool bTexMatricesChanged[2], bPosNormalMatrixChanged, bProjectionChanged, bViewportChanged;
@ -92,7 +90,7 @@ void VertexShaderMngr::Shutdown()
}
float VertexShaderMngr::GetPixelAspectRatio() {
return rawViewport[0] != 0 ? (float)Renderer::GetTargetWidth() / 640.0f : 1.0f;
return xfregs.rawViewport[0] != 0 ? (float)Renderer::GetTargetWidth() / 640.0f : 1.0f;
}
VERTEXSHADER* VertexShaderMngr::GetShader(u32 components)
@ -378,8 +376,8 @@ void VertexShaderMngr::SetConstants()
wAdj = ratio;
hAdj = 1;
wid = ceil(fabs(2 * rawViewport[0]) / wAdj);
hei = ceil(fabs(2 * rawViewport[1]) / hAdj);
wid = ceil(fabs(2 * xfregs.rawViewport[0]) / wAdj);
hei = ceil(fabs(2 * xfregs.rawViewport[1]) / hAdj);
actualWid = ceil((float)winw / ratio);
actualRatiow = (float)actualWid / (float)wid; // the picture versus the screen
@ -393,8 +391,8 @@ void VertexShaderMngr::SetConstants()
wAdj = 1;
hAdj = ratio;
wid = ceil(fabs(2 * rawViewport[0]) / wAdj);
hei = ceil(fabs(2 * rawViewport[1]) / hAdj);
wid = ceil(fabs(2 * xfregs.rawViewport[0]) / wAdj);
hei = ceil(fabs(2 * xfregs.rawViewport[1]) / hAdj);
actualHei = ceil((float)winh / ratio);
actualRatioh = (float)actualHei / (float)hei; // the picture versus the screen
@ -404,52 +402,56 @@ void VertexShaderMngr::SetConstants()
}
else
{
wid = ceil(fabs(2 * rawViewport[0]));
hei = ceil(fabs(2 * rawViewport[1]));
wid = ceil(fabs(2 * xfregs.rawViewport[0]));
hei = ceil(fabs(2 * xfregs.rawViewport[1]));
}
if (g_Config.bStretchToFit)
{
glViewport(
(int)(rawViewport[3]-rawViewport[0]-342-scissorXOff) + xoffs,
Renderer::GetTargetHeight() - ((int)(rawViewport[4]-rawViewport[1]-342-scissorYOff)) + yoffs,
(int)(xfregs.rawViewport[3]-xfregs.rawViewport[0]-342-scissorXOff) + xoffs,
Renderer::GetTargetHeight() - ((int)(xfregs.rawViewport[4]-xfregs.rawViewport[1]-342-scissorYOff)) + yoffs,
wid, // width
hei // height
);
}
else
{
glViewport((int)(rawViewport[3]-rawViewport[0]-342-scissorXOff) * MValueX,
Renderer::GetTargetHeight()-((int)(rawViewport[4]-rawViewport[1]-342-scissorYOff)) * MValueY,
abs((int)(2 * rawViewport[0])) * MValueX, abs((int)(2 * rawViewport[1])) * MValueY);
glViewport((int)(xfregs.rawViewport[3]-xfregs.rawViewport[0]-342-scissorXOff) * MValueX,
Renderer::GetTargetHeight()-((int)(xfregs.rawViewport[4]-xfregs.rawViewport[1]-342-scissorYOff)) * MValueY,
abs((int)(2 * xfregs.rawViewport[0])) * MValueX, abs((int)(2 * xfregs.rawViewport[1])) * MValueY);
}
// Standard depth range
//glDepthRange(-(0.0f - (xfregs.rawViewport[5]-xfregs.rawViewport[2])/-16777215.0f), xfregs.rawViewport[5]/16777215.0f);
// Metroid Prime 1 & 2 likes this
glDepthRange((g_Config.bInvertDepth ? -1 : 1) * -(0.0f - (rawViewport[5]-rawViewport[2])/16777215.0f), rawViewport[5]/16777215.0f);
//glDepthRange(-(0.0f - (xfregs.rawViewport[5]-xfregs.rawViewport[2])/16777215.0f), xfregs.rawViewport[5]/16777215.0f);
glDepthRange((g_Config.bInvertDepth ? -1 : 1) * -(0.0f - (xfregs.rawViewport[5]-xfregs.rawViewport[2])/16777215.0f), xfregs.rawViewport[5]/16777215.0f);
// FZero stage likes this (a sonic hack)
// glDepthRange(-(0.0f - (rawViewport[5]-rawViewport[2])/-16777215.0f), rawViewport[5]/16777215.0f);
// glDepthRange(-(0.0f - (xfregs.rawViewport[5]-xfregs.rawViewport[2])/-16777215.0f), xfregs.rawViewport[5]/16777215.0f);
}
if (bProjectionChanged) {
bProjectionChanged = false;
if (rawProjection[6] == 0) {
g_fProjectionMatrix[0] = rawProjection[0];
if (xfregs.rawProjection[6] == 0) {
g_fProjectionMatrix[0] = xfregs.rawProjection[0];
g_fProjectionMatrix[1] = 0.0f;
g_fProjectionMatrix[2] = rawProjection[1];
g_fProjectionMatrix[2] = xfregs.rawProjection[1];
g_fProjectionMatrix[3] = 0;
g_fProjectionMatrix[4] = 0.0f;
g_fProjectionMatrix[5] = rawProjection[2];
g_fProjectionMatrix[6] = rawProjection[3];
g_fProjectionMatrix[5] = xfregs.rawProjection[2];
g_fProjectionMatrix[6] = xfregs.rawProjection[3];
g_fProjectionMatrix[7] = 0;
g_fProjectionMatrix[8] = 0.0f;
g_fProjectionMatrix[9] = 0.0f;
g_fProjectionMatrix[10] = rawProjection[4];
g_fProjectionMatrix[10] = xfregs.rawProjection[4];
// Working bloom in ZTP
g_fProjectionMatrix[11] = -(0.0f - rawProjection[5]); // Yes, it's important that it's done this way.
g_fProjectionMatrix[11] = -(0.0f - xfregs.rawProjection[5]); // Yes, it's important that it's done this way.
// Working projection in PSO
// g_fProjectionMatrix[11] = -(1.0f - rawProjection[5]);
@ -459,23 +461,23 @@ void VertexShaderMngr::SetConstants()
g_fProjectionMatrix[15] = 0.0f;
}
else {
g_fProjectionMatrix[0] = rawProjection[0];
g_fProjectionMatrix[0] = xfregs.rawProjection[0];
g_fProjectionMatrix[1] = 0.0f;
g_fProjectionMatrix[2] = 0.0f;
g_fProjectionMatrix[3] = rawProjection[1];
g_fProjectionMatrix[3] = xfregs.rawProjection[1];
g_fProjectionMatrix[4] = 0.0f;
g_fProjectionMatrix[5] = rawProjection[2];
g_fProjectionMatrix[5] = xfregs.rawProjection[2];
g_fProjectionMatrix[6] = 0.0f;
g_fProjectionMatrix[7] = rawProjection[3];
g_fProjectionMatrix[7] = xfregs.rawProjection[3];
g_fProjectionMatrix[8] = 0.0f;
g_fProjectionMatrix[9] = 0.0f;
g_fProjectionMatrix[10] = rawProjection[4];
g_fProjectionMatrix[10] = xfregs.rawProjection[4];
// Working bloom in ZTP
g_fProjectionMatrix[11] = -(-1.0f - rawProjection[5]); // Yes, it's important that it's done this way.
// Working projection in PSO
// g_fProjectionMatrix[11] = -(0.0f - rawProjection[5]);
//g_fProjectionMatrix[11] = -(-1.0f - rawProjection[5]); // Yes, it's important that it's done this way.
// Working projection in PSO, working Super Monkey Ball
g_fProjectionMatrix[11] = -(0.0f - xfregs.rawProjection[5]);
g_fProjectionMatrix[12] = 0;
g_fProjectionMatrix[13] = 0;
@ -483,7 +485,7 @@ void VertexShaderMngr::SetConstants()
g_fProjectionMatrix[15] = 1.0f;
}
PRIM_LOG("Projection: %f %f %f %f %f %f\n", rawProjection[0], rawProjection[1], rawProjection[2], rawProjection[3], rawProjection[4], rawProjection[5]);
PRIM_LOG("Projection: %f %f %f %f %f %f\n", xfregs.rawProjection[0], xfregs.rawProjection[1], xfregs.rawProjection[2], xfregs.rawProjection[3], xfregs.rawProjection[4], xfregs.rawProjection[5]);
SetVSConstant4fv(C_PROJECTION, &g_fProjectionMatrix[0]);
SetVSConstant4fv(C_PROJECTION+1, &g_fProjectionMatrix[4]);
SetVSConstant4fv(C_PROJECTION+2, &g_fProjectionMatrix[8]);
@ -591,11 +593,11 @@ void VertexShaderMngr::SetTexMatrixChangedB(u32 Value)
void VertexShaderMngr::SetViewport(float* _Viewport)
{
// Workaround for paper mario, yep this is bizarre.
for (size_t i = 0; i < ARRAYSIZE(rawViewport); ++i) {
for (size_t i = 0; i < ARRAYSIZE(xfregs.rawViewport); ++i) {
if (*(u32*)(_Viewport + i) == 0x7f800000) // invalid fp number
return;
}
memcpy(rawViewport, _Viewport, sizeof(rawViewport));
memcpy(xfregs.rawViewport, _Viewport, sizeof(xfregs.rawViewport));
bViewportChanged = true;
}
@ -606,12 +608,65 @@ void VertexShaderMngr::SetViewportChanged()
void VertexShaderMngr::SetProjection(float* _pProjection, int constantIndex)
{
memcpy(rawProjection, _pProjection, sizeof(rawProjection));
memcpy(xfregs.rawProjection, _pProjection, sizeof(xfregs.rawProjection));
bProjectionChanged = true;
}
float* VertexShaderMngr::GetPosNormalMat()
{
return (float*)xfmem + MatrixIndexA.PosNormalMtxIdx * 4;
}
// Mash together all the inputs that contribute to the code of a generated vertex shader into
// a unique identifier, basically containing all the bits. Yup, it's a lot ....
void VertexShaderMngr::GetVertexShaderId(VERTEXSHADERUID& vid, u32 components)
{
u32 zbufrender = (bpmem.ztex2.op == ZTEXTURE_ADD) || Renderer::GetZBufferTarget() != 0;
vid.values[0] = components |
(xfregs.numTexGens << 23) |
(xfregs.nNumChans << 27) |
((u32)xfregs.bEnableDualTexTransform << 29) |
(zbufrender << 30);
for (int i = 0; i < 2; ++i) {
vid.values[1+i] = xfregs.colChans[i].color.enablelighting ?
(u32)xfregs.colChans[i].color.hex :
(u32)xfregs.colChans[i].color.matsource;
vid.values[1+i] |= (xfregs.colChans[i].alpha.enablelighting ?
(u32)xfregs.colChans[i].alpha.hex :
(u32)xfregs.colChans[i].alpha.matsource) << 15;
}
// fog
vid.values[1] |= (((u32)bpmem.fog.c_proj_fsel.fsel & 3) << 30);
vid.values[2] |= (((u32)bpmem.fog.c_proj_fsel.fsel >> 2) << 30);
u32* pcurvalue = &vid.values[3];
for (int i = 0; i < xfregs.numTexGens; ++i) {
TexMtxInfo tinfo = xfregs.texcoords[i].texmtxinfo;
if (tinfo.texgentype != XF_TEXGEN_EMBOSS_MAP)
tinfo.hex &= 0x7ff;
if (tinfo.texgentype != XF_TEXGEN_REGULAR)
tinfo.projection = 0;
u32 val = ((tinfo.hex >> 1) & 0x1ffff);
if (xfregs.bEnableDualTexTransform && tinfo.texgentype == XF_TEXGEN_REGULAR) {
// rewrite normalization and post index
val |= ((u32)xfregs.texcoords[i].postmtxinfo.index << 17) | ((u32)xfregs.texcoords[i].postmtxinfo.normalize << 23);
}
switch (i & 3) {
case 0: pcurvalue[0] |= val; break;
case 1: pcurvalue[0] |= val << 24; pcurvalue[1] = val >> 8; ++pcurvalue; break;
case 2: pcurvalue[0] |= val << 16; pcurvalue[1] = val >> 16; ++pcurvalue; break;
case 3: pcurvalue[0] |= val << 8; ++pcurvalue; break;
}
}
}
// LoadXFReg 0x10
void VertexShaderMngr::LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
{
u32 address = baseAddress;
for (int i = 0; i < (int)transferSize; i++)
@ -622,7 +677,7 @@ void VertexShaderMngr::LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
if (address < 0x1000)
{
VertexManager::Flush();
InvalidateXFRange(address, address+transferSize);
VertexShaderMngr::InvalidateXFRange(address, address + transferSize);
//PRIM_LOG("xfmem write: 0x%x-0x%x\n", address, address+transferSize);
u32* p1 = &xfmem[address];
@ -748,16 +803,16 @@ void VertexShaderMngr::LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
break;
case 0x1018:
//_assert_msg_(GX_XF, 0, "XF matrixindex0");
SetTexMatrixChangedA(data); //?
VertexShaderMngr::SetTexMatrixChangedA(data); //?
break;
case 0x1019:
//_assert_msg_(GX_XF, 0, "XF matrixindex1");
SetTexMatrixChangedB(data); //?
VertexShaderMngr::SetTexMatrixChangedB(data); //?
break;
case 0x101a:
VertexManager::Flush();
SetViewport((float*)&pData[i]);
VertexShaderMngr::SetViewport((float*)&pData[i]);
i += 6;
break;
@ -812,7 +867,7 @@ void VertexShaderMngr::LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
break;
}
}
else if (address>=0x4000)
else if (address >= 0x4000)
{
// MessageBox(NULL, "1", "1", MB_OK);
//4010 __GXSetGenMode
@ -821,7 +876,7 @@ void VertexShaderMngr::LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
}
// TODO - verify that it is correct. Seems to work, though.
void VertexShaderMngr::LoadIndexedXF(u32 val, int array)
void LoadIndexedXF(u32 val, int array)
{
int index = val >> 16;
int address = val & 0xFFF; //check mask
@ -829,61 +884,9 @@ void VertexShaderMngr::LoadIndexedXF(u32 val, int array)
//load stuff from array to address in xf mem
VertexManager::Flush();
InvalidateXFRange(address, address+size);
VertexShaderMngr::InvalidateXFRange(address, address+size);
//PRIM_LOG("xfmem iwrite: 0x%x-0x%x\n", address, address+size);
for (int i = 0; i < size; i++)
xfmem[address + i] = Memory_Read_U32(arraybases[array] + arraystrides[array]*index + i*4);
}
float* VertexShaderMngr::GetPosNormalMat()
{
return (float*)xfmem + MatrixIndexA.PosNormalMtxIdx * 4;
}
// Mash together all the inputs that contribute to the code of a generated vertex shader into
// a unique identifier, basically containing all the bits. Yup, it's a lot ....
void VertexShaderMngr::GetVertexShaderId(VERTEXSHADERUID& vid, u32 components)
{
u32 zbufrender = (bpmem.ztex2.op == ZTEXTURE_ADD) || Renderer::GetZBufferTarget() != 0;
vid.values[0] = components |
(xfregs.numTexGens << 23) |
(xfregs.nNumChans << 27) |
((u32)xfregs.bEnableDualTexTransform << 29) |
(zbufrender << 30);
for (int i = 0; i < 2; ++i) {
vid.values[1+i] = xfregs.colChans[i].color.enablelighting ?
(u32)xfregs.colChans[i].color.hex :
(u32)xfregs.colChans[i].color.matsource;
vid.values[1+i] |= (xfregs.colChans[i].alpha.enablelighting ?
(u32)xfregs.colChans[i].alpha.hex :
(u32)xfregs.colChans[i].alpha.matsource) << 15;
}
// fog
vid.values[1] |= (((u32)bpmem.fog.c_proj_fsel.fsel & 3) << 30);
vid.values[2] |= (((u32)bpmem.fog.c_proj_fsel.fsel >> 2) << 30);
u32* pcurvalue = &vid.values[3];
for (int i = 0; i < xfregs.numTexGens; ++i) {
TexMtxInfo tinfo = xfregs.texcoords[i].texmtxinfo;
if (tinfo.texgentype != XF_TEXGEN_EMBOSS_MAP)
tinfo.hex &= 0x7ff;
if (tinfo.texgentype != XF_TEXGEN_REGULAR)
tinfo.projection = 0;
u32 val = ((tinfo.hex >> 1) & 0x1ffff);
if (xfregs.bEnableDualTexTransform && tinfo.texgentype == XF_TEXGEN_REGULAR) {
// rewrite normalization and post index
val |= ((u32)xfregs.texcoords[i].postmtxinfo.index << 17) | ((u32)xfregs.texcoords[i].postmtxinfo.normalize << 23);
}
switch (i & 3) {
case 0: pcurvalue[0] |= val; break;
case 1: pcurvalue[0] |= val << 24; pcurvalue[1] = val >> 8; ++pcurvalue; break;
case 2: pcurvalue[0] |= val << 16; pcurvalue[1] = val >> 16; ++pcurvalue; break;
case 3: pcurvalue[0] |= val << 8; ++pcurvalue; break;
}
}
}

View File

@ -121,12 +121,11 @@ public:
static void SetTexMatrixChangedA(u32 Value);
static void SetTexMatrixChangedB(u32 Value);
static void LoadXFReg(u32 transferSize, u32 address, u32 *pData);
static void LoadIndexedXF(u32 val, int array);
static float* GetPosNormalMat();
static float GetPixelAspectRatio();
};
void LoadXFReg(u32 transferSize, u32 address, u32 *pData);
void LoadIndexedXF(u32 val, int array);
#endif

View File

@ -116,27 +116,12 @@ void XFB_Write(u8 *xfb_in_ram, const TRectangle& sourceRc, u32 dstWd, u32 dstHt,
Renderer::RestoreGLState();
GL_REPORT_ERRORD();
// TODO - verify that XFB pixel order. probably reverse of GL pixel order
// TODO - use shader for conversion
ConvertToXFB((u32 *)xfb_in_ram, efb_buffer, dstWd, dstHt);
// old way
/*glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, Renderer::GetRenderTarget());
TextureMngr::EnableTexRECT(0);
glGetTexImage(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, GL_UNSIGNED_BYTE, efb_buffer);
static u8 *efbEndAddress = efb_buffer + ((nBackbufferWidth * nBackbufferHeight) - 1) * 4;
ConvertToXFBReverse((u32 *)xfb_in_ram, efbEndAddress, dstWd, dstHt);*/
}
void XFB_Draw(u8 *xfb_in_ram, u32 width, u32 height, s32 yOffset)
{
if(width == 0 || height == 0)
return;
OpenGL_Update(); // just updates the render window position and the backbuffer size
Renderer::SetRenderMode(Renderer::RM_Normal);

View File

@ -246,7 +246,7 @@ void Video_Shutdown(void)
VertexShaderMngr::Shutdown();
PixelShaderMngr::Shutdown();
Fifo_Shutdown();
VertexManager::Destroy();
VertexManager::Shutdown();
TextureMngr::Shutdown();
OpcodeDecoder_Shutdown();
Renderer::Shutdown();