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-framebuffer.h"
22 #include "test-graphics-reflection.h"
23 #include "test-graphics-sampler.h"
24 #include "test-graphics-shader.h"
25 #include "test-graphics-texture.h"
27 #include <dali/integration-api/gl-defines.h>
34 std::ostream& operator<<(std::ostream& o, const Graphics::BufferCreateInfo& bufferCreateInfo)
36 return o << "usage:" << std::hex << bufferCreateInfo.usage << ", size:" << std::dec << bufferCreateInfo.size;
39 std::ostream& operator<<(std::ostream& o, const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo)
41 return o << "level:" << (commandBufferCreateInfo.level == Graphics::CommandBufferLevel::PRIMARY ? "PRIMARY" : "SECONDARY")
42 << ", fixedCapacity:" << std::dec << commandBufferCreateInfo.fixedCapacity;
45 std::ostream& operator<<(std::ostream& o, const Graphics::TextureType& textureType)
49 case Graphics::TextureType::TEXTURE_2D:
52 case Graphics::TextureType::TEXTURE_3D:
55 case Graphics::TextureType::TEXTURE_CUBEMAP:
56 o << "TEXTURE_CUBEMAP";
62 std::ostream& operator<<(std::ostream& o, const Graphics::Extent2D extent)
64 o << "width:" << extent.width << ", height:" << extent.height;
68 std::ostream& operator<<(std::ostream& o, const Graphics::TextureCreateInfo& createInfo)
70 o << "textureType:" << createInfo.textureType
71 << " size:" << createInfo.size
72 << " format:" << static_cast<uint32_t>(createInfo.format)
73 << " mipMapFlag:" << createInfo.mipMapFlag
74 << " layout:" << (createInfo.layout == Graphics::TextureLayout::LINEAR ? "LINEAR" : "OPTIMAL")
75 << " usageFlags:" << std::hex << createInfo.usageFlags
76 << " data:" << std::hex << createInfo.data
77 << " dataSize:" << std::dec << createInfo.dataSize
78 << " nativeImagePtr:" << std::hex << createInfo.nativeImagePtr;
82 std::ostream& operator<<(std::ostream& o, Graphics::SamplerAddressMode addressMode)
86 case Graphics::SamplerAddressMode::REPEAT:
89 case Graphics::SamplerAddressMode::MIRRORED_REPEAT:
90 o << "MIRRORED_REPEAT";
92 case Graphics::SamplerAddressMode::CLAMP_TO_EDGE:
95 case Graphics::SamplerAddressMode::CLAMP_TO_BORDER:
96 o << "CLAMP_TO_BORDER";
98 case Graphics::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE:
99 o << "MIRROR_CLAMP_TO_EDGE";
105 std::ostream& operator<<(std::ostream& o, Graphics::SamplerFilter filterMode)
109 case Graphics::SamplerFilter::LINEAR:
112 case Graphics::SamplerFilter::NEAREST:
119 std::ostream& operator<<(std::ostream& o, Graphics::SamplerMipmapMode mipmapMode)
123 case Graphics::SamplerMipmapMode::NONE:
126 case Graphics::SamplerMipmapMode::LINEAR:
129 case Graphics::SamplerMipmapMode::NEAREST:
136 std::ostream& operator<<(std::ostream& o, const Graphics::SamplerCreateInfo& createInfo)
138 o << "minFilter:" << createInfo.minFilter
139 << " magFilter:" << createInfo.magFilter
140 << " wrapModeU:" << createInfo.addressModeU
141 << " wrapModeV:" << createInfo.addressModeV
142 << " wrapModeW:" << createInfo.addressModeW
143 << " mipMapMode:" << createInfo.mipMapMode;
147 std::ostream& operator<<(std::ostream& o, const Graphics::ColorAttachment& colorAttachment)
149 o << "attachmentId:" << colorAttachment.attachmentId
150 << " layerId:" << colorAttachment.layerId
151 << " levelId:" << colorAttachment.levelId
152 << " texture:" << colorAttachment.texture;
156 std::ostream& operator<<(std::ostream& o, const Graphics::DepthStencilAttachment& depthStencilAttachment)
158 o << "depthTexture:" << depthStencilAttachment.depthTexture
159 << "depthLevel:" << depthStencilAttachment.depthLevel
160 << "stencilTexture:" << depthStencilAttachment.stencilTexture
161 << "stencilLevel:" << depthStencilAttachment.stencilLevel;
165 std::ostream& operator<<(std::ostream& o, const Graphics::FramebufferCreateInfo& createInfo)
167 o << "colorAttachments:";
168 for(auto i = 0u; i < createInfo.colorAttachments.size(); ++i)
170 o << "[" << i << "]=" << createInfo.colorAttachments[i] << " ";
172 o << "depthStencilAttachment:" << createInfo.depthStencilAttachment;
173 o << "size: " << createInfo.size;
178 int GetNumComponents(Graphics::VertexInputFormat vertexFormat)
182 case Graphics::VertexInputFormat::UNDEFINED:
183 case Graphics::VertexInputFormat::FLOAT:
184 case Graphics::VertexInputFormat::INTEGER:
186 case Graphics::VertexInputFormat::IVECTOR2:
187 case Graphics::VertexInputFormat::FVECTOR2:
189 case Graphics::VertexInputFormat::IVECTOR3:
190 case Graphics::VertexInputFormat::FVECTOR3:
192 case Graphics::VertexInputFormat::FVECTOR4:
193 case Graphics::VertexInputFormat::IVECTOR4:
199 GLint GetSize(Graphics::VertexInputFormat vertexFormat)
203 case Graphics::VertexInputFormat::UNDEFINED:
205 case Graphics::VertexInputFormat::INTEGER:
206 case Graphics::VertexInputFormat::IVECTOR2:
207 case Graphics::VertexInputFormat::IVECTOR3:
208 case Graphics::VertexInputFormat::IVECTOR4:
210 case Graphics::VertexInputFormat::FLOAT:
211 case Graphics::VertexInputFormat::FVECTOR2:
212 case Graphics::VertexInputFormat::FVECTOR3:
213 case Graphics::VertexInputFormat::FVECTOR4:
219 GLint GetGlType(Graphics::VertexInputFormat vertexFormat)
223 case Graphics::VertexInputFormat::UNDEFINED:
225 case Graphics::VertexInputFormat::INTEGER:
226 case Graphics::VertexInputFormat::IVECTOR2:
227 case Graphics::VertexInputFormat::IVECTOR3:
228 case Graphics::VertexInputFormat::IVECTOR4:
230 case Graphics::VertexInputFormat::FLOAT:
231 case Graphics::VertexInputFormat::FVECTOR2:
232 case Graphics::VertexInputFormat::FVECTOR3:
233 case Graphics::VertexInputFormat::FVECTOR4:
239 GLenum GetTopology(Graphics::PrimitiveTopology topology)
243 case Graphics::PrimitiveTopology::POINT_LIST:
246 case Graphics::PrimitiveTopology::LINE_LIST:
249 case Graphics::PrimitiveTopology::LINE_LOOP:
252 case Graphics::PrimitiveTopology::LINE_STRIP:
253 return GL_LINE_STRIP;
255 case Graphics::PrimitiveTopology::TRIANGLE_LIST:
258 case Graphics::PrimitiveTopology::TRIANGLE_STRIP:
259 return GL_TRIANGLE_STRIP;
261 case Graphics::PrimitiveTopology::TRIANGLE_FAN:
262 return GL_TRIANGLE_FAN;
267 GLenum GetCullFace(Graphics::CullMode cullMode)
271 case Graphics::CullMode::NONE:
273 case Graphics::CullMode::FRONT:
275 case Graphics::CullMode::BACK:
277 case Graphics::CullMode::FRONT_AND_BACK:
278 return GL_FRONT_AND_BACK;
283 GLenum GetFrontFace(Graphics::FrontFace frontFace)
285 if(frontFace == Graphics::FrontFace::CLOCKWISE)
292 GLenum GetBlendFactor(Graphics::BlendFactor blendFactor)
294 GLenum glFactor = GL_ZERO;
298 case Graphics::BlendFactor::ZERO:
301 case Graphics::BlendFactor::ONE:
304 case Graphics::BlendFactor::SRC_COLOR:
305 glFactor = GL_SRC_COLOR;
307 case Graphics::BlendFactor::ONE_MINUS_SRC_COLOR:
308 glFactor = GL_ONE_MINUS_SRC_COLOR;
310 case Graphics::BlendFactor::DST_COLOR:
311 glFactor = GL_DST_COLOR;
313 case Graphics::BlendFactor::ONE_MINUS_DST_COLOR:
314 glFactor = GL_ONE_MINUS_DST_COLOR;
316 case Graphics::BlendFactor::SRC_ALPHA:
317 glFactor = GL_SRC_ALPHA;
319 case Graphics::BlendFactor::ONE_MINUS_SRC_ALPHA:
320 glFactor = GL_ONE_MINUS_SRC_ALPHA;
322 case Graphics::BlendFactor::DST_ALPHA:
323 glFactor = GL_DST_ALPHA;
325 case Graphics::BlendFactor::ONE_MINUS_DST_ALPHA:
326 glFactor = GL_ONE_MINUS_DST_ALPHA;
328 case Graphics::BlendFactor::CONSTANT_COLOR:
329 glFactor = GL_CONSTANT_COLOR;
331 case Graphics::BlendFactor::ONE_MINUS_CONSTANT_COLOR:
332 glFactor = GL_ONE_MINUS_CONSTANT_COLOR;
334 case Graphics::BlendFactor::CONSTANT_ALPHA:
335 glFactor = GL_CONSTANT_ALPHA;
337 case Graphics::BlendFactor::ONE_MINUS_CONSTANT_ALPHA:
338 glFactor = GL_ONE_MINUS_CONSTANT_ALPHA;
340 case Graphics::BlendFactor::SRC_ALPHA_SATURATE:
341 glFactor = GL_SRC_ALPHA_SATURATE;
343 // GLES doesn't appear to have dual source blending.
344 case Graphics::BlendFactor::SRC1_COLOR:
345 glFactor = GL_SRC_COLOR;
347 case Graphics::BlendFactor::ONE_MINUS_SRC1_COLOR:
348 glFactor = GL_ONE_MINUS_SRC_COLOR;
350 case Graphics::BlendFactor::SRC1_ALPHA:
351 glFactor = GL_SRC_ALPHA;
353 case Graphics::BlendFactor::ONE_MINUS_SRC1_ALPHA:
354 glFactor = GL_ONE_MINUS_SRC_ALPHA;
360 GLenum GetBlendOp(Graphics::BlendOp blendOp)
362 GLenum op = GL_FUNC_ADD;
365 case Graphics::BlendOp::ADD:
368 case Graphics::BlendOp::SUBTRACT:
369 op = GL_FUNC_SUBTRACT;
371 case Graphics::BlendOp::REVERSE_SUBTRACT:
372 op = GL_FUNC_REVERSE_SUBTRACT;
374 case Graphics::BlendOp::MIN:
377 case Graphics::BlendOp::MAX:
381 // @todo Add advanced blend equations
387 class TestGraphicsMemory : public Graphics::Memory
390 TestGraphicsMemory(TraceCallStack& callStack, TestGraphicsBuffer& buffer, uint32_t mappedOffset, uint32_t mappedSize)
391 : mCallStack(callStack),
393 mMappedOffset(mappedOffset),
394 mMappedSize(mappedSize),
400 void* LockRegion(uint32_t offset, uint32_t size) override
402 std::ostringstream o;
403 o << offset << ", " << size;
404 mCallStack.PushCall("Memory::LockRegion", o.str());
406 if(offset > mMappedOffset + mMappedSize ||
407 size + offset > mMappedOffset + mMappedSize)
409 fprintf(stderr, "TestGraphics.Memory::LockRegion() Out of bounds");
410 mBuffer.memory.resize(mMappedOffset + offset + size); // Grow to prevent memcpy from crashing
412 mLockedOffset = offset;
414 return &mBuffer.memory[mMappedOffset + offset];
417 void Unlock(bool flush) override
419 mCallStack.PushCall("Memory::Unlock", (flush ? "Flush" : "NoFlush"));
426 void Flush() override
428 mCallStack.PushCall("Memory::Flush", "");
430 mBuffer.Upload(mMappedOffset + mLockedOffset, mLockedSize);
434 TraceCallStack& mCallStack;
435 TestGraphicsBuffer& mBuffer;
436 uint32_t mMappedOffset;
437 uint32_t mMappedSize;
438 uint32_t mLockedOffset;
439 uint32_t mLockedSize;
442 TestGraphicsController::TestGraphicsController()
443 : mCallStack(true, "TestGraphicsController."),
444 mCommandBufferCallStack(true, "TestCommandBuffer."),
445 mFrameBufferCallStack(true, "TestFrameBuffer.")
447 mCallStack.Enable(true);
448 mCommandBufferCallStack.Enable(true);
449 auto& trace = mGl.GetTextureTrace();
451 trace.EnableLogging(true);
455 void TestGraphicsController::SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo)
457 TraceCallStack::NamedParams namedParams;
458 namedParams["submitInfo"] << "cmdBuffer[" << submitInfo.cmdBuffer.size()
459 << "], flags:" << std::hex << submitInfo.flags;
461 mCallStack.PushCall("SubmitCommandBuffers", "", namedParams);
463 mSubmitStack.emplace_back(submitInfo);
465 for(auto& graphicsCommandBuffer : submitInfo.cmdBuffer)
467 auto commandBuffer = Uncast<TestGraphicsCommandBuffer>(graphicsCommandBuffer);
469 // Change framebuffer
470 auto bindPipelineCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_PIPELINE);
471 if(!bindPipelineCmds.empty())
473 auto pipeline = bindPipelineCmds[0]->data.bindPipeline.pipeline;
474 auto framebuffer = pipeline->framebufferState.framebuffer;
477 auto graphicsFramebuffer = Uncast<TestGraphicsFramebuffer>(framebuffer);
478 graphicsFramebuffer->Bind();
482 mGl.BindFramebuffer(GL_FRAMEBUFFER, 0);
486 auto value = commandBuffer->GetCommandsByType(0 | CommandType::BIND_TEXTURES);
490 for(auto& binding : value[0]->data.bindTextures.textureBindings)
494 auto texture = Uncast<TestGraphicsTexture>(binding.texture);
496 texture->Bind(binding.binding);
500 auto sampler = Uncast<TestGraphicsSampler>(binding.sampler);
503 sampler->Apply(texture->GetTarget());
507 texture->Prepare(); // Ensure native texture is ready
512 // IndexBuffer binding,
513 auto bindIndexBufferCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_INDEX_BUFFER);
514 if(!bindIndexBufferCmds.empty())
516 auto& indexBufferBinding = bindIndexBufferCmds[0]->data.bindIndexBuffer;
517 if(indexBufferBinding.buffer)
519 auto buffer = Uncast<TestGraphicsBuffer>(indexBufferBinding.buffer);
524 // VertexBuffer binding,
525 auto bindVertexBufferCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_VERTEX_BUFFERS);
526 if(!bindVertexBufferCmds.empty())
528 for(auto& binding : bindVertexBufferCmds[0]->data.bindVertexBuffers.vertexBufferBindings)
530 auto graphicsBuffer = binding.buffer;
531 auto vertexBuffer = Uncast<TestGraphicsBuffer>(graphicsBuffer);
532 vertexBuffer->Bind();
536 bool scissorEnabled = false;
538 auto scissorTestList = commandBuffer->GetCommandsByType(0 | CommandType::SET_SCISSOR_TEST);
539 if(!scissorTestList.empty())
541 if(scissorTestList[0]->data.scissorTest.enable)
543 mGl.Enable(GL_SCISSOR_TEST);
544 scissorEnabled = true;
548 mGl.Disable(GL_SCISSOR_TEST);
552 auto scissorList = commandBuffer->GetCommandsByType(0 | CommandType::SET_SCISSOR);
553 if(!scissorList.empty() && scissorEnabled)
555 auto& rect = scissorList[0]->data.scissor.region;
556 mGl.Scissor(rect.x, rect.y, rect.width, rect.height);
559 auto viewportList = commandBuffer->GetCommandsByType(0 | CommandType::SET_VIEWPORT);
560 if(!viewportList.empty())
562 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);
565 // ignore viewport enable
567 // Pipeline attribute setup
568 if(!bindPipelineCmds.empty())
570 auto pipeline = bindPipelineCmds[0]->data.bindPipeline.pipeline;
571 auto& vi = pipeline->vertexInputState;
572 for(auto& attribute : vi.attributes)
574 mGl.EnableVertexAttribArray(attribute.location);
575 uint32_t attributeOffset = attribute.offset;
576 GLsizei stride = vi.bufferBindings[attribute.binding].stride;
578 mGl.VertexAttribPointer(attribute.location,
579 GetNumComponents(attribute.format),
580 GetGlType(attribute.format),
581 GL_FALSE, // Not normalized
583 reinterpret_cast<void*>(attributeOffset));
587 auto& rasterizationState = pipeline->rasterizationState;
588 if(rasterizationState.cullMode == Graphics::CullMode::NONE)
590 mGl.Disable(GL_CULL_FACE);
594 mGl.Enable(GL_CULL_FACE);
595 mGl.CullFace(GetCullFace(rasterizationState.cullMode));
598 mGl.FrontFace(GetFrontFace(rasterizationState.frontFace));
599 // We don't modify glPolygonMode in our context/abstraction from GL_FILL (the GL default),
600 // so it isn't present in the API (and won't have any tests!)
603 auto& colorBlendState = pipeline->colorBlendState;
604 if(colorBlendState.blendEnable)
606 mGl.Enable(GL_BLEND);
608 mGl.BlendFuncSeparate(GetBlendFactor(colorBlendState.srcColorBlendFactor),
609 GetBlendFactor(colorBlendState.dstColorBlendFactor),
610 GetBlendFactor(colorBlendState.srcAlphaBlendFactor),
611 GetBlendFactor(colorBlendState.dstAlphaBlendFactor));
612 if(colorBlendState.colorBlendOp != colorBlendState.alphaBlendOp)
614 mGl.BlendEquationSeparate(GetBlendOp(colorBlendState.colorBlendOp), GetBlendOp(colorBlendState.alphaBlendOp));
618 mGl.BlendEquation(GetBlendOp(colorBlendState.colorBlendOp));
620 mGl.BlendColor(colorBlendState.blendConstants[0],
621 colorBlendState.blendConstants[1],
622 colorBlendState.blendConstants[2],
623 colorBlendState.blendConstants[3]);
627 mGl.Disable(GL_BLEND);
631 auto topology = pipeline->inputAssemblyState.topology;
633 // UniformBuffer binding (once we know pipeline)
634 auto bindUniformBuffersCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_UNIFORM_BUFFER);
635 if(!bindUniformBuffersCmds.empty())
637 auto buffer = bindUniformBuffersCmds[0]->data.bindUniformBuffers.standaloneUniformsBufferBinding;
639 // based on reflection, issue gl calls
640 buffer.buffer->BindAsUniformBuffer(static_cast<const TestGraphicsProgram*>(pipeline->programState.program));
643 auto drawCmds = commandBuffer->GetCommandsByType(0 |
645 CommandType::DRAW_INDEXED_INDIRECT |
646 CommandType::DRAW_INDEXED);
648 if(!drawCmds.empty())
650 if(drawCmds[0]->data.draw.type == DrawCallDescriptor::Type::DRAW_INDEXED)
652 mGl.DrawElements(GetTopology(topology),
653 static_cast<GLsizei>(drawCmds[0]->data.draw.drawIndexed.indexCount),
655 reinterpret_cast<void*>(drawCmds[0]->data.draw.drawIndexed.firstIndex));
659 mGl.DrawArrays(GetTopology(topology), 0, drawCmds[0]->data.draw.draw.vertexCount);
663 for(auto& attribute : vi.attributes)
665 mGl.DisableVertexAttribArray(attribute.location);
672 * @brief Presents render target
673 * @param renderTarget render target to present
675 void TestGraphicsController::PresentRenderTarget(Graphics::RenderTarget* renderTarget)
677 TraceCallStack::NamedParams namedParams;
678 namedParams["renderTarget"] << std::hex << renderTarget;
679 mCallStack.PushCall("PresentRenderTarget", "", namedParams);
683 * @brief Waits until the GPU is idle
685 void TestGraphicsController::WaitIdle()
687 mCallStack.PushCall("WaitIdle", "");
691 * @brief Lifecycle pause event
693 void TestGraphicsController::Pause()
695 mCallStack.PushCall("Pause", "");
699 * @brief Lifecycle resume event
701 void TestGraphicsController::Resume()
703 mCallStack.PushCall("Resume", "");
706 void TestGraphicsController::Shutdown()
708 mCallStack.PushCall("Shutdown", "");
711 void TestGraphicsController::Destroy()
713 mCallStack.PushCall("Destroy", "");
716 void TestGraphicsController::UpdateTextures(const std::vector<Graphics::TextureUpdateInfo>& updateInfoList,
717 const std::vector<Graphics::TextureUpdateSourceInfo>& sourceList)
719 TraceCallStack::NamedParams namedParams;
720 namedParams["updateInfoList"] << "[" << updateInfoList.size() << "]:";
721 namedParams["sourceList"] << "[" << sourceList.size() << "]:";
723 mCallStack.PushCall("UpdateTextures", "", namedParams);
725 // Call either TexImage2D or TexSubImage2D
726 for(unsigned int i = 0; i < updateInfoList.size(); ++i)
728 auto& updateInfo = updateInfoList[i];
729 auto& source = sourceList[i];
731 auto texture = static_cast<TestGraphicsTexture*>(updateInfo.dstTexture);
732 texture->Bind(0); // Use first texture unit during resource update
733 texture->Update(updateInfo, source);
737 bool TestGraphicsController::EnableDepthStencilBuffer(bool enableDepth, bool enableStencil)
739 TraceCallStack::NamedParams namedParams;
740 namedParams["enableDepth"] << (enableDepth ? "T" : "F");
741 namedParams["enableStencil"] << (enableStencil ? "T" : "F");
742 mCallStack.PushCall("EnableDepthStencilBuffer", "", namedParams);
746 void TestGraphicsController::RunGarbageCollector(size_t numberOfDiscardedRenderers)
748 TraceCallStack::NamedParams namedParams;
749 namedParams["numberOfDiscardedRenderers"] << numberOfDiscardedRenderers;
750 mCallStack.PushCall("RunGarbageCollector", "", namedParams);
753 void TestGraphicsController::DiscardUnusedResources()
755 mCallStack.PushCall("DiscardUnusedResources", "");
758 bool TestGraphicsController::IsDiscardQueueEmpty()
760 mCallStack.PushCall("IsDiscardQueueEmpty", "");
761 return isDiscardQueueEmptyResult;
765 * @brief Test if the graphics subsystem has resumed & should force a draw
767 * @return true if the graphics subsystem requires a re-draw
769 bool TestGraphicsController::IsDrawOnResumeRequired()
771 mCallStack.PushCall("IsDrawOnResumeRequired", "");
772 return isDrawOnResumeRequiredResult;
775 Graphics::UniquePtr<Graphics::Buffer> TestGraphicsController::CreateBuffer(const Graphics::BufferCreateInfo& createInfo, Graphics::UniquePtr<Graphics::Buffer>&& oldBuffer)
777 std::ostringstream oss;
778 oss << "bufferCreateInfo:" << createInfo;
779 mCallStack.PushCall("CreateBuffer", oss.str());
780 return Graphics::MakeUnique<TestGraphicsBuffer>(mCallStack, mGl, createInfo.size, createInfo.usage);
783 Graphics::UniquePtr<Graphics::CommandBuffer> TestGraphicsController::CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<Graphics::CommandBuffer>&& oldCommandBuffer)
785 std::ostringstream oss;
786 oss << "commandBufferCreateInfo:" << commandBufferCreateInfo;
787 mCallStack.PushCall("CreateCommandBuffer", oss.str());
788 return Graphics::MakeUnique<TestGraphicsCommandBuffer>(mCommandBufferCallStack, mGl);
791 Graphics::UniquePtr<Graphics::RenderPass> TestGraphicsController::CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<Graphics::RenderPass>&& oldRenderPass)
793 mCallStack.PushCall("CreateRenderPass", "");
797 Graphics::UniquePtr<Graphics::Texture> TestGraphicsController::CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Graphics::Texture>&& oldTexture)
799 TraceCallStack::NamedParams namedParams;
800 namedParams["textureCreateInfo"] << textureCreateInfo;
801 mCallStack.PushCall("CreateTexture", namedParams.str(), namedParams);
803 return Graphics::MakeUnique<TestGraphicsTexture>(mGl, textureCreateInfo);
806 Graphics::UniquePtr<Graphics::Framebuffer> TestGraphicsController::CreateFramebuffer(
807 const Graphics::FramebufferCreateInfo& createInfo,
808 Graphics::UniquePtr<Graphics::Framebuffer>&& oldFramebuffer)
810 TraceCallStack::NamedParams namedParams;
811 namedParams["framebufferCreateInfo"] << createInfo;
812 mCallStack.PushCall("Controller::CreateFramebuffer", namedParams.str(), namedParams);
814 return Graphics::MakeUnique<TestGraphicsFramebuffer>(mFrameBufferCallStack, mGl, createInfo);
817 Graphics::UniquePtr<Graphics::Pipeline> TestGraphicsController::CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Graphics::Pipeline>&& oldPipeline)
819 mCallStack.PushCall("CreatePipeline", "");
820 return std::make_unique<TestGraphicsPipeline>(mGl, pipelineCreateInfo);
823 Graphics::UniquePtr<Graphics::Program> TestGraphicsController::CreateProgram(const Graphics::ProgramCreateInfo& programCreateInfo, Graphics::UniquePtr<Graphics::Program>&& oldProgram)
825 mCallStack.PushCall("CreateProgram", "");
827 for(auto cacheEntry : mProgramCache)
830 for(auto& shader : *(programCreateInfo.shaderState))
832 auto graphicsShader = Uncast<TestGraphicsShader>(shader.shader);
833 std::vector<uint8_t> source;
834 source.resize(graphicsShader->mCreateInfo.sourceSize);
835 memcpy(&source[0], graphicsShader->mCreateInfo.sourceData, graphicsShader->mCreateInfo.sourceSize);
837 if(!std::equal(source.begin(), source.end(), cacheEntry.shaders[shader.pipelineStage].begin()))
845 return Graphics::MakeUnique<TestGraphicsProgram>(cacheEntry.programImpl);
849 mProgramCache.emplace_back();
850 mProgramCache.back().programImpl = new TestGraphicsProgramImpl(mGl, programCreateInfo, mVertexFormats, mCustomUniforms);
851 for(auto& shader : *(programCreateInfo.shaderState))
853 auto graphicsShader = Uncast<TestGraphicsShader>(shader.shader);
854 mProgramCache.back().shaders[shader.pipelineStage].resize(graphicsShader->mCreateInfo.sourceSize);
855 memcpy(&mProgramCache.back().shaders[shader.pipelineStage][0], graphicsShader->mCreateInfo.sourceData, graphicsShader->mCreateInfo.sourceSize);
857 return Graphics::MakeUnique<TestGraphicsProgram>(mProgramCache.back().programImpl);
860 Graphics::UniquePtr<Graphics::Shader> TestGraphicsController::CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Graphics::Shader>&& oldShader)
862 mCallStack.PushCall("CreateShader", "");
863 return Graphics::MakeUnique<TestGraphicsShader>(mGl, shaderCreateInfo);
866 Graphics::UniquePtr<Graphics::Sampler> TestGraphicsController::CreateSampler(const Graphics::SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Graphics::Sampler>&& oldSampler)
868 TraceCallStack::NamedParams namedParams;
869 namedParams["samplerCreateInfo"] << samplerCreateInfo;
870 mCallStack.PushCall("CreateSampler", namedParams.str(), namedParams);
872 return Graphics::MakeUnique<TestGraphicsSampler>(mGl, samplerCreateInfo);
875 Graphics::UniquePtr<Graphics::RenderTarget> TestGraphicsController::CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<Graphics::RenderTarget>&& oldRenderTarget)
877 mCallStack.PushCall("CreateRenderTarget", "");
881 Graphics::UniquePtr<Graphics::Memory> TestGraphicsController::MapBufferRange(const Graphics::MapBufferInfo& mapInfo)
883 mCallStack.PushCall("MapBufferRange", "");
885 auto buffer = static_cast<TestGraphicsBuffer*>(mapInfo.buffer);
886 buffer->memory.resize(mapInfo.offset + mapInfo.size); // For initial testing, allow writes past capacity
888 return std::make_unique<TestGraphicsMemory>(mCallStack, *buffer, mapInfo.offset, mapInfo.size);
891 Graphics::UniquePtr<Graphics::Memory> TestGraphicsController::MapTextureRange(const Graphics::MapTextureInfo& mapInfo)
893 mCallStack.PushCall("MapTextureRange", "");
897 void TestGraphicsController::UnmapMemory(Graphics::UniquePtr<Graphics::Memory> memory)
899 mCallStack.PushCall("UnmapMemory", "");
902 Graphics::MemoryRequirements TestGraphicsController::GetTextureMemoryRequirements(Graphics::Texture& texture) const
904 mCallStack.PushCall("GetTextureMemoryRequirements", "");
905 return Graphics::MemoryRequirements{};
908 Graphics::MemoryRequirements TestGraphicsController::GetBufferMemoryRequirements(Graphics::Buffer& buffer) const
910 mCallStack.PushCall("GetBufferMemoryRequirements", "");
911 return Graphics::MemoryRequirements{};
914 const Graphics::TextureProperties& TestGraphicsController::GetTextureProperties(const Graphics::Texture& texture)
916 static Graphics::TextureProperties textureProperties{};
917 mCallStack.PushCall("GetTextureProperties", "");
919 return textureProperties;
922 const Graphics::Reflection& TestGraphicsController::GetProgramReflection(const Graphics::Program& program)
924 mCallStack.PushCall("GetProgramReflection", "");
926 return static_cast<const TestGraphicsProgram*>(&program)->GetReflection();
929 bool TestGraphicsController::PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const
931 mCallStack.PushCall("PipelineEquals", "");
935 bool TestGraphicsController::GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData)
937 mCallStack.PushCall("GetProgramParameter", "");
938 auto graphicsProgram = Uncast<TestGraphicsProgram>(&program);
939 return graphicsProgram->GetParameter(parameterId, outData);