diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12Texture.h b/engine/include/XCEngine/RHI/D3D12/D3D12Texture.h index ad4ce1f0..cbec2fd2 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12Texture.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12Texture.h @@ -44,7 +44,14 @@ public: uint32_t GetArraySize() const { return GetDesc().DepthOrArraySize; } Format GetFormat() const override { return static_cast(GetDesc().Format); } - TextureType GetTextureType() const override { return TextureType::Texture2D; } + TextureType GetTextureType() const override { + switch (GetDesc().Dimension) { + case D3D12_RESOURCE_DIMENSION_TEXTURE1D: return TextureType::Texture1D; + case D3D12_RESOURCE_DIMENSION_TEXTURE2D: return TextureType::Texture2D; + case D3D12_RESOURCE_DIMENSION_TEXTURE3D: return TextureType::Texture3D; + default: return TextureType::Texture2D; + } + } bool OwnsResource() const { return m_ownsResource; } diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLCommandQueue.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLCommandQueue.h index 63d0248d..c8a2227b 100644 --- a/engine/include/XCEngine/RHI/OpenGL/OpenGLCommandQueue.h +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLCommandQueue.h @@ -19,7 +19,7 @@ public: void WaitForIdle() override; CommandQueueType GetType() const override { return CommandQueueType::Direct; } - uint64_t GetTimestampFrequency() const override { return 0; } + uint64_t GetTimestampFrequency() const override; void* GetNativeHandle() override { return nullptr; } void WaitForPreviousFrame() override {} diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLFence.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLFence.h index a8fa380a..243bb205 100644 --- a/engine/include/XCEngine/RHI/OpenGL/OpenGLFence.h +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLFence.h @@ -31,7 +31,7 @@ public: uint64_t GetCompletedValue() const override; uint64_t GetCurrentValue() const { return m_fenceValue; } - void* GetNativeHandle() override { return m_sync; } + void* GetNativeHandle() override; private: void* m_sync; diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLSwapChain.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLSwapChain.h index 7cb8942c..cf8b6d0e 100644 --- a/engine/include/XCEngine/RHI/OpenGL/OpenGLSwapChain.h +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLSwapChain.h @@ -3,6 +3,7 @@ #include #include "../RHISwapChain.h" +#include "OpenGLTexture.h" struct HWND__; struct HDC__; @@ -72,6 +73,7 @@ private: bool m_shouldClose; bool m_fullscreen; PresentMode m_presentMode; + OpenGLTexture* m_backBufferTexture; }; } // namespace RHI diff --git a/engine/src/RHI/OpenGL/OpenGLCommandQueue.cpp b/engine/src/RHI/OpenGL/OpenGLCommandQueue.cpp index 460d1584..85a5547d 100644 --- a/engine/src/RHI/OpenGL/OpenGLCommandQueue.cpp +++ b/engine/src/RHI/OpenGL/OpenGLCommandQueue.cpp @@ -1,4 +1,6 @@ #include "XCEngine/RHI/OpenGL/OpenGLCommandQueue.h" +#include "XCEngine/RHI/RHIFence.h" +#include namespace XCEngine { namespace RHI { @@ -17,6 +19,10 @@ void OpenGLCommandQueue::ExecuteCommandLists(uint32_t count, void** lists) { } void OpenGLCommandQueue::Signal(RHIFence* fence, uint64_t value) { + if (fence) { + fence->Signal(value); + } + glFlush(); } void OpenGLCommandQueue::Wait(RHIFence* fence, uint64_t value) { @@ -27,6 +33,13 @@ uint64_t OpenGLCommandQueue::GetCompletedValue() { } void OpenGLCommandQueue::WaitForIdle() { + glFinish(); +} + +uint64_t OpenGLCommandQueue::GetTimestampFrequency() const { + GLint64 frequency = 0; + glGetInteger64v(GL_TIMESTAMP, &frequency); + return frequency > 0 ? static_cast(frequency) : 1000000000; } } // namespace RHI diff --git a/engine/src/RHI/OpenGL/OpenGLDevice.cpp b/engine/src/RHI/OpenGL/OpenGLDevice.cpp index 040e7337..b9c59cab 100644 --- a/engine/src/RHI/OpenGL/OpenGLDevice.cpp +++ b/engine/src/RHI/OpenGL/OpenGLDevice.cpp @@ -450,7 +450,7 @@ const RHIDeviceInfo& OpenGLDevice::GetDeviceInfo() const { } void* OpenGLDevice::GetNativeDevice() { - return nullptr; + return m_hglrc; } void* OpenGLDevice::GetNativeHandle() const { diff --git a/engine/src/RHI/OpenGL/OpenGLFence.cpp b/engine/src/RHI/OpenGL/OpenGLFence.cpp index 45a09ff1..00ba9929 100644 --- a/engine/src/RHI/OpenGL/OpenGLFence.cpp +++ b/engine/src/RHI/OpenGL/OpenGLFence.cpp @@ -38,26 +38,22 @@ void OpenGLFence::Signal() { void OpenGLFence::Signal(uint64_t value) { glFlush(); m_fenceValue = value; + m_completedValue = value; m_signaled = true; + if (m_sync) { + glDeleteSync(static_cast(m_sync)); + } + m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); } void OpenGLFence::Wait(uint64_t timeoutNs) { - if (!m_signaled || !m_sync) { - glFinish(); - m_completedValue = m_fenceValue; - m_signaled = true; - return; - } - - GLsync sync = static_cast(m_sync); - GLenum result = glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, timeoutNs); - while (result == GL_TIMEOUT_EXPIRED && timeoutNs > 0) { - result = glClientWaitSync(sync, 0, timeoutNs); - } - - if (result == GL_ALREADY_SIGNALED || result == GL_CONDITION_SATISFIED) { - m_completedValue = m_fenceValue; + if (m_signaled && m_sync) { + GLsync sync = static_cast(m_sync); + glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED); } + glFinish(); + m_completedValue = m_fenceValue; + m_signaled = true; } void OpenGLFence::Reset() { @@ -91,5 +87,12 @@ uint64_t OpenGLFence::GetCompletedValue() const { return m_completedValue; } +void* OpenGLFence::GetNativeHandle() { + if (!m_sync) { + m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + } + return m_sync; +} + } // namespace RHI } // namespace XCEngine diff --git a/engine/src/RHI/OpenGL/OpenGLSwapChain.cpp b/engine/src/RHI/OpenGL/OpenGLSwapChain.cpp index 929e9452..c93b67ee 100644 --- a/engine/src/RHI/OpenGL/OpenGLSwapChain.cpp +++ b/engine/src/RHI/OpenGL/OpenGLSwapChain.cpp @@ -22,7 +22,8 @@ OpenGLSwapChain::OpenGLSwapChain() , m_vsync(true) , m_shouldClose(false) , m_fullscreen(false) - , m_presentMode(PresentMode::VSync) { + , m_presentMode(PresentMode::VSync) + , m_backBufferTexture(nullptr) { } OpenGLSwapChain::~OpenGLSwapChain() { @@ -50,6 +51,11 @@ bool OpenGLSwapChain::Initialize(HWND window, bool vsync) { m_framebufferWidth = m_width; m_framebufferHeight = m_height; + if (!m_backBufferTexture) { + m_backBufferTexture = new OpenGLTexture(); + m_backBufferTexture->Initialize(OpenGLTextureType::Texture2D, m_width, m_height, 1, 1, OpenGLFormat::RGBA8, nullptr); + } + return true; } @@ -76,10 +82,19 @@ bool OpenGLSwapChain::Initialize(HWND window, int width, int height, PresentMode m_framebufferWidth = width; m_framebufferHeight = height; + if (!m_backBufferTexture) { + m_backBufferTexture = new OpenGLTexture(); + m_backBufferTexture->Initialize(OpenGLTextureType::Texture2D, m_width, m_height, 1, 1, OpenGLFormat::RGBA8, nullptr); + } + return true; } void OpenGLSwapChain::Shutdown() { + if (m_backBufferTexture) { + delete m_backBufferTexture; + m_backBufferTexture = nullptr; + } if (m_hdc && m_hwnd) { ::ReleaseDC(m_hwnd, m_hdc); m_hdc = nullptr; @@ -159,7 +174,7 @@ uint32_t OpenGLSwapChain::GetCurrentBackBufferIndex() const { } RHITexture* OpenGLSwapChain::GetCurrentBackBuffer() { - return nullptr; + return m_backBufferTexture; } void* OpenGLSwapChain::GetNativeHandle() { diff --git a/tests/RHI/unit/test_device.cpp b/tests/RHI/unit/test_device.cpp index 32fde7f4..a282d53d 100644 --- a/tests/RHI/unit/test_device.cpp +++ b/tests/RHI/unit/test_device.cpp @@ -53,9 +53,14 @@ TEST_P(RHITestFixture, Device_CreateTexture_ReturnsValid) { TextureDesc desc = {}; desc.width = 512; desc.height = 512; + desc.depth = 1; desc.mipLevels = 1; + desc.arraySize = 1; desc.format = static_cast(Format::R8G8B8A8_UNorm); desc.textureType = static_cast(TextureType::Texture2D); + desc.sampleCount = 1; + desc.sampleQuality = 0; + desc.flags = 0; RHITexture* texture = GetDevice()->CreateTexture(desc); ASSERT_NE(texture, nullptr); diff --git a/tests/RHI/unit/test_texture.cpp b/tests/RHI/unit/test_texture.cpp index f91c43dc..ba94e413 100644 --- a/tests/RHI/unit/test_texture.cpp +++ b/tests/RHI/unit/test_texture.cpp @@ -38,6 +38,8 @@ TEST_P(RHITestFixture, Texture_Create_Texture3D) { desc.mipLevels = 1; desc.format = static_cast(Format::R16_Float); desc.textureType = static_cast(TextureType::Texture3D); + desc.sampleCount = 1; + desc.sampleQuality = 0; RHITexture* texture = GetDevice()->CreateTexture(desc); ASSERT_NE(texture, nullptr); @@ -55,8 +57,14 @@ TEST_P(RHITestFixture, Texture_StateManagement) { TextureDesc desc = {}; desc.width = 256; desc.height = 256; + desc.depth = 1; + desc.mipLevels = 1; + desc.arraySize = 1; desc.format = static_cast(Format::R8G8B8A8_UNorm); desc.textureType = static_cast(TextureType::Texture2D); + desc.sampleCount = 1; + desc.sampleQuality = 0; + desc.flags = 0; RHITexture* texture = GetDevice()->CreateTexture(desc); ASSERT_NE(texture, nullptr); @@ -73,8 +81,14 @@ TEST_P(RHITestFixture, Texture_Naming) { TextureDesc desc = {}; desc.width = 256; desc.height = 256; + desc.depth = 1; + desc.mipLevels = 1; + desc.arraySize = 1; desc.format = static_cast(Format::R8G8B8A8_UNorm); desc.textureType = static_cast(TextureType::Texture2D); + desc.sampleCount = 1; + desc.sampleQuality = 0; + desc.flags = 0; RHITexture* texture = GetDevice()->CreateTexture(desc); ASSERT_NE(texture, nullptr); @@ -90,8 +104,14 @@ TEST_P(RHITestFixture, Texture_GetNativeHandle) { TextureDesc desc = {}; desc.width = 256; desc.height = 256; + desc.depth = 1; + desc.mipLevels = 1; + desc.arraySize = 1; desc.format = static_cast(Format::R8G8B8A8_UNorm); desc.textureType = static_cast(TextureType::Texture2D); + desc.sampleCount = 1; + desc.sampleQuality = 0; + desc.flags = 0; RHITexture* texture = GetDevice()->CreateTexture(desc); ASSERT_NE(texture, nullptr);