implement some code to reduce the amounts of calls to setup vertex format, in d3d9 it gives no noticeable speedup, in opengl it still does not work right.

thanks to neobrain for the idea
This commit is contained in:
rodolfoosvaldobogado 2012-10-26 23:18:09 -03:00
parent eaa1ea71c1
commit ee72852491
9 changed files with 305 additions and 110 deletions

View File

@ -159,6 +159,9 @@ void VertexManager::AddVertices(int primitive, int numVertices)
void VertexManager::Flush()
{
if (LocalVBuffer == s_pCurBufferPointer) return;
if (Flushed) return;
Flushed = true;
g_vertex_manager->vFlush();
}

View File

@ -211,9 +211,6 @@ void VertexManager::Draw(UINT stride)
void VertexManager::vFlush()
{
if (LocalVBuffer == s_pCurBufferPointer) return;
if (Flushed) return;
Flushed=true;
VideoFifo_CheckEFBAccess();
u32 usedtextures = 0;

View File

@ -66,6 +66,7 @@ static int numAdapters;
static int cur_adapter;
// Value caches for state filtering
const int MaxStreamSources = 16;
const int MaxTextureStages = 9;
const int MaxRenderStates = 210 + 46;
const int MaxTextureTypes = 33;
@ -83,10 +84,23 @@ static DWORD m_SamplerStates[MaxSamplerSize][MaxSamplerTypes];
static bool m_SamplerStatesSet[MaxSamplerSize][MaxSamplerTypes];
static bool m_SamplerStatesChanged[MaxSamplerSize][MaxSamplerTypes];
LPDIRECT3DBASETEXTURE9 m_Textures[16];
LPDIRECT3DVERTEXDECLARATION9 m_VtxDecl;
LPDIRECT3DPIXELSHADER9 m_PixelShader;
LPDIRECT3DVERTEXSHADER9 m_VertexShader;
static LPDIRECT3DBASETEXTURE9 m_Textures[16];
static LPDIRECT3DVERTEXDECLARATION9 m_VtxDecl;
static bool m_VtxDeclChanged;
static LPDIRECT3DPIXELSHADER9 m_PixelShader;
static bool m_PixelShaderChanged;
static LPDIRECT3DVERTEXSHADER9 m_VertexShader;
static bool m_VertexShaderChanged;
struct StreamSourceDescriptor
{
LPDIRECT3DVERTEXBUFFER9 pStreamData;
UINT OffsetInBytes;
UINT Stride;
};
static StreamSourceDescriptor m_stream_sources[MaxStreamSources];
static bool m_stream_sources_Changed[MaxStreamSources];
static LPDIRECT3DINDEXBUFFER9 m_index_buffer;
static bool m_index_buffer_Changed;
// Z buffer formats to be used for EFB depth surface
D3DFORMAT DepthFormats[] = {
@ -170,9 +184,9 @@ void EnableAlphaToCoverage()
{
// Each vendor has their own specific little hack.
if (GetCurAdapter().ident.VendorId == VENDOR_ATI)
D3D::SetRenderState(D3DRS_POINTSIZE, (D3DFORMAT)MAKEFOURCC('A', '2', 'M', '1'));
SetRenderState(D3DRS_POINTSIZE, (D3DFORMAT)MAKEFOURCC('A', '2', 'M', '1'));
else
D3D::SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C'));
SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C'));
}
void InitPP(int adapter, int f, int aa_mode, D3DPRESENT_PARAMETERS *pp)
@ -215,14 +229,14 @@ void InitPP(int adapter, int f, int aa_mode, D3DPRESENT_PARAMETERS *pp)
void Enumerate()
{
numAdapters = D3D::D3D->GetAdapterCount();
numAdapters = D3D->GetAdapterCount();
for (int i = 0; i < std::min(MAX_ADAPTERS, numAdapters); i++)
{
Adapter &a = adapters[i];
a.aa_levels.clear();
a.resolutions.clear();
D3D::D3D->GetAdapterIdentifier(i, 0, &a.ident);
D3D->GetAdapterIdentifier(i, 0, &a.ident);
bool isNvidia = a.ident.VendorId == VENDOR_NVIDIA;
// Add SuperSamples modes
@ -233,17 +247,17 @@ void Enumerate()
//disable them will they are not implemnted
/*
DWORD qlevels = 0;
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels))
if (qlevels > 0)
a.aa_levels.push_back(AALevel("2x MSAA", D3DMULTISAMPLE_2_SAMPLES, 0));
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels))
if (qlevels > 0)
a.aa_levels.push_back(AALevel("4x MSAA", D3DMULTISAMPLE_4_SAMPLES, 0));
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels))
if (qlevels > 0)
a.aa_levels.push_back(AALevel("8x MSAA", D3DMULTISAMPLE_8_SAMPLES, 0));
@ -251,7 +265,7 @@ void Enumerate()
if (isNvidia)
{
// CSAA support
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_4_SAMPLES, &qlevels))
{
if (qlevels > 2)
@ -262,7 +276,7 @@ void Enumerate()
a.aa_levels.push_back(AALevel("8xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 0));
}
}
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels))
{
if (qlevels > 2)
@ -296,11 +310,11 @@ void Enumerate()
{
strcpy(a.aa_levels[0].name, "(Not supported on this device)");
}
int numModes = D3D::D3D->GetAdapterModeCount(i, D3DFMT_X8R8G8B8);
int numModes = D3D->GetAdapterModeCount(i, D3DFMT_X8R8G8B8);
for (int m = 0; m < numModes; m++)
{
D3DDISPLAYMODE mode;
D3D::D3D->EnumAdapterModes(i, D3DFMT_X8R8G8B8, m, &mode);
D3D->EnumAdapterModes(i, D3DFMT_X8R8G8B8, m, &mode);
int found = -1;
for (int x = 0; x < (int)a.resolutions.size(); x++)
@ -440,8 +454,8 @@ HRESULT Create(int adapter, HWND wnd, int _resolution, int aa_mode, bool auto_de
dev->GetRenderTarget(0, &back_buffer);
if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND)
back_buffer_z = NULL;
D3D::SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE );
D3D::SetRenderState(D3DRS_FILLMODE, g_Config.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE );
SetRenderState(D3DRS_FILLMODE, g_Config.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
memset(m_Textures, 0, sizeof(m_Textures));
memset(m_TextureStageStatesSet, 0, sizeof(m_TextureStageStatesSet));
memset(m_RenderStatesSet, 0, sizeof(m_RenderStatesSet));
@ -452,6 +466,15 @@ HRESULT Create(int adapter, HWND wnd, int _resolution, int aa_mode, bool auto_de
m_VtxDecl = NULL;
m_PixelShader = NULL;
m_VertexShader = NULL;
m_index_buffer = NULL;
memset(m_stream_sources, 0, sizeof(m_stream_sources));
m_index_buffer = NULL;
m_VtxDeclChanged = false;
m_PixelShaderChanged = false;
m_VertexShaderChanged = false;
memset(m_stream_sources_Changed, 0 , sizeof(m_stream_sources_Changed));
m_index_buffer_Changed = false;
// Device state would normally be set here
return S_OK;
}
@ -516,7 +539,7 @@ bool CheckDepthStencilSupport(D3DFORMAT target_format, D3DFORMAT depth_format)
D3DFORMAT GetSupportedDepthTextureFormat()
{
for (int i = 0; i < sizeof(DepthFormats)/sizeof(D3DFORMAT); ++i)
if (D3D::CheckTextureSupport(D3DUSAGE_DEPTHSTENCIL, DepthFormats[i]))
if (CheckTextureSupport(D3DUSAGE_DEPTHSTENCIL, DepthFormats[i]))
return DepthFormats[i];
return D3DFMT_UNKNOWN;
@ -525,7 +548,7 @@ D3DFORMAT GetSupportedDepthTextureFormat()
D3DFORMAT GetSupportedDepthSurfaceFormat(D3DFORMAT target_format)
{
for (int i = 0; i < sizeof(DepthFormats)/sizeof(D3DFORMAT); ++i)
if (D3D::CheckDepthStencilSupport(target_format, DepthFormats[i]))
if (CheckDepthStencilSupport(target_format, DepthFormats[i]))
return DepthFormats[i];
return D3DFMT_UNKNOWN;
@ -533,13 +556,13 @@ D3DFORMAT GetSupportedDepthSurfaceFormat(D3DFORMAT target_format)
const char *VertexShaderVersionString()
{
int version = ((D3D::caps.VertexShaderVersion >> 8) & 0xFF);
int version = ((caps.VertexShaderVersion >> 8) & 0xFF);
return vsVersions[std::min(4, version)];
}
const char *PixelShaderVersionString()
{
int version = ((D3D::caps.PixelShaderVersion >> 8) & 0xFF);
int version = ((caps.PixelShaderVersion >> 8) & 0xFF);
return psVersions[std::min(4, version)];
}
@ -653,14 +676,14 @@ void ApplyCachedState()
for (int type = 0; type < MaxSamplerTypes; type++)
{
if(m_SamplerStatesSet[sampler][type])
D3D::dev->SetSamplerState(sampler, (D3DSAMPLERSTATETYPE)type, m_SamplerStates[sampler][type]);
dev->SetSamplerState(sampler, (D3DSAMPLERSTATETYPE)type, m_SamplerStates[sampler][type]);
}
}
for (int rs = 0; rs < MaxRenderStates; rs++)
{
if (m_RenderStatesSet[rs])
D3D::dev->SetRenderState((D3DRENDERSTATETYPE)rs, m_RenderStates[rs]);
dev->SetRenderState((D3DRENDERSTATETYPE)rs, m_RenderStates[rs]);
}
// We don't bother restoring these so let's just wipe the state copy
@ -671,6 +694,13 @@ void ApplyCachedState()
m_VtxDecl = NULL;
m_PixelShader = NULL;
m_VertexShader = NULL;
memset(m_stream_sources, 0, sizeof(m_stream_sources));
m_index_buffer = NULL;
m_VtxDeclChanged = false;
m_PixelShaderChanged = false;
m_VertexShaderChanged = false;
memset(m_stream_sources_Changed, 0 , sizeof(m_stream_sources_Changed));
m_index_buffer_Changed = false;
}
void SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture)
@ -678,7 +708,7 @@ void SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture)
if (m_Textures[Stage] != pTexture)
{
m_Textures[Stage] = pTexture;
D3D::dev->SetTexture(Stage, pTexture);
dev->SetTexture(Stage, pTexture);
}
}
@ -686,7 +716,7 @@ void RefreshRenderState(D3DRENDERSTATETYPE State)
{
if(m_RenderStatesSet[State] && m_RenderStatesChanged[State])
{
D3D::dev->SetRenderState(State, m_RenderStates[State]);
dev->SetRenderState(State, m_RenderStates[State]);
m_RenderStatesChanged[State] = false;
}
}
@ -698,7 +728,7 @@ void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value)
m_RenderStates[State] = Value;
m_RenderStatesSet[State] = true;
m_RenderStatesChanged[State] = false;
D3D::dev->SetRenderState(State, Value);
dev->SetRenderState(State, Value);
}
}
@ -707,7 +737,7 @@ void ChangeRenderState(D3DRENDERSTATETYPE State, DWORD Value)
if (m_RenderStates[State] != Value || !m_RenderStatesSet[State])
{
m_RenderStatesChanged[State] = m_RenderStatesSet[State];
D3D::dev->SetRenderState(State, Value);
dev->SetRenderState(State, Value);
}
else
{
@ -722,7 +752,7 @@ void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Valu
m_TextureStageStates[Stage][Type] = Value;
m_TextureStageStatesSet[Stage][Type]=true;
m_TextureStageStatesChanged[Stage][Type]=false;
D3D::dev->SetTextureStageState(Stage, Type, Value);
dev->SetTextureStageState(Stage, Type, Value);
}
}
@ -730,7 +760,7 @@ void RefreshTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type)
{
if(m_TextureStageStatesSet[Stage][Type] && m_TextureStageStatesChanged[Stage][Type])
{
D3D::dev->SetTextureStageState(Stage, Type, m_TextureStageStates[Stage][Type]);
dev->SetTextureStageState(Stage, Type, m_TextureStageStates[Stage][Type]);
m_TextureStageStatesChanged[Stage][Type] = false;
}
}
@ -740,7 +770,7 @@ void ChangeTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD V
if (m_TextureStageStates[Stage][Type] != Value || !m_TextureStageStatesSet[Stage][Type])
{
m_TextureStageStatesChanged[Stage][Type] = m_TextureStageStatesSet[Stage][Type];
D3D::dev->SetTextureStageState(Stage, Type, Value);
dev->SetTextureStageState(Stage, Type, Value);
}
else
{
@ -755,7 +785,7 @@ void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value)
m_SamplerStates[Sampler][Type] = Value;
m_SamplerStatesSet[Sampler][Type] = true;
m_SamplerStatesChanged[Sampler][Type] = false;
D3D::dev->SetSamplerState(Sampler, Type, Value);
dev->SetSamplerState(Sampler, Type, Value);
}
}
@ -763,7 +793,7 @@ void RefreshSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type)
{
if(m_SamplerStatesSet[Sampler][Type] && m_SamplerStatesChanged[Sampler][Type])
{
D3D::dev->SetSamplerState(Sampler, Type, m_SamplerStates[Sampler][Type]);
dev->SetSamplerState(Sampler, Type, m_SamplerStates[Sampler][Type]);
m_SamplerStatesChanged[Sampler][Type] = false;
}
}
@ -773,7 +803,7 @@ void ChangeSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value)
if (m_SamplerStates[Sampler][Type] != Value || !m_SamplerStatesSet[Sampler][Type])
{
m_SamplerStatesChanged[Sampler][Type] = m_SamplerStatesSet[Sampler][Type];
D3D::dev->SetSamplerState(Sampler, Type, Value);
dev->SetSamplerState(Sampler, Type, Value);
}
else
{
@ -783,67 +813,155 @@ void ChangeSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value)
void RefreshVertexDeclaration()
{
if (m_VtxDecl)
if (m_VtxDeclChanged)
{
D3D::dev->SetVertexDeclaration(m_VtxDecl);
dev->SetVertexDeclaration(m_VtxDecl);
m_VtxDeclChanged = false;
}
}
void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl)
{
if (!decl) {
m_VtxDecl = NULL;
return;
}
if (decl != m_VtxDecl)
{
D3D::dev->SetVertexDeclaration(decl);
dev->SetVertexDeclaration(decl);
m_VtxDecl = decl;
m_VtxDeclChanged = false;
}
}
void ChangeVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl)
{
if (decl != m_VtxDecl) {
dev->SetVertexDeclaration(decl);
m_VtxDeclChanged = true;
}
}
void ChangeVertexShader(LPDIRECT3DVERTEXSHADER9 shader)
{
if (shader != m_VertexShader)
{
dev->SetVertexShader(shader);
m_VertexShaderChanged = true;
}
}
void RefreshVertexShader()
{
if (m_VertexShader)
if (m_VertexShaderChanged)
{
D3D::dev->SetVertexShader(m_VertexShader);
dev->SetVertexShader(m_VertexShader);
m_VertexShaderChanged = false;
}
}
void SetVertexShader(LPDIRECT3DVERTEXSHADER9 shader)
{
if (!shader) {
m_VertexShader = NULL;
return;
}
if (shader != m_VertexShader)
{
D3D::dev->SetVertexShader(shader);
dev->SetVertexShader(shader);
m_VertexShader = shader;
m_VertexShaderChanged = false;
}
}
void RefreshPixelShader()
{
if (m_PixelShader)
if (m_PixelShaderChanged)
{
D3D::dev->SetPixelShader(m_PixelShader);
dev->SetPixelShader(m_PixelShader);
m_PixelShaderChanged = false;
}
}
void SetPixelShader(LPDIRECT3DPIXELSHADER9 shader)
{
if (!shader) {
m_PixelShader = NULL;
return;
}
if (shader != m_PixelShader)
{
D3D::dev->SetPixelShader(shader);
dev->SetPixelShader(shader);
m_PixelShader = shader;
m_PixelShaderChanged = false;
}
}
void ChangePixelShader(LPDIRECT3DPIXELSHADER9 shader)
{
if (shader != m_PixelShader)
{
dev->SetPixelShader(shader);
m_PixelShaderChanged = true;
}
}
void SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride)
{
if (m_stream_sources[StreamNumber].OffsetInBytes != OffsetInBytes
|| m_stream_sources[StreamNumber].pStreamData != pStreamData
|| m_stream_sources[StreamNumber].Stride != Stride)
{
m_stream_sources[StreamNumber].OffsetInBytes = OffsetInBytes;
m_stream_sources[StreamNumber].pStreamData = pStreamData;
m_stream_sources[StreamNumber].Stride = Stride;
dev->SetStreamSource(StreamNumber, pStreamData, OffsetInBytes, Stride);
m_stream_sources_Changed[StreamNumber] = false;
}
}
void ChangeStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride)
{
if (m_stream_sources[StreamNumber].OffsetInBytes != OffsetInBytes
|| m_stream_sources[StreamNumber].pStreamData != pStreamData
|| m_stream_sources[StreamNumber].Stride != Stride)
{
dev->SetStreamSource(StreamNumber, pStreamData, OffsetInBytes, Stride);
m_stream_sources_Changed[StreamNumber] = true;
}
}
void RefreshStreamSource(UINT StreamNumber)
{
if (m_PixelShaderChanged)
{
dev->SetStreamSource(
StreamNumber,
m_stream_sources[StreamNumber].pStreamData,
m_stream_sources[StreamNumber].OffsetInBytes,
m_stream_sources[StreamNumber].Stride);
m_stream_sources_Changed[StreamNumber] = false;
}
}
void SetIndices(LPDIRECT3DINDEXBUFFER9 pIndexData)
{
if(pIndexData != m_index_buffer)
{
m_index_buffer = pIndexData;
dev->SetIndices(pIndexData);
m_index_buffer_Changed = false;
}
}
void ChangeIndices(LPDIRECT3DINDEXBUFFER9 pIndexData)
{
if(pIndexData != m_index_buffer)
{
dev->SetIndices(pIndexData);
m_index_buffer_Changed = true;
}
}
void RefreshIndices()
{
if (m_index_buffer_Changed)
{
dev->SetIndices(m_index_buffer);
m_index_buffer_Changed = false;
}
}
} // namespace

View File

@ -100,12 +100,23 @@ void ChangeSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
void RefreshVertexDeclaration();
void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl);
void ChangeVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl);
void RefreshVertexShader();
void SetVertexShader(LPDIRECT3DVERTEXSHADER9 shader);
void ChangeVertexShader(LPDIRECT3DVERTEXSHADER9 shader);
void RefreshPixelShader();
void SetPixelShader(LPDIRECT3DPIXELSHADER9 shader);
void ChangePixelShader(LPDIRECT3DPIXELSHADER9 shader);
void SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride);
void ChangeStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride);
void RefreshStreamSource(UINT StreamNumber);
void SetIndices(LPDIRECT3DINDEXBUFFER9 pIndexData);
void ChangeIndices(LPDIRECT3DINDEXBUFFER9 pIndexData);
void RefreshIndices();
void ApplyCachedState();

View File

@ -198,6 +198,8 @@ const int TS[6][2] =
void RestoreShaders()
{
D3D::SetTexture(0, 0);
D3D::RefreshStreamSource(0);
D3D::RefreshIndices();
D3D::RefreshVertexDeclaration();
D3D::RefreshPixelShader();
D3D::RefreshVertexShader();
@ -217,9 +219,9 @@ void CD3DFont::SetRenderStates()
{
D3D::SetTexture(0, m_pTexture);
dev->SetPixelShader(0);
dev->SetVertexShader(0);
D3D::ChangePixelShader(0);
D3D::ChangeVertexShader(0);
D3D::ChangeVertexDeclaration(0);
dev->SetFVF(D3DFVF_FONT2DVERTEX);
for (int i = 0; i < 6; i++)
@ -236,7 +238,7 @@ int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, flo
return 0;
SetRenderStates();
dev->SetStreamSource(0, m_pVB, 0, sizeof(FONT2DVERTEX));
D3D::SetStreamSource(0, m_pVB, 0, sizeof(FONT2DVERTEX));
float vpWidth = 1;
float vpHeight = 1;
@ -389,9 +391,10 @@ void drawShadedTexQuad(IDirect3DTexture9 *texture,
{ 1.0f - dw,-1.0f + dh, 0.0f,1.0f, u2, v2, sw, sh, g},
{ 1.0f - dw, 1.0f + dh, 0.0f,1.0f, u2, v1, sw, sh, g}
};
dev->SetVertexShader(Vshader);
dev->SetPixelShader(PShader);
D3D::ChangeVertexShader(Vshader);
D3D::ChangePixelShader(PShader);
D3D::SetTexture(0, texture);
D3D::ChangeVertexDeclaration(0);
dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(2));
dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex));
RestoreShaders();
@ -424,9 +427,10 @@ void drawShadedTexSubQuad(IDirect3DTexture9 *texture,
{ rDest->right - dw , rDest->top + dh, 1.0f,1.0f, u2, v2, sw, sh, g},
{ rDest->right - dw , rDest->bottom + dh, 1.0f,1.0f, u2, v1, sw, sh, g}
};
dev->SetVertexShader(Vshader);
dev->SetPixelShader(PShader);
D3D::ChangeVertexShader(Vshader);
D3D::ChangePixelShader(PShader);
D3D::SetTexture(0, texture);
D3D::ChangeVertexDeclaration(0);
dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(2));
dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex));
RestoreShaders();
@ -442,8 +446,9 @@ void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2)
{ x1, y1, 0.f, 1.f, Color },
{ x2, y1, 0.f, 1.f, Color },
};
dev->SetVertexShader(VertexShaderCache::GetClearVertexShader());
dev->SetPixelShader(PixelShaderCache::GetClearProgram());
D3D::ChangeVertexShader(VertexShaderCache::GetClearVertexShader());
D3D::ChangePixelShader(PixelShaderCache::GetClearProgram());
D3D::ChangeVertexDeclaration(0);
dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE);
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(CQVertex));
RestoreShaders();
@ -457,8 +462,9 @@ void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVer
{ 1.0f, -1.0f, z, 1.0f, Color},
{-1.0f, -1.0f, z, 1.0f, Color}
};
dev->SetVertexShader(Vshader);
dev->SetPixelShader(PShader);
D3D::ChangeVertexShader(Vshader);
D3D::ChangePixelShader(PShader);
D3D::ChangeVertexDeclaration(0);
dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE);
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
RestoreShaders();

View File

@ -105,7 +105,7 @@ void VertexManager::CreateDeviceObjects()
m_current_index_buffer = 0;
m_index_buffer_cursor = m_index_buffer_size;
m_vertex_buffer_cursor = m_vertex_buffer_size;
m_current_stride = 0;
if (Fail)
{
m_buffers_count--;
@ -119,8 +119,8 @@ void VertexManager::CreateDeviceObjects()
}
void VertexManager::DestroyDeviceObjects()
{
D3D::dev->SetStreamSource( 0, NULL, 0, 0);
D3D::dev->SetIndices(NULL);
D3D::SetStreamSource( 0, NULL, 0, 0);
D3D::SetIndices(NULL);
for (int i = 0; i < MAX_VBUFFER_COUNT; i++)
{
if(m_vertex_buffers)
@ -160,14 +160,14 @@ void VertexManager::PrepareDrawBuffers(u32 stride)
int PDataSize = IndexGenerator::GetPointindexLen();
int IndexDataSize = TdataSize + LDataSize + PDataSize;
DWORD LockMode = D3DLOCK_NOOVERWRITE;
m_vertex_buffer_cursor--;
m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride;
if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize)
{
LockMode = D3DLOCK_DISCARD;
m_vertex_buffer_cursor = 0;
m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count;
}
if(FAILED(m_vertex_buffers[m_current_vertex_buffer]->Lock(m_vertex_buffer_cursor, datasize,(VOID**)(&pVertices), LockMode)))
{
DestroyDeviceObjects();
@ -177,7 +177,6 @@ void VertexManager::PrepareDrawBuffers(u32 stride)
m_vertex_buffers[m_current_vertex_buffer]->Unlock();
LockMode = D3DLOCK_NOOVERWRITE;
if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize)
{
LockMode = D3DLOCK_DISCARD;
@ -204,12 +203,16 @@ void VertexManager::PrepareDrawBuffers(u32 stride)
{
memcpy(pIndices, PIBuffer, PDataSize * sizeof(u16));
}
m_index_buffers[m_current_index_buffer]->Unlock();
D3D::dev->SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], m_vertex_buffer_cursor, stride);
if(m_index_buffer_cursor == 0)
if(m_current_stride != stride || m_vertex_buffer_cursor == 0)
{
D3D::dev->SetIndices(m_index_buffers[m_current_index_buffer]);
m_current_stride = stride;
D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, stride);
}
if (m_index_buffer_cursor == 0)
{
D3D::SetIndices(m_index_buffers[m_current_index_buffer]);
}
m_index_buffers[m_current_index_buffer]->Unlock();
}
void VertexManager::DrawVertexBuffer(int stride)
@ -218,7 +221,7 @@ void VertexManager::DrawVertexBuffer(int stride)
{
if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,
0,
m_vertex_buffer_cursor / stride,
0,
IndexGenerator::GetNumVerts(),
m_index_buffer_cursor,
@ -232,7 +235,7 @@ void VertexManager::DrawVertexBuffer(int stride)
{
if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_LINELIST,
0,
m_vertex_buffer_cursor / stride,
0,
IndexGenerator::GetNumVerts(),
m_index_buffer_cursor + IndexGenerator::GetTriangleindexLen(),
@ -246,7 +249,7 @@ void VertexManager::DrawVertexBuffer(int stride)
{
if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_POINTLIST,
0,
m_vertex_buffer_cursor / stride,
0,
IndexGenerator::GetNumVerts(),
m_index_buffer_cursor + IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen(),
@ -307,11 +310,7 @@ void VertexManager::DrawVertexArray(int stride)
void VertexManager::vFlush()
{
if (LocalVBuffer == s_pCurBufferPointer) return;
if (Flushed) return;
Flushed = true;
VideoFifo_CheckEFBAccess();
u32 usedtextures = 0;
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
if (bpmem.tevorders[i / 2].getEnable(i & 1))

View File

@ -40,6 +40,7 @@ private:
u32 m_index_buffer_size;
u32 m_buffers_count;
u32 m_current_vertex_buffer;
u32 m_current_stride;
u32 m_current_index_buffer;
LPDIRECT3DVERTEXBUFFER9 *m_vertex_buffers;
LPDIRECT3DINDEXBUFFER9 *m_index_buffers;

View File

@ -114,8 +114,9 @@ void VertexManager::CreateDeviceObjects()
m_buffers_count = MAX_VBUFFER_COUNT;
m_current_index_buffer = 0;
m_current_vertex_buffer = 0;
m_index_buffer_cursor = 0;
m_vertex_buffer_cursor = 0;
m_index_buffer_cursor = m_index_buffer_size;
m_vertex_buffer_cursor = m_vertex_buffer_size;
m_CurrentVertexFmt = NULL;
}
void VertexManager::DestroyDeviceObjects()
{
@ -154,17 +155,19 @@ void VertexManager::PrepareDrawBuffers(u32 stride)
int point_index_size = IndexGenerator::GetPointindexLen() * sizeof(u16);
int index_data_size = triangle_index_size + line_index_size + point_index_size;
GLbitfield LockMode = GL_MAP_WRITE_BIT;
m_vertex_buffer_cursor--;
m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride;
if (m_vertex_buffer_cursor > m_vertex_buffer_size - vertex_data_size)
{
LockMode |= GL_MAP_INVALIDATE_BUFFER_BIT;
m_vertex_buffer_cursor = 0;
m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count;
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[m_current_vertex_buffer]);
}
else
{
LockMode |= GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
}
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers[m_current_vertex_buffer]);
if(GLEW_ARB_map_buffer_range)
{
pVertices = (u8*)glMapBufferRange(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LockMode);
@ -190,12 +193,12 @@ void VertexManager::PrepareDrawBuffers(u32 stride)
LockMode |= GL_MAP_INVALIDATE_BUFFER_BIT;
m_index_buffer_cursor = 0;
m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers[m_current_index_buffer]);
}
else
{
LockMode |= GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers[m_current_index_buffer]);
if(GLEW_ARB_map_buffer_range)
{
pIndices = (u16*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor , index_data_size, LockMode);
@ -279,11 +282,33 @@ void VertexManager::DrawVertexBufferObject()
}
}
void VertexManager::DrawVertexBufferObjectBase(u32 stride)
{
int triangle_index_size = IndexGenerator::GetTriangleindexLen();
int line_index_size = IndexGenerator::GetLineindexLen();
int point_index_size = IndexGenerator::GetPointindexLen();
int StartIndex = m_index_buffer_cursor;
if (triangle_index_size > 0)
{
glDrawElementsBaseVertex(GL_TRIANGLES, triangle_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, m_vertex_buffer_cursor / stride);
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (line_index_size > 0)
{
StartIndex += triangle_index_size * sizeof(u16);
glDrawElementsBaseVertex(GL_LINES, line_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, m_vertex_buffer_cursor / stride);
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (point_index_size > 0)
{
StartIndex += line_index_size * sizeof(u16);
glDrawElementsBaseVertex(GL_POINTS, point_index_size, GL_UNSIGNED_SHORT, (GLvoid*)StartIndex, m_vertex_buffer_cursor / stride);
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
}
void VertexManager::vFlush()
{
if (LocalVBuffer == s_pCurBufferPointer) return;
if (Flushed) return;
Flushed=true;
VideoFifo_CheckEFBAccess();
#if defined(_DEBUG) || defined(DEBUGFAST)
PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfregs.numTexGen.numTexGens,
@ -318,13 +343,18 @@ void VertexManager::vFlush()
u32 stride = g_nativeVertexFmt->GetVertexStride();
PrepareDrawBuffers(stride);
if(m_buffers_count)
//still testing if this line is enabled to reduce the amount of vertex setup call everything goes wrong
//if(m_CurrentVertexFmt != g_nativeVertexFmt || !GLEW_ARB_draw_elements_base_vertex )
{
((GLVertexFormat*)g_nativeVertexFmt)->SetupVertexPointersOffset(m_vertex_buffer_cursor);
}
else
{
g_nativeVertexFmt->SetupVertexPointers();
if(m_buffers_count)
{
((GLVertexFormat*)g_nativeVertexFmt)->SetupVertexPointersOffset(GLEW_ARB_draw_elements_base_vertex ? 0 : m_vertex_buffer_cursor);
}
else
{
g_nativeVertexFmt->SetupVertexPointers();
}
m_CurrentVertexFmt = g_nativeVertexFmt;
}
GL_REPORT_ERRORD();
@ -402,7 +432,21 @@ void VertexManager::vFlush()
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here.
if (vs) VertexShaderCache::SetCurrentShader(vs->glprogid);
if(m_buffers_count) { DrawVertexBufferObject(); }else{ DrawVertexArray();};
if(m_buffers_count)
{
if(GLEW_ARB_draw_elements_base_vertex)
{
DrawVertexBufferObjectBase(stride);
}
else
{
DrawVertexBufferObject();
}
}
else
{
DrawVertexArray();
}
// run through vertex groups again to set alpha
if (useDstAlpha && !dualSourcePossible)
@ -415,7 +459,21 @@ void VertexManager::vFlush()
glDisable(GL_BLEND);
if(m_buffers_count) { DrawVertexBufferObject(); }else{ DrawVertexArray();};
if(m_buffers_count)
{
if(GLEW_ARB_draw_elements_base_vertex)
{
DrawVertexBufferObjectBase(stride);
}
else
{
DrawVertexBufferObject();
}
}
else
{
DrawVertexArray();
}
// restore color mask
g_renderer->SetColorMask();

View File

@ -52,6 +52,7 @@ public:
private:
void DrawVertexArray();
void DrawVertexBufferObject();
void DrawVertexBufferObjectBase(u32 stride);
void vFlush();
void PrepareDrawBuffers(u32 stride);
u32 m_vertex_buffer_cursor;
@ -63,6 +64,7 @@ private:
u32 m_current_index_buffer;
GLuint* m_vertex_buffers;
GLuint* m_index_buffers;
NativeVertexFormat *m_CurrentVertexFmt;
};
}