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 "test-graphics-buffer.h"
20 #include "test-graphics-command-buffer.h"
21 #include "test-graphics-reflection.h"
22 #include "test-graphics-sampler.h"
23 #include "test-graphics-shader.h"
24 #include "test-graphics-texture.h"
26 #include <dali/integration-api/gl-defines.h>
34 T* Uncast(const Graphics::CommandBuffer* object)
36 return const_cast<T*>(static_cast<const T*>(object));
40 T* Uncast(const Graphics::Texture* object)
42 return const_cast<T*>(static_cast<const T*>(object));
46 T* Uncast(const Graphics::Sampler* object)
48 return const_cast<T*>(static_cast<const T*>(object));
52 T* Uncast(const Graphics::Buffer* object)
54 return const_cast<T*>(static_cast<const T*>(object));
58 T* Uncast(const Graphics::Shader* object)
60 return const_cast<T*>(static_cast<const T*>(object));
63 std::ostream& operator<<(std::ostream& o, const Graphics::BufferCreateInfo& bufferCreateInfo)
65 return o << "usage:" << std::hex << bufferCreateInfo.usage << ", size:" << std::dec << bufferCreateInfo.size;
68 std::ostream& operator<<(std::ostream& o, const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo)
70 return o << "level:" << (commandBufferCreateInfo.level == Graphics::CommandBufferLevel::PRIMARY ? "PRIMARY" : "SECONDARY")
71 << ", fixedCapacity:" << std::dec << commandBufferCreateInfo.fixedCapacity;
74 std::ostream& operator<<(std::ostream& o, const Graphics::TextureType& textureType)
78 case Graphics::TextureType::TEXTURE_2D:
81 case Graphics::TextureType::TEXTURE_3D:
84 case Graphics::TextureType::TEXTURE_CUBEMAP:
85 o << "TEXTURE_CUBEMAP";
91 std::ostream& operator<<(std::ostream& o, const Graphics::Extent2D extent)
93 o << "width:" << extent.width << ", height:" << extent.height;
97 std::ostream& operator<<(std::ostream& o, const Graphics::TextureCreateInfo& createInfo)
99 o << "textureType:" << createInfo.textureType
100 << " size:" << createInfo.size
101 << " format:" << static_cast<uint32_t>(createInfo.format)
102 << " mipMapFlag:" << createInfo.mipMapFlag
103 << " layout:" << (createInfo.layout == Graphics::TextureLayout::LINEAR ? "LINEAR" : "OPTIMAL")
104 << " usageFlags:" << std::hex << createInfo.usageFlags
105 << " data:" << std::hex << createInfo.data
106 << " dataSize:" << std::dec << createInfo.dataSize
107 << " nativeImagePtr:" << std::hex << createInfo.nativeImagePtr;
111 std::ostream& operator<<(std::ostream& o, Graphics::SamplerAddressMode addressMode)
115 case Graphics::SamplerAddressMode::REPEAT:
118 case Graphics::SamplerAddressMode::MIRRORED_REPEAT:
119 o << "MIRRORED_REPEAT";
121 case Graphics::SamplerAddressMode::CLAMP_TO_EDGE:
122 o << "CLAMP_TO_EDGE";
124 case Graphics::SamplerAddressMode::CLAMP_TO_BORDER:
125 o << "CLAMP_TO_BORDER";
127 case Graphics::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE:
128 o << "MIRROR_CLAMP_TO_EDGE";
134 std::ostream& operator<<(std::ostream& o, Graphics::SamplerFilter filterMode)
138 case Graphics::SamplerFilter::LINEAR:
141 case Graphics::SamplerFilter::NEAREST:
148 std::ostream& operator<<(std::ostream& o, Graphics::SamplerMipmapMode mipmapMode)
152 case Graphics::SamplerMipmapMode::NONE:
155 case Graphics::SamplerMipmapMode::LINEAR:
158 case Graphics::SamplerMipmapMode::NEAREST:
165 std::ostream& operator<<(std::ostream& o, const Graphics::SamplerCreateInfo& createInfo)
167 o << "minFilter:" << createInfo.minFilter
168 << " magFilter:" << createInfo.magFilter
169 << " wrapModeU:" << createInfo.addressModeU
170 << " wrapModeV:" << createInfo.addressModeV
171 << " wrapModeW:" << createInfo.addressModeW
172 << " mipMapMode:" << createInfo.mipMapMode;
176 class TestGraphicsMemory : public Graphics::Memory
179 TestGraphicsMemory(TraceCallStack& callStack, TestGraphicsBuffer& buffer, uint32_t mappedOffset, uint32_t mappedSize)
180 : mCallStack(callStack),
182 mMappedOffset(mappedOffset),
183 mMappedSize(mappedSize),
189 void* LockRegion(uint32_t offset, uint32_t size) override
191 std::ostringstream o;
192 o << offset << ", " << size;
193 mCallStack.PushCall("Memory::LockRegion", o.str());
195 if(offset > mMappedOffset + mMappedSize ||
196 size + offset > mMappedOffset + mMappedSize)
198 fprintf(stderr, "TestGraphics.Memory::LockRegion() Out of bounds");
199 mBuffer.memory.resize(mMappedOffset + offset + size); // Grow to prevent memcpy from crashing
201 mLockedOffset = offset;
203 return &mBuffer.memory[mMappedOffset + offset];
206 void Unlock(bool flush) override
208 mCallStack.PushCall("Memory::Unlock", (flush ? "Flush" : "NoFlush"));
215 void Flush() override
217 mCallStack.PushCall("Memory::Flush", "");
219 mBuffer.Upload(mMappedOffset + mLockedOffset, mLockedSize);
223 TraceCallStack& mCallStack;
224 TestGraphicsBuffer& mBuffer;
225 uint32_t mMappedOffset;
226 uint32_t mMappedSize;
227 uint32_t mLockedOffset;
228 uint32_t mLockedSize;
231 TestGraphicsController::TestGraphicsController()
232 : mCallStack(true, "TestGraphicsController."),
233 mCommandBufferCallStack(true, "TestCommandBuffer.")
235 mCallStack.Enable(true);
236 mCommandBufferCallStack.Enable(true);
237 auto& trace = mGl.GetTextureTrace();
239 trace.EnableLogging(true);
242 int GetNumComponents(Graphics::VertexInputFormat vertexFormat)
246 case Graphics::VertexInputFormat::UNDEFINED:
247 case Graphics::VertexInputFormat::FLOAT:
248 case Graphics::VertexInputFormat::INTEGER:
250 case Graphics::VertexInputFormat::IVECTOR2:
251 case Graphics::VertexInputFormat::FVECTOR2:
253 case Graphics::VertexInputFormat::IVECTOR3:
254 case Graphics::VertexInputFormat::FVECTOR3:
256 case Graphics::VertexInputFormat::FVECTOR4:
257 case Graphics::VertexInputFormat::IVECTOR4:
263 GLint GetSize(Graphics::VertexInputFormat vertexFormat)
267 case Graphics::VertexInputFormat::UNDEFINED:
269 case Graphics::VertexInputFormat::INTEGER:
270 case Graphics::VertexInputFormat::IVECTOR2:
271 case Graphics::VertexInputFormat::IVECTOR3:
272 case Graphics::VertexInputFormat::IVECTOR4:
274 case Graphics::VertexInputFormat::FLOAT:
275 case Graphics::VertexInputFormat::FVECTOR2:
276 case Graphics::VertexInputFormat::FVECTOR3:
277 case Graphics::VertexInputFormat::FVECTOR4:
283 GLint GetGlType(Graphics::VertexInputFormat vertexFormat)
287 case Graphics::VertexInputFormat::UNDEFINED:
289 case Graphics::VertexInputFormat::INTEGER:
290 case Graphics::VertexInputFormat::IVECTOR2:
291 case Graphics::VertexInputFormat::IVECTOR3:
292 case Graphics::VertexInputFormat::IVECTOR4:
294 case Graphics::VertexInputFormat::FLOAT:
295 case Graphics::VertexInputFormat::FVECTOR2:
296 case Graphics::VertexInputFormat::FVECTOR3:
297 case Graphics::VertexInputFormat::FVECTOR4:
303 GLenum GetTopology(Graphics::PrimitiveTopology topology)
307 case Graphics::PrimitiveTopology::POINT_LIST:
310 case Graphics::PrimitiveTopology::LINE_LIST:
313 case Graphics::PrimitiveTopology::LINE_LOOP:
316 case Graphics::PrimitiveTopology::LINE_STRIP:
317 return GL_LINE_STRIP;
319 case Graphics::PrimitiveTopology::TRIANGLE_LIST:
322 case Graphics::PrimitiveTopology::TRIANGLE_STRIP:
323 return GL_TRIANGLE_STRIP;
325 case Graphics::PrimitiveTopology::TRIANGLE_FAN:
326 return GL_TRIANGLE_FAN;
331 GLenum GetCullFace(Graphics::CullMode cullMode)
335 case Graphics::CullMode::NONE:
337 case Graphics::CullMode::FRONT:
339 case Graphics::CullMode::BACK:
341 case Graphics::CullMode::FRONT_AND_BACK:
342 return GL_FRONT_AND_BACK;
347 GLenum GetFrontFace(Graphics::FrontFace frontFace)
349 if(frontFace == Graphics::FrontFace::CLOCKWISE)
356 GLenum GetBlendFactor(Graphics::BlendFactor blendFactor)
358 GLenum glFactor = GL_ZERO;
362 case Graphics::BlendFactor::ZERO:
365 case Graphics::BlendFactor::ONE:
368 case Graphics::BlendFactor::SRC_COLOR:
369 glFactor = GL_SRC_COLOR;
371 case Graphics::BlendFactor::ONE_MINUS_SRC_COLOR:
372 glFactor = GL_ONE_MINUS_SRC_COLOR;
374 case Graphics::BlendFactor::DST_COLOR:
375 glFactor = GL_DST_COLOR;
377 case Graphics::BlendFactor::ONE_MINUS_DST_COLOR:
378 glFactor = GL_ONE_MINUS_DST_COLOR;
380 case Graphics::BlendFactor::SRC_ALPHA:
381 glFactor = GL_SRC_ALPHA;
383 case Graphics::BlendFactor::ONE_MINUS_SRC_ALPHA:
384 glFactor = GL_ONE_MINUS_SRC_ALPHA;
386 case Graphics::BlendFactor::DST_ALPHA:
387 glFactor = GL_DST_ALPHA;
389 case Graphics::BlendFactor::ONE_MINUS_DST_ALPHA:
390 glFactor = GL_ONE_MINUS_DST_ALPHA;
392 case Graphics::BlendFactor::CONSTANT_COLOR:
393 glFactor = GL_CONSTANT_COLOR;
395 case Graphics::BlendFactor::ONE_MINUS_CONSTANT_COLOR:
396 glFactor = GL_ONE_MINUS_CONSTANT_COLOR;
398 case Graphics::BlendFactor::CONSTANT_ALPHA:
399 glFactor = GL_CONSTANT_ALPHA;
401 case Graphics::BlendFactor::ONE_MINUS_CONSTANT_ALPHA:
402 glFactor = GL_ONE_MINUS_CONSTANT_ALPHA;
404 case Graphics::BlendFactor::SRC_ALPHA_SATURATE:
405 glFactor = GL_SRC_ALPHA_SATURATE;
407 // GLES doesn't appear to have dual source blending.
408 case Graphics::BlendFactor::SRC1_COLOR:
409 glFactor = GL_SRC_COLOR;
411 case Graphics::BlendFactor::ONE_MINUS_SRC1_COLOR:
412 glFactor = GL_ONE_MINUS_SRC_COLOR;
414 case Graphics::BlendFactor::SRC1_ALPHA:
415 glFactor = GL_SRC_ALPHA;
417 case Graphics::BlendFactor::ONE_MINUS_SRC1_ALPHA:
418 glFactor = GL_ONE_MINUS_SRC_ALPHA;
424 GLenum GetBlendOp(Graphics::BlendOp blendOp)
426 GLenum op = GL_FUNC_ADD;
429 case Graphics::BlendOp::ADD:
432 case Graphics::BlendOp::SUBTRACT:
433 op = GL_FUNC_SUBTRACT;
435 case Graphics::BlendOp::REVERSE_SUBTRACT:
436 op = GL_FUNC_REVERSE_SUBTRACT;
438 case Graphics::BlendOp::MIN:
441 case Graphics::BlendOp::MAX:
445 // @todo Add advanced blend equations
450 void TestGraphicsController::SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo)
452 TraceCallStack::NamedParams namedParams;
453 namedParams["submitInfo"] << "cmdBuffer[" << submitInfo.cmdBuffer.size()
454 << "], flags:" << std::hex << submitInfo.flags;
456 mCallStack.PushCall("SubmitCommandBuffers", "", namedParams);
458 mSubmitStack.emplace_back(submitInfo);
460 for(auto& graphicsCommandBuffer : submitInfo.cmdBuffer)
462 auto commandBuffer = Uncast<TestGraphicsCommandBuffer>(graphicsCommandBuffer);
464 auto value = commandBuffer->GetCommandsByType(0 | CommandType::BIND_TEXTURES);
468 for(auto& binding : value[0]->data.bindTextures.textureBindings)
472 auto texture = Uncast<TestGraphicsTexture>(binding.texture);
474 texture->Bind(binding.binding);
478 auto sampler = Uncast<TestGraphicsSampler>(binding.sampler);
481 sampler->Apply(texture->GetTarget());
485 texture->Prepare(); // Ensure native texture is ready
490 // IndexBuffer binding,
491 auto bindIndexBufferCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_INDEX_BUFFER);
492 if(!bindIndexBufferCmds.empty())
494 auto& indexBufferBinding = bindIndexBufferCmds[0]->data.bindIndexBuffer;
495 if(indexBufferBinding.buffer)
497 auto buffer = Uncast<TestGraphicsBuffer>(indexBufferBinding.buffer);
502 // VertexBuffer binding,
503 auto bindVertexBufferCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_VERTEX_BUFFERS);
504 if(!bindVertexBufferCmds.empty())
506 for(auto& binding : bindVertexBufferCmds[0]->data.bindVertexBuffers.vertexBufferBindings)
508 auto graphicsBuffer = binding.buffer;
509 auto vertexBuffer = Uncast<TestGraphicsBuffer>(graphicsBuffer);
510 vertexBuffer->Bind();
514 bool scissorEnabled = false;
516 auto scissorTestList = commandBuffer->GetCommandsByType(0 | CommandType::SET_SCISSOR_TEST);
517 if(!scissorTestList.empty())
519 if(scissorTestList[0]->data.scissorTest.enable)
521 mGl.Enable(GL_SCISSOR_TEST);
522 scissorEnabled = true;
526 mGl.Disable(GL_SCISSOR_TEST);
530 auto scissorList = commandBuffer->GetCommandsByType(0 | CommandType::SET_SCISSOR);
531 if(!scissorList.empty() && scissorEnabled)
533 auto& rect = scissorList[0]->data.scissor.region;
534 mGl.Scissor(rect.x, rect.y, rect.width, rect.height);
537 auto viewportList = commandBuffer->GetCommandsByType(0 | CommandType::SET_VIEWPORT);
538 if(!viewportList.empty())
540 mGl.Viewport(viewportList[0]->data.viewport.region.x, viewportList[0]->data.viewport.region.y, viewportList[0]->data.viewport.region.width, viewportList[0]->data.viewport.region.height);
543 // ignore viewport enable
545 // Pipeline attribute setup
546 auto bindPipelineCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_PIPELINE);
547 if(!bindPipelineCmds.empty())
549 auto pipeline = bindPipelineCmds[0]->data.bindPipeline.pipeline;
550 auto& vi = pipeline->vertexInputState;
551 for(auto& attribute : vi.attributes)
553 mGl.EnableVertexAttribArray(attribute.location);
554 uint32_t attributeOffset = attribute.offset;
555 GLsizei stride = vi.bufferBindings[attribute.binding].stride;
557 mGl.VertexAttribPointer(attribute.location,
558 GetNumComponents(attribute.format),
559 GetGlType(attribute.format),
560 GL_FALSE, // Not normalized
562 reinterpret_cast<void*>(attributeOffset));
566 auto& rasterizationState = pipeline->rasterizationState;
567 if(rasterizationState.cullMode == Graphics::CullMode::NONE)
569 mGl.Disable(GL_CULL_FACE);
573 mGl.Enable(GL_CULL_FACE);
574 mGl.CullFace(GetCullFace(rasterizationState.cullMode));
577 mGl.FrontFace(GetFrontFace(rasterizationState.frontFace));
578 // We don't modify glPolygonMode in our context/abstraction from GL_FILL (the GL default),
579 // so it isn't present in the API (and won't have any tests!)
582 auto& colorBlendState = pipeline->colorBlendState;
583 if(colorBlendState.blendEnable)
585 mGl.Enable(GL_BLEND);
587 mGl.BlendFuncSeparate(GetBlendFactor(colorBlendState.srcColorBlendFactor),
588 GetBlendFactor(colorBlendState.dstColorBlendFactor),
589 GetBlendFactor(colorBlendState.srcAlphaBlendFactor),
590 GetBlendFactor(colorBlendState.dstAlphaBlendFactor));
591 if(colorBlendState.colorBlendOp != colorBlendState.alphaBlendOp)
593 mGl.BlendEquationSeparate(GetBlendOp(colorBlendState.colorBlendOp), GetBlendOp(colorBlendState.alphaBlendOp));
597 mGl.BlendEquation(GetBlendOp(colorBlendState.colorBlendOp));
599 mGl.BlendColor(colorBlendState.blendConstants[0],
600 colorBlendState.blendConstants[1],
601 colorBlendState.blendConstants[2],
602 colorBlendState.blendConstants[3]);
606 mGl.Disable(GL_BLEND);
610 auto topology = pipeline->inputAssemblyState.topology;
612 // UniformBuffer binding (once we know pipeline)
613 auto bindUniformBuffersCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_UNIFORM_BUFFER);
614 if(!bindUniformBuffersCmds.empty())
616 auto buffer = bindUniformBuffersCmds[0]->data.bindUniformBuffers.standaloneUniformsBufferBinding;
618 // based on reflection, issue gl calls
619 buffer.buffer->BindAsUniformBuffer(static_cast<const TestGraphicsProgram*>(pipeline->programState.program));
622 auto drawCmds = commandBuffer->GetCommandsByType(0 |
624 CommandType::DRAW_INDEXED_INDIRECT |
625 CommandType::DRAW_INDEXED);
627 if(!drawCmds.empty())
629 if(drawCmds[0]->data.draw.type == DrawCallDescriptor::Type::DRAW_INDEXED)
631 mGl.DrawElements(GetTopology(topology),
632 static_cast<GLsizei>(drawCmds[0]->data.draw.drawIndexed.indexCount),
634 reinterpret_cast<void*>(drawCmds[0]->data.draw.drawIndexed.firstIndex));
638 mGl.DrawArrays(GetTopology(topology), 0, drawCmds[0]->data.draw.draw.vertexCount);
642 for(auto& attribute : vi.attributes)
644 mGl.DisableVertexAttribArray(attribute.location);
651 * @brief Presents render target
652 * @param renderTarget render target to present
654 void TestGraphicsController::PresentRenderTarget(Graphics::RenderTarget* renderTarget)
656 TraceCallStack::NamedParams namedParams;
657 namedParams["renderTarget"] << std::hex << renderTarget;
658 mCallStack.PushCall("PresentRenderTarget", "", namedParams);
662 * @brief Waits until the GPU is idle
664 void TestGraphicsController::WaitIdle()
666 mCallStack.PushCall("WaitIdle", "");
670 * @brief Lifecycle pause event
672 void TestGraphicsController::Pause()
674 mCallStack.PushCall("Pause", "");
678 * @brief Lifecycle resume event
680 void TestGraphicsController::Resume()
682 mCallStack.PushCall("Resume", "");
685 void TestGraphicsController::UpdateTextures(const std::vector<Graphics::TextureUpdateInfo>& updateInfoList,
686 const std::vector<Graphics::TextureUpdateSourceInfo>& sourceList)
688 TraceCallStack::NamedParams namedParams;
689 namedParams["updateInfoList"] << "[" << updateInfoList.size() << "]:";
690 namedParams["sourceList"] << "[" << sourceList.size() << "]:";
692 mCallStack.PushCall("UpdateTextures", "", namedParams);
694 // Call either TexImage2D or TexSubImage2D
695 for(unsigned int i = 0; i < updateInfoList.size(); ++i)
697 auto& updateInfo = updateInfoList[i];
698 auto& source = sourceList[i];
700 auto texture = static_cast<TestGraphicsTexture*>(updateInfo.dstTexture);
701 texture->Bind(0); // Use first texture unit during resource update
702 texture->Update(updateInfo, source);
706 bool TestGraphicsController::EnableDepthStencilBuffer(bool enableDepth, bool enableStencil)
708 TraceCallStack::NamedParams namedParams;
709 namedParams["enableDepth"] << (enableDepth ? "T" : "F");
710 namedParams["enableStencil"] << (enableStencil ? "T" : "F");
711 mCallStack.PushCall("EnableDepthStencilBuffer", "", namedParams);
715 void TestGraphicsController::RunGarbageCollector(size_t numberOfDiscardedRenderers)
717 TraceCallStack::NamedParams namedParams;
718 namedParams["numberOfDiscardedRenderers"] << numberOfDiscardedRenderers;
719 mCallStack.PushCall("RunGarbageCollector", "", namedParams);
722 void TestGraphicsController::DiscardUnusedResources()
724 mCallStack.PushCall("DiscardUnusedResources", "");
727 bool TestGraphicsController::IsDiscardQueueEmpty()
729 mCallStack.PushCall("IsDiscardQueueEmpty", "");
730 return isDiscardQueueEmptyResult;
734 * @brief Test if the graphics subsystem has resumed & should force a draw
736 * @return true if the graphics subsystem requires a re-draw
738 bool TestGraphicsController::IsDrawOnResumeRequired()
740 mCallStack.PushCall("IsDrawOnResumeRequired", "");
741 return isDrawOnResumeRequiredResult;
744 Graphics::UniquePtr<Graphics::Buffer> TestGraphicsController::CreateBuffer(const Graphics::BufferCreateInfo& createInfo, Graphics::UniquePtr<Graphics::Buffer>&& oldBuffer)
746 std::ostringstream oss;
747 oss << "bufferCreateInfo:" << createInfo;
748 mCallStack.PushCall("CreateBuffer", oss.str());
749 return Graphics::MakeUnique<TestGraphicsBuffer>(mCallStack, mGl, createInfo.size, createInfo.usage);
752 Graphics::UniquePtr<Graphics::CommandBuffer> TestGraphicsController::CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<Graphics::CommandBuffer>&& oldCommandBuffer)
754 std::ostringstream oss;
755 oss << "commandBufferCreateInfo:" << commandBufferCreateInfo;
756 mCallStack.PushCall("CreateCommandBuffer", oss.str());
757 return Graphics::MakeUnique<TestGraphicsCommandBuffer>(mCommandBufferCallStack, mGl);
760 Graphics::UniquePtr<Graphics::RenderPass> TestGraphicsController::CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<Graphics::RenderPass>&& oldRenderPass)
762 mCallStack.PushCall("CreateRenderPass", "");
766 Graphics::UniquePtr<Graphics::Texture> TestGraphicsController::CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Graphics::Texture>&& oldTexture)
768 TraceCallStack::NamedParams namedParams;
769 namedParams["textureCreateInfo"] << textureCreateInfo;
770 mCallStack.PushCall("CreateTexture", namedParams.str(), namedParams);
772 return Graphics::MakeUnique<TestGraphicsTexture>(mGl, textureCreateInfo);
775 Graphics::UniquePtr<Graphics::Framebuffer> TestGraphicsController::CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Graphics::Framebuffer>&& oldFramebuffer)
777 mCallStack.PushCall("CreateFramebuffer", "");
781 Graphics::UniquePtr<Graphics::Pipeline> TestGraphicsController::CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Graphics::Pipeline>&& oldPipeline)
783 mCallStack.PushCall("CreatePipeline", "");
784 return std::make_unique<TestGraphicsPipeline>(mGl, pipelineCreateInfo);
787 Graphics::UniquePtr<Graphics::Program> TestGraphicsController::CreateProgram(const Graphics::ProgramCreateInfo& programCreateInfo, Graphics::UniquePtr<Graphics::Program>&& oldProgram)
789 mCallStack.PushCall("CreateProgram", "");
791 for(auto cacheEntry : mProgramCache)
794 for(auto& shader : *(programCreateInfo.shaderState))
796 auto graphicsShader = Uncast<TestGraphicsShader>(shader.shader);
797 std::vector<uint8_t> source;
798 source.resize(graphicsShader->mCreateInfo.sourceSize);
799 memcpy(&source[0], graphicsShader->mCreateInfo.sourceData, graphicsShader->mCreateInfo.sourceSize);
801 if(!std::equal(source.begin(), source.end(), cacheEntry.shaders[shader.pipelineStage].begin()))
809 return Graphics::MakeUnique<TestGraphicsProgram>(cacheEntry.programImpl);
813 mProgramCache.emplace_back();
814 mProgramCache.back().programImpl = new TestGraphicsProgramImpl(mGl, programCreateInfo, mVertexFormats, mCustomUniforms);
815 for(auto& shader : *(programCreateInfo.shaderState))
817 auto graphicsShader = Uncast<TestGraphicsShader>(shader.shader);
818 mProgramCache.back().shaders[shader.pipelineStage].resize(graphicsShader->mCreateInfo.sourceSize);
819 memcpy(&mProgramCache.back().shaders[shader.pipelineStage][0], graphicsShader->mCreateInfo.sourceData, graphicsShader->mCreateInfo.sourceSize);
821 return Graphics::MakeUnique<TestGraphicsProgram>(mProgramCache.back().programImpl);
824 Graphics::UniquePtr<Graphics::Shader> TestGraphicsController::CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Graphics::Shader>&& oldShader)
826 mCallStack.PushCall("CreateShader", "");
827 return Graphics::MakeUnique<TestGraphicsShader>(mGl, shaderCreateInfo);
830 Graphics::UniquePtr<Graphics::Sampler> TestGraphicsController::CreateSampler(const Graphics::SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Graphics::Sampler>&& oldSampler)
832 TraceCallStack::NamedParams namedParams;
833 namedParams["samplerCreateInfo"] << samplerCreateInfo;
834 mCallStack.PushCall("CreateSampler", namedParams.str(), namedParams);
836 return Graphics::MakeUnique<TestGraphicsSampler>(mGl, samplerCreateInfo);
839 Graphics::UniquePtr<Graphics::RenderTarget> TestGraphicsController::CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<Graphics::RenderTarget>&& oldRenderTarget)
841 mCallStack.PushCall("CreateRenderTarget", "");
845 Graphics::UniquePtr<Graphics::Memory> TestGraphicsController::MapBufferRange(const Graphics::MapBufferInfo& mapInfo)
847 mCallStack.PushCall("MapBufferRange", "");
849 auto buffer = static_cast<TestGraphicsBuffer*>(mapInfo.buffer);
850 buffer->memory.resize(mapInfo.offset + mapInfo.size); // For initial testing, allow writes past capacity
852 return std::make_unique<TestGraphicsMemory>(mCallStack, *buffer, mapInfo.offset, mapInfo.size);
855 Graphics::UniquePtr<Graphics::Memory> TestGraphicsController::MapTextureRange(const Graphics::MapTextureInfo& mapInfo)
857 mCallStack.PushCall("MapTextureRange", "");
861 void TestGraphicsController::UnmapMemory(Graphics::UniquePtr<Graphics::Memory> memory)
863 mCallStack.PushCall("UnmapMemory", "");
866 Graphics::MemoryRequirements TestGraphicsController::GetTextureMemoryRequirements(Graphics::Texture& texture) const
868 mCallStack.PushCall("GetTextureMemoryRequirements", "");
869 return Graphics::MemoryRequirements{};
872 Graphics::MemoryRequirements TestGraphicsController::GetBufferMemoryRequirements(Graphics::Buffer& buffer) const
874 mCallStack.PushCall("GetBufferMemoryRequirements", "");
875 return Graphics::MemoryRequirements{};
878 const Graphics::TextureProperties& TestGraphicsController::GetTextureProperties(const Graphics::Texture& texture)
880 static Graphics::TextureProperties textureProperties{};
881 mCallStack.PushCall("GetTextureProperties", "");
883 return textureProperties;
886 const Graphics::Reflection& TestGraphicsController::GetProgramReflection(const Graphics::Program& program)
888 mCallStack.PushCall("GetProgramReflection", "");
890 return static_cast<const TestGraphicsProgram*>(&program)->GetReflection();
893 bool TestGraphicsController::PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const
895 mCallStack.PushCall("PipelineEquals", "");
899 bool TestGraphicsController::GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData)
901 mCallStack.PushCall("GetProgramParameter", "");
902 auto graphicsProgram = Uncast<TestGraphicsProgram>(&program);
903 return graphicsProgram->GetParameter(parameterId, outData);