2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "test-graphics-controller.h"
19 #include "dali-test-suite-utils.h"
20 #include "test-graphics-buffer.h"
21 #include "test-graphics-command-buffer.h"
22 #include "test-graphics-sampler.h"
23 #include "test-graphics-texture.h"
25 #include <dali/integration-api/gl-defines.h>
31 std::ostream& operator<<(std::ostream& o, const Graphics::BufferCreateInfo& bufferCreateInfo)
33 return o << "usage:" << std::hex << bufferCreateInfo.usage << ", size:" << std::dec << bufferCreateInfo.size;
36 std::ostream& operator<<(std::ostream& o, const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo)
38 return o << "level:" << (commandBufferCreateInfo.level == Graphics::CommandBufferLevel::PRIMARY ? "PRIMARY" : "SECONDARY")
39 << ", fixedCapacity:" << std::dec << commandBufferCreateInfo.fixedCapacity;
42 std::ostream& operator<<(std::ostream& o, const Graphics::TextureType& textureType)
46 case Graphics::TextureType::TEXTURE_2D:
49 case Graphics::TextureType::TEXTURE_3D:
52 case Graphics::TextureType::TEXTURE_CUBEMAP:
53 o << "TEXTURE_CUBEMAP";
59 std::ostream& operator<<(std::ostream& o, const Graphics::Extent2D extent)
61 o << "width:" << extent.width << ", height:" << extent.height;
65 std::ostream& operator<<(std::ostream& o, const Graphics::TextureCreateInfo& createInfo)
67 o << "textureType:" << createInfo.textureType
68 << " size:" << createInfo.size
69 << " format:" << static_cast<uint32_t>(createInfo.format)
70 << " mipMapFlag:" << createInfo.mipMapFlag
71 << " layout:" << (createInfo.layout == Graphics::TextureLayout::LINEAR ? "LINEAR" : "OPTIMAL")
72 << " usageFlags:" << std::hex << createInfo.usageFlags
73 << " data:" << std::hex << createInfo.data
74 << " dataSize:" << std::dec << createInfo.dataSize
75 << " nativeImagePtr:" << std::hex << createInfo.nativeImagePtr;
79 std::ostream& operator<<(std::ostream& o, Graphics::SamplerAddressMode addressMode)
83 case Graphics::SamplerAddressMode::REPEAT:
86 case Graphics::SamplerAddressMode::MIRRORED_REPEAT:
87 o << "MIRRORED_REPEAT";
89 case Graphics::SamplerAddressMode::CLAMP_TO_EDGE:
92 case Graphics::SamplerAddressMode::CLAMP_TO_BORDER:
93 o << "CLAMP_TO_BORDER";
95 case Graphics::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE:
96 o << "MIRROR_CLAMP_TO_EDGE";
102 std::ostream& operator<<(std::ostream& o, Graphics::SamplerFilter filterMode)
106 case Graphics::SamplerFilter::LINEAR:
109 case Graphics::SamplerFilter::NEAREST:
116 std::ostream& operator<<(std::ostream& o, Graphics::SamplerMipmapMode mipmapMode)
120 case Graphics::SamplerMipmapMode::NONE:
123 case Graphics::SamplerMipmapMode::LINEAR:
126 case Graphics::SamplerMipmapMode::NEAREST:
133 std::ostream& operator<<(std::ostream& o, const Graphics::SamplerCreateInfo& createInfo)
135 o << "minFilter:" << createInfo.minFilter
136 << " magFilter:" << createInfo.magFilter
137 << " wrapModeU:" << createInfo.addressModeU
138 << " wrapModeV:" << createInfo.addressModeV
139 << " wrapModeW:" << createInfo.addressModeW
140 << " mipMapMode:" << createInfo.mipMapMode;
144 class TestGraphicsMemory : public Graphics::Memory
147 TestGraphicsMemory(TraceCallStack& callStack, TestGraphicsBuffer& buffer, uint32_t mappedOffset, uint32_t mappedSize)
148 : mCallStack(callStack),
150 mMappedOffset(mappedOffset),
151 mMappedSize(mappedSize)
155 void* LockRegion(uint32_t offset, uint32_t size) override
157 std::ostringstream o;
158 o << offset << ", " << size;
159 mCallStack.PushCall("Memory::LockRegion", o.str());
161 if(offset > mMappedOffset + mMappedSize ||
162 size + offset > mMappedOffset + mMappedSize)
164 tet_infoline("TestGraphics.Memory::LockRegion() Out of bounds");
165 mBuffer.memory.resize(mMappedOffset + offset + size); // Grow to prevent memcpy from crashing
167 mLockedOffset = offset;
169 return &mBuffer.memory[mMappedOffset + offset];
172 void Unlock(bool flush) override
174 mCallStack.PushCall("Memory::Unlock", (flush ? "Flush" : "NoFlush"));
181 void Flush() override
183 mCallStack.PushCall("Memory::Flush", "");
185 mBuffer.Upload(mMappedOffset + mLockedOffset, mLockedSize);
189 TraceCallStack& mCallStack;
190 TestGraphicsBuffer& mBuffer;
191 uint32_t mMappedOffset;
192 uint32_t mMappedSize;
193 uint32_t mLockedOffset;
194 uint32_t mLockedSize;
197 TestGraphicsController::TestGraphicsController()
199 mCallStack.Enable(true);
200 mCallStack.EnableLogging(true);
201 mCommandBufferCallStack.Enable(true);
202 mCommandBufferCallStack.EnableLogging(true);
203 auto& trace = mGlAbstraction.GetTextureTrace();
205 trace.EnableLogging(true);
208 void TestGraphicsController::SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo)
210 std::ostringstream out;
211 TraceCallStack::NamedParams namedParams;
212 out << "cmdBuffer[" << submitInfo.cmdBuffer.size() << "], flags:" << std::hex << submitInfo.flags;
213 namedParams["submitInfo"] = out.str();
215 mCallStack.PushCall("Controller::SubmitCommandBuffers", "", namedParams);
217 for(auto& commandBuffer : submitInfo.cmdBuffer)
219 for(auto& binding : (static_cast<TestGraphicsCommandBuffer*>(commandBuffer))->mTextureBindings)
223 auto texture = const_cast<TestGraphicsTexture*>(static_cast<const TestGraphicsTexture*>(binding.texture));
225 texture->Bind(binding.binding);
229 auto sampler = const_cast<TestGraphicsSampler*>(static_cast<const TestGraphicsSampler*>(binding.sampler));
232 sampler->Apply(texture->GetTarget());
236 texture->Prepare(); // Ensure native texture is ready
243 * @brief Presents render target
244 * @param renderTarget render target to present
246 void TestGraphicsController::PresentRenderTarget(Graphics::RenderTarget* renderTarget)
248 std::ostringstream out;
249 TraceCallStack::NamedParams namedParams;
250 out << std::hex << renderTarget;
251 namedParams["renderTarget"] = out.str();
252 mCallStack.PushCall("Controller::PresentRenderTarget", "", namedParams);
256 * @brief Waits until the GPU is idle
258 void TestGraphicsController::WaitIdle()
260 mCallStack.PushCall("Controller::WaitIdle", "");
264 * @brief Lifecycle pause event
266 void TestGraphicsController::Pause()
268 mCallStack.PushCall("Controller::Pause", "");
272 * @brief Lifecycle resume event
274 void TestGraphicsController::Resume()
276 mCallStack.PushCall("Controller::Resume", "");
279 void TestGraphicsController::UpdateTextures(const std::vector<Graphics::TextureUpdateInfo>& updateInfoList,
280 const std::vector<Graphics::TextureUpdateSourceInfo>& sourceList)
282 std::ostringstream out;
283 TraceCallStack::NamedParams namedParams;
284 out << "[" << updateInfoList.size() << "]:";
285 namedParams["updateInfoList"] = out.str();
287 out << "[" << sourceList.size() << "]:";
288 namedParams["sourceList"] = out.str();
290 mCallStack.PushCall("Controller::UpdateTextures", "", namedParams);
292 // Call either TexImage2D or TexSubImage2D
293 for(unsigned int i = 0; i < updateInfoList.size(); ++i)
295 auto& updateInfo = updateInfoList[i];
296 auto& source = sourceList[i];
298 auto texture = static_cast<TestGraphicsTexture*>(updateInfo.dstTexture);
299 texture->Bind(0); // Use first texture unit during resource update
300 texture->Update(updateInfo, source);
304 bool TestGraphicsController::EnableDepthStencilBuffer(bool enableDepth, bool enableStencil)
306 TraceCallStack::NamedParams namedParams;
307 namedParams["enableDepth"] = enableDepth ? "T" : "F";
308 namedParams["enableStencil"] = enableStencil ? "T" : "F";
309 mCallStack.PushCall("Controller::EnableDepthStencilBuffer", "", namedParams);
313 void TestGraphicsController::RunGarbageCollector(size_t numberOfDiscardedRenderers)
315 std::ostringstream out;
316 out << numberOfDiscardedRenderers;
317 TraceCallStack::NamedParams namedParams;
318 namedParams["numberOfDiscardedrenderers"] = out.str();
319 mCallStack.PushCall("Controller::RunGarbageCollector", "", namedParams);
322 void TestGraphicsController::DiscardUnusedResources()
324 mCallStack.PushCall("Controller::DiscardUnusedResources", "");
327 bool TestGraphicsController::IsDiscardQueueEmpty()
329 mCallStack.PushCall("Controller::IsDiscardQueueEmpty", "");
330 return isDiscardQueueEmptyResult;
334 * @brief Test if the graphics subsystem has resumed & should force a draw
336 * @return true if the graphics subsystem requires a re-draw
338 bool TestGraphicsController::IsDrawOnResumeRequired()
340 mCallStack.PushCall("Controller::IsDrawOnResumeRequired", "");
341 return isDrawOnResumeRequiredResult;
344 Graphics::UniquePtr<Graphics::Buffer> TestGraphicsController::CreateBuffer(const Graphics::BufferCreateInfo& createInfo, Graphics::UniquePtr<Graphics::Buffer>&& oldBuffer)
346 std::ostringstream oss;
347 oss << "bufferCreateInfo:" << createInfo;
348 mCallStack.PushCall("Controller::CreateBuffer", oss.str());
349 return Graphics::MakeUnique<TestGraphicsBuffer>(mCallStack, mGlAbstraction, createInfo.size, createInfo.usage);
352 Graphics::UniquePtr<Graphics::CommandBuffer> TestGraphicsController::CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<Graphics::CommandBuffer>&& oldCommandBuffer)
354 std::ostringstream oss;
355 oss << "commandBufferCreateInfo:" << commandBufferCreateInfo;
356 mCallStack.PushCall("Controller::CreateCommandBuffer", oss.str());
357 return Graphics::MakeUnique<TestGraphicsCommandBuffer>(mCommandBufferCallStack, mGlAbstraction);
360 Graphics::UniquePtr<Graphics::RenderPass> TestGraphicsController::CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<Graphics::RenderPass>&& oldRenderPass)
362 mCallStack.PushCall("Controller::CreateRenderPass", "");
366 Graphics::UniquePtr<Graphics::Texture> TestGraphicsController::CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Graphics::Texture>&& oldTexture)
368 std::ostringstream params, oss;
369 params << "textureCreateInfo:" << textureCreateInfo;
370 TraceCallStack::NamedParams namedParams;
371 oss << textureCreateInfo;
372 namedParams["textureCreateInfo"] = oss.str();
373 mCallStack.PushCall("Controller::CreateTexture", params.str(), namedParams);
375 return Graphics::MakeUnique<TestGraphicsTexture>(mGlAbstraction, textureCreateInfo);
378 Graphics::UniquePtr<Graphics::Framebuffer> TestGraphicsController::CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Graphics::Framebuffer>&& oldFramebuffer)
380 mCallStack.PushCall("Controller::CreateFramebuffer", "");
384 Graphics::UniquePtr<Graphics::Pipeline> TestGraphicsController::CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Graphics::Pipeline>&& oldPipeline)
386 mCallStack.PushCall("Controller::CreatePipeline", "");
390 Graphics::UniquePtr<Graphics::Shader> TestGraphicsController::CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Graphics::Shader>&& oldShader)
392 mCallStack.PushCall("Controller::CreateShader", "");
396 Graphics::UniquePtr<Graphics::Sampler> TestGraphicsController::CreateSampler(const Graphics::SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Graphics::Sampler>&& oldSampler)
398 std::ostringstream params, oss;
399 params << "samplerCreateInfo:" << samplerCreateInfo;
400 TraceCallStack::NamedParams namedParams;
401 oss << samplerCreateInfo;
402 namedParams["samplerCreateInfo"] = oss.str();
403 mCallStack.PushCall("Controller::CreateSampler", params.str(), namedParams);
405 return Graphics::MakeUnique<TestGraphicsSampler>(mGlAbstraction, samplerCreateInfo);
408 Graphics::UniquePtr<Graphics::RenderTarget> TestGraphicsController::CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<Graphics::RenderTarget>&& oldRenderTarget)
410 mCallStack.PushCall("Controller::CreateRenderTarget", "");
414 Graphics::UniquePtr<Graphics::Memory> TestGraphicsController::MapBufferRange(const Graphics::MapBufferInfo& mapInfo)
416 mCallStack.PushCall("Controller::MapBufferRange", "");
418 auto buffer = static_cast<TestGraphicsBuffer*>(mapInfo.buffer);
419 buffer->memory.resize(mapInfo.offset + mapInfo.size); // For initial testing, allow writes past capacity
421 return std::make_unique<TestGraphicsMemory>(mCallStack, *buffer, mapInfo.offset, mapInfo.size);
424 Graphics::UniquePtr<Graphics::Memory> TestGraphicsController::MapTextureRange(const Graphics::MapTextureInfo& mapInfo)
426 mCallStack.PushCall("Controller::MapTextureRange", "");
430 void TestGraphicsController::UnmapMemory(Graphics::UniquePtr<Graphics::Memory> memory)
432 mCallStack.PushCall("Controller::UnmapMemory", "");
435 Graphics::MemoryRequirements TestGraphicsController::GetTextureMemoryRequirements(Graphics::Texture& texture) const
437 mCallStack.PushCall("Controller::GetTextureMemoryRequirements", "");
438 return Graphics::MemoryRequirements{};
441 Graphics::MemoryRequirements TestGraphicsController::GetBufferMemoryRequirements(Graphics::Buffer& buffer) const
443 mCallStack.PushCall("Controller::GetBufferMemoryRequirements", "");
444 return Graphics::MemoryRequirements{};
447 const Graphics::TextureProperties& TestGraphicsController::GetTextureProperties(const Graphics::Texture& texture)
449 static Graphics::TextureProperties textureProperties{};
450 mCallStack.PushCall("Controller::GetTextureProperties", "");
452 return textureProperties;
455 bool TestGraphicsController::PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const
457 mCallStack.PushCall("Controller::PipelineEquals", "");