From 78690d4683391e2a67ee2bbd143c517bc385db86 Mon Sep 17 00:00:00 2001 From: David Steele Date: Wed, 27 Jan 2021 23:29:45 +0000 Subject: [PATCH] Converted GPU buffers for geometry to new API Added test code and traces to ensure gl behaviour can be followed. Existing buffer test cases pass. Change-Id: I53ebd874c708fc44b9d1d4484f0cea29b9e60a27 --- automated-tests/src/dali-internal/CMakeLists.txt | 3 +- automated-tests/src/dali/CMakeLists.txt | 1 + .../dali-test-suite-utils/test-gl-abstraction.h | 36 ++++- .../dali-test-suite-utils/test-graphics-buffer.cpp | 81 +++++++++++ .../dali-test-suite-utils/test-graphics-buffer.h | 17 ++- .../test-graphics-controller.cpp | 121 +++++++++++----- automated-tests/src/dali/utc-Dali-Geometry.cpp | 20 ++- automated-tests/src/dali/utc-Dali-VertexBuffer.cpp | 6 +- build/tizen/CMakeLists.txt | 1 + build/tizen/linker-test.cpp | 21 +-- dali/internal/render/common/render-manager.cpp | 2 +- dali/internal/render/gl-resources/gpu-buffer.cpp | 154 ++++----------------- dali/internal/render/gl-resources/gpu-buffer.h | 69 +++------ dali/internal/render/renderers/render-geometry.cpp | 67 +++++++-- dali/internal/render/renderers/render-geometry.h | 19 +-- dali/internal/render/renderers/render-renderer.cpp | 13 +- dali/internal/render/renderers/render-renderer.h | 3 +- .../render/renderers/render-vertex-buffer.cpp | 14 +- .../render/renderers/render-vertex-buffer.h | 18 ++- 19 files changed, 386 insertions(+), 280 deletions(-) create mode 100644 automated-tests/src/dali/dali-test-suite-utils/test-graphics-buffer.cpp diff --git a/automated-tests/src/dali-internal/CMakeLists.txt b/automated-tests/src/dali-internal/CMakeLists.txt index db51810..3e8070d 100644 --- a/automated-tests/src/dali-internal/CMakeLists.txt +++ b/automated-tests/src/dali-internal/CMakeLists.txt @@ -32,8 +32,9 @@ LIST(APPEND TC_SOURCES ../dali/dali-test-suite-utils/test-application.cpp ../dali/dali-test-suite-utils/test-gl-abstraction.cpp ../dali/dali-test-suite-utils/test-gl-sync-abstraction.cpp - ../dali/dali-test-suite-utils/test-graphics-controller.cpp + ../dali/dali-test-suite-utils/test-graphics-buffer.cpp ../dali/dali-test-suite-utils/test-graphics-command-buffer.cpp + ../dali/dali-test-suite-utils/test-graphics-controller.cpp ../dali/dali-test-suite-utils/test-graphics-texture.cpp ../dali/dali-test-suite-utils/test-graphics-sampler.cpp ../dali/dali-test-suite-utils/test-native-image.cpp diff --git a/automated-tests/src/dali/CMakeLists.txt b/automated-tests/src/dali/CMakeLists.txt index 864d923..fc8a1cc 100644 --- a/automated-tests/src/dali/CMakeLists.txt +++ b/automated-tests/src/dali/CMakeLists.txt @@ -112,6 +112,7 @@ LIST(APPEND TC_SOURCES dali-test-suite-utils/test-gesture-generator.cpp dali-test-suite-utils/test-gl-abstraction.cpp dali-test-suite-utils/test-gl-sync-abstraction.cpp + dali-test-suite-utils/test-graphics-buffer.cpp dali-test-suite-utils/test-graphics-command-buffer.cpp dali-test-suite-utils/test-graphics-controller.cpp dali-test-suite-utils/test-graphics-texture.cpp diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h b/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h index 2af9660..4e14dd9 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h @@ -102,6 +102,12 @@ public: inline void BindBuffer(GLenum target, GLuint buffer) override { + std::ostringstream o; + o << std::hex << target << ", " << buffer; + TraceCallStack::NamedParams namedParams; + namedParams["target"] = target; + namedParams["buffer"] = buffer; + mBufferTrace.PushCall("BindBuffer", o.str(), namedParams); } inline void BindFramebuffer(GLenum target, GLuint framebuffer) override @@ -242,11 +248,28 @@ public: inline void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage) override { + std::ostringstream o; + o << std::hex << target << ", " << size << ", " << data << ", " << usage; + TraceCallStack::NamedParams namedParams; + namedParams["target"] = target; + namedParams["size"] = size; + namedParams["usage"] = usage; + + mBufferTrace.PushCall("BufferData", o.str(), namedParams); + mBufferDataCalls.push_back(size); } inline void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) override { + std::ostringstream o; + o << std::hex << target << ", " << offset << ", " << size << ", " << data; + TraceCallStack::NamedParams namedParams; + namedParams["target"] = target; + namedParams["offset"] = offset; + namedParams["size"] = size; + mBufferTrace.PushCall("BufferSubData", o.str()); + mBufferSubDataCalls.push_back(size); } @@ -613,6 +636,12 @@ public: { // avoids an assert in GpuBuffers *buffers = 1u; + + std::ostringstream o; + o << n; + TraceCallStack::NamedParams namedParams; + namedParams["n"] = o.str(); + mBufferTrace.PushCall("GenBuffers", o.str(), namedParams); } inline void GenerateMipmap(GLenum target) override @@ -2171,6 +2200,10 @@ public: // TEST FUNCTIONS { return mViewportTrace; } + inline TraceCallStack& GetBufferTrace() + { + return mBufferTrace; + } template inline bool GetUniformValue(const char* name, T& value) const @@ -2434,10 +2467,11 @@ private: ActiveTextureType mActiveTextures[MIN_TEXTURE_UNIT_LIMIT]; + TraceCallStack mBufferTrace{"gl"}; TraceCallStack mCullFaceTrace; TraceCallStack mEnableDisableTrace; TraceCallStack mShaderTrace; - TraceCallStack mTextureTrace{"GlA Texture:"}; + TraceCallStack mTextureTrace{"gl"}; TraceCallStack mTexParamaterTrace; TraceCallStack mDrawTrace; TraceCallStack mDepthFunctionTrace; diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-buffer.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-buffer.cpp new file mode 100644 index 0000000..2696078 --- /dev/null +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-buffer.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test-graphics-buffer.h" + +#include + +namespace Dali +{ +TestGraphicsBuffer::TestGraphicsBuffer(TraceCallStack& callStack, TestGlAbstraction& glAbstraction, uint32_t size, Graphics::BufferUsageFlags usage) +: mCallStack(callStack), + mGl(glAbstraction), + mUsage(usage) +{ + memory.reserve(size); + mGl.GetBufferTrace().EnableLogging(true); +} + +void TestGraphicsBuffer::Bind() +{ + mCallStack.PushCall("Buffer::Bind", ""); + if(!mId) + { + mGl.GenBuffers(1, &mId); + } + mGl.BindBuffer(GetTarget(), mId); +} + +void TestGraphicsBuffer::Unbind() +{ + mCallStack.PushCall("Buffer::Unbind", ""); + if(mId) + { + mGl.BindBuffer(GetTarget(), 0); + } +} + +void TestGraphicsBuffer::Upload(uint32_t offset, uint32_t size) +{ + std::ostringstream o; + o << offset << ", " << size; + TraceCallStack::NamedParams namedParams; + namedParams["offset"] = offset; + namedParams["size"] = size; + mCallStack.PushCall("Buffer::Upload", o.str(), namedParams); + if(size <= memory.size() && mCreated) + { + // Use subData to avoid re-allocation + mGl.BufferSubData(GetTarget(), offset, size, &memory[offset]); + } + else + { + mGl.BufferData(GetTarget(), size, &memory[0], GL_STATIC_DRAW); //@todo Query - do we need other usages? + mCreated = true; + } +} + +GLenum TestGraphicsBuffer::GetTarget() +{ + GLenum target = GL_ARRAY_BUFFER; + if((mUsage & static_cast(Graphics::BufferUsage::INDEX_BUFFER)) != 0) + { + target = GL_ELEMENT_ARRAY_BUFFER; + } + return target; +} + +} // namespace Dali diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-buffer.h b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-buffer.h index 6a0acac..c4abc3e 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-buffer.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-buffer.h @@ -18,13 +18,28 @@ */ #include +#include + +#include "test-gl-abstraction.h" +#include "test-trace-call-stack.h" namespace Dali { class TestGraphicsBuffer : public Graphics::Buffer { public: - TestGraphicsBuffer() = default; + TestGraphicsBuffer(TraceCallStack& callStack, TestGlAbstraction& glAbstraction, uint32_t size, Graphics::BufferUsageFlags usage); + void Bind(); + void Unbind(); + void Upload(uint32_t offset, uint32_t size); + GLenum GetTarget(); + + TraceCallStack& mCallStack; + TestGlAbstraction& mGl; + std::vector memory; + Graphics::BufferUsageFlags mUsage; + GLuint mId{0}; + bool mCreated{false}; }; } // namespace Dali diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp index 4732a9a..e7f80cd 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp @@ -16,6 +16,7 @@ #include "test-graphics-controller.h" +#include "dali-test-suite-utils.h" #include "test-graphics-buffer.h" #include "test-graphics-command-buffer.h" #include "test-graphics-sampler.h" @@ -140,6 +141,59 @@ std::ostream& operator<<(std::ostream& o, const Graphics::SamplerCreateInfo& cre return o; } +class TestGraphicsMemory : public Graphics::Memory +{ +public: + TestGraphicsMemory(TraceCallStack& callStack, TestGraphicsBuffer& buffer, uint32_t mappedOffset, uint32_t mappedSize) + : mCallStack(callStack), + mBuffer(buffer), + mMappedOffset(mappedOffset), + mMappedSize(mappedSize) + { + } + + void* LockRegion(uint32_t offset, uint32_t size) override + { + std::ostringstream o; + o << offset << ", " << size; + mCallStack.PushCall("Memory::LockRegion", o.str()); + + if(offset > mMappedOffset + mMappedSize || + size + offset > mMappedOffset + mMappedSize) + { + tet_infoline("TestGraphics.Memory::LockRegion() Out of bounds"); + mBuffer.memory.resize(mMappedOffset + offset + size); // Grow to prevent memcpy from crashing + } + mLockedOffset = offset; + mLockedSize = size; + return &mBuffer.memory[mMappedOffset + offset]; + } + + void Unlock(bool flush) override + { + mCallStack.PushCall("Memory::Unlock", (flush ? "Flush" : "NoFlush")); + if(flush) + { + Flush(); + } + } + + void Flush() override + { + mCallStack.PushCall("Memory::Flush", ""); + mBuffer.Bind(); + mBuffer.Upload(mMappedOffset + mLockedOffset, mLockedSize); + mBuffer.Unbind(); + } + + TraceCallStack& mCallStack; + TestGraphicsBuffer& mBuffer; + uint32_t mMappedOffset; + uint32_t mMappedSize; + uint32_t mLockedOffset; + uint32_t mLockedSize; +}; + TestGraphicsController::TestGraphicsController() { mCallStack.Enable(true); @@ -158,7 +212,7 @@ void TestGraphicsController::SubmitCommandBuffers(const Graphics::SubmitInfo& su out << "cmdBuffer[" << submitInfo.cmdBuffer.size() << "], flags:" << std::hex << submitInfo.flags; namedParams["submitInfo"] = out.str(); - mCallStack.PushCall("SubmitCommandBuffers", "", namedParams); + mCallStack.PushCall("Controller::SubmitCommandBuffers", "", namedParams); for(auto& commandBuffer : submitInfo.cmdBuffer) { @@ -195,7 +249,7 @@ void TestGraphicsController::PresentRenderTarget(Graphics::RenderTarget* renderT TraceCallStack::NamedParams namedParams; out << std::hex << renderTarget; namedParams["renderTarget"] = out.str(); - mCallStack.PushCall("PresentRenderTarget", "", namedParams); + mCallStack.PushCall("Controller::PresentRenderTarget", "", namedParams); } /** @@ -203,7 +257,7 @@ void TestGraphicsController::PresentRenderTarget(Graphics::RenderTarget* renderT */ void TestGraphicsController::WaitIdle() { - mCallStack.PushCall("WaitIdle", ""); + mCallStack.PushCall("Controller::WaitIdle", ""); } /** @@ -211,7 +265,7 @@ void TestGraphicsController::WaitIdle() */ void TestGraphicsController::Pause() { - mCallStack.PushCall("Pause", ""); + mCallStack.PushCall("Controller::Pause", ""); } /** @@ -219,7 +273,7 @@ void TestGraphicsController::Pause() */ void TestGraphicsController::Resume() { - mCallStack.PushCall("Resume", ""); + mCallStack.PushCall("Controller::Resume", ""); } void TestGraphicsController::UpdateTextures(const std::vector& updateInfoList, @@ -233,7 +287,7 @@ void TestGraphicsController::UpdateTextures(const std::vector TestGraphicsController::CreateBuffer(const Graphics::BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr&& oldBuffer) +Graphics::UniquePtr TestGraphicsController::CreateBuffer(const Graphics::BufferCreateInfo& createInfo, Graphics::UniquePtr&& oldBuffer) { std::ostringstream oss; - oss << "bufferCreateInfo:" << bufferCreateInfo; - mCallStack.PushCall("CreateBuffer", oss.str()); - - return Graphics::MakeUnique(); + oss << "bufferCreateInfo:" << createInfo; + mCallStack.PushCall("Controller::CreateBuffer", oss.str()); + return Graphics::MakeUnique(mCallStack, mGlAbstraction, createInfo.size, createInfo.usage); } Graphics::UniquePtr TestGraphicsController::CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr&& oldCommandBuffer) { std::ostringstream oss; oss << "commandBufferCreateInfo:" << commandBufferCreateInfo; - mCallStack.PushCall("CreateCommandBuffer", oss.str()); + mCallStack.PushCall("Controller::CreateCommandBuffer", oss.str()); return Graphics::MakeUnique(mCommandBufferCallStack, mGlAbstraction); } Graphics::UniquePtr TestGraphicsController::CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr&& oldRenderPass) { - mCallStack.PushCall("CreateRenderPass", ""); + mCallStack.PushCall("Controller::CreateRenderPass", ""); return nullptr; } @@ -317,26 +370,26 @@ Graphics::UniquePtr TestGraphicsController::CreateTexture(con TraceCallStack::NamedParams namedParams; oss << textureCreateInfo; namedParams["textureCreateInfo"] = oss.str(); - mCallStack.PushCall("CreateTexture", params.str(), namedParams); + mCallStack.PushCall("Controller::CreateTexture", params.str(), namedParams); return Graphics::MakeUnique(mGlAbstraction, textureCreateInfo); } Graphics::UniquePtr TestGraphicsController::CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr&& oldFramebuffer) { - mCallStack.PushCall("CreateFramebuffer", ""); + mCallStack.PushCall("Controller::CreateFramebuffer", ""); return nullptr; } Graphics::UniquePtr TestGraphicsController::CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr&& oldPipeline) { - mCallStack.PushCall("CreatePipeline", ""); + mCallStack.PushCall("Controller::CreatePipeline", ""); return nullptr; } Graphics::UniquePtr TestGraphicsController::CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr&& oldShader) { - mCallStack.PushCall("CreateShader", ""); + mCallStack.PushCall("Controller::CreateShader", ""); return nullptr; } @@ -347,57 +400,61 @@ Graphics::UniquePtr TestGraphicsController::CreateSampler(con TraceCallStack::NamedParams namedParams; oss << samplerCreateInfo; namedParams["samplerCreateInfo"] = oss.str(); - mCallStack.PushCall("CreateSampler", params.str(), namedParams); + mCallStack.PushCall("Controller::CreateSampler", params.str(), namedParams); return Graphics::MakeUnique(mGlAbstraction, samplerCreateInfo); } Graphics::UniquePtr TestGraphicsController::CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr&& oldRenderTarget) { - mCallStack.PushCall("CreateRenderTarget", ""); + mCallStack.PushCall("Controller::CreateRenderTarget", ""); return nullptr; } Graphics::UniquePtr TestGraphicsController::MapBufferRange(const Graphics::MapBufferInfo& mapInfo) { - mCallStack.PushCall("MapBufferRange", ""); - return nullptr; + mCallStack.PushCall("Controller::MapBufferRange", ""); + + auto buffer = static_cast(mapInfo.buffer); + buffer->memory.resize(mapInfo.offset + mapInfo.size); // For initial testing, allow writes past capacity + + return std::make_unique(mCallStack, *buffer, mapInfo.offset, mapInfo.size); } Graphics::UniquePtr TestGraphicsController::MapTextureRange(const Graphics::MapTextureInfo& mapInfo) { - mCallStack.PushCall("MapTextureRange", ""); + mCallStack.PushCall("Controller::MapTextureRange", ""); return nullptr; } void TestGraphicsController::UnmapMemory(Graphics::UniquePtr memory) { - mCallStack.PushCall("UnmapMemory", ""); + mCallStack.PushCall("Controller::UnmapMemory", ""); } Graphics::MemoryRequirements TestGraphicsController::GetTextureMemoryRequirements(Graphics::Texture& texture) const { - mCallStack.PushCall("GetTextureMemoryRequirements", ""); + mCallStack.PushCall("Controller::GetTextureMemoryRequirements", ""); return Graphics::MemoryRequirements{}; } Graphics::MemoryRequirements TestGraphicsController::GetBufferMemoryRequirements(Graphics::Buffer& buffer) const { - mCallStack.PushCall("GetBufferMemoryRequirements", ""); + mCallStack.PushCall("Controller::GetBufferMemoryRequirements", ""); return Graphics::MemoryRequirements{}; } const Graphics::TextureProperties& TestGraphicsController::GetTextureProperties(const Graphics::Texture& texture) { static Graphics::TextureProperties textureProperties{}; - mCallStack.PushCall("GetTextureProperties", ""); + mCallStack.PushCall("Controller::GetTextureProperties", ""); return textureProperties; } bool TestGraphicsController::PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const { - mCallStack.PushCall("PipelineEquals", ""); + mCallStack.PushCall("Controller::PipelineEquals", ""); return false; } diff --git a/automated-tests/src/dali/utc-Dali-Geometry.cpp b/automated-tests/src/dali/utc-Dali-Geometry.cpp index f43288b..bbf9d3a 100644 --- a/automated-tests/src/dali/utc-Dali-Geometry.cpp +++ b/automated-tests/src/dali/utc-Dali-Geometry.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -178,6 +178,9 @@ int UtcDaliGeometryAddVertexBuffer(void) TestApplication application; tet_infoline("Test AddVertexBuffer"); + auto& bufferTrace = application.GetGlAbstraction().GetBufferTrace(); + bufferTrace.Enable(true); + bufferTrace.EnableLogging(true); VertexBuffer vertexBuffer1 = CreateVertexBuffer("aPosition1", "aTexCoord1"); Geometry geometry = Geometry::New(); @@ -229,6 +232,9 @@ int UtcDaliGeometryAddVertexBuffer(void) int UtcDaliGeometryGetNumberOfVertexBuffers(void) { TestApplication application; + auto& bufferTrace = application.GetGlAbstraction().GetBufferTrace(); + bufferTrace.Enable(true); + bufferTrace.EnableLogging(true); tet_infoline("Test GetNumberOfVertexBuffers"); VertexBuffer vertexBuffer1 = CreateVertexBuffer("aPosition1", "aTexCoord1"); @@ -252,6 +258,9 @@ int UtcDaliGeometryGetNumberOfVertexBuffers(void) int UtcDaliGeometryRemoveVertexBuffer(void) { TestApplication application; + auto& bufferTrace = application.GetGlAbstraction().GetBufferTrace(); + bufferTrace.Enable(true); + bufferTrace.EnableLogging(true); tet_infoline("Test RemoveVertexBuffer"); @@ -286,6 +295,9 @@ int UtcDaliGeometryRemoveVertexBuffer(void) int UtcDaliGeometrySetIndexBuffer(void) { TestApplication application; + auto& bufferTrace = application.GetGlAbstraction().GetBufferTrace(); + bufferTrace.Enable(true); + bufferTrace.EnableLogging(true); tet_infoline("Test SetIndexBuffer"); @@ -342,6 +354,9 @@ int UtcDaliGeometrySetIndexBuffer(void) int UtcDaliGeometrySetGetGeometryType01(void) { TestApplication application; + auto& bufferTrace = application.GetGlAbstraction().GetBufferTrace(); + bufferTrace.Enable(true); + bufferTrace.EnableLogging(true); tet_infoline("Test SetType and GetType: without index buffer"); @@ -470,6 +485,9 @@ int UtcDaliGeometrySetGetGeometryType01(void) int UtcDaliGeometrySetGetGeometryType02(void) { TestApplication application; + auto& bufferTrace = application.GetGlAbstraction().GetBufferTrace(); + bufferTrace.Enable(true); + bufferTrace.EnableLogging(true); tet_infoline("Test SetType and GetType: with index buffer"); diff --git a/automated-tests/src/dali/utc-Dali-VertexBuffer.cpp b/automated-tests/src/dali/utc-Dali-VertexBuffer.cpp index 96ac321..d2bec9f 100644 --- a/automated-tests/src/dali/utc-Dali-VertexBuffer.cpp +++ b/automated-tests/src/dali/utc-Dali-VertexBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -238,9 +238,7 @@ int UtcDaliVertexBufferSetData02(void) application.GetScene().Add(actor); application.SendNotification(); - application.Render(0); application.Render(); - application.SendNotification(); { const TestGlAbstraction::BufferDataCalls& bufferDataCalls = @@ -256,8 +254,6 @@ int UtcDaliVertexBufferSetData02(void) application.SendNotification(); application.Render(0); - application.Render(); - application.SendNotification(); { const TestGlAbstraction::BufferSubDataCalls& bufferSubDataCalls = diff --git a/build/tizen/CMakeLists.txt b/build/tizen/CMakeLists.txt index 518b3db..6e89fa0 100644 --- a/build/tizen/CMakeLists.txt +++ b/build/tizen/CMakeLists.txt @@ -368,6 +368,7 @@ IF( ENABLE_LINK_TEST ) ${DALI_TEST_SUITE_DIR}/test-graphics-controller.cpp ${DALI_TEST_SUITE_DIR}/test-graphics-sampler.cpp ${DALI_TEST_SUITE_DIR}/test-graphics-texture.cpp + ${DALI_TEST_SUITE_DIR}/test-graphics-buffer.cpp ${DALI_TEST_SUITE_DIR}/test-graphics-command-buffer.cpp ${DALI_TEST_SUITE_DIR}/test-platform-abstraction.cpp ${DALI_TEST_SUITE_DIR}/test-render-controller.cpp diff --git a/build/tizen/linker-test.cpp b/build/tizen/linker-test.cpp index d2588b7..ed9d2f7 100644 --- a/build/tizen/linker-test.cpp +++ b/build/tizen/linker-test.cpp @@ -21,17 +21,20 @@ #include // Link with TET Test application, need to redefine TET functions -void tet_infoline(const char* str) +extern "C" { - puts(str); -} + void tet_infoline(const char* str) + { + puts(str); + } -void tet_printf(const char* str, ...) -{ - va_list args; - va_start(args, str); - vprintf(str, args); - va_end(args); + void tet_printf(const char* str, ...) + { + va_list args; + va_start(args, str); + vprintf(str, args); + va_end(args); + } } #include "test-application.h" diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index f7bdb21..b12019b 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -532,7 +532,7 @@ void RenderManager::PreRender(Integration::RenderStatus& status, bool forceClear const RenderItem& item = renderList->GetItem(itemIndex); if(DALI_LIKELY(item.mRenderer)) { - item.mRenderer->Upload(*mImpl->currentContext); + item.mRenderer->Upload(); } } } diff --git a/dali/internal/render/gl-resources/gpu-buffer.cpp b/dali/internal/render/gl-resources/gpu-buffer.cpp index 9e9a77b..b13d2a1 100644 --- a/dali/internal/render/gl-resources/gpu-buffer.cpp +++ b/dali/internal/render/gl-resources/gpu-buffer.cpp @@ -19,7 +19,9 @@ #include // INTERNAL INCLUDES +#include #include +#include namespace Dali { @@ -27,158 +29,54 @@ namespace Internal { namespace { -/** - * Helper to get our drawmode enum as GL enum - * @param type to convert - * @return the corresponding GL enum or -1 - */ -inline GLenum ModeAsGlEnum(GpuBuffer::Usage type) -{ - GLenum retval(-1); - switch(type) - { - case GpuBuffer::STREAM_DRAW: - { - retval = GL_STREAM_DRAW; - break; - } - case GpuBuffer::STATIC_DRAW: - { - retval = GL_STATIC_DRAW; - break; - } - case GpuBuffer::DYNAMIC_DRAW: - { - retval = GL_DYNAMIC_DRAW; - break; - } - } - return retval; -} - } // namespace -GpuBuffer::GpuBuffer(Context& context) -: mContext(context), - mCapacity(0), - mSize(0), - mBufferId(0), +GpuBuffer::GpuBuffer(Graphics::Controller& graphicsController, Graphics::BufferUsageFlags usage) +: mUsage(usage), mBufferCreated(false) { } GpuBuffer::~GpuBuffer() { - // If we have a buffer then delete it. - if(mBufferId) - { - // If a buffer object that is currently bound is deleted, the binding reverts to 0 - // (the absence of any buffer object, which reverts to client memory usage) - mContext.DeleteBuffers(1, &mBufferId); - } } -/* - * Creates or updates the buffer data depending on whether it - * already exists or not. - */ -void GpuBuffer::UpdateDataBuffer(Context& context, GLsizeiptr size, const GLvoid* data, Usage usage, Target target) +void GpuBuffer::UpdateDataBuffer(Graphics::Controller& graphicsController, uint32_t size, const void* data) { DALI_ASSERT_DEBUG(size > 0); mSize = size; - // make sure we have a buffer name/id before uploading - if(mBufferId == 0) - { - mContext.GenBuffers(1, &mBufferId); - DALI_ASSERT_DEBUG(mBufferId); - } - - GLenum glTargetEnum = GL_ARRAY_BUFFER; - - // make sure the buffer is bound, don't perform any checks because size may be zero - if(ARRAY_BUFFER == target) - { - context.BindArrayBuffer(mBufferId); - } - else if(ELEMENT_ARRAY_BUFFER == target) - { - glTargetEnum = GL_ELEMENT_ARRAY_BUFFER; - context.BindElementArrayBuffer(mBufferId); - } - else if(TRANSFORM_FEEDBACK_BUFFER == target) - { - glTargetEnum = GL_TRANSFORM_FEEDBACK_BUFFER; - context.BindTransformFeedbackBuffer(mBufferId); - } - // if the buffer has already been created, just update the data providing it fits - if(mBufferCreated) - { - // if the data will fit in the existing buffer, just update it - if(size <= mCapacity) - { - context.BufferSubData(glTargetEnum, 0, size, data); - } - else - { - // create a new buffer of the larger size, - // gl should automatically deallocate the old buffer - context.BufferData(glTargetEnum, size, data, ModeAsGlEnum(usage)); - mCapacity = size; - } - } - else + if(!mGraphicsObject) { - // create the buffer - context.BufferData(glTargetEnum, size, data, ModeAsGlEnum(usage)); - mBufferCreated = true; - mCapacity = size; + Graphics::BufferCreateInfo createInfo{}; + createInfo.SetUsage(mUsage).SetSize(size); + mGraphicsObject = graphicsController.CreateBuffer(createInfo, nullptr); + mCapacity = size; } - if(ARRAY_BUFFER == target) - { - context.BindArrayBuffer(0); - } - else if(ELEMENT_ARRAY_BUFFER == target) - { - context.BindElementArrayBuffer(0); - } - else if(TRANSFORM_FEEDBACK_BUFFER == target) - { - context.BindTransformFeedbackBuffer(0); - } -} - -void GpuBuffer::Bind(Context& context, Target target) const -{ - DALI_ASSERT_DEBUG(mCapacity); - - if(target == ARRAY_BUFFER) - { - context.BindArrayBuffer(mBufferId); - } - else if(target == ELEMENT_ARRAY_BUFFER) - { - context.BindElementArrayBuffer(mBufferId); - } - else if(target == TRANSFORM_FEEDBACK_BUFFER) - { - context.BindTransformFeedbackBuffer(mBufferId); - } + Graphics::MapBufferInfo info; + info.buffer = mGraphicsObject.get(); + info.usage = 0 | Graphics::MemoryUsageFlagBits::WRITE; + info.offset = 0; + info.size = size; + + auto memory = graphicsController.MapBufferRange(info); + void* ptr = memory->LockRegion(0, size); + memcpy(ptr, data, size); + memory->Unlock(true); + graphicsController.UnmapMemory(std::move(memory)); } bool GpuBuffer::BufferIsValid() const { - return mBufferCreated && (0 != mCapacity); + return mGraphicsObject && (0 != mCapacity); } -void GpuBuffer::GlContextDestroyed() +void GpuBuffer::Destroy() { - // If the context is destroyed, GL would have released the buffer. - mCapacity = 0; - mSize = 0; - mBufferId = 0; - mBufferCreated = false; + mCapacity = 0; + mSize = 0; + mGraphicsObject.reset(); } } // namespace Internal diff --git a/dali/internal/render/gl-resources/gpu-buffer.h b/dali/internal/render/gl-resources/gpu-buffer.h index 918c82e..7734643 100644 --- a/dali/internal/render/gl-resources/gpu-buffer.h +++ b/dali/internal/render/gl-resources/gpu-buffer.h @@ -19,6 +19,7 @@ */ // INTERNAL INCLUDES +#include #include namespace Dali @@ -39,31 +40,11 @@ class GpuBuffer { public: /** - * Enum to encapsulate the GL buffer type. This is to avoid having to store a whole int for type - */ - enum Target - { - ARRAY_BUFFER, ///< GL_ARRAY_BUFFER - ELEMENT_ARRAY_BUFFER, ///< GL_ELEMENT_ARRAY_BUFFER - TRANSFORM_FEEDBACK_BUFFER ///< GL_TRANSFORM_FEEDBACK_BUFFER - }; - - /** - * Enum to encapsulate the GL draw mode. This is to avoid having to store a whole int for mode - */ - enum Usage - { - STREAM_DRAW, ///< GL_STREAM_DRAW - STATIC_DRAW, ///< GL_STATIC_DRAW - DYNAMIC_DRAW, ///< GL_DYNAMIC_DRAW - }; - -public: - /** * constructor - * @param context drawing context + * @param[in] graphicsController the graphics controller + * @param[in] usage The type of buffer */ - GpuBuffer(Context& context); + GpuBuffer(Graphics::Controller& graphicsController, Graphics::BufferUsageFlags usage); /** * Destructor, non virtual as no virtual methods or inheritance @@ -73,21 +54,11 @@ public: /** * * Creates or updates a buffer object and binds it to the target. - * @param context The context to bind the the buffer + * @param graphicsController The graphics controller * @param size Specifies the size in bytes of the buffer object's new data store. * @param data pointer to the data to load - * @param usage How the buffer will be used - * @param target The target buffer to update */ - void UpdateDataBuffer(Context& context, GLsizeiptr size, const GLvoid* data, Usage usage, Target target); - - /** - * Bind the buffer object to the target - * Will assert if the buffer size is zero - * @param context The context to bind the the buffer - * @param target The target buffer to bind - */ - void Bind(Context& context, Target target) const; + void UpdateDataBuffer(Graphics::Controller& graphicsController, uint32_t size, const void* data); /** * @return true if the GPU buffer is valid, i.e. its created and not empty @@ -98,30 +69,28 @@ public: * Get the size of the buffer * @return size */ - GLsizeiptr GetBufferSize() const + uint32_t GetBufferSize() const { return mSize; } - /** - * Needs to be called when GL context is destroyed - */ - void GlContextDestroyed(); + inline Graphics::Buffer* GetGraphicsObject() + { + return mGraphicsObject.get(); + } -private: /** - * Perfoms a bind without checking the size of the buffer - * @param bufferId to bind + * ??? */ - void BindNoChecks(GLuint bufferId) const; + void Destroy(); -private: // Data - Context& mContext; ///< shared context for dali drawing - GLsizeiptr mCapacity; ///< buffer capacity - GLsizeiptr mSize; ///< buffer size - GLuint mBufferId; ///< buffer object name(id) +private: + Graphics::UniquePtr mGraphicsObject; + uint32_t mCapacity{0}; ///< buffer capacity + uint32_t mSize{0}; ///< buffer size - bool mBufferCreated : 1; ///< whether buffer has been created + Graphics::BufferUsageFlags mUsage; + bool mBufferCreated : 1; ///< whether buffer has been created }; } // namespace Internal diff --git a/dali/internal/render/renderers/render-geometry.cpp b/dali/internal/render/renderers/render-geometry.cpp index d825af3..364fc30 100644 --- a/dali/internal/render/renderers/render-geometry.cpp +++ b/dali/internal/render/renderers/render-geometry.cpp @@ -106,7 +106,7 @@ void Geometry::OnRenderFinished() mAttributesChanged = false; } -void Geometry::Upload(Context& context) +void Geometry::Upload(Graphics::Controller& graphicsController) { if(!mHasBeenUpdated) { @@ -121,11 +121,11 @@ void Geometry::Upload(Context& context) { if(mIndexBuffer == nullptr) { - mIndexBuffer = new GpuBuffer(context); + mIndexBuffer = new GpuBuffer(graphicsController, 0 | Graphics::BufferUsage::INDEX_BUFFER); } uint32_t bufferSize = static_cast(sizeof(uint16_t) * mIndices.Size()); - mIndexBuffer->UpdateDataBuffer(context, bufferSize, &mIndices[0], GpuBuffer::STATIC_DRAW, GpuBuffer::ELEMENT_ARRAY_BUFFER); + mIndexBuffer->UpdateDataBuffer(graphicsController, bufferSize, &mIndices[0]); } mIndicesChanged = false; @@ -133,7 +133,7 @@ void Geometry::Upload(Context& context) for(auto&& buffer : mVertexBuffers) { - if(!buffer->Update(context)) + if(!buffer->Update(graphicsController)) { //Vertex buffer is not ready ( Size, data or format has not been specified yet ) return; @@ -145,20 +145,32 @@ void Geometry::Upload(Context& context) } void Geometry::Draw( - Context& context, - BufferIndex bufferIndex, - Vector& attributeLocation, - uint32_t elementBufferOffset, - uint32_t elementBufferCount) + Context& context, + Graphics::Controller& graphicsController, + Graphics::CommandBuffer& commandBuffer, + BufferIndex bufferIndex, + Vector& attributeLocation, + uint32_t elementBufferOffset, + uint32_t elementBufferCount) { //Bind buffers to attribute locations uint32_t base = 0u; const uint32_t vertexBufferCount = static_cast(mVertexBuffers.Count()); + + std::vector buffers; + std::vector offsets; + for(uint32_t i = 0; i < vertexBufferCount; ++i) { - mVertexBuffers[i]->BindBuffer(context, GpuBuffer::ARRAY_BUFFER); - base += mVertexBuffers[i]->EnableVertexAttributes(context, attributeLocation, base); + Graphics::Buffer* buffer = mVertexBuffers[i]->GetGpuBuffer().GetGraphicsObject(); + + if(buffer) + { + buffers.push_back(buffer); + offsets.push_back(0u); + } } + commandBuffer.BindVertexBuffers(0, buffers, offsets); uint32_t numIndices(0u); intptr_t firstIndexOffset(0u); @@ -223,7 +235,25 @@ void Geometry::Draw( if(mIndexBuffer && geometryGLType != GL_POINTS) { //Indexed draw call - mIndexBuffer->Bind(context, GpuBuffer::ELEMENT_ARRAY_BUFFER); + Graphics::Buffer* ibo = mIndexBuffer->GetGraphicsObject(); + if(ibo) + { + commandBuffer.BindIndexBuffer(*ibo, 0, Graphics::Format::R16_UINT); + } + + // Command buffer contains Texture bindings, vertex bindings and index buffer binding. + Graphics::SubmitInfo submitInfo{{}, 0 | Graphics::SubmitFlagBits::FLUSH}; + submitInfo.cmdBuffer.push_back(&commandBuffer); + graphicsController.SubmitCommandBuffers(submitInfo); + + //@todo This should all be done from inside Pipeline implementation. + //If there is only 1 vertex buffer, it should have been bound by SubmitCommandBuffers, + //and the single GL call from this will work on that bound buffer. + for(uint32_t i = 0; i < vertexBufferCount; ++i) + { + base += mVertexBuffers[i]->EnableVertexAttributes(context, attributeLocation, base); + } + // numIndices truncated, no value loss happening in practice context.DrawElements(geometryGLType, static_cast(numIndices), GL_UNSIGNED_SHORT, reinterpret_cast(firstIndexOffset)); } @@ -237,6 +267,19 @@ void Geometry::Draw( numVertices = static_cast(mVertexBuffers[0]->GetElementCount()); } + // Command buffer contains Texture bindings & vertex bindings + Graphics::SubmitInfo submitInfo{{}, 0 | Graphics::SubmitFlagBits::FLUSH}; + submitInfo.cmdBuffer.push_back(&commandBuffer); + graphicsController.SubmitCommandBuffers(submitInfo); + + //@todo This should all be done from inside Pipeline implementation. + //If there is only 1 vertex buffer, it should have been bound by SubmitCommandBuffers, + //and the single GL call from this will work on that bound buffer. + for(uint32_t i = 0; i < vertexBufferCount; ++i) + { + base += mVertexBuffers[i]->EnableVertexAttributes(context, attributeLocation, base); + } + context.DrawArrays(geometryGLType, 0, numVertices); } diff --git a/dali/internal/render/renderers/render-geometry.h b/dali/internal/render/renderers/render-geometry.h index a5cb51d..cacfbce 100644 --- a/dali/internal/render/renderers/render-geometry.h +++ b/dali/internal/render/renderers/render-geometry.h @@ -19,6 +19,7 @@ // INTERNAL INCLUDES #include +#include #include #include #include @@ -116,23 +117,25 @@ public: /** * Upload the geometry if it has changed - * @param[in] context The GL context */ - void Upload(Context& context); + void Upload(Graphics::Controller& graphicsController); /** * Set up the attributes and perform the Draw call corresponding to the geometry type - * @param[in] context The GL context + * @param[in] context The GL context @todo remove + * @param[in] graphicsController The graphics controller * @param[in] bufferIndex The current buffer index * @param[in] attributeLocation The location for the attributes in the shader * @param[in] elementBufferOffset The index of first element to draw if index buffer bound * @param[in] elementBufferCount Number of elements to draw if index buffer bound, uses whole buffer when 0 */ - void Draw(Context& context, - BufferIndex bufferIndex, - Vector& attributeLocation, - uint32_t elementBufferOffset, - uint32_t elementBufferCount); + void Draw(Context& context, + Graphics::Controller& graphicsController, + Graphics::CommandBuffer& commandBuffer, + BufferIndex bufferIndex, + Vector& attributeLocation, + uint32_t elementBufferOffset, + uint32_t elementBufferCount); private: // VertexBuffers diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index 4be7532..767a11d 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -559,9 +559,9 @@ StencilOperation::Type Renderer::GetStencilOperationOnZPass() const return mStencilParameters.stencilOperationOnZPass; } -void Renderer::Upload(Context& context) +void Renderer::Upload() { - mGeometry->Upload(context); + mGeometry->Upload(*mGraphicsController); } void Renderer::Render(Context& context, @@ -651,11 +651,6 @@ void Renderer::Render(Context& conte { // Only set up and draw if we have textures and they are all valid - // @todo Move to render manager. For now, ensure textures are bound before drawing - Graphics::SubmitInfo submitInfo{{}, 0 | Graphics::SubmitFlagBits::FLUSH}; - submitInfo.cmdBuffer.push_back(commandBuffer.get()); - mGraphicsController->SubmitCommandBuffers(submitInfo); - // set projection and view matrix if program has not yet received them yet this frame SetMatrices(*program, modelMatrix, viewMatrix, projectionMatrix, modelViewMatrix); @@ -693,6 +688,8 @@ void Renderer::Render(Context& conte SetBlending(context, blend); mGeometry->Draw(context, + *mGraphicsController, + *commandBuffer.get(), bufferIndex, mAttributesLocation, mIndexedDrawFirstElement, @@ -706,7 +703,7 @@ void Renderer::Render(Context& conte { //Set blending mode SetBlending(context, cmd->queue == DevelRenderer::RENDER_QUEUE_OPAQUE ? false : blend); - mGeometry->Draw(context, bufferIndex, mAttributesLocation, cmd->firstIndex, cmd->elementCount); + mGeometry->Draw(context, *mGraphicsController, *commandBuffer.get(), bufferIndex, mAttributesLocation, cmd->firstIndex, cmd->elementCount); } } } diff --git a/dali/internal/render/renderers/render-renderer.h b/dali/internal/render/renderers/render-renderer.h index f567e2a..d73a21f 100644 --- a/dali/internal/render/renderers/render-renderer.h +++ b/dali/internal/render/renderers/render-renderer.h @@ -347,9 +347,8 @@ public: /** * Called to upload during RenderManager::Render(). - * @param[in] context The context used for uploading */ - void Upload(Context& context); + void Upload(); /** * Called to render during RenderManager::Render(). diff --git a/dali/internal/render/renderers/render-vertex-buffer.cpp b/dali/internal/render/renderers/render-vertex-buffer.cpp index 421b022..fa34075 100644 --- a/dali/internal/render/renderers/render-vertex-buffer.cpp +++ b/dali/internal/render/renderers/render-vertex-buffer.cpp @@ -138,7 +138,7 @@ void VertexBuffer::SetData(Dali::Vector* data, uint32_t size) mDataChanged = true; } -bool VertexBuffer::Update(Context& context) +bool VertexBuffer::Update(Graphics::Controller& graphicsController) { if(!mData || !mFormat || !mSize) { @@ -149,14 +149,14 @@ bool VertexBuffer::Update(Context& context) { if(!mGpuBuffer) { - mGpuBuffer = new GpuBuffer(context); + mGpuBuffer = new GpuBuffer(graphicsController, 0 | Graphics::BufferUsage::VERTEX_BUFFER); } // Update the GpuBuffer if(mGpuBuffer) { DALI_ASSERT_DEBUG(mSize && "No data in the property buffer!"); - mGpuBuffer->UpdateDataBuffer(context, GetDataSize(), &((*mData)[0]), GpuBuffer::STATIC_DRAW, GpuBuffer::ARRAY_BUFFER); + mGpuBuffer->UpdateDataBuffer(graphicsController, GetDataSize(), &((*mData)[0])); } mDataChanged = false; @@ -165,14 +165,6 @@ bool VertexBuffer::Update(Context& context) return true; } -void VertexBuffer::BindBuffer(Context& context, GpuBuffer::Target target) -{ - if(mGpuBuffer) - { - mGpuBuffer->Bind(context, target); - } -} - uint32_t VertexBuffer::EnableVertexAttributes(Context& context, Vector& vAttributeLocation, uint32_t locationBase) { const uint32_t attributeCount = static_cast(mFormat->components.size()); diff --git a/dali/internal/render/renderers/render-vertex-buffer.h b/dali/internal/render/renderers/render-vertex-buffer.h index 30b0427..acda1e2 100644 --- a/dali/internal/render/renderers/render-vertex-buffer.h +++ b/dali/internal/render/renderers/render-vertex-buffer.h @@ -87,17 +87,10 @@ public: void SetSize(uint32_t size); /** - * @brief Bind the property buffer - * @param context The context to bind the the buffer - * @param[in] target The binding point + * Perform the upload of the buffer only when required + * @param graphicsController The controller */ - void BindBuffer(Context& context, GpuBuffer::Target target); - - /** - * Perform the upload of the buffer only when requiered - * @param[in] context The GL context - */ - bool Update(Context& context); + bool Update(Graphics::Controller& graphicsController); /** * Enable the vertex attributes for each vertex buffer from the corresponding @@ -184,6 +177,11 @@ public: return mFormat.Get(); } + inline GpuBuffer& GetGpuBuffer() + { + return *(const_cast(mGpuBuffer.Get())); // @todo change to unique_ptr to avoid const cast? + } + private: OwnerPointer mFormat; ///< Format of the buffer OwnerPointer > mData; ///< Data -- 2.7.4