diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp index 4118e3dcbd..7c1fe9ff6c 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp @@ -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(); } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index 48f84b9aca..347d294eb7 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -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; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp index ff3f68a6cd..31466d1c84 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp @@ -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 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h index d1e7eeaa91..7be482a55f 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h @@ -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(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp index 9510ad444c..222d7849d0 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp @@ -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(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 884f16f826..874fc6316c 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -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; - } - + 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,13 +177,12 @@ 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; m_index_buffer_cursor = 0; - m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; - } + m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; + } if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) { @@ -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) @@ -217,8 +220,8 @@ void VertexManager::DrawVertexBuffer(int stride) if (IndexGenerator::GetNumTriangles() > 0) { if (FAILED(D3D::dev->DrawIndexedPrimitive( - D3DPT_TRIANGLELIST, - 0, + D3DPT_TRIANGLELIST, + 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)) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h index 51cf9b953d..2a165aa9af 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h @@ -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; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 03927413d8..2bd5936099 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -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() { @@ -153,18 +154,20 @@ void VertexManager::PrepareDrawBuffers(u32 stride) int line_index_size = IndexGenerator::GetLineindexLen() * sizeof(u16); 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; + 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); @@ -189,13 +192,13 @@ 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; + 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(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h index ac45151999..db80f87a2b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h @@ -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; }; }