From 2801b876e61a518593de2a6b7829518eb4293225 Mon Sep 17 00:00:00 2001 From: tobid7 Date: Thu, 3 Sep 2026 09:18:49 +0200 Subject: [PATCH] Upload pools once per Gfx::Draw and FIX DX9 --- backends/include/pd_system/gfx_citro3d.hpp | 1 + backends/include/pd_system/gfx_directx9.hpp | 1 + backends/include/pd_system/gfx_opengl2.hpp | 1 + backends/include/pd_system/gfx_opengl3.hpp | 1 + backends/source/gfx_citro3d.cpp | 10 ++- backends/source/gfx_directx9.cpp | 76 ++++++++++----------- backends/source/gfx_opengl2.cpp | 22 +++--- backends/source/gfx_opengl3.cpp | 27 +++++--- include/pd/drivers/gfx.hpp | 2 + tests/gfx/source/main.cpp | 28 +++++--- tests/gfx/source/os/desktopos.cpp | 3 + 11 files changed, 103 insertions(+), 69 deletions(-) diff --git a/backends/include/pd_system/gfx_citro3d.hpp b/backends/include/pd_system/gfx_citro3d.hpp index 24a65d8..fdddf73 100644 --- a/backends/include/pd_system/gfx_citro3d.hpp +++ b/backends/include/pd_system/gfx_citro3d.hpp @@ -28,6 +28,7 @@ class GfxCitro3D : public GfxDriverBase { TextureFormat type = TextureFormat::RGBA32, TextureFilter filter = TextureFilter::Linear) override; void DeleteTexture(const Li::Texture& tex) override; + void UploadPools() override; private: struct Impl; diff --git a/backends/include/pd_system/gfx_directx9.hpp b/backends/include/pd_system/gfx_directx9.hpp index 486a76a..bc6f377 100644 --- a/backends/include/pd_system/gfx_directx9.hpp +++ b/backends/include/pd_system/gfx_directx9.hpp @@ -28,6 +28,7 @@ class GfxDirectX9 : public GfxDriverBase { TextureFormat type = TextureFormat::RGBA32, TextureFilter filter = TextureFilter::Linear) override; void DeleteTexture(const Li::Texture& tex) override; + void UploadPools() override; private: struct Impl; diff --git a/backends/include/pd_system/gfx_opengl2.hpp b/backends/include/pd_system/gfx_opengl2.hpp index da4ccdc..d250857 100644 --- a/backends/include/pd_system/gfx_opengl2.hpp +++ b/backends/include/pd_system/gfx_opengl2.hpp @@ -27,6 +27,7 @@ class GfxOpenGL2 : public GfxDriverBase { TextureFormat type = TextureFormat::RGBA32, TextureFilter filter = TextureFilter::Linear) override; void DeleteTexture(const Li::Texture& tex) override; + void UploadPools() override; private: void pSetupShaderAttribs(u32 shader); diff --git a/backends/include/pd_system/gfx_opengl3.hpp b/backends/include/pd_system/gfx_opengl3.hpp index 3f116a0..8b6da99 100644 --- a/backends/include/pd_system/gfx_opengl3.hpp +++ b/backends/include/pd_system/gfx_opengl3.hpp @@ -27,6 +27,7 @@ class GfxOpenGL3 : public GfxDriverBase { TextureFormat type = TextureFormat::RGBA32, TextureFilter filter = TextureFilter::Linear) override; void DeleteTexture(const Li::Texture& tex) override; + void UploadPools() override; private: u32 pShader = 0; diff --git a/backends/source/gfx_citro3d.cpp b/backends/source/gfx_citro3d.cpp index c2901f5..37b64d2 100644 --- a/backends/source/gfx_citro3d.cpp +++ b/backends/source/gfx_citro3d.cpp @@ -152,9 +152,6 @@ void GfxCitro3D::Submit(size_t count, size_t start) { C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, impl->uLocProjection, &proj); // C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, impl->uLocProjection, // (C3D_Mtx*)&Projection); - auto buf = C3D_GetBufInfo(); - BufInfo_Init(buf); - BufInfo_Add(buf, GetVertexBufPtr(0), sizeof(Li::Vertex), 3, 0x210); C3D_DrawElements(GPU_TRIANGLES, count, C3D_UNSIGNED_SHORT, GetIndexBufPtr(start)); impl->CurrentTex = nullptr; @@ -240,6 +237,12 @@ void GfxCitro3D::DeleteTexture(const Li::Texture& tex) { C3D_TexDelete(t); delete t; } + +void GfxCitro3D::UploadPools() { + auto buf = C3D_GetBufInfo(); + BufInfo_Init(buf); + BufInfo_Add(buf, GetVertexBufPtr(0), sizeof(Li::Vertex), 3, 0x210); +} } // namespace PD #else namespace PD { @@ -258,5 +261,6 @@ Li::Texture GfxCitro3D::LoadTexture(const std::vector& pixels, int w, return Li::Texture(); } void GfxCitro3D::DeleteTexture(const Li::Texture& tex) {} +void GfxCitro3D::UploadPools() {} } // namespace PD #endif \ No newline at end of file diff --git a/backends/source/gfx_directx9.cpp b/backends/source/gfx_directx9.cpp index 2e0144a..107bf58 100644 --- a/backends/source/gfx_directx9.cpp +++ b/backends/source/gfx_directx9.cpp @@ -30,7 +30,7 @@ VS_OUT main(VS_IN input) { VS_OUT o; o.pos = mul(projection, float4(input.pos, 0.0, 1.0)); o.uv = input.uv; - o.col = input.col; + o.col = input.col.bgra; return o; } )"; @@ -132,44 +132,8 @@ void GfxDirectX9::Submit(size_t count, size_t start) { if (!impl || !impl->Device || !impl->VBO || !impl->IBO) return; BindTexture(CurrentTex); - impl->Device->SetVertexShaderConstantF( - 0, reinterpret_cast(&Projection), 4); - if (!impl->VBO || impl->VertexBufferSize != GetVertexPoolSize()) { - if (impl->VBO) { - impl->VBO->Release(); - impl->VBO = nullptr; - impl->VertexBufferSize = 0; - } - if (impl->Device->CreateVertexBuffer( - GetVertexPoolSize() * sizeof(Li::Vertex), - D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, - &impl->VBO, nullptr) < 0) - return; - impl->VertexBufferSize = GetVertexPoolSize(); - } - if (!impl->IBO || impl->IndexBufferSize != GetIndexPoolSize()) { - if (impl->IBO) { - impl->IBO->Release(); - impl->IBO = nullptr; - impl->IndexBufferSize = 0; - } - if (impl->Device->CreateIndexBuffer(GetVertexPoolSize() * sizeof(u16), - D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, - D3DFMT_INDEX16, D3DPOOL_DEFAULT, - &impl->IBO, nullptr) < 0) - return; - impl->IndexBufferSize = GetIndexPoolSize(); - } - void* vptr; - impl->VBO->Lock(0, 0, &vptr, D3DLOCK_DISCARD); - memcpy(vptr, GetVertexBufPtr(0), CurrentVertex * sizeof(PD::Li::Vertex)); - impl->VBO->Unlock(); - - void* iptr; - impl->IBO->Lock(0, 0, &iptr, D3DLOCK_DISCARD); - memcpy(iptr, GetIndexBufPtr(0), CurrentIndex * sizeof(u16)); - impl->IBO->Unlock(); + impl->Device->SetVertexShaderConstantF(0, Projection.Ptr(), 4); impl->Device->SetStreamSource(0, impl->VBO, 0, sizeof(PD::Li::Vertex)); impl->Device->SetIndices(impl->IBO); @@ -177,8 +141,8 @@ void GfxDirectX9::Submit(size_t count, size_t start) { impl->Device->SetVertexShader(impl->VS); impl->Device->SetPixelShader(impl->FS); - impl->Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, CurrentVertex, - start, count / 3); + impl->Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, + GetVertexPoolSize(), start, count / 3); } void GfxDirectX9::BindTexture(TextureID id) { @@ -200,6 +164,7 @@ void GfxDirectX9::BindTexture(TextureID id) { void GfxDirectX9::SysReset() { if (!impl || !impl->Device) return; + impl->Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); impl->Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); impl->Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); impl->Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); @@ -279,6 +244,36 @@ void GfxDirectX9::DeleteTexture(const Li::Texture& tex) { IDirect3DTexture9* t = (IDirect3DTexture9*)tex.GetID(); t->Release(); } +void GfxDirectX9::UploadPools() { + if (!impl || !impl->Device) return; + + if (!impl->VBO || impl->VertexBufferSize != GetVertexPoolSize()) { + if (impl->VBO) impl->VBO->Release(); + impl->Device->CreateVertexBuffer(GetVertexPoolSize() * sizeof(Li::Vertex), + D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, + D3DPOOL_DEFAULT, &impl->VBO, nullptr); + impl->VertexBufferSize = GetVertexPoolSize(); + } + + if (!impl->IBO || impl->IndexBufferSize != GetIndexPoolSize()) { + if (impl->IBO) impl->IBO->Release(); + impl->Device->CreateIndexBuffer( + GetIndexPoolSize() * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, + D3DFMT_INDEX16, D3DPOOL_DEFAULT, &impl->IBO, nullptr); + impl->IndexBufferSize = GetIndexPoolSize(); + } + + void* vptr; + impl->VBO->Lock(0, 0, &vptr, D3DLOCK_DISCARD); + memcpy(vptr, GetVertexBufPtr(0), + GetVertexPoolSize() * sizeof(PD::Li::Vertex)); + impl->VBO->Unlock(); + + void* iptr; + impl->IBO->Lock(0, 0, &iptr, D3DLOCK_DISCARD); + memcpy(iptr, GetIndexBufPtr(0), GetIndexPoolSize() * sizeof(u16)); + impl->IBO->Unlock(); +} } // namespace PD #else namespace PD { @@ -297,5 +292,6 @@ Li::Texture GfxDirectX9::LoadTexture(const std::vector& pixels, int w, return Li::Texture(); } void GfxDirectX9::DeleteTexture(const Li::Texture& tex) {} +void GfxDirectX9::UploadPools() {} } // namespace PD #endif \ No newline at end of file diff --git a/backends/source/gfx_opengl2.cpp b/backends/source/gfx_opengl2.cpp index 3c9b528..9e39be4 100644 --- a/backends/source/gfx_opengl2.cpp +++ b/backends/source/gfx_opengl2.cpp @@ -94,19 +94,14 @@ void GfxOpenGL2::Submit(size_t count, size_t start) { BindTexture(CurrentTex); glUseProgram(pShader); glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data()); + glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, GetVertexPoolSize() * sizeof(PD::Li::Vertex), - GetVertexBufPtr(0), GL_DYNAMIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexPoolSize() * sizeof(u16), - GetIndexBufPtr(0), GL_DYNAMIC_DRAW); - pSetupShaderAttribs(pShader); - GLint ibo = 0; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &ibo); + glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, reinterpret_cast(start * sizeof(u16))); + glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); BindTexture(0); @@ -171,6 +166,16 @@ void GfxOpenGL2::DeleteTexture(const Li::Texture& tex) { GLuint tex_ = tex.GetID(); glDeleteTextures(1, &tex_); } + +void GfxOpenGL2::UploadPools() { + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, GetVertexPoolSize() * sizeof(PD::Li::Vertex), + GetVertexBufPtr(0), GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexPoolSize() * sizeof(u16), + GetIndexBufPtr(0), GL_DYNAMIC_DRAW); +} } // namespace PD #else namespace PD { @@ -190,5 +195,6 @@ Li::Texture GfxOpenGL2::LoadTexture(const std::vector& pixels, int w, } void GfxOpenGL2::DeleteTexture(const Li::Texture& tex) {} void GfxOpenGL2::pSetupShaderAttribs(u32 shader) {} +void GfxOpenGL2::UploadPools() {} } // namespace PD #endif \ No newline at end of file diff --git a/backends/source/gfx_opengl3.cpp b/backends/source/gfx_opengl3.cpp index 46ebc7c..49a8b9b 100644 --- a/backends/source/gfx_opengl3.cpp +++ b/backends/source/gfx_opengl3.cpp @@ -65,20 +65,12 @@ void GfxOpenGL3::Submit(size_t count, size_t start) { BindTexture(CurrentTex); glUseProgram(pShader); glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data()); + glBindVertexArray(VAO); - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, GetVertexPoolSize() * sizeof(PD::Li::Vertex), - GetVertexBufPtr(0), GL_DYNAMIC_DRAW); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexPoolSize() * sizeof(u16), - GetIndexBufPtr(0), GL_DYNAMIC_DRAW); - glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, reinterpret_cast(start * sizeof(u16))); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindVertexArray(0); + BindTexture(0); } @@ -141,6 +133,20 @@ void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) { GLuint tex_ = tex.GetID(); glDeleteTextures(1, &tex_); } + +void GfxOpenGL3::UploadPools() { + glBindVertexArray(VAO); + + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, GetVertexPoolSize() * sizeof(PD::Li::Vertex), + GetVertexBufPtr(0), GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexPoolSize() * sizeof(u16), + GetIndexBufPtr(0), GL_DYNAMIC_DRAW); + + glBindVertexArray(0); +} } // namespace PD #else namespace PD { @@ -159,5 +165,6 @@ Li::Texture GfxOpenGL3::LoadTexture(const std::vector& pixels, int w, return Li::Texture(); } void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) {} +void GfxOpenGL3::UploadPools() {} } // namespace PD #endif \ No newline at end of file diff --git a/include/pd/drivers/gfx.hpp b/include/pd/drivers/gfx.hpp index 51fe2c4..18a4e52 100755 --- a/include/pd/drivers/gfx.hpp +++ b/include/pd/drivers/gfx.hpp @@ -63,6 +63,7 @@ class PD_API GfxDriver : public DriverInterface { virtual void SysInit() {} virtual void SysReset() {} virtual void Submit(size_t count, size_t start) {} + virtual void UploadPools() {} // not every driver requires it void RegisterTexture(const Li::Texture& tex); void UnregisterTexture(const Li::Texture& tex); @@ -110,6 +111,7 @@ class GfxDriverBase : public GfxDriver { void Draw(const Pool& commands) override { pCountCommands += commands.size(); size_t index = 0; + UploadPools(); while (index < commands.size()) { CurrentTex = commands[index].Tex; if (!CurrentTex) { diff --git a/tests/gfx/source/main.cpp b/tests/gfx/source/main.cpp index 79fba90..c7c88ee 100644 --- a/tests/gfx/source/main.cpp +++ b/tests/gfx/source/main.cpp @@ -119,7 +119,7 @@ class MainMenu : public PD::Ultra::Layout { Push(pBackground); pText.SetColor("#ffffff"); pText.SetText("MousePos: "); - pText.SetAlignment(UltraAlignment_TopLeft); + pText.SetAlignment(UltraAlignment_TopRight); Push(pText); pBtn.SetText("Test"); pBtn.SetAlignment(UltraAlignment_Center); @@ -198,6 +198,7 @@ int main(int argc, char** argv) { Cursor RightStick; RightStick.pColor = "#00ffff"; while (pOs->Mainloop()) { + PD::TT::Scope __st("MainLoop"); PD::Hid::Update(); PD::Gfx::NewFrame(); pOs->ClearViewPort(); @@ -219,7 +220,7 @@ int main(int argc, char** argv) { PD::Hid::Gamepad::CSUp | PD::Hid::Gamepad::CSDown)) { RightStick.pPos.y += PD::Hid::GetRightStick().y * 15; } - pList.DrawText( + /*pList.DrawText( PD::fvec2(5, 37), std::format( "Input:\n Driver: {}\n Gamepad: {}\n {}\n {}\n " @@ -249,12 +250,12 @@ int main(int argc, char** argv) { ComboGpOut(PD::Hid::Gamepad::CSDown), PD::Hid::GetLeftStick(), PD::Hid::GetRightStick(), LeftStick.pPos) .c_str(), - "#ffffff"); - LeftStick.Render(pList); - RightStick.Render(pList); + "#ffffff");*/ + // LeftStick.Render(pList); + // RightStick.Render(pList); pList.UnbindTexture(); pList.PathRect(50, PD::fvec2(450, 240)); - pList.PathFillGradient("#ff0000", "#990000", PD::Radians(135)); + /*pList.PathFillGradient("#ff0000", "#990000", PD::Radians(135)); pList.PathAdd(PD::fvec2(100, 120)); pList.PathAdd(PD::fvec2(250, 260)); pList.PathAdd(PD::fvec2(420, 180)); @@ -262,9 +263,20 @@ int main(int argc, char** argv) { pList.PathAdd(PD::fvec2(820, 220)); pList.PathAdd(PD::fvec2(1000, 360)); - pList.PathStroke("#ff00ff", 10, LiDrawFlags_AA); - PD::Gfx::Reset(); // needs to be on top now + pList.PathStroke("#ff00ff", 10, LiDrawFlags_AA);*/ + int __i = 0; + for (auto& it : PD::TT::GetTraceMap()) { + pList.DrawText( + PD::fvec2(2, 2 + (__i++) * 17), + std::format("{}: {}", it.second.GetID(), + PD::Strings::FormatNanos(it.second.GetLastDiff())) + .c_str(), + "#ff00ff"); + } + PD::Gfx::Reset(); + PD::TT::Beg("PD::Gfx::Draw"); PD::Gfx::Draw(pList); + PD::TT::End("PD::Gfx::Draw"); pList.Clear(); pOs->SwapBuffers(); } diff --git a/tests/gfx/source/os/desktopos.cpp b/tests/gfx/source/os/desktopos.cpp index 02f9dc9..1cc5762 100644 --- a/tests/gfx/source/os/desktopos.cpp +++ b/tests/gfx/source/os/desktopos.cpp @@ -60,6 +60,9 @@ void DesktopOS::Init() { d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hwnd; + d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; + d3dpp.EnableAutoDepthStencil = TRUE; + d3dpp.AutoDepthStencilFormat = D3DFMT_D16; HRESULT hr = impl->d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,