diff --git a/Source/Core/VideoCommon/Src/LightingShaderGen.cpp b/Source/Core/VideoCommon/Src/LightingShaderGen.cpp index 5933a7d28f..2b717bdba6 100644 --- a/Source/Core/VideoCommon/Src/LightingShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/LightingShaderGen.cpp @@ -23,7 +23,7 @@ int GetLightingShaderId(u32* out) { - for (int i = 0; i < xfregs.numChan.numColorChans; ++i) + for (u32 i = 0; i < xfregs.numChan.numColorChans; ++i) { out[i] = xfregs.color[i].enablelighting ? (u32)xfregs.color[i].hex : diff --git a/Source/Core/VideoCommon/Src/NativeVertexFormat.h b/Source/Core/VideoCommon/Src/NativeVertexFormat.h index 02184fde1c..1340991b21 100644 --- a/Source/Core/VideoCommon/Src/NativeVertexFormat.h +++ b/Source/Core/VideoCommon/Src/NativeVertexFormat.h @@ -102,7 +102,7 @@ public: virtual void SetupVertexPointers() = 0; virtual void EnableComponents(u32 components) {} - int GetVertexStride() const { return vertex_stride; } + u32 GetVertexStride() const { return vertex_stride; } // TODO: move this under private: u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present. diff --git a/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp b/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp index 4f7f86d655..a1ff1a9985 100644 --- a/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp +++ b/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp @@ -346,7 +346,7 @@ static void Decode() // Display lists get added directly into the FIFO stream if (g_bRecordFifoData && cmd_byte != GX_CMD_CALL_DL) - FifoRecorder::GetInstance().WriteGPCommand(opcodeStart, g_pVideoData - opcodeStart); + FifoRecorder::GetInstance().WriteGPCommand(opcodeStart, u32(g_pVideoData - opcodeStart)); } static void DecodeSemiNop() @@ -429,7 +429,7 @@ static void DecodeSemiNop() } if (g_bRecordFifoData && cmd_byte != GX_CMD_CALL_DL) - FifoRecorder::GetInstance().WriteGPCommand(opcodeStart, g_pVideoData - opcodeStart); + FifoRecorder::GetInstance().WriteGPCommand(opcodeStart, u32(g_pVideoData - opcodeStart)); } void OpcodeDecoder_Init() diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 26e33a9beb..7969fcc86d 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -192,7 +192,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo *ptr++ = components; } - uid->num_values = ptr - uid->values; + uid->num_values = int(ptr - uid->values); } void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u32 components) @@ -225,7 +225,7 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u *ptr++ = bpmem.tevindref.hex; // 32 - for (int i = 0; i < bpmem.genMode.numtevstages+1; ++i) // up to 16 times + for (u32 i = 0; i < bpmem.genMode.numtevstages+1; ++i) // up to 16 times { *ptr++ = bpmem.combiners[i].colorC.hex; // 33+5*i *ptr++ = bpmem.combiners[i].alphaC.hex; // 34+5*i diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp index 5be72e4fcf..bcd46c5faf 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp @@ -163,6 +163,9 @@ void VertexManager::Flush() // loading a state will invalidate BP, so check for it g_video_backend->CheckInvalidState(); + 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 7026522cf6..347d294eb7 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -41,39 +41,39 @@ namespace DX11 // TODO: Find sensible values for these two const UINT IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16 * sizeof(u16); const UINT VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16; -const UINT MAXVBUFFER_COUNT = 2; +const UINT MAX_VBUFFER_COUNT = 2; void VertexManager::CreateDeviceObjects() { D3D11_BUFFER_DESC bufdesc = CD3D11_BUFFER_DESC(IBUFFER_SIZE, D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); - m_vertexDrawOffset = 0; - m_triangleDrawIndex = 0; - m_lineDrawIndex = 0; - m_pointDrawIndex = 0; - m_indexBuffers = new PID3D11Buffer[MAXVBUFFER_COUNT]; - m_vertexBuffers = new PID3D11Buffer[MAXVBUFFER_COUNT]; - for (m_activeIndexBuffer = 0; m_activeIndexBuffer < MAXVBUFFER_COUNT; m_activeIndexBuffer++) + m_vertex_draw_offset = 0; + m_triangle_draw_index = 0; + m_line_draw_index = 0; + m_point_draw_index = 0; + m_index_buffers = new PID3D11Buffer[MAX_VBUFFER_COUNT]; + m_vertex_buffers = new PID3D11Buffer[MAX_VBUFFER_COUNT]; + for (m_current_index_buffer = 0; m_current_index_buffer < MAX_VBUFFER_COUNT; m_current_index_buffer++) { - m_indexBuffers[m_activeIndexBuffer] = NULL; - CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_indexBuffers[m_activeIndexBuffer])), + m_index_buffers[m_current_index_buffer] = NULL; + CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_index_buffers[m_current_index_buffer])), "Failed to create index buffer."); - D3D::SetDebugObjectName((ID3D11DeviceChild*)m_indexBuffers[m_activeIndexBuffer], "index buffer of VertexManager"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_index_buffers[m_current_index_buffer], "index buffer of VertexManager"); } bufdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; bufdesc.ByteWidth = VBUFFER_SIZE; - for (m_activeVertexBuffer = 0; m_activeVertexBuffer < MAXVBUFFER_COUNT; m_activeVertexBuffer++) + for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) { - m_vertexBuffers[m_activeVertexBuffer] = NULL; - CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_vertexBuffers[m_activeVertexBuffer])), + m_vertex_buffers[m_current_vertex_buffer] = NULL; + CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_vertex_buffers[m_current_vertex_buffer])), "Failed to create vertex buffer."); - D3D::SetDebugObjectName((ID3D11DeviceChild*)m_vertexBuffers[m_activeVertexBuffer], "Vertex buffer of VertexManager"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_vertex_buffers[m_current_vertex_buffer], "Vertex buffer of VertexManager"); } - m_activeVertexBuffer = 0; - m_activeIndexBuffer = 0; - m_indexBufferCursor = IBUFFER_SIZE; - m_vertexBufferCursor = VBUFFER_SIZE; + m_current_vertex_buffer = 0; + m_current_index_buffer = 0; + m_index_buffer_cursor = IBUFFER_SIZE; + m_vertex_buffer_cursor = VBUFFER_SIZE; m_lineShader.Init(); m_pointShader.Init(); } @@ -82,10 +82,10 @@ void VertexManager::DestroyDeviceObjects() { m_pointShader.Shutdown(); m_lineShader.Shutdown(); - for (m_activeVertexBuffer = 0; m_activeVertexBuffer < MAXVBUFFER_COUNT; m_activeVertexBuffer++) + for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) { - SAFE_RELEASE(m_vertexBuffers[m_activeVertexBuffer]); - SAFE_RELEASE(m_indexBuffers[m_activeVertexBuffer]); + SAFE_RELEASE(m_vertex_buffers[m_current_vertex_buffer]); + SAFE_RELEASE(m_index_buffers[m_current_vertex_buffer]); } } @@ -100,47 +100,47 @@ VertexManager::~VertexManager() DestroyDeviceObjects(); } -void VertexManager::LoadBuffers() +void VertexManager::PrepareDrawBuffers() { D3D11_MAPPED_SUBRESOURCE map; UINT vSize = UINT(s_pCurBufferPointer - LocalVBuffer); D3D11_MAP MapType = D3D11_MAP_WRITE_NO_OVERWRITE; - if (m_vertexBufferCursor + vSize >= VBUFFER_SIZE) + if (m_vertex_buffer_cursor + vSize >= VBUFFER_SIZE) { // Wrap around - m_activeVertexBuffer = (m_activeVertexBuffer + 1) % MAXVBUFFER_COUNT; - m_vertexBufferCursor = 0; + m_current_vertex_buffer = (m_current_vertex_buffer + 1) % MAX_VBUFFER_COUNT; + m_vertex_buffer_cursor = 0; MapType = D3D11_MAP_WRITE_DISCARD; } - D3D::context->Map(m_vertexBuffers[m_activeVertexBuffer], 0, MapType, 0, &map); + D3D::context->Map(m_vertex_buffers[m_current_vertex_buffer], 0, MapType, 0, &map); - memcpy((u8*)map.pData + m_vertexBufferCursor, LocalVBuffer, vSize); - D3D::context->Unmap(m_vertexBuffers[m_activeVertexBuffer], 0); - m_vertexDrawOffset = m_vertexBufferCursor; - m_vertexBufferCursor += vSize; + memcpy((u8*)map.pData + m_vertex_buffer_cursor, LocalVBuffer, vSize); + D3D::context->Unmap(m_vertex_buffers[m_current_vertex_buffer], 0); + m_vertex_draw_offset = m_vertex_buffer_cursor; + m_vertex_buffer_cursor += vSize; UINT iCount = IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); MapType = D3D11_MAP_WRITE_NO_OVERWRITE; - if (m_indexBufferCursor + iCount >= (IBUFFER_SIZE / sizeof(u16))) + if (m_index_buffer_cursor + iCount >= (IBUFFER_SIZE / sizeof(u16))) { // Wrap around - m_activeIndexBuffer = (m_activeIndexBuffer + 1) % MAXVBUFFER_COUNT; - m_indexBufferCursor = 0; + m_current_index_buffer = (m_current_index_buffer + 1) % MAX_VBUFFER_COUNT; + m_index_buffer_cursor = 0; MapType = D3D11_MAP_WRITE_DISCARD; } - D3D::context->Map(m_indexBuffers[m_activeIndexBuffer], 0, MapType, 0, &map); + D3D::context->Map(m_index_buffers[m_current_index_buffer], 0, MapType, 0, &map); - m_triangleDrawIndex = m_indexBufferCursor; - m_lineDrawIndex = m_triangleDrawIndex + IndexGenerator::GetTriangleindexLen(); - m_pointDrawIndex = m_lineDrawIndex + IndexGenerator::GetLineindexLen(); - memcpy((u16*)map.pData + m_triangleDrawIndex, TIBuffer, sizeof(u16) * IndexGenerator::GetTriangleindexLen()); - memcpy((u16*)map.pData + m_lineDrawIndex, LIBuffer, sizeof(u16) * IndexGenerator::GetLineindexLen()); - memcpy((u16*)map.pData + m_pointDrawIndex, PIBuffer, sizeof(u16) * IndexGenerator::GetPointindexLen()); - D3D::context->Unmap(m_indexBuffers[m_activeIndexBuffer], 0); - m_indexBufferCursor += iCount; + m_triangle_draw_index = m_index_buffer_cursor; + m_line_draw_index = m_triangle_draw_index + IndexGenerator::GetTriangleindexLen(); + m_point_draw_index = m_line_draw_index + IndexGenerator::GetLineindexLen(); + memcpy((u16*)map.pData + m_triangle_draw_index, TIBuffer, sizeof(u16) * IndexGenerator::GetTriangleindexLen()); + memcpy((u16*)map.pData + m_line_draw_index, LIBuffer, sizeof(u16) * IndexGenerator::GetLineindexLen()); + memcpy((u16*)map.pData + m_point_draw_index, PIBuffer, sizeof(u16) * IndexGenerator::GetPointindexLen()); + D3D::context->Unmap(m_index_buffers[m_current_index_buffer], 0); + m_index_buffer_cursor += iCount; } static const float LINE_PT_TEX_OFFSETS[8] = { @@ -149,13 +149,13 @@ static const float LINE_PT_TEX_OFFSETS[8] = { void VertexManager::Draw(UINT stride) { - D3D::context->IASetVertexBuffers(0, 1, &m_vertexBuffers[m_activeVertexBuffer], &stride, &m_vertexDrawOffset); - D3D::context->IASetIndexBuffer(m_indexBuffers[m_activeIndexBuffer], DXGI_FORMAT_R16_UINT, 0); + D3D::context->IASetVertexBuffers(0, 1, &m_vertex_buffers[m_current_vertex_buffer], &stride, &m_vertex_draw_offset); + D3D::context->IASetIndexBuffer(m_index_buffers[m_current_index_buffer], DXGI_FORMAT_R16_UINT, 0); if (IndexGenerator::GetNumTriangles() > 0) { D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - D3D::context->DrawIndexed(IndexGenerator::GetTriangleindexLen(), m_triangleDrawIndex, 0); + D3D::context->DrawIndexed(IndexGenerator::GetTriangleindexLen(), m_triangle_draw_index, 0); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } // Disable culling for lines and points @@ -177,7 +177,7 @@ void VertexManager::Draw(UINT stride) texOffset, vpWidth, vpHeight, texOffsetEnable)) { D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); - D3D::context->DrawIndexed(IndexGenerator::GetLineindexLen(), m_lineDrawIndex, 0); + D3D::context->DrawIndexed(IndexGenerator::GetLineindexLen(), m_line_draw_index, 0); INCSTAT(stats.thisFrame.numIndexedDrawCalls); D3D::context->GSSetShader(NULL, NULL, 0); @@ -199,7 +199,7 @@ void VertexManager::Draw(UINT stride) texOffset, vpWidth, vpHeight, texOffsetEnable)) { D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); - D3D::context->DrawIndexed(IndexGenerator::GetPointindexLen(), m_pointDrawIndex, 0); + D3D::context->DrawIndexed(IndexGenerator::GetPointindexLen(), m_point_draw_index, 0); INCSTAT(stats.thisFrame.numIndexedDrawCalls); D3D::context->GSSetShader(NULL, NULL, 0); @@ -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; @@ -270,7 +267,7 @@ void VertexManager::vFlush() GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); goto shader_fail; } - LoadBuffers(); + PrepareDrawBuffers(); unsigned int stride = g_nativeVertexFmt->GetVertexStride(); g_nativeVertexFmt->SetupVertexPointers(); g_renderer->ApplyState(useDstAlpha); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h index 9e6b7f2dca..b5d0d21757 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.h @@ -37,22 +37,22 @@ public: private: - void LoadBuffers(); - void Draw(UINT stride); + void PrepareDrawBuffers(); + void Draw(u32 stride); // temp void vFlush(); - UINT m_indexBufferCursor; - UINT m_vertexBufferCursor; - UINT m_vertexDrawOffset; - UINT m_triangleDrawIndex; - UINT m_lineDrawIndex; - UINT m_pointDrawIndex; - UINT m_activeVertexBuffer; - UINT m_activeIndexBuffer; + u32 m_vertex_buffer_cursor; + u32 m_vertex_draw_offset; + u32 m_index_buffer_cursor; + u32 m_current_vertex_buffer; + u32 m_current_index_buffer; + u32 m_triangle_draw_index; + u32 m_line_draw_index; + u32 m_point_draw_index; typedef ID3D11Buffer* PID3D11Buffer; - PID3D11Buffer* m_indexBuffers; - PID3D11Buffer* m_vertexBuffers; + PID3D11Buffer* m_index_buffers; + PID3D11Buffer* m_vertex_buffers; LineGeometryShader m_lineShader; PointGeometryShader m_pointShader; 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..d24720e6f9 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::ChangeStreamSource(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/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index a26b041ba0..4e8f6ee68a 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -67,6 +67,7 @@ static int s_fps = 0; static u32 s_blendMode; static u32 s_LastAA; static bool IS_AMD; +static float m_fMaxPointSize; static char *st; @@ -329,6 +330,9 @@ Renderer::Renderer() D3D::BeginFrame(); D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true); D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); + D3D::SetRenderState(D3DRS_POINTSCALEENABLE,false); + m_fMaxPointSize = D3D::GetCaps().MaxPointSize; + } Renderer::~Renderer() @@ -1304,7 +1308,15 @@ void Renderer::SetLineWidth() // We can't change line width in D3D unless we use ID3DXLine float fratio = xfregs.viewport.wd != 0 ? Renderer::EFBToScaledXf(1.f) : 1.0f; float psize = bpmem.lineptwidth.linesize * fratio / 6.0f; + //little hack to compensate scalling problems in dx9 must be taken out when scalling is fixed. + psize *= 2.0f; + if (psize > m_fMaxPointSize) + { + psize = m_fMaxPointSize; + } D3D::SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&psize)); + D3D::SetRenderState(D3DRS_POINTSIZE_MIN, *((DWORD*)&psize)); + D3D::SetRenderState(D3DRS_POINTSIZE_MAX, *((DWORD*)&psize)); } void Renderer::SetSamplerState(int stage, int texindex) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 17a7aa1498..925617f3f5 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -44,7 +44,7 @@ namespace DX9 //This are the initially requeted size for the buffers expresed in elements const u32 IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16; const u32 VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16; -const u32 MAXVBUFFER_COUNT = 2; +const u32 MAX_VBUFFER_COUNT = 2; inline void DumpBadShaders() { @@ -67,88 +67,88 @@ inline void DumpBadShaders() void VertexManager::CreateDeviceObjects() { - NumVBuffers = 0; - VBuffers = NULL; - IBuffers = NULL; + m_buffers_count = 0; + m_vertex_buffers = NULL; + m_index_buffers = NULL; D3DCAPS9 DeviceCaps = D3D::GetCaps(); u32 devicevMaxBufferSize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride; //Calculate Device Dependant size - CurrentVBufferSize = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_SIZE; - CurrentIBufferSize = (IBUFFER_SIZE > DeviceCaps.MaxVertexIndex) ? DeviceCaps.MaxVertexIndex : IBUFFER_SIZE; + m_vertex_buffer_size = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_SIZE; + m_index_buffer_size = (IBUFFER_SIZE > DeviceCaps.MaxVertexIndex) ? DeviceCaps.MaxVertexIndex : IBUFFER_SIZE; //if device caps are not enough for Vbuffer fall back to vertex arrays - if (CurrentIBufferSize < MAXIBUFFERSIZE || CurrentVBufferSize < MAXVBUFFERSIZE) return; + if (m_index_buffer_size < MAXIBUFFERSIZE || m_vertex_buffer_size < MAXVBUFFERSIZE) return; - VBuffers = new LPDIRECT3DVERTEXBUFFER9[MAXVBUFFER_COUNT]; - IBuffers = new LPDIRECT3DINDEXBUFFER9[MAXVBUFFER_COUNT]; + m_vertex_buffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBUFFER_COUNT]; + m_index_buffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBUFFER_COUNT]; bool Fail = false; - for (CurrentVBuffer = 0; CurrentVBuffer < MAXVBUFFER_COUNT; CurrentVBuffer++) + for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) { - VBuffers[CurrentVBuffer] = NULL; - IBuffers[CurrentVBuffer] = NULL; + m_vertex_buffers[m_current_vertex_buffer] = NULL; + m_index_buffers[m_current_vertex_buffer] = NULL; } - for (CurrentVBuffer = 0; CurrentVBuffer < MAXVBUFFER_COUNT; CurrentVBuffer++) + for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) { - if(FAILED( D3D::dev->CreateVertexBuffer( CurrentVBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &VBuffers[CurrentVBuffer], NULL ) ) ) + if(FAILED( D3D::dev->CreateVertexBuffer( m_vertex_buffer_size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertex_buffers[m_current_vertex_buffer], NULL ) ) ) { Fail = true; break; } - if( FAILED( D3D::dev->CreateIndexBuffer( CurrentIBufferSize * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &IBuffers[CurrentVBuffer], NULL ) ) ) + if( FAILED( D3D::dev->CreateIndexBuffer( m_index_buffer_size * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_index_buffers[m_current_vertex_buffer], NULL ) ) ) { Fail = true; return; } } - NumVBuffers = CurrentVBuffer; - CurrentVBuffer = 0; - CurrentIBuffer = 0; - CurrentIBufferIndex = CurrentIBufferSize; - CurrentVBufferIndex = CurrentVBufferSize; - + m_buffers_count = m_current_vertex_buffer; + m_current_vertex_buffer = 0; + 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) { - NumVBuffers--; - if (NumVBuffers < 2) + m_buffers_count--; + if (m_buffers_count < 2) { //Error creating Vertex buffers. clean and fall to Vertex arrays - NumVBuffers = MAXVBUFFER_COUNT; + m_buffers_count = MAX_VBUFFER_COUNT; DestroyDeviceObjects(); } } } void VertexManager::DestroyDeviceObjects() { - D3D::dev->SetStreamSource( 0, NULL, 0, 0); - D3D::dev->SetIndices(NULL); - for (int i = 0; i < MAXVBUFFER_COUNT; i++) + D3D::SetStreamSource( 0, NULL, 0, 0); + D3D::SetIndices(NULL); + for (int i = 0; i < MAX_VBUFFER_COUNT; i++) { - if(VBuffers) + if(m_vertex_buffers) { - if (VBuffers[i]) + if (m_vertex_buffers[i]) { - VBuffers[i]->Release(); - VBuffers[i] = NULL; + m_vertex_buffers[i]->Release(); + m_vertex_buffers[i] = NULL; } } - if (IBuffers[i]) + if (m_index_buffers[i]) { - IBuffers[i]->Release(); - IBuffers[i] = NULL; + m_index_buffers[i]->Release(); + m_index_buffers[i] = NULL; } } - if(VBuffers) - delete [] VBuffers; - if(IBuffers) - delete [] IBuffers; - VBuffers = NULL; - IBuffers = NULL; + if(m_vertex_buffers) + delete [] m_vertex_buffers; + if(m_index_buffers) + delete [] m_index_buffers; + m_vertex_buffers = NULL; + m_index_buffers = NULL; } -void VertexManager::PrepareVBuffers(int stride) +void VertexManager::PrepareDrawBuffers(u32 stride) { - if (!NumVBuffers) + if (!m_buffers_count) { return; } @@ -158,34 +158,33 @@ void VertexManager::PrepareVBuffers(int stride) int TdataSize = IndexGenerator::GetTriangleindexLen(); int LDataSize = IndexGenerator::GetLineindexLen(); int PDataSize = IndexGenerator::GetPointindexLen(); - int IndexDataSize = TdataSize + LDataSize + PDataSize; + int IndexDataSize = TdataSize + LDataSize; DWORD LockMode = D3DLOCK_NOOVERWRITE; - - if (CurrentVBufferIndex > CurrentVBufferSize - datasize) + 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; - CurrentVBufferIndex = 0; - CurrentVBuffer = (CurrentVBuffer + 1) % NumVBuffers; - } - - if(FAILED(VBuffers[CurrentVBuffer]->Lock(CurrentVBufferIndex, datasize,(VOID**)(&pVertices), LockMode))) + 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(); return; } memcpy(pVertices, LocalVBuffer, datasize); - VBuffers[CurrentVBuffer]->Unlock(); + m_vertex_buffers[m_current_vertex_buffer]->Unlock(); LockMode = D3DLOCK_NOOVERWRITE; - - if (CurrentIBufferIndex > CurrentIBufferSize - IndexDataSize) + if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize) { LockMode = D3DLOCK_DISCARD; - CurrentIBufferIndex = 0; - CurrentIBuffer = (CurrentIBuffer + 1) % NumVBuffers; - } + m_index_buffer_cursor = 0; + m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; + } - if(FAILED(IBuffers[CurrentIBuffer]->Lock(CurrentIBufferIndex * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) + if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) { DestroyDeviceObjects(); return; @@ -200,72 +199,88 @@ void VertexManager::PrepareVBuffers(int stride) memcpy(pIndices, LIBuffer, LDataSize * sizeof(u16)); pIndices += LDataSize; } - if(PDataSize) - { - memcpy(pIndices, PIBuffer, PDataSize * sizeof(u16)); - } - IBuffers[CurrentIBuffer]->Unlock(); - D3D::dev->SetStreamSource( 0, VBuffers[CurrentVBuffer], CurrentVBufferIndex, stride); - if(CurrentIBufferIndex == 0) + m_index_buffers[m_current_index_buffer]->Unlock(); + if(m_current_stride != stride || m_vertex_buffer_cursor == 0) { - D3D::dev->SetIndices(IBuffers[CurrentIBuffer]); + m_current_stride = stride; + D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, stride); } -} - -void VertexManager::DrawVB(int stride) -{ - if (IndexGenerator::GetNumTriangles() > 0) + if (m_index_buffer_cursor == 0) { - if (FAILED(D3D::dev->DrawIndexedPrimitive( - D3DPT_TRIANGLELIST, - 0, - 0, - IndexGenerator::GetNumVerts(), - CurrentIBufferIndex, - IndexGenerator::GetNumTriangles()))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (IndexGenerator::GetNumLines() > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitive( - D3DPT_LINELIST, - 0, - 0, - IndexGenerator::GetNumVerts(), - CurrentIBufferIndex + IndexGenerator::GetTriangleindexLen(), - IndexGenerator::GetNumLines()))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (IndexGenerator::GetNumPoints() > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitive( - D3DPT_POINTLIST, - 0, - 0, - IndexGenerator::GetNumVerts(), - CurrentIBufferIndex + IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen(), - IndexGenerator::GetNumPoints()))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); + D3D::SetIndices(m_index_buffers[m_current_index_buffer]); } } -void VertexManager::DrawVA(int stride) -{ - if (IndexGenerator::GetNumTriangles() > 0) +void VertexManager::DrawVertexBuffer(int stride) +{ + int triangles = IndexGenerator::GetNumTriangles(); + int lines = IndexGenerator::GetNumLines(); + int points = IndexGenerator::GetNumPoints(); + int numverts = IndexGenerator::GetNumVerts(); + int StartIndex = m_index_buffer_cursor; + int basevertex = m_vertex_buffer_cursor / stride; + if (triangles > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitive( + D3DPT_TRIANGLELIST, + basevertex, + 0, + numverts, + StartIndex, + triangles))) + { + DumpBadShaders(); + } + StartIndex += IndexGenerator::GetTriangleindexLen(); + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (lines > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitive( + D3DPT_LINELIST, + basevertex, + 0, + numverts, + StartIndex, + IndexGenerator::GetNumLines()))) + { + DumpBadShaders(); + } + StartIndex += IndexGenerator::GetLineindexLen(); + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (points > 0) + { + //DrawIndexedPrimitive does not support point list so we have to draw the points one by one + for (int i = 0; i < points; i++) + { + if (FAILED(D3D::dev->DrawPrimitive( + D3DPT_POINTLIST, + basevertex + PIBuffer[i], + 1))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numDrawCalls); + } + + + } + +} + +void VertexManager::DrawVertexArray(int stride) +{ + int triangles = IndexGenerator::GetNumTriangles(); + int lines = IndexGenerator::GetNumLines(); + int points = IndexGenerator::GetNumPoints(); + int numverts = IndexGenerator::GetNumVerts(); + if (triangles > 0) { if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST, - 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumTriangles(), + 0, numverts, triangles, TIBuffer, D3DFMT_INDEX16, LocalVBuffer, @@ -275,11 +290,11 @@ void VertexManager::DrawVA(int stride) } INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - if (IndexGenerator::GetNumLines() > 0) + if (lines > 0) { if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( D3DPT_LINELIST, - 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumLines(), + 0, numverts, lines, LIBuffer, D3DFMT_INDEX16, LocalVBuffer, @@ -289,11 +304,11 @@ void VertexManager::DrawVA(int stride) } INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - if (IndexGenerator::GetNumPoints() > 0) + if (points > 0) { if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( D3DPT_POINTLIST, - 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumPoints(), + 0, numverts, points, PIBuffer, D3DFMT_INDEX16, LocalVBuffer, @@ -307,11 +322,7 @@ void VertexManager::DrawVA(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)) @@ -350,7 +361,7 @@ void VertexManager::vFlush() // set global constants VertexShaderManager::SetConstants(); PixelShaderManager::SetConstants(); - int stride = g_nativeVertexFmt->GetVertexStride(); + u32 stride = g_nativeVertexFmt->GetVertexStride(); if (!PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components)) { GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); @@ -362,9 +373,16 @@ void VertexManager::vFlush() goto shader_fail; } - PrepareVBuffers(stride); + PrepareDrawBuffers(stride); g_nativeVertexFmt->SetupVertexPointers(); - if(NumVBuffers){ DrawVB(stride);} else { DrawVA(stride);} + if(m_buffers_count) + { + DrawVertexBuffer(stride); + } + else + { + DrawVertexArray(stride); + } bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; @@ -377,16 +395,23 @@ void VertexManager::vFlush() } // update alpha only g_renderer->ApplyState(true); - if(NumVBuffers){ DrawVB(stride);} else { DrawVA(stride);} + if(m_buffers_count) + { + DrawVertexBuffer(stride); + } + else + { + DrawVertexArray(stride); + } g_renderer->RestoreState(); } GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); shader_fail: - if(NumVBuffers) + if(m_buffers_count) { - CurrentIBufferIndex += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); - CurrentVBufferIndex += IndexGenerator::GetNumVerts() * stride; + m_index_buffer_cursor += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); + m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride; } ResetBuffer(); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h index aa4e9ed57b..2a165aa9af 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.h @@ -34,18 +34,19 @@ public: void CreateDeviceObjects(); void DestroyDeviceObjects(); private: - u32 CurrentVBufferIndex; - u32 CurrentVBufferSize; - u32 CurrentIBufferIndex; - u32 CurrentIBufferSize; - u32 NumVBuffers; - u32 CurrentVBuffer; - u32 CurrentIBuffer; - LPDIRECT3DVERTEXBUFFER9 *VBuffers; - LPDIRECT3DINDEXBUFFER9 *IBuffers; - void PrepareVBuffers(int stride); - void DrawVB(int stride); - void DrawVA(int stride); + u32 m_vertex_buffer_cursor; + u32 m_vertex_buffer_size; + u32 m_index_buffer_cursor; + 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; + void PrepareDrawBuffers(u32 stride); + void DrawVertexBuffer(int stride); + void DrawVertexArray(int stride); // temp void vFlush(); }; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp index 6b894df6c7..5fa0a5552a 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp @@ -26,48 +26,9 @@ #include "NativeVertexFormat.h" #include "VertexManager.h" -#define COMPILED_CODE_SIZE 4096 - -// TODO: Use this again for performance, but without VAO we never know exactly the last configuration -static u32 s_prevcomponents; // previous state set - -/* -#ifdef _WIN32 -#ifdef _M_IX86 -#define USE_JIT -#endif -#endif -*/ -// Note the use of CallCdeclFunction3I etc. -// This is a horrible hack that is necessary because in 64-bit mode, Opengl32.dll is based way, way above the 32-bit -// address space that is within reach of a CALL, and just doing &fn gives us these high uncallable addresses. So we -// want to grab the function pointers from the import table instead. - -// This problem does not apply to glew functions, only core opengl32 functions. - // Here's some global state. We only use this to keep track of what we've sent to the OpenGL state // machine. -#ifdef USE_JIT -DECLARE_IMPORT(glNormalPointer); -DECLARE_IMPORT(glVertexPointer); -DECLARE_IMPORT(glColorPointer); -DECLARE_IMPORT(glTexCoordPointer); -#endif - -class GLVertexFormat : public NativeVertexFormat -{ - u8 *m_compiledCode; - PortableVertexDeclaration vtx_decl; - -public: - GLVertexFormat(); - ~GLVertexFormat(); - - virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); - virtual void SetupVertexPointers(); -}; - namespace OGL { @@ -76,23 +37,14 @@ NativeVertexFormat* VertexManager::CreateNativeVertexFormat() return new GLVertexFormat(); } -} - GLVertexFormat::GLVertexFormat() { -#ifdef USE_JIT - m_compiledCode = (u8 *)AllocateExecutableMemory(COMPILED_CODE_SIZE, false); - if (m_compiledCode) - memset(m_compiledCode, 0, COMPILED_CODE_SIZE); -#endif + } GLVertexFormat::~GLVertexFormat() { -#ifdef USE_JIT - FreeMemoryPages(m_compiledCode, COMPILED_CODE_SIZE); - m_compiledCode = 0; -#endif + glDeleteVertexArrays(1, &VAO); } inline GLuint VarToGL(VarType t) @@ -105,105 +57,44 @@ inline GLuint VarToGL(VarType t) void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) { - s_prevcomponents = 0; - - vertex_stride = _vtx_decl.stride; - using namespace Gen; + this->vtx_decl = _vtx_decl; + vertex_stride = vtx_decl.stride; // We will not allow vertex components causing uneven strides. - if (_vtx_decl.stride & 3) - PanicAlert("Uneven vertex stride: %i", _vtx_decl.stride); - -#ifdef USE_JIT - Gen::XEmitter emit(m_compiledCode); - // Alright, we have our vertex declaration. Compile some crazy code to set it quickly using GL. - emit.ABI_EmitPrologue(6); + if (vertex_stride & 3) + PanicAlert("Uneven vertex stride: %i", vertex_stride); - emit.CallCdeclFunction4_I(glVertexPointer, 3, GL_FLOAT, _vtx_decl.stride, 0); - - if (_vtx_decl.num_normals >= 1) - { - emit.CallCdeclFunction3_I(glNormalPointer, VarToGL(_vtx_decl.normal_gl_type), _vtx_decl.stride, _vtx_decl.normal_offset[0]); - if (_vtx_decl.num_normals == 3) { - emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM1_ATTRIB, _vtx_decl.normal_gl_size, VarToGL(_vtx_decl.normal_gl_type), GL_TRUE, _vtx_decl.stride, _vtx_decl.normal_offset[1]); - emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM2_ATTRIB, _vtx_decl.normal_gl_size, VarToGL(_vtx_decl.normal_gl_type), GL_TRUE, _vtx_decl.stride, _vtx_decl.normal_offset[2]); - } - } - - for (int i = 0; i < 2; i++) - { - if (_vtx_decl.color_offset[i] != -1) - { - if (i == 0) - emit.CallCdeclFunction4_I(glColorPointer, 4, GL_UNSIGNED_BYTE, _vtx_decl.stride, _vtx_decl.color_offset[i]); - else - emit.CallCdeclFunction4((void *)glSecondaryColorPointer, 4, GL_UNSIGNED_BYTE, _vtx_decl.stride, _vtx_decl.color_offset[i]); - } - } - - for (int i = 0; i < 8; i++) - { - if (_vtx_decl.texcoord_offset[i] != -1) - { - int id = GL_TEXTURE0 + i; -#ifdef _M_X64 -#ifdef _MSC_VER - emit.MOV(32, R(RCX), Imm32(id)); -#else - emit.MOV(32, R(RDI), Imm32(id)); -#endif -#else - emit.ABI_AlignStack(1 * 4); - emit.PUSH(32, Imm32(id)); -#endif - emit.CALL((void *)glClientActiveTexture); -#ifndef _M_X64 -#ifdef _WIN32 - // don't inc stack on windows, stdcall -#else - emit.ABI_RestoreStack(1 * 4); -#endif -#endif - emit.CallCdeclFunction4_I( - glTexCoordPointer, _vtx_decl.texcoord_size[i], VarToGL(_vtx_decl.texcoord_gl_type[i]), - _vtx_decl.stride, _vtx_decl.texcoord_offset[i]); - } - } - - if (_vtx_decl.posmtx_offset != -1) - emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, _vtx_decl.stride, _vtx_decl.posmtx_offset); - - emit.ABI_EmitEpilogue(6); - - if (emit.GetCodePtr() - (u8*)m_compiledCode > COMPILED_CODE_SIZE) - Crash(); - -#endif - this->vtx_decl = _vtx_decl; -} - -void GLVertexFormat::SetupVertexPointers() { - // Cast a pointer to compiled code to a pointer to a function taking no parameters, through a (void *) cast first to - // get around type checking errors, and call it. -#ifdef USE_JIT - ((void (*)())(void*)m_compiledCode)(); -#else + VertexManager *vm = (OGL::VertexManager*)g_vertex_manager; + + glGenVertexArrays(1, &VAO); + glBindVertexArray(VAO); + + // the element buffer is bound directly to the vao, so we must it set for every vao + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->m_index_buffers); + glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, vtx_decl.stride, (u8*)NULL); - glVertexPointer(3, GL_FLOAT, vtx_decl.stride, VertexManager::s_pBaseBufferPointer); if (vtx_decl.num_normals >= 1) { - glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[0])); + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[0]); if (vtx_decl.num_normals == 3) { - glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[1])); - glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[2])); + glEnableVertexAttribArray(SHADER_NORM1_ATTRIB); + glEnableVertexAttribArray(SHADER_NORM2_ATTRIB); + glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[1]); + glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[2]); } } for (int i = 0; i < 2; i++) { if (vtx_decl.color_offset[i] != -1) { - if (i == 0) - glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.color_offset[i])); - else { - glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.color_offset[i])); + if (i == 0) { + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]); + } else { + glEnableClientState(GL_SECONDARY_COLOR_ARRAY); + glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]); } } } @@ -212,75 +103,21 @@ void GLVertexFormat::SetupVertexPointers() { if (vtx_decl.texcoord_offset[i] != -1) { int id = GL_TEXTURE0 + i; glClientActiveTexture(id); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]), - vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.texcoord_offset[i])); + vtx_decl.stride, (u8*)NULL + vtx_decl.texcoord_offset[i]); } } if (vtx_decl.posmtx_offset != -1) { - glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.posmtx_offset)); + glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB); + glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (u8*)NULL + vtx_decl.posmtx_offset); } -#endif - if (s_prevcomponents != m_components) - { - // vertices - glEnableClientState(GL_VERTEX_ARRAY); - - // matrices - if ((m_components & VB_HAS_POSMTXIDX) != (s_prevcomponents & VB_HAS_POSMTXIDX)) - { - if (m_components & VB_HAS_POSMTXIDX) - glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB); - else - glDisableVertexAttribArray(SHADER_POSMTX_ATTRIB); - } - - // normals - if ((m_components & VB_HAS_NRM0) != (s_prevcomponents & VB_HAS_NRM0)) - { - if (m_components & VB_HAS_NRM0) - glEnableClientState(GL_NORMAL_ARRAY); - else - glDisableClientState(GL_NORMAL_ARRAY); - } - if ((m_components & VB_HAS_NRM1) != (s_prevcomponents & VB_HAS_NRM1)) - { - if (m_components & VB_HAS_NRM1) { - glEnableVertexAttribArray(SHADER_NORM1_ATTRIB); - glEnableVertexAttribArray(SHADER_NORM2_ATTRIB); - } - else { - glDisableVertexAttribArray(SHADER_NORM1_ATTRIB); - glDisableVertexAttribArray(SHADER_NORM2_ATTRIB); - } - } - - // color - for (int i = 0; i < 2; ++i) - { - if ((m_components & (VB_HAS_COL0 << i)) != (s_prevcomponents & (VB_HAS_COL0 << i))) - { - if (m_components & (VB_HAS_COL0 << i)) - glEnableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY); - else - glDisableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY); - } - } - - // tex - for (int i = 0; i < 8; ++i) - { - if ((m_components & (VB_HAS_UV0 << i)) != (s_prevcomponents & (VB_HAS_UV0 << i))) - { - glClientActiveTexture(GL_TEXTURE0 + i); - if (m_components & (VB_HAS_UV0 << i)) - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - else - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - } - - s_prevcomponents = m_components; - } + vm->m_last_vao = VAO; +} + +void GLVertexFormat::SetupVertexPointers() { +} + } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/RasterFont.cpp b/Source/Plugins/Plugin_VideoOGL/Src/RasterFont.cpp index b6401e42df..beac56148f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/RasterFont.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/RasterFont.cpp @@ -193,10 +193,6 @@ RasterFont::RasterFont() glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, NULL); glEnableVertexAttribArray(SHADER_TEXTURE0_ATTRIB); glVertexAttribPointer(SHADER_TEXTURE0_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL+2); - - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); } RasterFont::~RasterFont() @@ -288,10 +284,6 @@ void RasterFont::printMultilineText(const char *text, double start_x, double sta glBindTexture(GL_TEXTURE_2D, texture); glDrawArrays(GL_TRIANGLES, 0, usage/4); - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glUseProgram(0); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 71a5edbc51..069a2a90aa 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -64,6 +64,7 @@ #include "BPFunctions.h" #include "FPSCounter.h" #include "ConfigManager.h" +#include "VertexManager.h" #include "main.h" // Local #ifdef _WIN32 @@ -296,6 +297,20 @@ Renderer::Renderer() "GPU: Does your video card support OpenGL 3.0?"); bSuccess = false; } + + if (!GLEW_ARB_map_buffer_range) + { + ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_map_buffer_range.\n" + "GPU: Does your video card support OpenGL 3.0?"); + bSuccess = false; + } + + if (!GLEW_ARB_draw_elements_base_vertex) + { + ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_draw_elements_base_vertex.\n" + "GPU: Does your video card support OpenGL 3.2?"); + bSuccess = false; + } s_bHaveCoverageMSAA = strstr(ptoken, "GL_NV_framebuffer_multisample_coverage") != NULL; @@ -415,10 +430,6 @@ Renderer::Renderer() glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*5, NULL); glEnableVertexAttribArray(SHADER_COLOR0_ATTRIB); glVertexAttribPointer(SHADER_COLOR0_ATTRIB, 3, GL_FLOAT, 0, sizeof(GLfloat)*5, (GLfloat*)NULL+2); - - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); glStencilFunc(GL_ALWAYS, 0, 0); glBlendFunc(GL_ONE, GL_ONE); @@ -603,10 +614,6 @@ void Renderer::DrawDebugInfo() ProgramShaderCache::SetBothShaders(s_ShowEFBCopyRegions_PS.glprogid, s_ShowEFBCopyRegions_VS.glprogid); glBindVertexArray( s_ShowEFBCopyRegions_VAO ); glDrawArrays(GL_LINES, 0, stats.efb_regions.size() * 2*6); - - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); // Restore Line Size glLineWidth(lSize); @@ -1429,6 +1436,10 @@ void Renderer::RestoreAPIState() glPolygonMode(GL_FRONT_AND_BACK, g_ActiveConfig.bWireFrame ? GL_LINE : GL_FILL); ProgramShaderCache::SetBothShaders(0, 0); + + VertexManager *vm = (OGL::VertexManager*)g_vertex_manager; + glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers); + vm->m_last_vao = 0; } void Renderer::SetGenerationMode() diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp index 231b89cbdc..390354ebd0 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp @@ -375,10 +375,6 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo glBindVertexArray(vbo_it->second.vao); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp index cd4f9e6d5b..ac88cceca4 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp @@ -183,10 +183,6 @@ void Init() glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL); glEnableVertexAttribArray(SHADER_TEXTURE0_ATTRIB); glVertexAttribPointer(SHADER_TEXTURE0_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL+2); - - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); glGenRenderbuffers(1, &s_dstRenderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, s_dstRenderBuffer); @@ -285,10 +281,6 @@ void EncodeToRamUsingShader(GLuint srcTexture, const TargetRectangle& sourceRc, glBindVertexArray( s_encode_VAO ); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); GL_REPORT_ERRORD(); @@ -475,10 +467,6 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur glBindVertexArray( s_decode_VAO ); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - GL_REPORT_ERRORD(); // reset state diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 038792a380..5d3840775a 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -49,58 +49,177 @@ extern NativeVertexFormat *g_nativeVertexFmt; namespace OGL { - -//static GLint max_Index_size = 0; - -//static GLuint s_vboBuffers[MAXVBOBUFFERCOUNT] = {0}; -//static int s_nCurVBOIndex = 0; // current free buffer +//This are the initially requeted size for the buffers expresed in bytes +const u32 MAX_IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16 * sizeof(u16); +const u32 MAX_VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16; +const u32 MIN_IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 1 * sizeof(u16); +const u32 MIN_VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 1; VertexManager::VertexManager() { - // TODO: doesn't seem to be used anywhere + CreateDeviceObjects(); +} - //glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*)&max_Index_size); - // - //if (max_Index_size > MAXIBUFFERSIZE) - // max_Index_size = MAXIBUFFERSIZE; - // - //GL_REPORT_ERRORD(); +VertexManager::~VertexManager() +{ + DestroyDeviceObjects(); } void VertexManager::CreateDeviceObjects() { + GL_REPORT_ERRORD(); + u32 max_Index_size = 0; + u32 max_Vertex_size = 0; + glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*)&max_Index_size); + glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*)&max_Vertex_size); + max_Index_size *= sizeof(u16); + GL_REPORT_ERROR(); + m_index_buffer_size = std::min(MAX_IBUFFER_SIZE, std::max(max_Index_size, MIN_IBUFFER_SIZE)); + m_vertex_buffer_size = std::min(MAX_VBUFFER_SIZE, std::max(max_Vertex_size, MIN_VBUFFER_SIZE)); + + // should be not bigger, but we need it. so try and have luck + if (m_index_buffer_size > max_Index_size) { + ERROR_LOG(VIDEO, "GL_MAX_ELEMENTS_INDICES to small, so try it anyway. good luck\n"); + } + if (m_vertex_buffer_size > max_Vertex_size) { + ERROR_LOG(VIDEO, "GL_MAX_ELEMENTS_VERTICES to small, so try it anyway. good luck\n"); + } + glGenBuffers(1, &m_vertex_buffers); + GL_REPORT_ERROR(); + glGenBuffers(1, &m_index_buffers); + GL_REPORT_ERROR(); + glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers ); + GL_REPORT_ERROR(); + glBufferData(GL_ARRAY_BUFFER, m_vertex_buffer_size, NULL, GL_STREAM_DRAW ); + GL_REPORT_ERROR(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers ); + GL_REPORT_ERROR(); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_size, NULL, GL_STREAM_DRAW ); + GL_REPORT_ERROR(); + m_index_buffer_cursor = 0; + m_vertex_buffer_cursor = 0; + m_CurrentVertexFmt = NULL; + m_last_vao = 0; } void VertexManager::DestroyDeviceObjects() { + GL_REPORT_ERRORD(); + glBindBuffer(GL_ARRAY_BUFFER, 0 ); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0 ); + GL_REPORT_ERROR(); + glDeleteBuffers(1, &m_vertex_buffers); + GL_REPORT_ERROR(); + + glDeleteBuffers(1, &m_index_buffers); + GL_REPORT_ERROR(); } -void VertexManager::Draw() +void VertexManager::PrepareDrawBuffers(u32 stride) { - if (IndexGenerator::GetNumTriangles() > 0) + u8* pVertices = NULL; + u16* pIndices = NULL; + int vertex_data_size = IndexGenerator::GetNumVerts() * stride; + int triangle_index_size = IndexGenerator::GetTriangleindexLen(); + int line_index_size = IndexGenerator::GetLineindexLen(); + int point_index_size = IndexGenerator::GetPointindexLen(); + int index_data_size = (triangle_index_size + line_index_size + point_index_size) * sizeof(u16); + 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 || m_index_buffer_cursor >= m_index_buffer_size - index_data_size) { - glDrawElements(GL_TRIANGLES, IndexGenerator::GetTriangleindexLen(), GL_UNSIGNED_SHORT, TIBuffer); + LockMode |= GL_MAP_INVALIDATE_BUFFER_BIT; + m_vertex_buffer_cursor = 0; + m_index_buffer_cursor = 0; + } + else + { + LockMode |= /*GL_MAP_INVALIDATE_RANGE_BIT |*/ GL_MAP_UNSYNCHRONIZED_BIT; + } + + pVertices = (u8*)glMapBufferRange(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LockMode); + if(pVertices) + { + memcpy(pVertices, LocalVBuffer, vertex_data_size); + glUnmapBuffer(GL_ARRAY_BUFFER); + } + else // could that happen? out-of-memory? + { + glBufferSubData(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LocalVBuffer); + } + + pIndices = (u16*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor , index_data_size, LockMode); + if(pIndices) + { + if(triangle_index_size) + { + memcpy(pIndices, TIBuffer, triangle_index_size * sizeof(u16)); + pIndices += triangle_index_size; + } + if(line_index_size) + { + memcpy(pIndices, LIBuffer, line_index_size * sizeof(u16)); + pIndices += line_index_size; + } + if(point_index_size) + { + memcpy(pIndices, PIBuffer, point_index_size * sizeof(u16)); + } + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); + } + else // could that happen? out-of-memory? + { + if(triangle_index_size) + { + triangle_index_size *= sizeof(u16); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor, triangle_index_size, TIBuffer); + } + if(line_index_size) + { + line_index_size *= sizeof(u16); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor + triangle_index_size, line_index_size, LIBuffer); + } + if(point_index_size) + { + point_index_size *= sizeof(u16); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor + triangle_index_size + line_index_size, point_index_size, PIBuffer); + } + } +} + +void VertexManager::Draw(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; + int basevertex = m_vertex_buffer_cursor / stride; + if (triangle_index_size > 0) + { + glDrawElementsBaseVertex(GL_TRIANGLES, triangle_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+StartIndex, basevertex); + StartIndex += triangle_index_size * sizeof(u16); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - if (IndexGenerator::GetNumLines() > 0) + if (line_index_size > 0) { - glDrawElements(GL_LINES, IndexGenerator::GetLineindexLen(), GL_UNSIGNED_SHORT, LIBuffer); + glDrawElementsBaseVertex(GL_LINES, line_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+StartIndex, basevertex); + StartIndex += line_index_size * sizeof(u16); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } - if (IndexGenerator::GetNumPoints() > 0) + if (point_index_size > 0) { - glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, PIBuffer); + glDrawElementsBaseVertex(GL_POINTS, point_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+StartIndex, basevertex); 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, @@ -132,10 +251,15 @@ void VertexManager::vFlush() (void)GL_REPORT_ERROR(); - //glBindBuffer(GL_ARRAY_BUFFER, s_vboBuffers[s_nCurVBOIndex]); - //glBufferData(GL_ARRAY_BUFFER, s_pCurBufferPointer - LocalVBuffer, LocalVBuffer, GL_STREAM_DRAW); - GL_REPORT_ERRORD(); + GLVertexFormat *nativeVertexFmt = (GLVertexFormat*)g_nativeVertexFmt; + u32 stride = nativeVertexFmt->GetVertexStride(); + + if(m_last_vao != nativeVertexFmt->VAO) { + glBindVertexArray(nativeVertexFmt->VAO); + m_last_vao = nativeVertexFmt->VAO; + } + PrepareDrawBuffers(stride); GL_REPORT_ERRORD(); u32 usedtextures = 0; @@ -148,7 +272,7 @@ void VertexManager::vFlush() if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt); - for (int i = 0; i < 8; i++) + for (u32 i = 0; i < 8; i++) { if (usedtextures & (1 << i)) { @@ -215,7 +339,7 @@ void VertexManager::vFlush() g_nativeVertexFmt->SetupVertexPointers(); GL_REPORT_ERRORD(); - Draw(); + Draw(stride); // run through vertex groups again to set alpha if (useDstAlpha && !dualSourcePossible) @@ -235,7 +359,8 @@ void VertexManager::vFlush() glDisable(GL_BLEND); - Draw(); + Draw(stride); + // restore color mask g_renderer->SetColorMask(); @@ -243,11 +368,11 @@ void VertexManager::vFlush() glEnable(GL_BLEND); } GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); - - //s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers); - s_pCurBufferPointer = LocalVBuffer; - IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer); - + + m_index_buffer_cursor += (IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen()) * sizeof(u16); + m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride; + + ResetBuffer(); #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS) { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h index 5cec1bf97e..4d820692b9 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.h @@ -24,6 +24,19 @@ namespace OGL { + class GLVertexFormat : public NativeVertexFormat + { + PortableVertexDeclaration vtx_decl; + + public: + GLVertexFormat(); + ~GLVertexFormat(); + + virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); + virtual void SetupVertexPointers(); + + GLuint VAO; + }; // Handles the OpenGL details of drawing lots of vertices quickly. // Other functionality is moving out. @@ -31,14 +44,24 @@ class VertexManager : public ::VertexManager { public: VertexManager(); - + ~VertexManager(); NativeVertexFormat* CreateNativeVertexFormat(); void CreateDeviceObjects(); void DestroyDeviceObjects(); + + // NativeVertexFormat use this + GLuint m_vertex_buffers; + GLuint m_index_buffers; + GLuint m_last_vao; private: - void Draw(); - // temp + void Draw(u32 stride); void vFlush(); + void PrepareDrawBuffers(u32 stride); + u32 m_vertex_buffer_cursor; + u32 m_vertex_buffer_size; + u32 m_index_buffer_cursor; + u32 m_index_buffer_size; + NativeVertexFormat *m_CurrentVertexFmt; }; }