From 5fdb17b7736522903528307a97956f42128b3f0a Mon Sep 17 00:00:00 2001 From: kotofyt Date: Tue, 26 May 2026 01:29:26 +0300 Subject: [PATCH] improved font rendering --- engine/engine.cpp | 18 ++-- engine/kottui.cpp | 96 +++++++++++++++---- funnyassets/shaders/kottui.shader | 10 +- game/client/game.cpp | 13 --- .../{milmobaui/menu.cpp => kotui/window.cpp} | 0 .../{milmobaui/menu.h => kotui/window.h} | 0 game/client/milmoba/mainmenu.cpp | 90 ----------------- game/client/milmoba/player.cpp | 2 +- game/client/milmoba/ui/gameplay.cpp | 0 game/client/milmoba/ui/gameplay.h | 0 game/client/milmoba/ui/mainmenu.cpp | 0 game/client/milmoba/ui/mainmenu.h | 0 materialsystem/vulkan/commandbuffer.cpp | 3 - materialsystem/vulkan/material.cpp | 3 +- materialsystem/vulkan/rendercommandlist.cpp | 44 +++++++-- materialsystem/vulkan/rendercontext.cpp | 4 + materialsystem/vulkan/shader.cpp | 28 ++++-- materialsystem/vulkan/utils.cpp | 27 +++++- materialsystem/vulkan/vulkan_state.h | 28 +++++- public/kottui/kottui.h | 5 +- public/materialsystem/imaterialsystem.h | 4 +- 21 files changed, 217 insertions(+), 158 deletions(-) rename game/client/{milmobaui/menu.cpp => kotui/window.cpp} (100%) rename game/client/{milmobaui/menu.h => kotui/window.h} (100%) delete mode 100644 game/client/milmoba/mainmenu.cpp create mode 100644 game/client/milmoba/ui/gameplay.cpp create mode 100644 game/client/milmoba/ui/gameplay.h create mode 100644 game/client/milmoba/ui/mainmenu.cpp create mode 100644 game/client/milmoba/ui/mainmenu.h diff --git a/engine/engine.cpp b/engine/engine.cpp index 17ca51f..4569805 100644 --- a/engine/engine.cpp +++ b/engine/engine.cpp @@ -57,23 +57,27 @@ extern "C" void FunnyMain( int argc, char **argv ) EngineConsts_t stConstants = {}; #ifdef STEAM - V_printf("Steam :)\n"); if(SteamAPI_RestartAppIfNecessary(480)) { V_printf("Mshallah we are doing reboot\n"); Plat_Exit(0); } - stConstants.m_bIsSteam = true; - if (!SteamAPI_Init()) + if (SteamAPI_Init()) + { + V_printf("Steam :)\n"); + stConstants.m_bIsSteam = true; + stConstants.LaunchServer = LaunchServerAtSteamRelay; + stConstants.ConnectSteamServer = ConnectBySteamID; + SteamNetworkingUtils()->SetDebugOutputFunction(k_ESteamNetworkingSocketsDebugOutputType_Msg, SteamAPIDebug); + } + else { V_printf("Steam :()\n"); stConstants.m_bIsSteam = false; - } - stConstants.LaunchServer = LaunchServerAtSteamRelay; - stConstants.ConnectSteamServer = ConnectBySteamID; - SteamNetworkingUtils()->SetDebugOutputFunction(k_ESteamNetworkingSocketsDebugOutputType_Msg, SteamAPIDebug); + } + #endif stConstants.m_bIsDedicated = CommandLine()->CheckParam("-dedicated"); stConstants.LaunchLocalBridge = LaunchLocalBridge; diff --git a/engine/kottui.cpp b/engine/kottui.cpp index 7f02679..4e40261 100644 --- a/engine/kottui.cpp +++ b/engine/kottui.cpp @@ -32,6 +32,10 @@ public: GlyphData_t *m_glyphs; uint32_t m_uGlyphCount; IImage *m_pAtlas; + + bool m_bIsMono = false; + uint32_t m_uMonoWidth = 0; + uint32_t m_uMonoHeight = 0; }; class CKotUIBuffer: public IKotUIBuffer @@ -41,8 +45,11 @@ public: virtual void Move( int iY, int iX ) override; - virtual void SetColor( char c ) override; - virtual void Clear( char c ) override; + + virtual void SetColor( float fX, float fY, float fZ, float fA ) override; + virtual void SetBackgroundColor( float fX, float fY, float fZ, float fA ) override; + virtual void Clear( float fX, float fY, float fZ, float fA ) override; + virtual void PutChar( char c ) override; virtual void Printf(const char *szFormat, ...) override; @@ -64,6 +71,12 @@ public: IKotRenderFont *m_pFont; uint32_t m_uCursor = 0; + + uint32_t m_uTextWidth = 16; + uint32_t m_uTextHeight = 16; + + ColorAlpha m_fgColor = {1,1,1,1}; + ColorAlpha m_bgColor = {0,0,0,0}; }; class CKotUIManager: public IKotUIManager @@ -155,6 +168,24 @@ float CKotRenderFont::GetHeight( uint32_t letter ) +bool CKotRenderFont::IsMono() +{ + return m_bIsMono; + +} + +uint32_t CKotRenderFont::GetLetterWidth() +{ + return m_uMonoWidth; + +} + +uint32_t CKotRenderFont::GetLetterHeight() +{ + return m_uMonoHeight; +} + + void CKotUIBuffer::SetPosition( int iY, int iX ) { @@ -166,19 +197,30 @@ void CKotUIBuffer::Move( int iY, int iX ) m_uCursor = m_uCursor % (m_iWidth * m_iHeight); } -void CKotUIBuffer::SetColor( char c ) + +void CKotUIBuffer::SetColor( float fX, float fY, float fZ, float fA ) +{ + m_fgColor = {fX, fY, fZ, fA}; +} + +void CKotUIBuffer::SetBackgroundColor( float fX, float fY, float fZ, float fA ) +{ + m_bgColor = {fX, fY, fZ, fA}; + +} + +void CKotUIBuffer::Clear( float fX, float fY, float fZ, float fA ) { } -void CKotUIBuffer::Clear( char c ) -{ -} void CKotUIBuffer::PutChar( char c ) { m_buffer[m_uCursor] = c; + m_primaryColor[m_uCursor] = m_fgColor; + m_secondaryColor[m_uCursor] = m_bgColor; Move(0, m_uCursor+1); } @@ -199,6 +241,8 @@ void CKotUIBuffer::Printf(const char *szFormat, ...) for ( size_t u = 0, i = m_uCursor; u < nSize; u++, i = (i + 1 % (m_iWidth * m_iHeight)) ) { m_buffer[i] = psz[u]; + m_primaryColor[i] = m_fgColor; + m_secondaryColor[i] = m_bgColor; } va_end(vlArgs2); V_free(psz); @@ -217,8 +261,8 @@ struct TextDrawData_t float m_fPosY; float m_fSizeX; float m_fSizeY; - float m_fColor[4]; - float m_fColor2[4]; + ColorAlpha m_fColor1; + ColorAlpha m_fColor2; }; struct ScreenData_t @@ -240,16 +284,16 @@ void CKotUIBuffer::Draw( IImage *pImage ) for ( uint32_t i = 0; i < uGlyphCount; i++ ) { uint32_t l = m_buffer[i]; - if ( !m_pFont->IsLetterPresent(l) ) - continue; pData[uRealGlyphCount].m_vTexcoordOffsetX = m_pFont->GetLetterX(l); pData[uRealGlyphCount].m_vTexcoordOffsetY = m_pFont->GetLetterY(l); pData[uRealGlyphCount].m_vTexcoordSizeX = m_pFont->GetWidth(l); pData[uRealGlyphCount].m_vTexcoordSizeY = m_pFont->GetHeight(l); - pData[uRealGlyphCount].m_fSizeX = 16; - pData[uRealGlyphCount].m_fSizeY = 16; - pData[uRealGlyphCount].m_fPosX = i%m_iWidth*16; - pData[uRealGlyphCount].m_fPosY = i/m_iWidth*16; + pData[uRealGlyphCount].m_fSizeX = m_uTextWidth; + pData[uRealGlyphCount].m_fSizeY = m_uTextHeight; + pData[uRealGlyphCount].m_fPosX = i%m_iWidth*m_uTextWidth; + pData[uRealGlyphCount].m_fPosY = i/m_iWidth*m_uTextHeight; + pData[uRealGlyphCount].m_fColor1 = m_primaryColor[i]; + pData[uRealGlyphCount].m_fColor2 = m_secondaryColor[i]; uRealGlyphCount++; } m_pDataBuffer->Unmap(); @@ -274,17 +318,24 @@ void CKotUIBuffer::Draw( IImage *pImage ) pList->SetLoadStoreModes(0, LOAD_MODE_LOAD, STORE_MODE_STORE); pList->SetRenderResolution(pImage->GetImageWidth(), pImage->GetImageHeight()); + pList->Barrier(m_pDataBuffer, true, false); + pList->Barrier(pScreenBuffer, true, false); + pList->Barrier(m_pFont->GetAtlas(), true, false); + pList->SetMaterial(m_pMaterial); pList->SetVertexBuffer(0, s_pGlyphBuffer); pList->DrawPrimitives(6, 0, uRealGlyphCount, 0); pList->EndRecording(); m_pRenderContext->SubmitCommandList(pList); + m_pRenderContext->DestroyBuffer(pScreenBuffer); } void CKotUIBuffer::SetTextSize( int iY, int iX ) { + m_uTextHeight = iY; + m_uTextWidth = iX; } @@ -301,7 +352,7 @@ void CKotUIManager::Init() s_pShader = m_pRenderContext->CreateShader("game/core/shaders/kottui.shader_c"); s_pShader->AddLayout(0, 8); s_pShader->AddAttribute(0, 0, VERTEX_FORMAT_XY32_SFLOAT, 0); - s_pShader->AddOutputImage(0, IMAGE_FORMAT_RGBA8_UNORM); + s_pShader->AddOutputImage(0, IMAGE_FORMAT_RGBA8_UNORM, true); s_pShader->Build(); s_pGlyphBuffer = m_pRenderContext->CreateVertexBuffer(sizeof(float)*12); void *pBuffer = s_pGlyphBuffer->Map(); @@ -349,9 +400,16 @@ IKotRenderFont *CKotUIManager::LoadFont( const char *szPath ) uint32_t uAtlas = m_pFonts->LoadTexture(szAtlas); CKotRenderFont *pFont = new CKotRenderFont; + IJSONObject *pAtlas = pValue->GetObject()->GetValue("atlas")->GetObject(); pFont->m_pAtlas = pFont->m_pAtlas = m_pFonts->GetTexture(uAtlas); - uint32_t atlasWidth = pValue->GetObject()->GetValue("atlas")->GetObject()->GetValue("width")->GetNumberValue(); - uint32_t atlasHeight = pValue->GetObject()->GetValue("atlas")->GetObject()->GetValue("height")->GetNumberValue(); + uint32_t atlasWidth = pAtlas->GetValue("width")->GetNumberValue(); + uint32_t atlasHeight = pAtlas->GetValue("height")->GetNumberValue(); + pFont->m_bIsMono = pAtlas->GetValue("grid") != NULL; + if (pFont->m_bIsMono) + { + pFont->m_uMonoWidth = pAtlas->GetValue("grid")->GetObject()->GetValue("cellWidth")->GetNumberValue(); + pFont->m_uMonoHeight = pAtlas->GetValue("grid")->GetObject()->GetValue("cellHeight")->GetNumberValue(); + } pFont->m_uGlyphCount = 0; pFont->m_glyphs = (GlyphData_t*)V_malloc(sizeof(GlyphData_t)*pGlyphs->GetCount()); @@ -385,6 +443,10 @@ IKotUIBuffer *CKotUIManager::CreateBuffer( int iWidth, int iHeight ) pBuffer->m_pRenderContext = m_pRenderContext; pBuffer->m_buffer = (uint32_t*)V_malloc(sizeof(uint32_t)*iWidth*iHeight); V_memset(pBuffer->m_buffer, 0, sizeof(uint32_t)*iWidth*iHeight); + pBuffer->m_primaryColor = (ColorAlpha*)V_malloc(sizeof(ColorAlpha)*iWidth*iHeight); + V_memset(pBuffer->m_primaryColor, 0, sizeof(ColorAlpha)*iWidth*iHeight); + pBuffer->m_secondaryColor = (ColorAlpha*)V_malloc(sizeof(ColorAlpha)*iWidth*iHeight); + V_memset(pBuffer->m_secondaryColor, 0, sizeof(ColorAlpha)*iWidth*iHeight); pBuffer->m_iWidth = iWidth; pBuffer->m_iHeight = iHeight; diff --git a/funnyassets/shaders/kottui.shader b/funnyassets/shaders/kottui.shader index 21bdfac..081abb7 100644 --- a/funnyassets/shaders/kottui.shader +++ b/funnyassets/shaders/kottui.shader @@ -5,13 +5,12 @@ COMMON { { float4 m_vPosition: SV_POSITION; float2 m_vUV: TEXCOORD0; - uint m_uFont; + uint m_uFont: SV_InstanceID; } struct TextDrawData_t { float2 m_vTexcoordOffset; float2 m_vTexcoordSize; - float2 m_vPos; float2 m_vSize; float4 m_vFGColor; @@ -51,6 +50,7 @@ VS PS_INPUT output = {}; output.m_vPosition = float4(position, 0, 1); output.m_vUV = uv; + output.m_uFont = uInstance; return output; } @@ -79,7 +79,11 @@ PS float fSd = median3(vMsd.x, vMsd.y, vMsd.z); float fScreenPixelDistance = ScreenPixelRange(input.m_vUV)*(fSd-0.5); float fOpacity = clamp(fScreenPixelDistance+0.5, 0.0, 1.0); - output.m_vAlbedo = fOpacity; + float4 vColor1 = g_textData[input.m_uFont].m_vFGColor; + float4 vColor2 = g_textData[input.m_uFont].m_vBGColor; + vColor1.xyz*=vColor1.w; + vColor2.xyz*=vColor2.w; + output.m_vAlbedo = lerp(vColor2, vColor1, fOpacity); return output; } } diff --git a/game/client/game.cpp b/game/client/game.cpp index 6574e26..15abef3 100644 --- a/game/client/game.cpp +++ b/game/client/game.cpp @@ -38,8 +38,6 @@ IEngineBridge *EngineBridge() EXPOSE_INTERFACE_FN(EngineBridge, IEngineBridge, ENGINE_BRIDGE_INTERFACE_VERSION) -static IKotUIBuffer *s_pUIBuffer; - void CFunnyGameBridge::Init() { Console()->AddCommand("exec game/core/default.cfg\n"); @@ -77,16 +75,6 @@ void CFunnyGameBridge::Init() g_pKotUI->ConnectInterface(g_pRenderContext, RENDER_CONTEXT_INTERFACE_VERSION); g_pKotUI->Init(); - IKotRenderFont *pFont = g_pKotUI->LoadFont("game/core/fonts/IBMPlexMono-Regular"); - s_pUIBuffer = g_pKotUI->CreateBuffer(40, 30); - s_pUIBuffer->SetTextFont(pFont); - s_pUIBuffer->SetTextSize(, int iX) - s_pUIBuffer->Move(0, 0); - s_pUIBuffer->Printf("hello %f", 20.0); - s_pUIBuffer->Move(1, 0); - s_pUIBuffer->Printf("hello %f", 40.0); - s_pUIBuffer->Move(2, 0); - s_pUIBuffer->Printf("hello %f", 40.0); } void CFunnyGameBridge::Tick( float fDelta ) @@ -183,7 +171,6 @@ void CFunnyGameBridge::Frame( float fDelta ) EntitySystem()->NetSendThink(pCurrentServer); } g_pWorldRenderer->Frame(fDelta); - s_pUIBuffer->Draw(g_pMainWindow->GetOutputImage()); } void CFunnyGameBridge::Shutdown() diff --git a/game/client/milmobaui/menu.cpp b/game/client/kotui/window.cpp similarity index 100% rename from game/client/milmobaui/menu.cpp rename to game/client/kotui/window.cpp diff --git a/game/client/milmobaui/menu.h b/game/client/kotui/window.h similarity index 100% rename from game/client/milmobaui/menu.h rename to game/client/kotui/window.h diff --git a/game/client/milmoba/mainmenu.cpp b/game/client/milmoba/mainmenu.cpp deleted file mode 100644 index 4c76bb6..0000000 --- a/game/client/milmoba/mainmenu.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "mainmenu.h" -#include "fgui/label.h" -#include "fgui/rect.h" -#include "fgui/widget.h" -#include "tier1/interface.h" - -class CMOBAMainMenuGUI: public CFGUI_Widget -{ -public: - CMOBAMainMenuGUI(); - virtual void Event( FGUI_Event_t event ) override; - virtual void Draw() override; - virtual void Frame() override; -private: - CFGUI_Rect *m_pBackground; - CFGUI_Label *m_pGameName; -}; - -CMOBAMainMenuGUI::CMOBAMainMenuGUI() -{ - SetPosition(0, 0); - - - m_pBackground = new CFGUI_Rect; - m_pBackground->SetParent(this); - m_pBackground->SetPosition(90,90); - m_pBackground->SetSize(300, 400); - m_pBackground->SetBoxColor(0.1, 0.1, 0.1, 1); - - m_pGameName = new CFGUI_Label; - m_pGameName->SetParent(this); - m_pGameName->SetFont("fonts/IBMPlexMono-Regular"); - m_pGameName->SetLabel("funnygame"); - m_pGameName->SetGlyphSize(24); - m_pGameName->SetPosition(100, 100); -}; - -void CMOBAMainMenuGUI::Event( FGUI_Event_t event ) -{ - -} - -void CMOBAMainMenuGUI::Draw() -{ -} - -void CMOBAMainMenuGUI::Frame() -{ -} - - - - -class CMOBAMainMenu: public IMainMenu -{ -public: - virtual void Init() override; - virtual void Frame() override; - virtual void Deinit() override; - - virtual void SetVisibility( bool bIsVisible ) override; -private: - CMOBAMainMenuGUI *m_pMainMenu; -}; - - -void CMOBAMainMenu::Init() -{ - m_pMainMenu = new CMOBAMainMenuGUI; - m_pMainMenu->SetVisibility(true); -} - -void CMOBAMainMenu::Frame() -{ -} - -void CMOBAMainMenu::SetVisibility( bool bIsVisible ) -{ - m_pMainMenu->SetVisibility(bIsVisible); -} - -void CMOBAMainMenu::Deinit() -{ - -} - -DECLARE_ENGINE_INTERFACE(MainMenu, CMOBAMainMenu); - - - diff --git a/game/client/milmoba/player.cpp b/game/client/milmoba/player.cpp index 55d4cc7..25beb07 100644 --- a/game/client/milmoba/player.cpp +++ b/game/client/milmoba/player.cpp @@ -32,7 +32,7 @@ void C_MOBAPlayer::Think( float fDelta ) g_pWorldRenderer->SetCameraPosition(vCameraPos); Quat vCameraRot; glm_euler_yxz_quat((vec3){m_fPitch, m_fYaw, 0}, *(versor*)&vCameraRot); - //g_pWorldRenderer->SetCameraRotation(vCameraRot); + g_pWorldRenderer->SetCameraRotation(vCameraRot); } BaseClass::Think(fDelta); }; diff --git a/game/client/milmoba/ui/gameplay.cpp b/game/client/milmoba/ui/gameplay.cpp new file mode 100644 index 0000000..e69de29 diff --git a/game/client/milmoba/ui/gameplay.h b/game/client/milmoba/ui/gameplay.h new file mode 100644 index 0000000..e69de29 diff --git a/game/client/milmoba/ui/mainmenu.cpp b/game/client/milmoba/ui/mainmenu.cpp new file mode 100644 index 0000000..e69de29 diff --git a/game/client/milmoba/ui/mainmenu.h b/game/client/milmoba/ui/mainmenu.h new file mode 100644 index 0000000..e69de29 diff --git a/materialsystem/vulkan/commandbuffer.cpp b/materialsystem/vulkan/commandbuffer.cpp index c211318..2108cfb 100644 --- a/materialsystem/vulkan/commandbuffer.cpp +++ b/materialsystem/vulkan/commandbuffer.cpp @@ -208,7 +208,6 @@ void CVkCommandBuffer::SortDependencies() } - /* for (auto &pCommand: m_commands) { for ( auto dependency: pCommand->m_dependencies) @@ -263,7 +262,6 @@ void CVkCommandBuffer::SortDependencies() } } } - */ } @@ -311,7 +309,6 @@ void CVkCommandBuffer::TryBarrier( int iCurrent, int iCurrentBuffer ) if (dynamic_cast(pObject)) { - VkImageMemoryBarrier2 imageMemoryBarrier = {}; imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2; imageMemoryBarrier.image = pImage->m_image; diff --git a/materialsystem/vulkan/material.cpp b/materialsystem/vulkan/material.cpp index ce355e2..c172b34 100644 --- a/materialsystem/vulkan/material.cpp +++ b/materialsystem/vulkan/material.cpp @@ -48,7 +48,7 @@ CVkMaterial::~CVkMaterial() void CVkMaterial::Frame() { - vkUpdateDescriptorSets(m_pVkShader->m_hDevice, m_writes.GetSize(), m_writes.GetData(), 0, 0); + //vkUpdateDescriptorSets(m_pVkShader->m_hDevice, m_writes.GetSize(), m_writes.GetData(), 0, 0); }; void CVkMaterial::VSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) @@ -185,7 +185,6 @@ void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderi writes[1].descriptorCount = 128; writes[1].pImageInfo = stWrites; vkUpdateDescriptorSets(m_pVkShader->m_hDevice, 2, writes, 0, 0); - m_pTextureArray = pArray; } } diff --git a/materialsystem/vulkan/rendercommandlist.cpp b/materialsystem/vulkan/rendercommandlist.cpp index bdccb97..a1b92d9 100644 --- a/materialsystem/vulkan/rendercommandlist.cpp +++ b/materialsystem/vulkan/rendercommandlist.cpp @@ -101,7 +101,7 @@ void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial ) pBeginCommand->nResolutionY = m_uHeight; for ( auto &i: pBeginCommand->images) { - pBeginCommand->AddDependency(i.m_stImage.m_pSingle, DEPENDENCY_MODE_DRAWCALL_OUTPUT_IMAGE); + pBeginCommand->AddDependency(i.m_stImage.m_pSingle, DEPENDENCY_MODE_DRAWCALL_MIXED_IMAGE); } if ( m_bDepthEnabled ) { @@ -118,10 +118,6 @@ void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial ) CVkSetShaderDataCommand *pSetShaderData = CREATE_COMMAND(m_pCommandBufferManager, SetShaderData); pSetShaderData->pShaderData = pMaterial; - { - CVkTextureArray *pArray = (CVkTextureArray*)((CVkMaterial*)pMaterial)->m_pTextureArray; - - } m_pCurrentMaterialBuffer->AddCommand(pSetShaderData); CVkSetScissorsCommand *pScissorsCommand = CREATE_COMMAND(m_pCommandBufferManager, SetScissors); @@ -146,6 +142,7 @@ void CVkRenderCommandList::SetVertexBuffer( uint32_t uBinding, IVertexBuffer *pB CVkSetVertexBufferCommand *pCmd = CREATE_COMMAND(m_pCommandBufferManager, SetVertexBuffer); pCmd->uBinding = uBinding; pCmd->pBuffer = pBuffer; + pCmd->AddDependency(pBuffer, DEPENDENCY_MODE_BUFFER_SOURCE); m_pCurrentMaterialBuffer->AddCommand(pCmd); } @@ -163,6 +160,34 @@ void CVkRenderCommandList::DrawPrimitives( uint32_t nVertexCount, uint32_t nFirs pCmd->nFirstVertex = nFirstVertex; pCmd->nInstanceCount = nInstanceCount; pCmd->nFirstInstance = nFirstInstance; + for ( auto &b: m_barriers ) + { + if (dynamic_cast(b.pObject)) + { + if (b.m_bIsRead) + if (b.m_bIsWrite) + pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_BUFFER_READ_WRITE); + else + pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_BUFFER_READ); + else + if (b.m_bIsWrite) + pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_BUFFER_WRITE); + + } + if (dynamic_cast(b.pObject)) + { + if (b.m_bIsRead) + if (b.m_bIsWrite) + pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_IMAGE_READ_WRITE); + else + pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_IMAGE_READ); + else + if (b.m_bIsWrite) + pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_IMAGE_WRITE); + + } + } + m_barriers = {}; m_pCurrentMaterialBuffer->AddCommand(pCmd); } @@ -182,8 +207,8 @@ void CVkRenderCommandList::ResolveImage( IImage *pOriginal, IImage *pResolved ) pCmd->stInputImage.m_pSingle = pOriginal; pCmd->stOutputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE; pCmd->stOutputImage.m_pSingle = pResolved; - pCmd->AddDependency(pOriginal, DEPENDENCY_MODE_IMAGE_SOURCE); - pCmd->AddDependency(pResolved, DEPENDENCY_MODE_IMAGE_DESTINATION); + pCmd->AddDependency(pOriginal, DEPENDENCY_MODE_IMAGE_RESOLVE_SOURCE); + pCmd->AddDependency(pResolved, DEPENDENCY_MODE_IMAGE_RESOLVE_DESTINATION); m_pPostRaster->AddCommand(pCmd); } @@ -198,6 +223,11 @@ void CVkRenderCommandList::EndRecording() SwitchRenderingStage(RENDERING_STAGE_FINISHED); } +void CVkRenderCommandList::Barrier( IRenderingObject *pObject, bool bIsRead, bool bIsWrite ) +{ + m_barriers.AppendTail({pObject, bIsRead, bIsWrite}); +} + void CVkRenderCommandList::Submit() { for ( auto m: m_pCommandBuffers) diff --git a/materialsystem/vulkan/rendercontext.cpp b/materialsystem/vulkan/rendercontext.cpp index a1de245..6f582e3 100644 --- a/materialsystem/vulkan/rendercontext.cpp +++ b/materialsystem/vulkan/rendercontext.cpp @@ -932,6 +932,7 @@ void CVkRenderContext::Frame( float fDeltaTime ) double a = Plat_GetTime(); i = 0; + CVkEmptyCommand *pEmptyCommand = CREATE_COMMAND(m_pCommandBufferManager, Empty); for ( auto &s: m_renderWindows ) { @@ -952,11 +953,14 @@ void CVkRenderContext::Frame( float fDeltaTime ) pBlitCommand->iDstMax[0] = s.m_pWindow->GetRenderWidth(); pBlitCommand->iDstMax[1] = s.m_pWindow->GetRenderHeight(); pBlitCommand->iDstMax[2] = 1; + + pEmptyCommand->AddDependency((IRenderingObject*)s.m_images[uSwapchainImageIndexes[i]], DEPENDENCY_MODE_IMAGE_PRESENT); } if (pBlitCommand != NULL) s_pPresentCommandBuffer->AddCommand(pBlitCommand); i++; } + s_pPresentCommandBuffer->AddCommand(pEmptyCommand); s_pPresentCommandBuffer->Render(); s_pPresentCommandBuffer->Submit(0); diff --git a/materialsystem/vulkan/shader.cpp b/materialsystem/vulkan/shader.cpp index 0282081..6f3778a 100644 --- a/materialsystem/vulkan/shader.cpp +++ b/materialsystem/vulkan/shader.cpp @@ -27,9 +27,9 @@ void CVkShader::SetTopology( ETopologyMode eTopology ) } -void CVkShader::AddOutputImage( int iImageIndex, EImageFormat eFormat ) +void CVkShader::AddOutputImage( int iImageIndex, EImageFormat eFormat, bool bBlendingEnabled ) { - m_eFormats.AppendTail(CVkImage::GetImageFormat(eFormat)); + m_formats.AppendTail({CVkImage::GetImageFormat(eFormat), bBlendingEnabled}); } void CVkShader::SetDepthImage( EImageFormat eFormat ) @@ -68,6 +68,7 @@ void CVkShader::Build() }; VkPipelineLayoutCreateInfo stPipelineLayout = {}; CUtlVector> bindings = {}; + CUtlVector formats = {}; // TODO: Filter by vulkan shaders at some points stages.Resize(m_shader.m_objects.GetSize()); @@ -163,10 +164,13 @@ void CVkShader::Build() msaa.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; msaa.rasterizationSamples = CVkImage::GetMultisampling(m_eMultiSampling); + formats.Resize(m_formats.GetSize()); + for ( uint32_t i = 0; i < m_formats.GetSize(); i++ ) + formats[i] = m_formats[i].m_eFormat; render.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO; - render.colorAttachmentCount = m_eFormats.GetSize(); - render.pColorAttachmentFormats = m_eFormats.GetData(); + render.colorAttachmentCount = formats.GetSize(); + render.pColorAttachmentFormats = formats.GetData(); depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; if (m_eDepthFormat == VK_FORMAT_D32_SFLOAT) @@ -177,11 +181,23 @@ void CVkShader::Build() render.depthAttachmentFormat = m_eDepthFormat; } - for ( auto e: m_eFormats ) + for ( auto e: m_formats ) { VkPipelineColorBlendAttachmentState a = {}; a.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - a.blendEnable = VK_FALSE; + if (e.m_bIsBlendingEnabled) + { + a.blendEnable = VK_TRUE; + a.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; + a.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + a.colorBlendOp = VK_BLEND_OP_ADD; + a.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + a.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + a.alphaBlendOp = VK_BLEND_OP_ADD; + + } + else + a.blendEnable = VK_FALSE; attachments.AppendTail(a); } diff --git a/materialsystem/vulkan/utils.cpp b/materialsystem/vulkan/utils.cpp index 14c11d2..c2fdc28 100644 --- a/materialsystem/vulkan/utils.cpp +++ b/materialsystem/vulkan/utils.cpp @@ -21,17 +21,26 @@ VkAccessFlags2 VulkanGetAccessFlags( EDependencyMode eMode ) case DEPENDENCY_MODE_JUST_CREATED: return VK_ACCESS_2_NONE; case DEPENDENCY_MODE_DRAWCALL_OUTPUT_IMAGE: return VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR; case DEPENDENCY_MODE_DRAWCALL_OUTPUT_DEPTH_IMAGE: return VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + case DEPENDENCY_MODE_DRAWCALL_MIXED_IMAGE: return VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR; case DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION: return VK_ACCESS_2_TRANSFER_WRITE_BIT; case DEPENDENCY_MODE_IMAGE_PRESENT: return VK_ACCESS_2_NONE; + case DEPENDENCY_MODE_SHADER_BUFFER_READ: return VK_ACCESS_2_SHADER_READ_BIT; + case DEPENDENCY_MODE_SHADER_BUFFER_WRITE: return VK_ACCESS_2_SHADER_READ_BIT; + case DEPENDENCY_MODE_SHADER_BUFFER_READ_WRITE: return VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT; + case DEPENDENCY_MODE_SHADER_IMAGE_READ: return VK_ACCESS_2_SHADER_READ_BIT; + case DEPENDENCY_MODE_SHADER_IMAGE_WRITE: return VK_ACCESS_2_SHADER_READ_BIT; + case DEPENDENCY_MODE_SHADER_IMAGE_READ_WRITE: return VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT; case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE: case DEPENDENCY_MODE_IMAGE_SOURCE: case DEPENDENCY_MODE_BUFFER_SOURCE: + case DEPENDENCY_MODE_IMAGE_RESOLVE_SOURCE: return VK_ACCESS_2_TRANSFER_READ_BIT; case DEPENDENCY_MODE_IMAGE_DESTINATION: case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION: case DEPENDENCY_MODE_BUFFER_DESTINATION: + case DEPENDENCY_MODE_IMAGE_RESOLVE_DESTINATION: return VK_ACCESS_2_TRANSFER_WRITE_BIT; default: @@ -46,19 +55,24 @@ VkPipelineStageFlags2 VulkanGetStageFlags( EDependencyMode eMode ) case DEPENDENCY_MODE_JUST_CREATED: return VK_PIPELINE_STAGE_2_NONE; case DEPENDENCY_MODE_DRAWCALL_OUTPUT_IMAGE: return VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; case DEPENDENCY_MODE_DRAWCALL_OUTPUT_DEPTH_IMAGE: return VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT; + case DEPENDENCY_MODE_DRAWCALL_MIXED_IMAGE: return VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; case DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION: return VK_PIPELINE_STAGE_2_TRANSFER_BIT; case DEPENDENCY_MODE_IMAGE_PRESENT: return VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; - case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION: case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE: + case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION: return VK_PIPELINE_STAGE_2_BLIT_BIT; case DEPENDENCY_MODE_BUFFER_SOURCE: - case DEPENDENCY_MODE_BUFFER_DESTINATION: case DEPENDENCY_MODE_IMAGE_SOURCE: + case DEPENDENCY_MODE_BUFFER_DESTINATION: case DEPENDENCY_MODE_IMAGE_DESTINATION: return VK_PIPELINE_STAGE_2_COPY_BIT; + case DEPENDENCY_MODE_IMAGE_RESOLVE_SOURCE: + case DEPENDENCY_MODE_IMAGE_RESOLVE_DESTINATION: + return VK_PIPELINE_STAGE_2_RESOLVE_BIT; + default: return VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; } @@ -71,16 +85,25 @@ VkImageLayout VulkanGetImageLayout( EDependencyMode eMode ) case DEPENDENCY_MODE_JUST_CREATED: return VK_IMAGE_LAYOUT_UNDEFINED; case DEPENDENCY_MODE_DRAWCALL_OUTPUT_IMAGE: return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; case DEPENDENCY_MODE_DRAWCALL_OUTPUT_DEPTH_IMAGE: return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + case DEPENDENCY_MODE_DRAWCALL_MIXED_IMAGE: return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; case DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; case DEPENDENCY_MODE_IMAGE_PRESENT: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE: case DEPENDENCY_MODE_IMAGE_SOURCE: case DEPENDENCY_MODE_BUFFER_SOURCE: + case DEPENDENCY_MODE_IMAGE_RESOLVE_SOURCE: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION: case DEPENDENCY_MODE_IMAGE_DESTINATION: case DEPENDENCY_MODE_BUFFER_DESTINATION: + case DEPENDENCY_MODE_IMAGE_RESOLVE_DESTINATION: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + + case DEPENDENCY_MODE_SHADER_IMAGE_READ: + case DEPENDENCY_MODE_SHADER_IMAGE_WRITE: + case DEPENDENCY_MODE_SHADER_IMAGE_READ_WRITE: + return VK_IMAGE_LAYOUT_GENERAL; + default: return VK_IMAGE_LAYOUT_UNDEFINED; } diff --git a/materialsystem/vulkan/vulkan_state.h b/materialsystem/vulkan/vulkan_state.h index 48a580f..ebc9efa 100644 --- a/materialsystem/vulkan/vulkan_state.h +++ b/materialsystem/vulkan/vulkan_state.h @@ -49,6 +49,8 @@ enum EDependencyMode DEPENDENCY_MODE_SHADER_BUFFER_READ, DEPENDENCY_MODE_SHADER_IMAGE_WRITE, DEPENDENCY_MODE_SHADER_BUFFER_WRITE, + DEPENDENCY_MODE_SHADER_BUFFER_READ_WRITE, + DEPENDENCY_MODE_SHADER_IMAGE_READ_WRITE, DEPENDENCY_MODE_SHADER_ACCELERATION_STRUCTURE, DEPENDENCY_MODE_DRAWCALL_VERTEX_BUFFER, @@ -63,6 +65,9 @@ enum EDependencyMode DEPENDENCY_MODE_IMAGE_DESTINATION, DEPENDENCY_MODE_BUFFER_DESTINATION, + DEPENDENCY_MODE_IMAGE_RESOLVE_SOURCE, + DEPENDENCY_MODE_IMAGE_RESOLVE_DESTINATION, + DEPENDENCY_MODE_BLIT_IMAGE_SOURCE, DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION, @@ -97,7 +102,7 @@ struct VulkanCommandParameter_t }; }; -abstract_class CVkCommand +class CVkCommand { public: virtual void Execute( VkCommandBuffer hCommandBuffer, int iCurrentFrame ) = 0; @@ -266,6 +271,12 @@ void CVk##name##PipelineLibrary::Build() \ vkCreateGraphicsPipelines(m_hDevice, NULL, 1, &pipeline, NULL, &m_hPipeline); \ } +struct VkOutputImageConfig_t +{ + VkFormat m_eFormat; + bool m_bIsBlendingEnabled; +}; + class CVkShader : public IShader { public: @@ -273,7 +284,7 @@ public: virtual void AddLayout( int iIndex, int iStride ) override; virtual void AddAttribute( int iBufferIndex, int iLocation, EVertexFormat eFormat, int iOffset ) override; virtual void SetTopology( ETopologyMode eTopology ) override; - virtual void AddOutputImage( int iImageIndex, EImageFormat eFormat ) override; + virtual void AddOutputImage( int iImageIndex, EImageFormat eFormat, bool bBlendingEnabled ) override; virtual void SetDepthImage( EImageFormat eFormat ) override; virtual void SetMultisampling( EMultisampleType eFormat ) override; virtual void DisablePixelShader( bool bDisable ) override; @@ -289,7 +300,7 @@ public: private: CUtlVector m_layouts; CUtlVector m_attributes; - CUtlVector m_eFormats; + CUtlVector m_formats; EMultisampleType m_eMultiSampling; VkFormat m_eDepthFormat; bool m_bIsFragmentEnabled; @@ -389,7 +400,6 @@ public: CVkShader *m_pVkShader; CUtlVector m_hSets; - ITextureArray *m_pTextureArray; private: VkDescriptorPool m_hPool; CUtlVector m_writes = {}; @@ -442,6 +452,13 @@ struct VulkanRenderOutput_t { EStoreMode m_eStoreMode; }; +struct VkRenderBarrier_t +{ + IRenderingObject *pObject; + bool m_bIsRead; + bool m_bIsWrite; +}; + class CVkRenderCommandList: public IRenderCommandList { public: @@ -472,6 +489,8 @@ public: virtual void StartRecording() override; virtual void EndRecording() override; + virtual void Barrier( IRenderingObject *pObject, bool bIsRead, bool bIsWrite ) override; + void Submit(); IVkCommandBufferManager *m_pCommandBufferManager; @@ -494,6 +513,7 @@ private: uint32_t m_uHeight; CUtlVector m_pCommandBuffers = {}; CUtlVector m_pScheduledDestroyPostRaster = {}; + CUtlVector m_barriers = {}; }; diff --git a/public/kottui/kottui.h b/public/kottui/kottui.h index 0565fa1..6ff7c8b 100644 --- a/public/kottui/kottui.h +++ b/public/kottui/kottui.h @@ -27,8 +27,9 @@ public: virtual void Move( int iY, int iX ) = 0; - virtual void SetColor( char c ) = 0; - virtual void Clear( char c ) = 0; + virtual void SetColor( float fX, float fY, float fZ, float fA ) = 0; + virtual void SetBackgroundColor( float fX, float fY, float fZ, float fA ) = 0; + virtual void Clear( float fX, float fY, float fZ, float fA ) = 0; virtual void PutChar( char c ) = 0; virtual void Printf(const char *szFormat, ...) = 0; diff --git a/public/materialsystem/imaterialsystem.h b/public/materialsystem/imaterialsystem.h index 0df4aef..ab36b86 100644 --- a/public/materialsystem/imaterialsystem.h +++ b/public/materialsystem/imaterialsystem.h @@ -220,7 +220,7 @@ public: virtual void AddLayout( int iIndex, int iStride ) = 0; virtual void AddAttribute( int iBufferIndex, int iLocation, EVertexFormat eFormat, int iOffset ) = 0; virtual void SetTopology( ETopologyMode eTopology ) = 0; - virtual void AddOutputImage( int iImageIndex, EImageFormat eFormat ) = 0; + virtual void AddOutputImage( int iImageIndex, EImageFormat eFormat, bool bBlendingEnabled = false ) = 0; virtual void SetDepthImage( EImageFormat eFormat ) = 0; virtual void SetMultisampling( EMultisampleType eFormat ) = 0; virtual void DisablePixelShader( bool bDisable) = 0; @@ -287,6 +287,8 @@ public: virtual void StartRecording() = 0; virtual void EndRecording() = 0; + + virtual void Barrier( IRenderingObject *pObject, bool bIsRead, bool bIsWrite ) = 0; }; //-----------------------------------------------------------------------------