Quellcode durchsuchen

Nuke GL and add the skeleton for DX12

Panagiotis Christopoulos Charitos vor 1 Jahr
Ursprung
Commit
4136b81fb8
77 geänderte Dateien mit 1397 neuen und 6976 gelöschten Zeilen
  1. 1 1
      .clang-format-hlsl
  2. 21 0
      AnKi/Gr/CMakeLists.txt
  3. 32 0
      AnKi/Gr/D3D/D3DAccelerationStructure.cpp
  4. 34 0
      AnKi/Gr/D3D/D3DAccelerationStructure.h
  5. 55 0
      AnKi/Gr/D3D/D3DBuffer.cpp
  6. 30 0
      AnKi/Gr/D3D/D3DBuffer.h
  7. 382 0
      AnKi/Gr/D3D/D3DCommandBuffer.cpp
  8. 32 0
      AnKi/Gr/D3D/D3DCommandBuffer.h
  9. 23 0
      AnKi/Gr/D3D/D3DCommon.h
  10. 21 0
      AnKi/Gr/D3D/D3DFence.cpp
  11. 8 10
      AnKi/Gr/D3D/D3DFence.h
  12. 33 0
      AnKi/Gr/D3D/D3DFramebuffer.cpp
  13. 30 0
      AnKi/Gr/D3D/D3DFramebuffer.h
  14. 123 0
      AnKi/Gr/D3D/D3DGrManager.cpp
  15. 38 0
      AnKi/Gr/D3D/D3DGrManager.h
  16. 32 0
      AnKi/Gr/D3D/D3DGrUpscaler.cpp
  17. 29 0
      AnKi/Gr/D3D/D3DGrUpscaler.h
  18. 38 0
      AnKi/Gr/D3D/D3DPipelineQuery.cpp
  19. 31 0
      AnKi/Gr/D3D/D3DPipelineQuery.h
  20. 32 0
      AnKi/Gr/D3D/D3DSampler.cpp
  21. 30 0
      AnKi/Gr/D3D/D3DSampler.h
  22. 32 0
      AnKi/Gr/D3D/D3DShader.cpp
  23. 30 0
      AnKi/Gr/D3D/D3DShader.h
  24. 45 0
      AnKi/Gr/D3D/D3DShaderProgram.cpp
  25. 30 0
      AnKi/Gr/D3D/D3DShaderProgram.h
  26. 33 0
      AnKi/Gr/D3D/D3DTexture.cpp
  27. 30 0
      AnKi/Gr/D3D/D3DTexture.h
  28. 28 0
      AnKi/Gr/D3D/D3DTextureView.cpp
  29. 36 0
      AnKi/Gr/D3D/D3DTextureView.h
  30. 38 0
      AnKi/Gr/D3D/D3DTimestampQuery.cpp
  31. 31 0
      AnKi/Gr/D3D/D3DTimestampQuery.h
  32. 0 63
      AnKi/Gr/Gl/Buffer.cpp
  33. 0 82
      AnKi/Gr/Gl/BufferImpl.cpp
  34. 0 117
      AnKi/Gr/Gl/BufferImpl.h
  35. 0 1566
      AnKi/Gr/Gl/CommandBuffer.cpp
  36. 0 334
      AnKi/Gr/Gl/CommandBufferImpl.cpp
  37. 0 132
      AnKi/Gr/Gl/CommandBufferImpl.h
  38. 0 468
      AnKi/Gr/Gl/Common.cpp
  39. 0 183
      AnKi/Gr/Gl/Common.h
  40. 0 50
      AnKi/Gr/Gl/Error.cpp
  41. 0 29
      AnKi/Gr/Gl/Error.h
  42. 0 105
      AnKi/Gr/Gl/Fence.cpp
  43. 0 54
      AnKi/Gr/Gl/FenceImpl.cpp
  44. 0 50
      AnKi/Gr/Gl/Framebuffer.cpp
  45. 0 256
      AnKi/Gr/Gl/FramebufferImpl.cpp
  46. 0 62
      AnKi/Gr/Gl/FramebufferImpl.h
  47. 0 89
      AnKi/Gr/Gl/GlObject.cpp
  48. 0 72
      AnKi/Gr/Gl/GlObject.h
  49. 0 199
      AnKi/Gr/Gl/GlState.cpp
  50. 0 73
      AnKi/Gr/Gl/GlState.h
  51. 0 152
      AnKi/Gr/Gl/GrManager.cpp
  52. 0 96
      AnKi/Gr/Gl/GrManagerImpl.cpp
  53. 0 81
      AnKi/Gr/Gl/GrManagerImpl.h
  54. 0 116
      AnKi/Gr/Gl/GrManagerImplSdl.cpp
  55. 0 50
      AnKi/Gr/Gl/OcclusionQuery.cpp
  56. 0 44
      AnKi/Gr/Gl/OcclusionQueryImpl.cpp
  57. 0 44
      AnKi/Gr/Gl/OcclusionQueryImpl.h
  58. 0 317
      AnKi/Gr/Gl/RenderingThread.cpp
  59. 0 92
      AnKi/Gr/Gl/RenderingThread.h
  60. 0 51
      AnKi/Gr/Gl/Sampler.cpp
  61. 0 57
      AnKi/Gr/Gl/SamplerImpl.cpp
  62. 0 34
      AnKi/Gr/Gl/SamplerImpl.h
  63. 0 70
      AnKi/Gr/Gl/Shader.cpp
  64. 0 153
      AnKi/Gr/Gl/ShaderImpl.cpp
  65. 0 41
      AnKi/Gr/Gl/ShaderImpl.h
  66. 0 66
      AnKi/Gr/Gl/ShaderProgram.cpp
  67. 0 201
      AnKi/Gr/Gl/ShaderProgramImpl.cpp
  68. 0 57
      AnKi/Gr/Gl/ShaderProgramImpl.h
  69. 0 585
      AnKi/Gr/Gl/StateTracker.h
  70. 0 54
      AnKi/Gr/Gl/Texture.cpp
  71. 0 417
      AnKi/Gr/Gl/TextureImpl.cpp
  72. 0 76
      AnKi/Gr/Gl/TextureImpl.h
  73. 0 52
      AnKi/Gr/Gl/TextureView.cpp
  74. 0 24
      AnKi/Gr/Gl/TextureViewImpl.cpp
  75. 0 44
      AnKi/Gr/Gl/TextureViewImpl.h
  76. 2 2
      AnKi/Shaders/Functions.hlsl
  77. 7 5
      CMakeLists.txt

+ 1 - 1
.clang-format-hlsl

@@ -164,7 +164,7 @@ SpacesInParentheses: false
 SpacesInSquareBrackets: false
 SpaceBeforeSquareBrackets: false
 BitFieldColonSpacing: Both
-Standard:        Latest
+Standard:        Cpp03
 StatementAttributeLikeMacros:
   - Q_EMIT
 StatementMacros:

+ 21 - 0
AnKi/Gr/CMakeLists.txt

@@ -123,6 +123,27 @@ if(VULKAN)
 	elseif(ANDROID)
 		set(backend_sources ${backend_sources} "Vulkan/GrManagerImplAndroid.cpp")
 	endif()
+elseif(DIRECTX)
+	set(backend_sources  ${backend_sources}
+		D3D/D3DGrManager.cpp
+		D3D/D3DBuffer.cpp
+		D3D/D3DCommandBuffer.cpp
+		D3D/D3DShader.cpp
+		D3D/D3DShaderProgram.cpp
+		D3D/D3DFence.cpp
+		D3D/D3DTexture.cpp
+		D3D/D3DTextureView.cpp
+		D3D/D3DPipelineQuery.cpp
+		D3D/D3DSampler.cpp
+		D3D/D3DFramebuffer.cpp
+		D3D/D3DGrUpscaler.cpp
+		D3D/D3DAccelerationStructure.cpp
+		D3D/D3DTimestampQuery.cpp)
+
+	set(backend_headers ${backend_headers}
+		D3D/D3DGrManager.h
+		D3D/D3DGrUpscaler.h
+		D3D/D3DCommon.h)
 endif()
 
 # Have 2 libraries. The AnKiGrCommon is the bare minimum for the AnKiShaderCompiler to work. Don't have

+ 32 - 0
AnKi/Gr/D3D/D3DAccelerationStructure.cpp

@@ -0,0 +1,32 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/D3D/D3DAccelerationStructure.h>
+
+namespace anki {
+
+AccelerationStructure* AccelerationStructure::newInstance(const AccelerationStructureInitInfo& init)
+{
+	AccelerationStructureImpl* impl = anki::newInstance<AccelerationStructureImpl>(GrMemoryPool::getSingleton(), init.getName());
+	const Error err = impl->init(init);
+	if(err)
+	{
+		deleteInstance(GrMemoryPool::getSingleton(), impl);
+		impl = nullptr;
+	}
+	return impl;
+}
+
+U64 AccelerationStructure::getGpuAddress() const
+{
+	ANKI_ASSERT(!"TODO");
+	return 0;
+}
+
+AccelerationStructureImpl::~AccelerationStructureImpl()
+{
+}
+
+} // end namespace anki

+ 34 - 0
AnKi/Gr/D3D/D3DAccelerationStructure.h

@@ -0,0 +1,34 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/AccelerationStructure.h>
+
+namespace anki {
+
+/// @addtogroup vulkan
+/// @{
+
+/// AccelerationStructure implementation.
+class AccelerationStructureImpl final : public AccelerationStructure
+{
+public:
+	AccelerationStructureImpl(CString name)
+		: AccelerationStructure(name)
+	{
+	}
+
+	~AccelerationStructureImpl();
+
+	Error init(const AccelerationStructureInitInfo& inf)
+	{
+		ANKI_ASSERT(!"TODO");
+		return Error::kNone;
+	}
+};
+/// @}
+
+} // end namespace anki

+ 55 - 0
AnKi/Gr/D3D/D3DBuffer.cpp

@@ -0,0 +1,55 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/Buffer.h>
+#include <AnKi/Gr/Vulkan/BufferImpl.h>
+#include <AnKi/Gr/GrManager.h>
+
+namespace anki {
+
+Buffer* Buffer::newInstance(const BufferInitInfo& init)
+{
+	BufferImpl* impl = anki::newInstance<BufferImpl>(GrMemoryPool::getSingleton(), init.getName());
+	const Error err = impl->init(init);
+	if(err)
+	{
+		deleteInstance(GrMemoryPool::getSingleton(), impl);
+		impl = nullptr;
+	}
+	return impl;
+}
+
+void* Buffer::map(PtrSize offset, PtrSize range, BufferMapAccessBit access)
+{
+	ANKI_ASSERT(!"TODO");
+	return nullptr;
+}
+
+void Buffer::unmap()
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void Buffer::flush(PtrSize offset, PtrSize range) const
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void Buffer::invalidate(PtrSize offset, PtrSize range) const
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+BufferImpl::~BufferImpl()
+{
+}
+
+Error BufferImpl::init(const BufferInitInfo& inf)
+{
+	ANKI_ASSERT(!"TODO");
+	return Error::kNone;
+}
+
+} // end namespace anki

+ 30 - 0
AnKi/Gr/D3D/D3DBuffer.h

@@ -0,0 +1,30 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/Buffer.h>
+
+namespace anki {
+
+/// @addtogroup directx
+/// @{
+
+/// Buffer implementation
+class BufferImpl final : public Buffer
+{
+public:
+	BufferImpl(CString name)
+		: Buffer(name)
+	{
+	}
+
+	~BufferImpl();
+
+	Error init(const BufferInitInfo& inf);
+};
+/// @}
+
+} // end namespace anki

+ 382 - 0
AnKi/Gr/D3D/D3DCommandBuffer.cpp

@@ -0,0 +1,382 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/D3D/D3DCommandBuffer.h>
+#include <AnKi/Util/Tracer.h>
+
+namespace anki {
+
+CommandBuffer* CommandBuffer::newInstance(const CommandBufferInitInfo& init)
+{
+	ANKI_TRACE_SCOPED_EVENT(D3DNewCommandBuffer);
+	CommandBufferImpl* impl = anki::newInstance<CommandBufferImpl>(GrMemoryPool::getSingleton(), init.getName());
+	const Error err = impl->init(init);
+	if(err)
+	{
+		deleteInstance(GrMemoryPool::getSingleton(), impl);
+		impl = nullptr;
+	}
+	return impl;
+}
+
+void CommandBuffer::flush(ConstWeakArray<FencePtr> waitFences, FencePtr* signalFence)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::bindVertexBuffer(U32 binding, Buffer* buff, PtrSize offset, PtrSize stride, VertexStepRate stepRate)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setVertexAttribute(U32 location, U32 buffBinding, Format fmt, PtrSize relativeOffset)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::bindIndexBuffer(Buffer* buff, PtrSize offset, IndexType type)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setPrimitiveRestart(Bool enable)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setViewport(U32 minx, U32 miny, U32 width, U32 height)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setScissor(U32 minx, U32 miny, U32 width, U32 height)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setFillMode(FillMode mode)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setCullMode(FaceSelectionBit mode)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setPolygonOffset(F32 factor, F32 units)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setStencilOperations(FaceSelectionBit face, StencilOperation stencilFail, StencilOperation stencilPassDepthFail,
+										 StencilOperation stencilPassDepthPass)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setStencilCompareOperation(FaceSelectionBit face, CompareOperation comp)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setStencilCompareMask(FaceSelectionBit face, U32 mask)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setStencilWriteMask(FaceSelectionBit face, U32 mask)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setStencilReference(FaceSelectionBit face, U32 ref)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setDepthWrite(Bool enable)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setDepthCompareOperation(CompareOperation op)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setAlphaToCoverage(Bool enable)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setColorChannelWriteMask(U32 attachment, ColorBit mask)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setBlendFactors(U32 attachment, BlendFactor srcRgb, BlendFactor dstRgb, BlendFactor srcA, BlendFactor dstA)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setBlendOperation(U32 attachment, BlendOperation funcRgb, BlendOperation funcA)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::bindTexture(U32 set, U32 binding, TextureView* texView, U32 arrayIdx)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::bindSampler(U32 set, U32 binding, Sampler* sampler, U32 arrayIdx)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::bindConstantBuffer(U32 set, U32 binding, Buffer* buff, PtrSize offset, PtrSize range, U32 arrayIdx)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::bindUavBuffer(U32 set, U32 binding, Buffer* buff, PtrSize offset, PtrSize range, U32 arrayIdx)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::bindUavTexture(U32 set, U32 binding, TextureView* img, U32 arrayIdx)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::bindAccelerationStructure(U32 set, U32 binding, AccelerationStructure* as, U32 arrayIdx)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::bindReadOnlyTextureBuffer(U32 set, U32 binding, Buffer* buff, PtrSize offset, PtrSize range, Format fmt, U32 arrayIdx)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::bindAllBindless(U32 set)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::bindShaderProgram(ShaderProgram* prog)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::beginRenderPass(Framebuffer* fb, const Array<TextureUsageBit, kMaxColorRenderTargets>& colorAttachmentUsages,
+									TextureUsageBit depthStencilAttachmentUsage, U32 minx, U32 miny, U32 width, U32 height)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::endRenderPass()
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setVrsRate(VrsRate rate)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::drawIndexed(PrimitiveTopology topology, U32 count, U32 instanceCount, U32 firstIndex, U32 baseVertex, U32 baseInstance)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::draw(PrimitiveTopology topology, U32 count, U32 instanceCount, U32 first, U32 baseInstance)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::drawIndirect(PrimitiveTopology topology, U32 drawCount, PtrSize offset, Buffer* buff)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::drawIndexedIndirectCount(PrimitiveTopology topology, Buffer* argBuffer, PtrSize argBufferOffset, U32 argBufferStride,
+											 Buffer* countBuffer, PtrSize countBufferOffset, U32 maxDrawCount)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::drawIndirectCount(PrimitiveTopology topology, Buffer* argBuffer, PtrSize argBufferOffset, U32 argBufferStride,
+									  Buffer* countBuffer, PtrSize countBufferOffset, U32 maxDrawCount)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::drawIndexedIndirect(PrimitiveTopology topology, U32 drawCount, PtrSize offset, Buffer* buff)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::drawMeshTasks(U32 groupCountX, U32 groupCountY, U32 groupCountZ)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::drawMeshTasksIndirect(Buffer* argBuffer, PtrSize argBufferOffset)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::dispatchCompute(U32 groupCountX, U32 groupCountY, U32 groupCountZ)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::dispatchComputeIndirect(Buffer* argBuffer, PtrSize argBufferOffset)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::traceRays(Buffer* sbtBuffer, PtrSize sbtBufferOffset, U32 sbtRecordSize, U32 hitGroupSbtRecordCount, U32 rayTypeCount, U32 width,
+							  U32 height, U32 depth)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::generateMipmaps2d(TextureView* texView)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::generateMipmaps3d([[maybe_unused]] TextureView* texView)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::blitTextureViews([[maybe_unused]] TextureView* srcView, [[maybe_unused]] TextureView* destView)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::clearTextureView(TextureView* texView, const ClearValue& clearValue)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::copyBufferToTextureView(Buffer* buff, PtrSize offset, PtrSize range, TextureView* texView)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::fillBuffer(Buffer* buff, PtrSize offset, PtrSize size, U32 value)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::writeOcclusionQueriesResultToBuffer(ConstWeakArray<OcclusionQuery*> queries, PtrSize offset, Buffer* buff)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::copyBufferToBuffer(Buffer* src, Buffer* dst, ConstWeakArray<CopyBufferToBufferInfo> copies)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::buildAccelerationStructure(AccelerationStructure* as, Buffer* scratchBuffer, PtrSize scratchBufferOffset)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::upscale(GrUpscaler* upscaler, TextureView* inColor, TextureView* outUpscaledColor, TextureView* motionVectors, TextureView* depth,
+							TextureView* exposure, Bool resetAccumulation, const Vec2& jitterOffset, const Vec2& motionVectorsScale)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setPipelineBarrier(ConstWeakArray<TextureBarrierInfo> textures, ConstWeakArray<BufferBarrierInfo> buffers,
+									   ConstWeakArray<AccelerationStructureBarrierInfo> accelerationStructures)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::resetOcclusionQueries(ConstWeakArray<OcclusionQuery*> queries)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::beginOcclusionQuery(OcclusionQuery* query)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::endOcclusionQuery(OcclusionQuery* query)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::beginPipelineQuery(PipelineQuery* query)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::endPipelineQuery(PipelineQuery* query)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::pushSecondLevelCommandBuffers(ConstWeakArray<CommandBuffer*> cmdbs)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::resetTimestampQueries(ConstWeakArray<TimestampQuery*> queries)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::writeTimestamp(TimestampQuery* query)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+Bool CommandBuffer::isEmpty() const
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setPushConstants(const void* data, U32 dataSize)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setRasterizationOrder(RasterizationOrder order)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::setLineWidth(F32 width)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::pushDebugMarker(CString name, Vec3 color)
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void CommandBuffer::popDebugMarker()
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+Error CommandBufferImpl::init(const CommandBufferInitInfo& init)
+{
+	ANKI_ASSERT(!"TODO");
+	return Error::kNone;
+}
+
+} // end namespace anki

+ 32 - 0
AnKi/Gr/D3D/D3DCommandBuffer.h

@@ -0,0 +1,32 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/CommandBuffer.h>
+
+namespace anki {
+
+/// @addtogroup directx
+/// @{
+
+/// Command buffer implementation.
+class CommandBufferImpl final : public CommandBuffer
+{
+public:
+	CommandBufferImpl(CString name)
+		: CommandBuffer(name)
+	{
+	}
+
+	~CommandBufferImpl()
+	{
+	}
+
+	Error init(const CommandBufferInitInfo& init);
+};
+/// @}
+
+} // end namespace anki

+ 23 - 0
AnKi/Gr/D3D/D3DCommon.h

@@ -0,0 +1,23 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/Common.h>
+#include <AnKi/Util/Logger.h>
+
+#include <d3d12.h>
+#include <dxgi1_6.h>
+#include <AnKi/Util/CleanupWindows.h>
+
+namespace anki {
+
+#define ANKI_D3D_LOGI(...) ANKI_LOG("D3D", kNormal, __VA_ARGS__)
+#define ANKI_D3D_LOGE(...) ANKI_LOG("D3D", kError, __VA_ARGS__)
+#define ANKI_D3D_LOGW(...) ANKI_LOG("D3D", kWarning, __VA_ARGS__)
+#define ANKI_D3D_LOGF(...) ANKI_LOG("D3D", kFatal, __VA_ARGS__)
+#define ANKI_D3D_LOGV(...) ANKI_LOG("D3D", kVerbose, __VA_ARGS__)
+
+} // end namespace anki

+ 21 - 0
AnKi/Gr/D3D/D3DFence.cpp

@@ -0,0 +1,21 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/D3D/D3DFence.h>
+
+namespace anki {
+
+Fence* Fence::newInstance()
+{
+	return anki::newInstance<FenceImpl>(GrMemoryPool::getSingleton(), "N/A");
+}
+
+Bool Fence::clientWait(Second seconds)
+{
+	ANKI_ASSERT(!"TODO");
+	return false;
+}
+
+} // end namespace anki

+ 8 - 10
AnKi/Gr/Gl/FenceImpl.h → AnKi/Gr/D3D/D3DFence.h

@@ -6,26 +6,24 @@
 #pragma once
 
 #include <AnKi/Gr/Fence.h>
-#include <AnKi/Gr/gl/GlObject.h>
 
 namespace anki {
 
-/// @addtogroup opengl
+/// @addtogroup directx
 /// @{
 
-/// Fence implementation.
-class FenceImpl final : public Fence, public GlObject
+/// Buffer implementation
+class FenceImpl final : public Fence
 {
 public:
-	GLsync m_fence = nullptr;
-	Atomic<Bool> m_signaled = {false};
-
-	FenceImpl(GrManager* gr, CString name)
-		: Fence(gr, name)
+	FenceImpl(CString name)
+		: Fence(name)
 	{
 	}
 
-	~FenceImpl();
+	~FenceImpl()
+	{
+	}
 };
 /// @}
 

+ 33 - 0
AnKi/Gr/D3D/D3DFramebuffer.cpp

@@ -0,0 +1,33 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/D3D/D3DFramebuffer.h>
+#include <AnKi/Gr/GrManager.h>
+
+namespace anki {
+
+Framebuffer* Framebuffer::newInstance(const FramebufferInitInfo& init)
+{
+	FramebufferImpl* impl = anki::newInstance<FramebufferImpl>(GrMemoryPool::getSingleton(), init.getName());
+	const Error err = impl->init(init);
+	if(err)
+	{
+		deleteInstance(GrMemoryPool::getSingleton(), impl);
+		impl = nullptr;
+	}
+	return impl;
+}
+
+FramebufferImpl::~FramebufferImpl()
+{
+}
+
+Error FramebufferImpl::init(const FramebufferInitInfo& init)
+{
+	ANKI_ASSERT(!"TODO");
+	return Error::kNone;
+}
+
+} // end namespace anki

+ 30 - 0
AnKi/Gr/D3D/D3DFramebuffer.h

@@ -0,0 +1,30 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/Framebuffer.h>
+
+namespace anki {
+
+/// @addtogroup directx
+/// @{
+
+/// Framebuffer implementation.
+class FramebufferImpl final : public Framebuffer
+{
+public:
+	FramebufferImpl(CString name)
+		: Framebuffer(name)
+	{
+	}
+
+	~FramebufferImpl();
+
+	Error init(const FramebufferInitInfo& init);
+};
+/// @}
+
+} // end namespace anki

+ 123 - 0
AnKi/Gr/D3D/D3DGrManager.cpp

@@ -0,0 +1,123 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/D3D/D3DGrManager.h>
+#include <AnKi/Gr/D3D/D3DAccelerationStructure.h>
+#include <AnKi/Gr/D3D/D3DTexture.h>
+#include <AnKi/Gr/D3D/D3DCommandBuffer.h>
+#include <AnKi/Gr/D3D/D3DShader.h>
+#include <AnKi/Gr/D3D/D3DShaderProgram.h>
+#include <AnKi/Gr/D3D/D3DTexture.h>
+#include <AnKi/Gr/D3D/D3DTextureView.h>
+#include <AnKi/Gr/D3D/D3DPipelineQuery.h>
+#include <AnKi/Gr/D3D/D3DSampler.h>
+#include <AnKi/Gr/D3D/D3DFramebuffer.h>
+#include <AnKi/Gr/RenderGraph.h>
+#include <AnKi/Gr/D3D/D3DGrUpscaler.h>
+#include <AnKi/Gr/D3D/D3DTimestampQuery.h>
+
+namespace anki {
+
+BoolCVar g_validationCVar(CVarSubsystem::kGr, "Validation", false, "Enable or not validation");
+BoolCVar g_vsyncCVar(CVarSubsystem::kGr, "Vsync", false, "Enable or not vsync");
+
+template<>
+template<>
+GrManager& MakeSingletonPtr<GrManager>::allocateSingleton<>()
+{
+	ANKI_ASSERT(m_global == nullptr);
+	m_global = new GrManagerImpl;
+
+#if ANKI_ASSERTIONS_ENABLED
+	++g_singletonsAllocated;
+#endif
+
+	return *m_global;
+}
+
+template<>
+void MakeSingletonPtr<GrManager>::freeSingleton()
+{
+	if(m_global)
+	{
+		delete static_cast<GrManagerImpl*>(m_global);
+		m_global = nullptr;
+#if ANKI_ASSERTIONS_ENABLED
+		--g_singletonsAllocated;
+#endif
+	}
+}
+
+GrManager::GrManager()
+{
+}
+
+GrManager::~GrManager()
+{
+}
+
+Error GrManager::init(GrManagerInitInfo& inf)
+{
+	ANKI_ASSERT(!"TODO");
+	return Error::kNone;
+}
+
+TexturePtr GrManager::acquireNextPresentableTexture()
+{
+	ANKI_ASSERT(!"TODO");
+	return TexturePtr(nullptr);
+}
+
+void GrManager::swapBuffers()
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+void GrManager::finish()
+{
+	ANKI_ASSERT(!"TODO");
+}
+
+#define ANKI_NEW_GR_OBJECT(type) \
+	type##Ptr GrManager::new##type(const type##InitInfo& init) \
+	{ \
+		type##Ptr ptr(nullptr); \
+		if(!ptr.isCreated()) [[unlikely]] \
+		{ \
+			ANKI_D3D_LOGF("Failed to create a " ANKI_STRINGIZE(type) " object"); \
+		} \
+		return ptr; \
+	}
+
+#define ANKI_NEW_GR_OBJECT_NO_INIT_INFO(type) \
+	type##Ptr GrManager::new##type() \
+	{ \
+		type##Ptr ptr(nullptr); \
+		if(!ptr.isCreated()) [[unlikely]] \
+		{ \
+			ANKI_D3D_LOGF("Failed to create a " ANKI_STRINGIZE(type) " object"); \
+		} \
+		return ptr; \
+	}
+
+ANKI_NEW_GR_OBJECT(Buffer)
+ANKI_NEW_GR_OBJECT(Texture)
+ANKI_NEW_GR_OBJECT(TextureView)
+ANKI_NEW_GR_OBJECT(Sampler)
+ANKI_NEW_GR_OBJECT(Shader)
+ANKI_NEW_GR_OBJECT(ShaderProgram)
+ANKI_NEW_GR_OBJECT(CommandBuffer)
+ANKI_NEW_GR_OBJECT(Framebuffer)
+// ANKI_NEW_GR_OBJECT_NO_INIT_INFO(OcclusionQuery)
+ANKI_NEW_GR_OBJECT_NO_INIT_INFO(TimestampQuery)
+ANKI_NEW_GR_OBJECT(PipelineQuery)
+ANKI_NEW_GR_OBJECT_NO_INIT_INFO(RenderGraph)
+ANKI_NEW_GR_OBJECT(AccelerationStructure)
+ANKI_NEW_GR_OBJECT(GrUpscaler)
+
+#undef ANKI_NEW_GR_OBJECT
+#undef ANKI_NEW_GR_OBJECT_NO_INIT_INFO
+
+} // end namespace anki

+ 38 - 0
AnKi/Gr/D3D/D3DGrManager.h

@@ -0,0 +1,38 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/GrManager.h>
+#include <AnKi/Gr/D3D/D3DCommon.h>
+
+namespace anki {
+
+/// @addtogroup directx
+/// @{
+
+/// DX implementation of GrManager.
+class GrManagerImpl : public GrManager
+{
+public:
+	GrManagerImpl()
+	{
+	}
+
+	~GrManagerImpl()
+	{
+	}
+
+	Error init(const GrManagerInitInfo& cfg)
+	{
+		ANKI_ASSERT(0);
+		return Error::kNone;
+	}
+
+private:
+};
+/// @}
+
+} // end namespace anki

+ 32 - 0
AnKi/Gr/D3D/D3DGrUpscaler.cpp

@@ -0,0 +1,32 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/D3D/D3DGrUpscaler.h>
+
+namespace anki {
+
+GrUpscaler* GrUpscaler::newInstance(const GrUpscalerInitInfo& initInfo)
+{
+	GrUpscalerImpl* impl = anki::newInstance<GrUpscalerImpl>(GrMemoryPool::getSingleton(), initInfo.getName());
+	const Error err = impl->initInternal(initInfo);
+	if(err)
+	{
+		deleteInstance(GrMemoryPool::getSingleton(), impl);
+		impl = nullptr;
+	}
+	return impl;
+}
+
+GrUpscalerImpl::~GrUpscalerImpl()
+{
+}
+
+Error GrUpscalerImpl::initInternal(const GrUpscalerInitInfo& initInfo)
+{
+	ANKI_ASSERT(!"TODO");
+	return Error::kNone;
+}
+
+} // end namespace anki

+ 29 - 0
AnKi/Gr/D3D/D3DGrUpscaler.h

@@ -0,0 +1,29 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/GrUpscaler.h>
+
+namespace anki {
+
+/// @addtogroup directx
+/// @{
+
+class GrUpscalerImpl final : public GrUpscaler
+{
+public:
+	GrUpscalerImpl(CString name)
+		: GrUpscaler(name)
+	{
+	}
+
+	~GrUpscalerImpl();
+
+	Error initInternal(const GrUpscalerInitInfo& initInfo);
+};
+/// @}
+
+} // end namespace anki

+ 38 - 0
AnKi/Gr/D3D/D3DPipelineQuery.cpp

@@ -0,0 +1,38 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/D3D/D3DPipelineQuery.h>
+
+namespace anki {
+
+PipelineQuery* PipelineQuery::newInstance(const PipelineQueryInitInfo& inf)
+{
+	PipelineQueryImpl* impl = anki::newInstance<PipelineQueryImpl>(GrMemoryPool::getSingleton(), inf.getName());
+	const Error err = impl->init(inf.m_type);
+	if(err)
+	{
+		deleteInstance(GrMemoryPool::getSingleton(), impl);
+		impl = nullptr;
+	}
+	return impl;
+}
+
+PipelineQueryResult PipelineQuery::getResult(U64& value) const
+{
+	ANKI_ASSERT(!"TODO");
+	return PipelineQueryResult::kNotAvailable;
+}
+
+PipelineQueryImpl::~PipelineQueryImpl()
+{
+}
+
+Error PipelineQueryImpl::init(PipelineQueryType type)
+{
+	ANKI_ASSERT(!"TODO");
+	return Error::kNone;
+}
+
+} // end namespace anki

+ 31 - 0
AnKi/Gr/D3D/D3DPipelineQuery.h

@@ -0,0 +1,31 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/PipelineQuery.h>
+
+namespace anki {
+
+/// @addtogroup vulkan
+/// @{
+
+/// Pipeline query.
+class PipelineQueryImpl final : public PipelineQuery
+{
+public:
+	PipelineQueryImpl(CString name)
+		: PipelineQuery(name)
+	{
+	}
+
+	~PipelineQueryImpl();
+
+	/// Create the query.
+	Error init(PipelineQueryType type);
+};
+/// @}
+
+} // end namespace anki

+ 32 - 0
AnKi/Gr/D3D/D3DSampler.cpp

@@ -0,0 +1,32 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/D3D/D3DSampler.h>
+
+namespace anki {
+
+Sampler* Sampler::newInstance(const SamplerInitInfo& init)
+{
+	SamplerImpl* impl = anki::newInstance<SamplerImpl>(GrMemoryPool::getSingleton(), init.getName());
+	const Error err = impl->init(init);
+	if(err)
+	{
+		deleteInstance(GrMemoryPool::getSingleton(), impl);
+		impl = nullptr;
+	}
+	return impl;
+}
+
+SamplerImpl::~SamplerImpl()
+{
+}
+
+Error SamplerImpl::init(const SamplerInitInfo& inf)
+{
+	ANKI_ASSERT(!"TODO");
+	return Error::kNone;
+}
+
+} // end namespace anki

+ 30 - 0
AnKi/Gr/D3D/D3DSampler.h

@@ -0,0 +1,30 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/Sampler.h>
+
+namespace anki {
+
+/// @addtogroup directx
+/// @{
+
+/// Vulkan implementation of Sampler.
+class SamplerImpl final : public Sampler
+{
+public:
+	SamplerImpl(CString name)
+		: Sampler(name)
+	{
+	}
+
+	~SamplerImpl();
+
+	Error init(const SamplerInitInfo& init);
+};
+/// @}
+
+} // end namespace anki

+ 32 - 0
AnKi/Gr/D3D/D3DShader.cpp

@@ -0,0 +1,32 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/D3D/D3DShader.h>
+
+namespace anki {
+
+Shader* Shader::newInstance(const ShaderInitInfo& init)
+{
+	ShaderImpl* impl = anki::newInstance<ShaderImpl>(GrMemoryPool::getSingleton(), init.getName());
+	const Error err = impl->init(init);
+	if(err)
+	{
+		deleteInstance(GrMemoryPool::getSingleton(), impl);
+		impl = nullptr;
+	}
+	return impl;
+}
+
+ShaderImpl::~ShaderImpl()
+{
+}
+
+Error ShaderImpl::init(const ShaderInitInfo& init)
+{
+	ANKI_ASSERT(!"TODO");
+	return Error::kNone;
+}
+
+} // end namespace anki

+ 30 - 0
AnKi/Gr/D3D/D3DShader.h

@@ -0,0 +1,30 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/Shader.h>
+
+namespace anki {
+
+/// @addtogroup directx
+/// @{
+
+/// Shader implementation.
+class ShaderImpl final : public Shader
+{
+public:
+	ShaderImpl(CString name)
+		: Shader(name)
+	{
+	}
+
+	~ShaderImpl();
+
+	Error init(const ShaderInitInfo& init);
+};
+/// @}
+
+} // end namespace anki

+ 45 - 0
AnKi/Gr/D3D/D3DShaderProgram.cpp

@@ -0,0 +1,45 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/D3D/D3DShaderProgram.h>
+
+namespace anki {
+
+ShaderProgram* ShaderProgram::newInstance(const ShaderProgramInitInfo& init)
+{
+	ShaderProgramImpl* impl = anki::newInstance<ShaderProgramImpl>(GrMemoryPool::getSingleton(), init.getName());
+	const Error err = impl->init(init);
+	if(err)
+	{
+		deleteInstance(GrMemoryPool::getSingleton(), impl);
+		impl = nullptr;
+	}
+	return impl;
+}
+
+ConstWeakArray<U8> ShaderProgram::getShaderGroupHandles() const
+{
+	ANKI_ASSERT(!"TODO");
+	return ConstWeakArray<U8>();
+}
+
+Buffer& ShaderProgram::getShaderGroupHandlesGpuBuffer() const
+{
+	ANKI_ASSERT(!"TODO");
+	void* ptr = nullptr;
+	return *reinterpret_cast<Buffer*>(ptr);
+}
+
+ShaderProgramImpl::~ShaderProgramImpl()
+{
+}
+
+Error ShaderProgramImpl::init(const ShaderProgramInitInfo& inf)
+{
+	ANKI_ASSERT(!"TODO");
+	return Error::kNone;
+}
+
+} // end namespace anki

+ 30 - 0
AnKi/Gr/D3D/D3DShaderProgram.h

@@ -0,0 +1,30 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/ShaderProgram.h>
+
+namespace anki {
+
+/// @addtogroup directx
+/// @{
+
+/// Shader program implementation.
+class ShaderProgramImpl final : public ShaderProgram
+{
+public:
+	ShaderProgramImpl(CString name)
+		: ShaderProgram(name)
+	{
+	}
+
+	~ShaderProgramImpl();
+
+	Error init(const ShaderProgramInitInfo& inf);
+};
+/// @}
+
+} // end namespace anki

+ 33 - 0
AnKi/Gr/D3D/D3DTexture.cpp

@@ -0,0 +1,33 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/Texture.h>
+#include <AnKi/Gr/D3D/D3DTexture.h>
+
+namespace anki {
+
+Texture* Texture::newInstance(const TextureInitInfo& init)
+{
+	TextureImpl* impl = anki::newInstance<TextureImpl>(GrMemoryPool::getSingleton(), init.getName());
+	const Error err = impl->init(init);
+	if(err)
+	{
+		deleteInstance(GrMemoryPool::getSingleton(), impl);
+		impl = nullptr;
+	}
+	return impl;
+}
+
+TextureImpl::~TextureImpl()
+{
+}
+
+Error TextureImpl::init(const TextureInitInfo& inf)
+{
+	ANKI_ASSERT(!"TODO");
+	return Error::kNone;
+}
+
+} // end namespace anki

+ 30 - 0
AnKi/Gr/D3D/D3DTexture.h

@@ -0,0 +1,30 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/Texture.h>
+
+namespace anki {
+
+/// @addtogroup directx
+/// @{
+
+/// Texture container.
+class TextureImpl final : public Texture
+{
+public:
+	TextureImpl(CString name)
+		: Texture(name)
+	{
+	}
+
+	~TextureImpl();
+
+	Error init(const TextureInitInfo& inf);
+};
+/// @}
+
+} // end namespace anki

+ 28 - 0
AnKi/Gr/D3D/D3DTextureView.cpp

@@ -0,0 +1,28 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/D3D/D3DTextureView.h>
+
+namespace anki {
+
+TextureView* TextureView::newInstance(const TextureViewInitInfo& init)
+{
+	TextureViewImpl* impl = anki::newInstance<TextureViewImpl>(GrMemoryPool::getSingleton(), init.getName());
+	const Error err = impl->init(init);
+	if(err)
+	{
+		deleteInstance(GrMemoryPool::getSingleton(), impl);
+		impl = nullptr;
+	}
+	return impl;
+}
+
+U32 TextureView::getOrCreateBindlessTextureIndex()
+{
+	ANKI_ASSERT(!"TODO");
+	return 0;
+}
+
+} // end namespace anki

+ 36 - 0
AnKi/Gr/D3D/D3DTextureView.h

@@ -0,0 +1,36 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/TextureView.h>
+
+namespace anki {
+
+/// @addtogroup directx
+/// @{
+
+/// Texture view implementation.
+class TextureViewImpl final : public TextureView
+{
+public:
+	TextureViewImpl(CString name)
+		: TextureView(name)
+	{
+	}
+
+	~TextureViewImpl()
+	{
+	}
+
+	Error init(const TextureViewInitInfo& inf)
+	{
+		ANKI_ASSERT(!"TODO");
+		return Error::kNone;
+	}
+};
+/// @}
+
+} // end namespace anki

+ 38 - 0
AnKi/Gr/D3D/D3DTimestampQuery.cpp

@@ -0,0 +1,38 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Gr/D3D/D3DTimestampQuery.h>
+
+namespace anki {
+
+TimestampQuery* TimestampQuery::newInstance()
+{
+	TimestampQueryImpl* impl = anki::newInstance<TimestampQueryImpl>(GrMemoryPool::getSingleton(), "N/A");
+	const Error err = impl->init();
+	if(err)
+	{
+		deleteInstance(GrMemoryPool::getSingleton(), impl);
+		impl = nullptr;
+	}
+	return impl;
+}
+
+TimestampQueryResult TimestampQuery::getResult(Second& timestamp) const
+{
+	ANKI_ASSERT(!"TODO");
+	return TimestampQueryResult::kNotAvailable;
+}
+
+TimestampQueryImpl::~TimestampQueryImpl()
+{
+}
+
+Error TimestampQueryImpl::init()
+{
+	ANKI_ASSERT(!"TODO");
+	return Error::kNone;
+}
+
+} // end namespace anki

+ 31 - 0
AnKi/Gr/D3D/D3DTimestampQuery.h

@@ -0,0 +1,31 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Gr/TimestampQuery.h>
+
+namespace anki {
+
+/// @addtogroup directx
+/// @{
+
+/// Timestamp query.
+class TimestampQueryImpl final : public TimestampQuery
+{
+public:
+	TimestampQueryImpl(CString name)
+		: TimestampQuery(name)
+	{
+	}
+
+	~TimestampQueryImpl();
+
+	/// Create the query.
+	Error init();
+};
+/// @}
+
+} // end namespace anki

+ 0 - 63
AnKi/Gr/Gl/Buffer.cpp

@@ -1,63 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/Buffer.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Gr/gl/BufferImpl.h>
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-
-namespace anki {
-
-Buffer* Buffer::newInstance(GrManager* manager, const BufferInitInfo& inf)
-{
-	class BufferCreateCommand final : public GlCommand
-	{
-	public:
-		BufferPtr m_buff;
-
-		BufferCreateCommand(Buffer* buff)
-			: m_buff(buff)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			BufferImpl& impl = static_cast<BufferImpl&>(*m_buff);
-
-			impl.init();
-
-			GlObject::State oldState = impl.setStateAtomically(GlObject::State::CREATED);
-			(void)oldState;
-			ANKI_ASSERT(oldState == GlObject::State::TO_BE_CREATED);
-
-			return Error::kNone;
-		}
-	};
-
-	BufferImpl* impl = manager->getAllocator().newInstance<BufferImpl>(manager, inf.getName());
-	impl->getRefcount().fetchAdd(1); // Hold a reference in case the command finishes and deletes quickly
-
-	impl->preInit(inf);
-
-	CommandBufferPtr cmdb = manager->newCommandBuffer(CommandBufferInitInfo());
-	static_cast<CommandBufferImpl&>(*cmdb).pushBackNewCommand<BufferCreateCommand>(impl);
-	static_cast<CommandBufferImpl&>(*cmdb).flush();
-
-	return impl;
-}
-
-void* Buffer::map(PtrSize offset, PtrSize range, BufferMapAccessBit access)
-{
-	ANKI_GL_SELF(BufferImpl);
-	return self.map(offset, range, access);
-}
-
-void Buffer::unmap()
-{
-	ANKI_GL_SELF(BufferImpl);
-	self.unmap();
-}
-
-} // end namespace anki

+ 0 - 82
AnKi/Gr/Gl/BufferImpl.cpp

@@ -1,82 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/BufferImpl.h>
-#include <AnKi/Util/Logger.h>
-#include <cmath>
-
-namespace anki {
-
-void BufferImpl::init()
-{
-	ANKI_ASSERT(!isCreated());
-
-	const BufferUsageBit usage = getBufferUsage();
-	const BufferMapAccessBit access = getMapAccess();
-
-	// Align size to satisfy BufferImpl::fill
-	m_realSize = getAlignedRoundUp(4, getSize());
-
-	// This is a guess, not very important since DSA doesn't care about it on creation
-	m_target = GL_ARRAY_BUFFER;
-
-	if((usage & BufferUsageBit::UNIFORM_ALL) != BufferUsageBit::kNone)
-	{
-		m_target = GL_UNIFORM_BUFFER;
-	}
-
-	if((usage & BufferUsageBit::STORAGE_ALL) != BufferUsageBit::kNone)
-	{
-		m_target = GL_SHADER_STORAGE_BUFFER;
-	}
-
-	//
-	// Determine the creation flags
-	//
-	GLbitfield flags = 0;
-	Bool shouldMap = false;
-	if((usage & BufferUsageBit::TRANSFER_ALL) != BufferUsageBit::kNone)
-	{
-		flags |= GL_DYNAMIC_STORAGE_BIT;
-	}
-
-	if((access & BufferMapAccessBit::kWrite) != BufferMapAccessBit::kNone)
-	{
-		flags |= GL_MAP_WRITE_BIT;
-		flags |= GL_MAP_PERSISTENT_BIT;
-		flags |= GL_MAP_COHERENT_BIT;
-
-		shouldMap = true;
-	}
-
-	if((access & BufferMapAccessBit::kRead) != BufferMapAccessBit::kNone)
-	{
-		flags |= GL_MAP_READ_BIT;
-		flags |= GL_MAP_PERSISTENT_BIT;
-		flags |= GL_MAP_COHERENT_BIT;
-
-		shouldMap = true;
-	}
-
-	//
-	// Create
-	//
-	glGenBuffers(1, &m_glName);
-	glBindBuffer(m_target, m_glName);
-	glBufferStorage(m_target, m_realSize, nullptr, flags);
-
-	//
-	// Map
-	//
-	if(shouldMap)
-	{
-		const GLbitfield MAP_BITS = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
-
-		m_persistentMapping = glMapBufferRange(m_target, 0, m_size, flags & MAP_BITS);
-		ANKI_ASSERT(m_persistentMapping != nullptr);
-	}
-}
-
-} // end namespace anki

+ 0 - 117
AnKi/Gr/Gl/BufferImpl.h

@@ -1,117 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/Buffer.h>
-#include <AnKi/Gr/gl/GlObject.h>
-
-namespace anki {
-
-/// @addtogroup opengl
-/// @{
-
-/// Buffer implementation
-class BufferImpl final : public Buffer, public GlObject
-{
-public:
-	BufferImpl(GrManager* manager, CString name)
-		: Buffer(manager, name)
-	{
-	}
-
-	~BufferImpl()
-	{
-		destroyDeferred(getManager(), glDeleteBuffers);
-	}
-
-	void preInit(const BufferInitInfo& init)
-	{
-		ANKI_ASSERT(init.isValid());
-		m_size = init.m_size;
-		m_usage = init.m_usage;
-		m_access = init.m_access;
-	}
-
-	void init();
-
-	void bind(GLenum target, U32 binding, PtrSize offset, PtrSize range) const
-	{
-		ANKI_ASSERT(isCreated());
-
-		range = (range == kMaxPtrSize) ? (m_size - offset) : range;
-		ANKI_ASSERT(range > 0);
-		ANKI_ASSERT(offset + range <= m_size);
-
-		glBindBufferRange(target, binding, m_glName, offset, range);
-	}
-
-	void bind(GLenum target, U32 binding, PtrSize offset) const
-	{
-		bind(target, binding, offset, kMaxPtrSize);
-	}
-
-	void write(GLuint pbo, U32 pboOffset, U32 offset, U32 size) const
-	{
-		ANKI_ASSERT(isCreated());
-		ANKI_ASSERT(offset + size <= m_size);
-
-		glCopyNamedBufferSubData(pbo, m_glName, pboOffset, offset, size);
-	}
-
-	void fill(PtrSize offset, PtrSize size, U32 value)
-	{
-		ANKI_ASSERT(isCreated());
-		ANKI_ASSERT(offset < m_size);
-		ANKI_ASSERT((offset % 4) == 0 && "Should be multiple of 4");
-
-		size = (size == kMaxPtrSize) ? (m_realSize - offset) : size;
-		ANKI_ASSERT(offset + size <= m_realSize);
-		ANKI_ASSERT((size % 4) == 0 && "Should be multiple of 4");
-
-		glClearNamedBufferSubData(m_glName, GL_R32UI, offset, size, GL_RED_INTEGER, GL_UNSIGNED_INT, &value);
-	}
-
-	void* map(PtrSize offset, PtrSize range, BufferMapAccessBit access)
-	{
-		// Wait for its creation
-		if(serializeRenderingThread(getManager()))
-		{
-			return nullptr;
-		}
-
-		// Sanity checks
-		ANKI_ASSERT(offset + range <= m_size);
-		ANKI_ASSERT(m_persistentMapping);
-
-		U8* ptr = static_cast<U8*>(m_persistentMapping);
-		ptr += offset;
-
-#if ANKI_EXTRA_CHECKS
-		ANKI_ASSERT(!m_mapped);
-		m_mapped = true;
-#endif
-		return static_cast<void*>(ptr);
-	}
-
-	void unmap()
-	{
-#if ANKI_EXTRA_CHECKS
-		ANKI_ASSERT(m_mapped);
-		m_mapped = false;
-#endif
-	}
-
-private:
-	void* m_persistentMapping = nullptr;
-	GLenum m_target = GL_NONE; ///< A guess
-#if ANKI_EXTRA_CHECKS
-	Bool m_mapped = false;
-#endif
-	PtrSize m_realSize = 0;
-};
-/// @}
-
-} // end namespace anki

+ 0 - 1566
AnKi/Gr/Gl/CommandBuffer.cpp

@@ -1,1566 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/CommandBuffer.h>
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Gr/gl/GrManagerImpl.h>
-#include <AnKi/Gr/gl/RenderingThread.h>
-#include <AnKi/Gr/gl/GlState.h>
-
-#include <AnKi/Gr/gl/FramebufferImpl.h>
-#include <AnKi/Gr/gl/OcclusionQueryImpl.h>
-#include <AnKi/Gr/gl/TextureImpl.h>
-#include <AnKi/Gr/gl/BufferImpl.h>
-#include <AnKi/Gr/gl/SamplerImpl.h>
-#include <AnKi/Gr/gl/ShaderProgramImpl.h>
-#include <AnKi/Gr/gl/TextureViewImpl.h>
-
-#include <AnKi/Core/Trace.h>
-
-namespace anki {
-
-CommandBuffer* CommandBuffer::newInstance(GrManager* manager, const CommandBufferInitInfo& inf)
-{
-	CommandBufferImpl* impl = manager->getAllocator().newInstance<CommandBufferImpl>(manager, inf.getName());
-	impl->init(inf);
-	return impl;
-}
-
-void CommandBuffer::flush(FencePtr* fence)
-{
-	ANKI_GL_SELF(CommandBufferImpl);
-
-	if(!self.isSecondLevel())
-	{
-		ANKI_ASSERT(!self.m_state.insideRenderPass());
-	}
-	else
-	{
-		ANKI_ASSERT(fence == nullptr);
-	}
-
-	if(!self.isSecondLevel())
-	{
-		static_cast<GrManagerImpl&>(getManager()).getRenderingThread().flushCommandBuffer(CommandBufferPtr(this), fence);
-	}
-}
-
-void CommandBuffer::bindVertexBuffer(U32 binding, BufferPtr buff, PtrSize offset, PtrSize stride, VertexStepRate stepRate)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		BufferPtr m_buff;
-		U32 m_binding;
-		PtrSize m_offset;
-		PtrSize m_stride;
-		Bool m_instanced;
-
-		Cmd(U32 binding, BufferPtr buff, PtrSize offset, PtrSize stride, Bool instanced)
-			: m_buff(buff)
-			, m_binding(binding)
-			, m_offset(offset)
-			, m_stride(stride)
-			, m_instanced(instanced)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			glBindVertexBuffer(m_binding, static_cast<const BufferImpl&>(*m_buff).getGlName(), m_offset, m_stride);
-			glVertexBindingDivisor(m_binding, (m_instanced) ? 1 : 0);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_ASSERT(buff);
-	ANKI_ASSERT(stride > 0);
-	ANKI_GL_SELF(CommandBufferImpl);
-
-	if(self.m_state.bindVertexBuffer(binding, buff, offset, stride, stepRate))
-	{
-		self.pushBackNewCommand<Cmd>(binding, buff, offset, stride, stepRate == VertexStepRate::INSTANCE);
-	}
-}
-
-void CommandBuffer::setVertexAttribute(U32 location, U32 buffBinding, Format fmt, PtrSize relativeOffset)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		U32 m_location;
-		U32 m_buffBinding;
-		U8 m_compSize;
-		GLenum m_fmt;
-		Bool m_normalized;
-		PtrSize m_relativeOffset;
-
-		Cmd(U32 location, U32 buffBinding, U8 compSize, GLenum fmt, Bool normalized, PtrSize relativeOffset)
-			: m_location(location)
-			, m_buffBinding(buffBinding)
-			, m_compSize(compSize)
-			, m_fmt(fmt)
-			, m_normalized(normalized)
-			, m_relativeOffset(relativeOffset)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			glVertexAttribFormat(m_location, m_compSize, m_fmt, m_normalized, m_relativeOffset);
-			glVertexAttribBinding(m_location, m_buffBinding);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-
-	if(self.m_state.setVertexAttribute(location, buffBinding, fmt, relativeOffset))
-	{
-		U compCount;
-		GLenum type;
-		Bool normalized;
-
-		convertVertexFormat(fmt, compCount, type, normalized);
-
-		self.pushBackNewCommand<Cmd>(location, buffBinding, compCount, type, normalized, relativeOffset);
-	}
-}
-
-void CommandBuffer::bindIndexBuffer(BufferPtr buff, PtrSize offset, IndexType type)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		BufferPtr m_buff;
-
-		Cmd(BufferPtr buff)
-			: m_buff(buff)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, static_cast<const BufferImpl&>(*m_buff).getGlName());
-			return Error::kNone;
-		}
-	};
-
-	ANKI_ASSERT(buff);
-	ANKI_GL_SELF(CommandBufferImpl);
-
-	if(self.m_state.bindIndexBuffer(buff, offset, type))
-	{
-		self.pushBackNewCommand<Cmd>(buff);
-	}
-}
-
-void CommandBuffer::setPrimitiveRestart(Bool enable)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		Bool m_enable;
-
-		Cmd(Bool enable)
-			: m_enable(enable)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			if(m_enable)
-			{
-				glEnable(GL_PRIMITIVE_RESTART);
-			}
-			else
-			{
-				glDisable(GL_PRIMITIVE_RESTART);
-			}
-
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	if(self.m_state.setPrimitiveRestart(enable))
-	{
-		self.pushBackNewCommand<Cmd>(enable);
-	}
-}
-
-void CommandBuffer::setViewport(U32 minx, U32 miny, U32 width, U32 height)
-{
-	class ViewportCommand final : public GlCommand
-	{
-	public:
-		Array<U32, 4> m_value;
-
-		ViewportCommand(U32 a, U32 b, U32 c, U32 d)
-		{
-			m_value = {{a, b, c, d}};
-		}
-
-		Error operator()(GlState& state)
-		{
-			glViewport(m_value[0], m_value[1], m_value[2], m_value[3]);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	if(self.m_state.setViewport(minx, miny, width, height))
-	{
-		self.pushBackNewCommand<ViewportCommand>(minx, miny, width, height);
-	}
-}
-
-void CommandBuffer::setScissor(U32 minx, U32 miny, U32 width, U32 height)
-{
-	ANKI_ASSERT(minx < kMaxU32 && miny < kMaxU32);
-	ANKI_ASSERT(width > 0 && height > 0);
-
-	class ScissorCommand final : public GlCommand
-	{
-	public:
-		Array<GLsizei, 4> m_value;
-
-		ScissorCommand(GLsizei a, GLsizei b, GLsizei c, GLsizei d)
-		{
-			m_value = {{a, b, c, d}};
-		}
-
-		Error operator()(GlState& state)
-		{
-			if(state.m_scissor[0] != m_value[0] || state.m_scissor[1] != m_value[1] || state.m_scissor[2] != m_value[2]
-			   || state.m_scissor[3] != m_value[3])
-			{
-				state.m_scissor = m_value;
-				glScissor(m_value[0], m_value[1], m_value[2], m_value[3]);
-			}
-			return Error::kNone;
-		}
-	};
-
-	// Limit the width and height to GLsizei
-	const GLsizei iwidth = (width == kMaxU32) ? kMaxI32 : width;
-	const GLsizei iheight = (height == kMaxU32) ? kMaxI32 : height;
-	const GLsizei iminx = minx;
-	const GLsizei iminy = miny;
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	if(self.m_state.setScissor(iminx, iminy, iwidth, iheight))
-	{
-		self.pushBackNewCommand<ScissorCommand>(iminx, iminy, iwidth, iheight);
-	}
-}
-
-void CommandBuffer::setFillMode(FillMode mode)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		GLenum m_fillMode;
-
-		Cmd(GLenum fillMode)
-			: m_fillMode(fillMode)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			glPolygonMode(GL_FRONT_AND_BACK, m_fillMode);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	if(self.m_state.setFillMode(mode))
-	{
-		self.pushBackNewCommand<Cmd>(convertFillMode(mode));
-	}
-}
-
-void CommandBuffer::setCullMode(FaceSelectionBit mode)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		GLenum m_mode;
-
-		Cmd(GLenum mode)
-			: m_mode(mode)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			glCullFace(m_mode);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	if(self.m_state.setCullMode(mode))
-	{
-		self.pushBackNewCommand<Cmd>(convertFaceMode(mode));
-	}
-}
-
-void CommandBuffer::setPolygonOffset(F32 factor, F32 units)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		F32 m_factor;
-		F32 m_units;
-
-		Cmd(F32 factor, F32 units)
-			: m_factor(factor)
-			, m_units(units)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			if(m_factor == 0.0 && m_units == 0.0)
-			{
-				glDisable(GL_POLYGON_OFFSET_FILL);
-			}
-			else
-			{
-				glEnable(GL_POLYGON_OFFSET_FILL);
-				glPolygonOffset(m_factor, m_units);
-			}
-
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	if(self.m_state.setPolygonOffset(factor, units))
-	{
-		self.pushBackNewCommand<Cmd>(factor, units);
-	}
-}
-
-void CommandBuffer::setStencilOperations(FaceSelectionBit face, StencilOperation stencilFail, StencilOperation stencilPassDepthFail,
-										 StencilOperation stencilPassDepthPass)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		GLenum m_face;
-		GLenum m_stencilFail;
-		GLenum m_stencilPassDepthFail;
-		GLenum m_stencilPassDepthPass;
-
-		Cmd(GLenum face, GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
-			: m_face(face)
-			, m_stencilFail(stencilFail)
-			, m_stencilPassDepthFail(stencilPassDepthFail)
-			, m_stencilPassDepthPass(stencilPassDepthPass)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			glStencilOpSeparate(m_face, m_stencilFail, m_stencilPassDepthFail, m_stencilPassDepthPass);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	if(self.m_state.setStencilOperations(face, stencilFail, stencilPassDepthFail, stencilPassDepthPass))
-	{
-		self.pushBackNewCommand<Cmd>(convertFaceMode(face), convertStencilOperation(stencilFail), convertStencilOperation(stencilPassDepthFail),
-									 convertStencilOperation(stencilPassDepthPass));
-	}
-}
-
-void CommandBuffer::setStencilCompareOperation(FaceSelectionBit face, CompareOperation comp)
-{
-	ANKI_GL_SELF(CommandBufferImpl);
-	self.m_state.setStencilCompareOperation(face, comp);
-}
-
-void CommandBuffer::setStencilCompareMask(FaceSelectionBit face, U32 mask)
-{
-	ANKI_GL_SELF(CommandBufferImpl);
-	self.m_state.setStencilCompareMask(face, mask);
-}
-
-void CommandBuffer::setStencilWriteMask(FaceSelectionBit face, U32 mask)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		GLenum m_face;
-		U32 m_mask;
-
-		Cmd(GLenum face, U32 mask)
-			: m_face(face)
-			, m_mask(mask)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			glStencilMaskSeparate(m_face, m_mask);
-
-			if(m_face == GL_FRONT)
-			{
-				state.m_stencilWriteMask[0] = m_mask;
-			}
-			else if(m_face == GL_BACK)
-			{
-				state.m_stencilWriteMask[1] = m_mask;
-			}
-			else
-			{
-				ANKI_ASSERT(m_face == GL_FRONT_AND_BACK);
-				state.m_stencilWriteMask[0] = state.m_stencilWriteMask[1] = m_mask;
-			}
-
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	if(self.m_state.setStencilWriteMask(face, mask))
-	{
-		self.pushBackNewCommand<Cmd>(convertFaceMode(face), mask);
-	}
-}
-
-void CommandBuffer::setStencilReference(FaceSelectionBit face, U32 ref)
-{
-	ANKI_GL_SELF(CommandBufferImpl);
-	self.m_state.setStencilReference(face, ref);
-}
-
-void CommandBuffer::setDepthWrite(Bool enable)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		Bool m_enable;
-
-		Cmd(Bool enable)
-			: m_enable(enable)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			glDepthMask(m_enable);
-			state.m_depthWriteMask = m_enable;
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	if(self.m_state.setDepthWrite(enable))
-	{
-		self.pushBackNewCommand<Cmd>(enable);
-	}
-}
-
-void CommandBuffer::setDepthCompareOperation(CompareOperation op)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		GLenum m_op;
-
-		Cmd(GLenum op)
-			: m_op(op)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			glDepthFunc(m_op);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	if(self.m_state.setDepthCompareOperation(op))
-	{
-		self.pushBackNewCommand<Cmd>(convertCompareOperation(op));
-	}
-}
-
-void CommandBuffer::setAlphaToCoverage(Bool enable)
-{
-	ANKI_ASSERT(!"TODO");
-}
-
-void CommandBuffer::setColorChannelWriteMask(U32 attachment, ColorBit mask)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		U8 m_attachment;
-		ColorBit m_mask;
-
-		Cmd(U8 attachment, ColorBit mask)
-			: m_attachment(attachment)
-			, m_mask(mask)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			const Bool r = !!(m_mask & ColorBit::RED);
-			const Bool g = !!(m_mask & ColorBit::GREEN);
-			const Bool b = !!(m_mask & ColorBit::BLUE);
-			const Bool a = !!(m_mask & ColorBit::ALPHA);
-
-			glColorMaski(m_attachment, r, g, b, a);
-
-			state.m_colorWriteMasks[m_attachment] = {{r, g, b, a}};
-
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	if(self.m_state.setColorChannelWriteMask(attachment, mask))
-	{
-		self.pushBackNewCommand<Cmd>(attachment, mask);
-	}
-}
-
-void CommandBuffer::setBlendFactors(U32 attachment, BlendFactor srcRgb, BlendFactor dstRgb, BlendFactor srcA, BlendFactor dstA)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		U8 m_attachment;
-		GLenum m_srcRgb;
-		GLenum m_dstRgb;
-		GLenum m_srcA;
-		GLenum m_dstA;
-
-		Cmd(U8 att, GLenum srcRgb, GLenum dstRgb, GLenum srcA, GLenum dstA)
-			: m_attachment(att)
-			, m_srcRgb(srcRgb)
-			, m_dstRgb(dstRgb)
-			, m_srcA(srcA)
-			, m_dstA(dstA)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			glBlendFuncSeparatei(m_attachment, m_srcRgb, m_dstRgb, m_srcA, m_dstA);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	if(self.m_state.setBlendFactors(attachment, srcRgb, dstRgb, srcA, dstA))
-	{
-		self.pushBackNewCommand<Cmd>(attachment, convertBlendFactor(srcRgb), convertBlendFactor(dstRgb), convertBlendFactor(srcA),
-									 convertBlendFactor(dstA));
-	}
-}
-
-void CommandBuffer::setBlendOperation(U32 attachment, BlendOperation funcRgb, BlendOperation funcA)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		U8 m_attachment;
-		GLenum m_funcRgb;
-		GLenum m_funcA;
-
-		Cmd(U8 att, GLenum funcRgb, GLenum funcA)
-			: m_attachment(att)
-			, m_funcRgb(funcRgb)
-			, m_funcA(funcA)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			glBlendEquationSeparatei(m_attachment, m_funcRgb, m_funcA);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	if(self.m_state.setBlendOperation(attachment, funcRgb, funcA))
-	{
-		self.pushBackNewCommand<Cmd>(attachment, convertBlendOperation(funcRgb), convertBlendOperation(funcA));
-	}
-}
-
-void CommandBuffer::bindTextureAndSampler(U32 set, U32 binding, TextureViewPtr texView, SamplerPtr sampler, TextureUsageBit usage)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		U32 m_unit;
-		TextureViewPtr m_texView;
-		SamplerPtr m_sampler;
-
-		Cmd(U32 unit, TextureViewPtr texView, SamplerPtr sampler)
-			: m_unit(unit)
-			, m_texView(texView)
-			, m_sampler(sampler)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			glBindTextureUnit(m_unit, static_cast<const TextureViewImpl&>(*m_texView).m_view.m_glName);
-			glBindSampler(m_unit, static_cast<const SamplerImpl&>(*m_sampler).getGlName());
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	ANKI_ASSERT(static_cast<const TextureViewImpl&>(*texView).m_tex->isSubresourceGoodForSampling(
-		static_cast<const TextureViewImpl&>(*texView).getSubresource()));
-
-	if(self.m_state.bindTextureViewAndSampler(set, binding, texView, sampler))
-	{
-		U unit = binding + MAX_TEXTURE_BINDINGS * set;
-		self.pushBackNewCommand<Cmd>(unit, texView, sampler);
-	}
-}
-
-void CommandBuffer::bindConstantBuffer(U32 set, U32 binding, BufferPtr buff, PtrSize offset, PtrSize range)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		BufferPtr m_buff;
-		PtrSize m_binding;
-		PtrSize m_offset;
-		PtrSize m_range;
-
-		Cmd(U32 binding, BufferPtr buff, PtrSize offset, PtrSize range)
-			: m_buff(buff)
-			, m_binding(binding)
-			, m_offset(offset)
-			, m_range(range)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			static_cast<const BufferImpl&>(*m_buff).bind(GL_UNIFORM_BUFFER, m_binding, m_offset, m_range);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_ASSERT(buff);
-	ANKI_ASSERT(range > 0);
-	ANKI_GL_SELF(CommandBufferImpl);
-
-	if(self.m_state.bindConstantBuffer(set, binding, buff, offset, range))
-	{
-		binding = binding + MAX_UNIFORM_BUFFER_BINDINGS * set;
-		self.pushBackNewCommand<Cmd>(binding, buff, offset, range);
-	}
-}
-
-void CommandBuffer::bindUavBuffer(U32 set, U32 binding, BufferPtr buff, PtrSize offset, PtrSize range)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		BufferPtr m_buff;
-		PtrSize m_binding;
-		PtrSize m_offset;
-		PtrSize m_range;
-
-		Cmd(U32 binding, BufferPtr buff, PtrSize offset, PtrSize range)
-			: m_buff(buff)
-			, m_binding(binding)
-			, m_offset(offset)
-			, m_range(range)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			static_cast<const BufferImpl&>(*m_buff).bind(GL_SHADER_STORAGE_BUFFER, m_binding, m_offset, m_range);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_ASSERT(buff);
-	ANKI_ASSERT(range > 0);
-	ANKI_GL_SELF(CommandBufferImpl);
-
-	if(self.m_state.bindUavBuffer(set, binding, buff, offset, range))
-	{
-		binding = binding + MAX_STORAGE_BUFFER_BINDINGS * set;
-		self.pushBackNewCommand<Cmd>(binding, buff, offset, range);
-	}
-}
-
-void CommandBuffer::bindUavTexture(U32 set, U32 binding, TextureViewPtr img)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		TextureViewPtr m_img;
-		U16 m_unit;
-
-		Cmd(U32 unit, TextureViewPtr img)
-			: m_img(img)
-			, m_unit(unit)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			const TextureViewImpl& view = static_cast<const TextureViewImpl&>(*m_img);
-
-			glBindImageTexture(m_unit, view.m_view.m_glName, 0, GL_TRUE, 0, GL_READ_WRITE,
-							   static_cast<const TextureImpl&>(*view.m_tex).m_internalFormat);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_ASSERT(img);
-	ANKI_GL_SELF(CommandBufferImpl);
-	ANKI_ASSERT(static_cast<const TextureViewImpl&>(*img).m_tex->isSubresourceGoodForImageLoadStore(
-		static_cast<const TextureViewImpl&>(*img).getSubresource()));
-
-	if(self.m_state.bindUavTexture(set, binding, img))
-	{
-		binding = binding + set * MAX_IMAGE_BINDINGS;
-		self.pushBackNewCommand<Cmd>(binding, img);
-	}
-}
-
-void CommandBuffer::bindTextureBuffer(U32 set, U32 binding, BufferPtr buff, PtrSize offset, PtrSize range, Format fmt)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		U32 m_set;
-		U32 m_binding;
-		BufferPtr m_buff;
-		PtrSize m_offset;
-		PtrSize m_range;
-		GLenum m_fmt;
-
-		Cmd(U32 set, U32 binding, BufferPtr buff, PtrSize offset, PtrSize range, GLenum fmt)
-			: m_set(set)
-			, m_binding(binding)
-			, m_buff(buff)
-			, m_offset(offset)
-			, m_range(range)
-			, m_fmt(fmt)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			ANKI_ASSERT(m_offset + m_range <= m_buff->getSize());
-
-			const GLuint tex = state.m_texBuffTextures[m_set][m_binding];
-			glTextureBufferRange(tex, m_fmt, static_cast<const BufferImpl&>(*m_buff).getGlName(), m_offset, m_range);
-
-			return Error::kNone;
-		}
-	};
-
-	Bool compressed;
-	GLenum format;
-	GLenum internalFormat;
-	GLenum type;
-	DepthStencilAspectBit dsAspect;
-	convertTextureInformation(fmt, compressed, format, internalFormat, type, dsAspect);
-	(void)compressed;
-	(void)format;
-	(void)type;
-	(void)dsAspect;
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	self.pushBackNewCommand<Cmd>(set, binding, buff, offset, range, internalFormat);
-}
-
-void CommandBuffer::bindShaderProgram(ShaderProgramPtr prog)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		ShaderProgramPtr m_prog;
-
-		Cmd(const ShaderProgramPtr& prog)
-			: m_prog(prog)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			state.m_crntProg = m_prog;
-			glUseProgram(static_cast<const ShaderProgramImpl&>(*m_prog).getGlName());
-			return Error::kNone;
-		}
-	};
-
-	ANKI_ASSERT(prog);
-	ANKI_GL_SELF(CommandBufferImpl);
-
-	if(self.m_state.bindShaderProgram(prog))
-	{
-		self.pushBackNewCommand<Cmd>(prog);
-	}
-	else
-	{
-		ANKI_TRACE_INC_COUNTER(GL_PROGS_SKIPPED, 1);
-	}
-}
-
-void CommandBuffer::beginRenderPass(FramebufferPtr fb, const Array<TextureUsageBit, kMaxColorRenderTargets>& colorAttachmentUsages,
-									TextureUsageBit depthStencilAttachmentUsage, U32 minx, U32 miny, U32 width, U32 height)
-{
-	class BindFramebufferCommand final : public GlCommand
-	{
-	public:
-		FramebufferPtr m_fb;
-		Array<U32, 4> m_renderArea;
-
-		BindFramebufferCommand(FramebufferPtr fb, U32 minx, U32 miny, U32 width, U32 height)
-			: m_fb(fb)
-			, m_renderArea{{minx, miny, width, height}}
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			static_cast<const FramebufferImpl&>(*m_fb).bind(state, m_renderArea[0], m_renderArea[1], m_renderArea[2], m_renderArea[3]);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	if(self.m_state.beginRenderPass(fb))
-	{
-		self.pushBackNewCommand<BindFramebufferCommand>(fb, minx, miny, width, height);
-	}
-}
-
-void CommandBuffer::endRenderPass()
-{
-	class Command final : public GlCommand
-	{
-	public:
-		const FramebufferImpl* m_fb;
-
-		Command(const FramebufferImpl* fb)
-			: m_fb(fb)
-		{
-			ANKI_ASSERT(fb);
-		}
-
-		Error operator()(GlState&)
-		{
-			m_fb->endRenderPass();
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	self.pushBackNewCommand<Command>(self.m_state.m_fb);
-	self.m_state.endRenderPass();
-}
-
-void CommandBuffer::drawElements(PrimitiveTopology topology, U32 count, U32 instanceCount, U32 firstIndex, U32 baseVertex, U32 baseInstance)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		GLenum m_topology;
-		GLenum m_indexType;
-		DrawElementsIndirectInfo m_info;
-
-		Cmd(GLenum topology, GLenum indexType, const DrawElementsIndirectInfo& info)
-			: m_topology(topology)
-			, m_indexType(indexType)
-			, m_info(info)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			glDrawElementsInstancedBaseVertexBaseInstance(m_topology, m_info.m_count, m_indexType, numberToPtr<void*>(m_info.m_firstIndex),
-														  m_info.m_instanceCount, m_info.m_baseVertex, m_info.m_baseInstance);
-
-			ANKI_TRACE_INC_COUNTER(GR_DRAWCALLS, 1);
-			ANKI_TRACE_INC_COUNTER(GR_VERTICES, m_info.m_instanceCount * m_info.m_count);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-
-	self.m_state.checkIndexedDracall();
-	self.flushDrawcall(*this);
-
-	U idxBytes;
-	if(self.m_state.m_idx.m_indexType == GL_UNSIGNED_SHORT)
-	{
-		idxBytes = sizeof(U16);
-	}
-	else
-	{
-		ANKI_ASSERT(self.m_state.m_idx.m_indexType == GL_UNSIGNED_INT);
-		idxBytes = sizeof(U32);
-	}
-
-	firstIndex = firstIndex * idxBytes + self.m_state.m_idx.m_offset;
-
-	DrawElementsIndirectInfo info(count, instanceCount, firstIndex, baseVertex, baseInstance);
-	self.pushBackNewCommand<Cmd>(convertPrimitiveTopology(topology), self.m_state.m_idx.m_indexType, info);
-}
-
-void CommandBuffer::drawArrays(PrimitiveTopology topology, U32 count, U32 instanceCount, U32 first, U32 baseInstance)
-{
-	class DrawArraysCommand final : public GlCommand
-	{
-	public:
-		GLenum m_topology;
-		DrawArraysIndirectInfo m_info;
-
-		DrawArraysCommand(GLenum topology, const DrawArraysIndirectInfo& info)
-			: m_topology(topology)
-			, m_info(info)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			glDrawArraysInstancedBaseInstance(m_topology, m_info.m_first, m_info.m_count, m_info.m_instanceCount, m_info.m_baseInstance);
-
-			ANKI_TRACE_INC_COUNTER(GR_DRAWCALLS, 1);
-			ANKI_TRACE_INC_COUNTER(GR_VERTICES, m_info.m_instanceCount * m_info.m_count);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-
-	self.m_state.checkNonIndexedDrawcall();
-	self.flushDrawcall(*this);
-
-	DrawArraysIndirectInfo info(count, instanceCount, first, baseInstance);
-	self.pushBackNewCommand<DrawArraysCommand>(convertPrimitiveTopology(topology), info);
-}
-
-void CommandBuffer::drawElementsIndirect(PrimitiveTopology topology, U32 drawCount, PtrSize offset, BufferPtr indirectBuff)
-{
-	class DrawElementsIndirectCommand final : public GlCommand
-	{
-	public:
-		GLenum m_topology;
-		GLenum m_indexType;
-		U32 m_drawCount;
-		PtrSize m_offset;
-		BufferPtr m_buff;
-
-		DrawElementsIndirectCommand(GLenum topology, GLenum indexType, U32 drawCount, PtrSize offset, BufferPtr buff)
-			: m_topology(topology)
-			, m_indexType(indexType)
-			, m_drawCount(drawCount)
-			, m_offset(offset)
-			, m_buff(buff)
-		{
-			ANKI_ASSERT(drawCount > 0);
-			ANKI_ASSERT((m_offset % 4) == 0);
-		}
-
-		Error operator()(GlState&)
-		{
-			const BufferImpl& buff = static_cast<const BufferImpl&>(*m_buff);
-
-			ANKI_ASSERT(m_offset + sizeof(DrawElementsIndirectInfo) * m_drawCount <= buff.getSize());
-
-			glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buff.getGlName());
-
-			glMultiDrawElementsIndirect(m_topology, m_indexType, numberToPtr<void*>(m_offset), m_drawCount, sizeof(DrawElementsIndirectInfo));
-
-			glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-
-	self.m_state.checkIndexedDracall();
-	self.flushDrawcall(*this);
-	self.pushBackNewCommand<DrawElementsIndirectCommand>(convertPrimitiveTopology(topology), self.m_state.m_idx.m_indexType, drawCount, offset,
-														 indirectBuff);
-}
-
-void CommandBuffer::drawArraysIndirect(PrimitiveTopology topology, U32 drawCount, PtrSize offset, BufferPtr indirectBuff)
-{
-	class DrawArraysIndirectCommand final : public GlCommand
-	{
-	public:
-		GLenum m_topology;
-		U32 m_drawCount;
-		PtrSize m_offset;
-		BufferPtr m_buff;
-
-		DrawArraysIndirectCommand(GLenum topology, U32 drawCount, PtrSize offset, BufferPtr buff)
-			: m_topology(topology)
-			, m_drawCount(drawCount)
-			, m_offset(offset)
-			, m_buff(buff)
-		{
-			ANKI_ASSERT(drawCount > 0);
-			ANKI_ASSERT((m_offset % 4) == 0);
-		}
-
-		Error operator()(GlState& state)
-		{
-			const BufferImpl& buff = static_cast<const BufferImpl&>(*m_buff);
-
-			ANKI_ASSERT(m_offset + sizeof(DrawArraysIndirectInfo) * m_drawCount <= buff.getSize());
-
-			glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buff.getGlName());
-
-			glMultiDrawArraysIndirect(m_topology, numberToPtr<void*>(m_offset), m_drawCount, sizeof(DrawArraysIndirectInfo));
-
-			glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	self.m_state.checkNonIndexedDrawcall();
-	self.flushDrawcall(*this);
-	self.pushBackNewCommand<DrawArraysIndirectCommand>(convertPrimitiveTopology(topology), drawCount, offset, indirectBuff);
-}
-
-void CommandBuffer::dispatchCompute(U32 groupCountX, U32 groupCountY, U32 groupCountZ)
-{
-	class DispatchCommand final : public GlCommand
-	{
-	public:
-		Array<U32, 3> m_size;
-
-		DispatchCommand(U32 x, U32 y, U32 z)
-			: m_size({{x, y, z}})
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			glDispatchCompute(m_size[0], m_size[1], m_size[2]);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-
-	ANKI_ASSERT(!!(self.m_flags & CommandBufferFlag::kComputeWork));
-	self.m_state.checkDispatch();
-	self.pushBackNewCommand<DispatchCommand>(groupCountX, groupCountY, groupCountZ);
-}
-
-void CommandBuffer::resetOcclusionQuery(OcclusionQueryPtr query)
-{
-	// Nothing for GL
-}
-
-void CommandBuffer::beginOcclusionQuery(OcclusionQueryPtr query)
-{
-	class OqBeginCommand final : public GlCommand
-	{
-	public:
-		OcclusionQueryPtr m_handle;
-
-		OqBeginCommand(const OcclusionQueryPtr& handle)
-			: m_handle(handle)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			static_cast<OcclusionQueryImpl&>(*m_handle).begin();
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	self.pushBackNewCommand<OqBeginCommand>(query);
-}
-
-void CommandBuffer::endOcclusionQuery(OcclusionQueryPtr query)
-{
-	class OqEndCommand final : public GlCommand
-	{
-	public:
-		OcclusionQueryPtr m_handle;
-
-		OqEndCommand(const OcclusionQueryPtr& handle)
-			: m_handle(handle)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			static_cast<OcclusionQueryImpl&>(*m_handle).end();
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	self.pushBackNewCommand<OqEndCommand>(query);
-}
-
-void CommandBuffer::copyBufferToTextureView(BufferPtr buff, PtrSize offset, PtrSize range, TextureViewPtr texView)
-{
-	class TexSurfUploadCommand final : public GlCommand
-	{
-	public:
-		BufferPtr m_buff;
-		PtrSize m_offset;
-		PtrSize m_range;
-		TextureViewPtr m_texView;
-
-		TexSurfUploadCommand(BufferPtr buff, PtrSize offset, PtrSize range, TextureViewPtr texView)
-			: m_buff(buff)
-			, m_offset(offset)
-			, m_range(range)
-			, m_texView(texView)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			const TextureViewImpl& viewImpl = static_cast<TextureViewImpl&>(*m_texView);
-			const TextureImpl& texImpl = static_cast<TextureImpl&>(*viewImpl.m_tex);
-
-			texImpl.copyFromBuffer(viewImpl.getSubresource(), static_cast<const BufferImpl&>(*m_buff).getGlName(), m_offset, m_range);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_ASSERT(texView);
-	ANKI_ASSERT(buff);
-	ANKI_ASSERT(range > 0);
-	ANKI_GL_SELF(CommandBufferImpl);
-	ANKI_ASSERT(!self.m_state.insideRenderPass());
-
-	self.pushBackNewCommand<TexSurfUploadCommand>(buff, offset, range, texView);
-}
-
-void CommandBuffer::copyBufferToBuffer(BufferPtr src, PtrSize srcOffset, BufferPtr dst, PtrSize dstOffset, PtrSize range)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		BufferPtr m_src;
-		PtrSize m_srcOffset;
-		BufferPtr m_dst;
-		PtrSize m_dstOffset;
-		PtrSize m_range;
-
-		Cmd(BufferPtr src, PtrSize srcOffset, BufferPtr dst, PtrSize dstOffset, PtrSize range)
-			: m_src(src)
-			, m_srcOffset(srcOffset)
-			, m_dst(dst)
-			, m_dstOffset(dstOffset)
-			, m_range(range)
-		{
-		}
-
-		Error operator()(GlState& state)
-		{
-			static_cast<BufferImpl&>(*m_dst).write(static_cast<const BufferImpl&>(*m_src).getGlName(), m_srcOffset, m_dstOffset, m_range);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_ASSERT(src);
-	ANKI_ASSERT(dst);
-	ANKI_ASSERT(range > 0);
-	ANKI_GL_SELF(CommandBufferImpl);
-	ANKI_ASSERT(!self.m_state.insideRenderPass());
-
-	self.pushBackNewCommand<Cmd>(src, srcOffset, dst, dstOffset, range);
-}
-
-void CommandBuffer::generateMipmaps2d(TextureViewPtr texView)
-{
-	class GenMipsCommand final : public GlCommand
-	{
-	public:
-		TextureViewPtr m_texView;
-
-		GenMipsCommand(const TextureViewPtr& view)
-			: m_texView(view)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			const TextureViewImpl& viewImpl = static_cast<TextureViewImpl&>(*m_texView);
-			const TextureImpl& texImpl = static_cast<TextureImpl&>(*viewImpl.m_tex);
-
-			texImpl.generateMipmaps2d(viewImpl);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	ANKI_ASSERT(!self.m_state.insideRenderPass());
-	self.pushBackNewCommand<GenMipsCommand>(texView);
-}
-
-void CommandBuffer::generateMipmaps3d(TextureViewPtr tex)
-{
-	ANKI_ASSERT(!!"TODO");
-}
-
-void CommandBuffer::pushSecondLevelCommandBuffer(CommandBufferPtr cmdb)
-{
-	class ExecCmdbCommand final : public GlCommand
-	{
-	public:
-		CommandBufferPtr m_cmdb;
-
-		ExecCmdbCommand(const CommandBufferPtr& cmdb)
-			: m_cmdb(cmdb)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			ANKI_TRACE_SCOPED_EVENT(GL_2ND_LEVEL_CMD_BUFFER);
-			return static_cast<CommandBufferImpl&>(*m_cmdb).executeAllCommands();
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	self.m_state.m_lastSecondLevelCmdb = static_cast<CommandBufferImpl*>(cmdb.get());
-	self.pushBackNewCommand<ExecCmdbCommand>(cmdb);
-}
-
-Bool CommandBuffer::isEmpty() const
-{
-	ANKI_GL_SELF_CONST(CommandBufferImpl);
-	return self.isEmpty();
-}
-
-void CommandBuffer::blitTextureViews(TextureViewPtr srcView, TextureViewPtr destView)
-{
-	ANKI_ASSERT(!"TODO");
-}
-
-void CommandBuffer::setBufferBarrier(BufferPtr buff, BufferUsageBit prevUsage, BufferUsageBit nextUsage, PtrSize offset, PtrSize size)
-{
-	class SetBufferMemBarrierCommand final : public GlCommand
-	{
-	public:
-		GLenum m_barrier;
-
-		SetBufferMemBarrierCommand(GLenum barrier)
-			: m_barrier(barrier)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			glMemoryBarrier(m_barrier);
-			return Error::kNone;
-		}
-	};
-
-	GLenum d = GL_NONE;
-	BufferUsageBit all = prevUsage | nextUsage;
-
-	if(!!(all & BufferUsageBit::UNIFORM_ALL))
-	{
-		d |= GL_UNIFORM_BARRIER_BIT;
-	}
-
-	if(!!(all & BufferUsageBit::STORAGE_ALL))
-	{
-		d |= GL_SHADER_STORAGE_BARRIER_BIT;
-	}
-
-	if(!!(all & BufferUsageBit::kIndex))
-	{
-		d |= GL_ELEMENT_ARRAY_BARRIER_BIT;
-	}
-
-	if(!!(all & BufferUsageBit::kVertex))
-	{
-		d |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT;
-	}
-
-	if(!!(all & BufferUsageBit::INDIRECT_ALL))
-	{
-		d |= GL_COMMAND_BARRIER_BIT;
-	}
-
-	if(!!(all & (BufferUsageBit::FILL | BufferUsageBit::BUFFER_UPLOAD_SOURCE | BufferUsageBit::BUFFER_UPLOAD_DESTINATION)))
-	{
-		d |= GL_BUFFER_UPDATE_BARRIER_BIT;
-	}
-
-	if(!!(all & BufferUsageBit::QUERY_RESULT))
-	{
-		d |= GL_QUERY_BUFFER_BARRIER_BIT;
-	}
-
-	ANKI_ASSERT(d);
-	ANKI_GL_SELF(CommandBufferImpl);
-	self.pushBackNewCommand<SetBufferMemBarrierCommand>(d);
-}
-
-void CommandBuffer::setTextureSurfaceBarrier(TexturePtr tex, TextureUsageBit prevUsage, TextureUsageBit nextUsage, const TextureSurfaceInfo& surf)
-{
-	TextureSubresourceInfo subresource;
-	setTextureBarrier(tex, prevUsage, nextUsage, subresource);
-}
-
-void CommandBuffer::setTextureVolumeBarrier(TexturePtr tex, TextureUsageBit prevUsage, TextureUsageBit nextUsage, const TextureVolumeInfo& vol)
-{
-	TextureSubresourceInfo subresource;
-	setTextureBarrier(tex, prevUsage, nextUsage, subresource);
-}
-
-void CommandBuffer::setTextureBarrier(TexturePtr tex, TextureUsageBit prevUsage, TextureUsageBit nextUsage, const TextureSubresourceInfo& subresource)
-{
-	class Cmd final : public GlCommand
-	{
-	public:
-		GLenum m_barrier;
-
-		Cmd(GLenum barrier)
-			: m_barrier(barrier)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			glMemoryBarrier(m_barrier);
-			return Error::kNone;
-		}
-	};
-
-	const TextureUsageBit usage = nextUsage;
-	GLenum e = 0;
-
-	if(!!(usage & TextureUsageBit::SAMPLED_ALL))
-	{
-		e |= GL_TEXTURE_FETCH_BARRIER_BIT;
-	}
-
-	if(!!(usage & TextureUsageBit::IMAGE_ALL))
-	{
-		e |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
-	}
-
-	if(!!(usage & TextureUsageBit::kTransferDestination))
-	{
-		e |= GL_TEXTURE_UPDATE_BARRIER_BIT;
-	}
-
-	if(!!(usage & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE))
-	{
-
-		e |= GL_FRAMEBUFFER_BARRIER_BIT;
-	}
-
-	if(!!(usage & TextureUsageBit::CLEAR))
-	{
-		// No idea
-	}
-
-	if(!!(usage & TextureUsageBit::kGenerateMipmaps))
-	{
-		// No idea
-	}
-
-	if(e != 0)
-	{
-		ANKI_GL_SELF(CommandBufferImpl);
-		self.pushBackNewCommand<Cmd>(e);
-	}
-}
-
-void CommandBuffer::clearTextureView(TextureViewPtr texView, const ClearValue& clearValue)
-{
-	class ClearTextCommand final : public GlCommand
-	{
-	public:
-		TextureViewPtr m_texView;
-		ClearValue m_val;
-
-		ClearTextCommand(TextureViewPtr texView, const ClearValue& val)
-			: m_texView(texView)
-			, m_val(val)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			const TextureViewImpl& viewImpl = static_cast<TextureViewImpl&>(*m_texView);
-			const TextureImpl& texImpl = static_cast<TextureImpl&>(*viewImpl.m_tex);
-
-			texImpl.clear(viewImpl.getSubresource(), m_val);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	ANKI_ASSERT(!self.m_state.insideRenderPass());
-	self.pushBackNewCommand<ClearTextCommand>(texView, clearValue);
-}
-
-void CommandBuffer::fillBuffer(BufferPtr buff, PtrSize offset, PtrSize size, U32 value)
-{
-	class FillBufferCommand final : public GlCommand
-	{
-	public:
-		BufferPtr m_buff;
-		PtrSize m_offset;
-		PtrSize m_size;
-		U32 m_value;
-
-		FillBufferCommand(BufferPtr buff, PtrSize offset, PtrSize size, U32 value)
-			: m_buff(buff)
-			, m_offset(offset)
-			, m_size(size)
-			, m_value(value)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			static_cast<BufferImpl&>(*m_buff).fill(m_offset, m_size, m_value);
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	ANKI_ASSERT(!self.m_state.insideRenderPass());
-	self.pushBackNewCommand<FillBufferCommand>(buff, offset, size, value);
-}
-
-void CommandBuffer::writeOcclusionQueryResultToBuffer(OcclusionQueryPtr query, PtrSize offset, BufferPtr buff)
-{
-	class WriteOcclResultToBuff final : public GlCommand
-	{
-	public:
-		OcclusionQueryPtr m_query;
-		PtrSize m_offset;
-		BufferPtr m_buff;
-
-		WriteOcclResultToBuff(OcclusionQueryPtr query, PtrSize offset, BufferPtr buff)
-			: m_query(query)
-			, m_offset(offset)
-			, m_buff(buff)
-		{
-			ANKI_ASSERT((m_offset % 4) == 0);
-		}
-
-		Error operator()(GlState&)
-		{
-			const BufferImpl& buff = static_cast<const BufferImpl&>(*m_buff);
-			ANKI_ASSERT(m_offset + 4 <= buff.getSize());
-
-			glBindBuffer(GL_QUERY_BUFFER, buff.getGlName());
-			glGetQueryObjectuiv(static_cast<const OcclusionQueryImpl&>(*m_query).getGlName(), GL_QUERY_RESULT, numberToPtr<GLuint*>(m_offset));
-			glBindBuffer(GL_QUERY_BUFFER, 0);
-
-			return Error::kNone;
-		}
-	};
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	ANKI_ASSERT(!self.m_state.insideRenderPass());
-	self.pushBackNewCommand<WriteOcclResultToBuff>(query, offset, buff);
-}
-
-void CommandBuffer::setPushConstants(const void* data, U32 dataSize)
-{
-	class PushConstants final : public GlCommand
-	{
-	public:
-		DynamicArrayRaii<Vec4> m_data;
-
-		PushConstants(const void* data, U32 dataSize, const CommandBufferAllocator<F32>& alloc)
-			: m_data(alloc)
-		{
-			m_data.create(dataSize / sizeof(Vec4));
-			memcpy(&m_data[0], data, dataSize);
-		}
-
-		Error operator()(GlState& state)
-		{
-			const ShaderProgramImplReflection& refl = static_cast<ShaderProgramImpl&>(*state.m_crntProg).getReflection();
-			ANKI_ASSERT(refl.m_uniformDataSize == m_data.getSizeInBytes());
-
-			const Bool transpose = true;
-			for(const ShaderProgramImplReflection::Uniform& uni : refl.m_uniforms)
-			{
-				const U8* data = reinterpret_cast<const U8*>(&m_data[0]) + uni.m_pushConstantOffset;
-				const U count = uni.m_arrSize;
-				const GLint loc = uni.m_location;
-
-				switch(uni.m_type)
-				{
-				case ShaderVariableDataType::VEC4:
-					glUniform4fv(loc, count, reinterpret_cast<const GLfloat*>(data));
-					break;
-				case ShaderVariableDataType::IVEC4:
-					glUniform4iv(loc, count, reinterpret_cast<const GLint*>(data));
-					break;
-				case ShaderVariableDataType::UVEC4:
-					glUniform4uiv(loc, count, reinterpret_cast<const GLuint*>(data));
-					break;
-				case ShaderVariableDataType::MAT4:
-					glUniformMatrix4fv(loc, count, transpose, reinterpret_cast<const GLfloat*>(data));
-					break;
-				case ShaderVariableDataType::MAT3:
-				{
-					// Remove the padding
-					ANKI_ASSERT(count == 1 && "TODO");
-					const Mat3x4* m34 = reinterpret_cast<const Mat3x4*>(data);
-					Mat3 m3(m34->getRotationPart());
-					glUniformMatrix3fv(loc, count, transpose, reinterpret_cast<const GLfloat*>(&m3));
-					break;
-				}
-				default:
-					ANKI_ASSERT(!"TODO");
-				}
-			}
-
-			return Error::kNone;
-		}
-	};
-
-	ANKI_ASSERT(data);
-	ANKI_ASSERT(dataSize);
-	ANKI_ASSERT(dataSize % 16 == 0);
-
-	ANKI_GL_SELF(CommandBufferImpl);
-	self.pushBackNewCommand<PushConstants>(data, dataSize, self.m_alloc);
-}
-
-void CommandBuffer::setRasterizationOrder(RasterizationOrder order)
-{
-	// Nothing for GL
-}
-
-} // end namespace anki

+ 0 - 334
AnKi/Gr/Gl/CommandBufferImpl.cpp

@@ -1,334 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Gr/gl/GrManagerImpl.h>
-#include <AnKi/Gr/gl/GlState.h>
-#include <AnKi/Gr/gl/Error.h>
-
-#include <AnKi/Gr/OcclusionQuery.h>
-#include <AnKi/Gr/gl/OcclusionQueryImpl.h>
-#include <AnKi/Gr/Buffer.h>
-#include <AnKi/Gr/gl/BufferImpl.h>
-
-#include <AnKi/Util/Logger.h>
-#include <AnKi/Core/Trace.h>
-#include <cstring>
-
-namespace anki {
-
-void CommandBufferImpl::init(const CommandBufferInitInfo& init)
-{
-	auto& pool = getManager().getAllocator().getMemoryPool();
-
-	m_alloc = CommandBufferAllocator<GlCommand*>(pool.getAllocationCallback(), pool.getAllocationCallbackUserData(), init.m_hints.m_chunkSize, 1.0, 0,
-												 false);
-
-	m_flags = init.m_flags;
-
-#if ANKI_EXTRA_CHECKS
-	m_state.m_secondLevel = !!(init.m_flags & CommandBufferFlag::kSecondLevel);
-#endif
-
-	if(!!(init.m_flags & CommandBufferFlag::kSecondLevel))
-	{
-		// TODO Need to hold a ref
-		m_state.m_fb = static_cast<const FramebufferImpl*>(init.m_framebuffer.get());
-	}
-}
-
-void CommandBufferImpl::destroy()
-{
-	ANKI_TRACE_SCOPED_EVENT(GL_CMD_BUFFER_DESTROY);
-
-#if ANKI_EXTRA_CHECKS
-	if(!m_executed && m_firstCommand)
-	{
-		ANKI_GL_LOGW("Chain contains commands but never executed. This should only happen on exceptions");
-	}
-#endif
-
-	GlCommand* command = m_firstCommand;
-	while(command != nullptr)
-	{
-		GlCommand* next = command->m_nextCommand; // Get next before deleting
-		m_alloc.deleteInstance(command);
-		command = next;
-	}
-
-	ANKI_ASSERT(m_alloc.getMemoryPool().getUsersCount() == 1 && "Someone is holding a reference to the command buffer's allocator");
-
-	m_alloc = CommandBufferAllocator<U8>();
-}
-
-Error CommandBufferImpl::executeAllCommands()
-{
-	ANKI_ASSERT(m_firstCommand != nullptr && "Empty command buffer");
-	ANKI_ASSERT(m_lastCommand != nullptr && "Empty command buffer");
-#if ANKI_EXTRA_CHECKS
-	m_executed = true;
-#endif
-
-	Error err = Error::kNone;
-	GlState& state = static_cast<GrManagerImpl&>(getManager()).getState();
-
-	GlCommand* command = m_firstCommand;
-
-	while(command != nullptr && !err)
-	{
-		err = (*command)(state);
-		ANKI_CHECK_GL_ERROR();
-
-		command = command->m_nextCommand;
-	}
-
-	return err;
-}
-
-void CommandBufferImpl::flushDrawcall(CommandBuffer& cmdb)
-{
-	ANKI_ASSERT(!!(m_flags & CommandBufferFlag::GRAPHICS_WORK));
-
-	//
-	// Set default state
-	//
-	if(m_state.m_mayContainUnsetState) [[unlikely]]
-	{
-		m_state.m_mayContainUnsetState = false;
-
-		if(m_state.m_primitiveRestart == 2)
-		{
-			cmdb.setPrimitiveRestart(false);
-		}
-
-		if(m_state.m_fillMode == FillMode::COUNT)
-		{
-			cmdb.setFillMode(FillMode::SOLID);
-		}
-
-		if(m_state.m_cullMode == static_cast<FaceSelectionBit>(0))
-		{
-			cmdb.setCullMode(FaceSelectionBit::BACK);
-		}
-
-		if(m_state.m_polyOffsetFactor == -1.0)
-		{
-			cmdb.setPolygonOffset(0.0, 0.0);
-		}
-
-		for(U i = 0; i < 2; ++i)
-		{
-			FaceSelectionBit face = (i == 0) ? FaceSelectionBit::FRONT : FaceSelectionBit::BACK;
-
-			if(m_state.m_stencilFail[i] == StencilOperation::COUNT)
-			{
-				cmdb.setStencilOperations(face, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP);
-			}
-
-			if(m_state.m_stencilCompare[i] == CompareOperation::COUNT)
-			{
-				cmdb.setStencilCompareOperation(face, CompareOperation::ALWAYS);
-			}
-
-			if(m_state.m_stencilCompareMask[i] == StateTracker::DUMMY_STENCIL_MASK)
-			{
-				cmdb.setStencilCompareMask(face, kMaxU32);
-			}
-
-			if(m_state.m_stencilWriteMask[i] == StateTracker::DUMMY_STENCIL_MASK)
-			{
-				cmdb.setStencilWriteMask(face, kMaxU32);
-			}
-
-			if(m_state.m_stencilRef[i] == StateTracker::DUMMY_STENCIL_MASK)
-			{
-				cmdb.setStencilReference(face, 0);
-			}
-		}
-
-		if(m_state.m_depthWrite == 2)
-		{
-			cmdb.setDepthWrite(true);
-		}
-
-		if(m_state.m_depthOp == CompareOperation::COUNT)
-		{
-			cmdb.setDepthCompareOperation(CompareOperation::LESS);
-		}
-
-		for(U i = 0; i < kMaxColorRenderTargets; ++i)
-		{
-			const auto& att = m_state.m_colorAtt[i];
-			if(att.m_writeMask == StateTracker::INVALID_COLOR_MASK)
-			{
-				cmdb.setColorChannelWriteMask(i, ColorBit::ALL);
-			}
-
-			if(att.m_blendSrcFactorRgb == BlendFactor::COUNT)
-			{
-				cmdb.setBlendFactors(i, BlendFactor::ONE, BlendFactor::ZERO, BlendFactor::ONE, BlendFactor::ZERO);
-			}
-
-			if(att.m_blendOpRgb == BlendOperation::COUNT)
-			{
-				cmdb.setBlendOperation(i, BlendOperation::ADD, BlendOperation::ADD);
-			}
-		}
-
-		if(!m_state.m_scissorSet)
-		{
-			cmdb.setScissor(0, 0, kMaxU32, kMaxU32);
-		}
-	}
-
-	//
-	// Fire commands to change some state
-	//
-	class StencilCmd final : public GlCommand
-	{
-	public:
-		GLenum m_face;
-		GLenum m_func;
-		GLint m_ref;
-		GLuint m_compareMask;
-
-		StencilCmd(GLenum face, GLenum func, GLint ref, GLuint mask)
-			: m_face(face)
-			, m_func(func)
-			, m_ref(ref)
-			, m_compareMask(mask)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			glStencilFuncSeparate(m_face, m_func, m_ref, m_compareMask);
-			return Error::kNone;
-		}
-	};
-
-	for(U i = 0; i < 2; ++i)
-	{
-		if(m_state.m_glStencilFuncSeparateDirty[i])
-		{
-			pushBackNewCommand<StencilCmd>(GL_FRONT + i, convertCompareOperation(m_state.m_stencilCompare[i]), m_state.m_stencilRef[i],
-										   m_state.m_stencilCompareMask[i]);
-
-			m_state.m_glStencilFuncSeparateDirty[i] = false;
-		}
-	}
-
-	class DepthTestCmd final : public GlCommand
-	{
-	public:
-		Bool m_enable;
-
-		DepthTestCmd(Bool enable)
-			: m_enable(enable)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			if(m_enable)
-			{
-				glEnable(GL_DEPTH_TEST);
-			}
-			else
-			{
-				glDisable(GL_DEPTH_TEST);
-			}
-			return Error::kNone;
-		}
-	};
-
-	if(m_state.maybeEnableDepthTest())
-	{
-		pushBackNewCommand<DepthTestCmd>(m_state.m_depthTestEnabled);
-	}
-
-	class StencilTestCmd final : public GlCommand
-	{
-	public:
-		Bool m_enable;
-
-		StencilTestCmd(Bool enable)
-			: m_enable(enable)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			if(m_enable)
-			{
-				glEnable(GL_STENCIL_TEST);
-			}
-			else
-			{
-				glDisable(GL_STENCIL_TEST);
-			}
-			return Error::kNone;
-		}
-	};
-
-	if(m_state.maybeEnableStencilTest())
-	{
-		pushBackNewCommand<StencilTestCmd>(m_state.m_stencilTestEnabled);
-	}
-
-	class BlendCmd final : public GlCommand
-	{
-	public:
-		U8 m_enableMask;
-		U8 m_disableMask;
-
-		BlendCmd(U8 enableMask, U8 disableMask)
-			: m_enableMask(enableMask)
-			, m_disableMask(disableMask)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			for(U i = 0; i < kMaxColorRenderTargets; ++i)
-			{
-				if(m_enableMask & (1 << i))
-				{
-					glEnablei(GL_BLEND, i);
-				}
-				else if(m_disableMask & (1 << i))
-				{
-					glDisablei(GL_BLEND, i);
-				}
-			}
-			return Error::kNone;
-		}
-	};
-
-	U8 blendEnableMask = 0;
-	U8 blendDisableMask = 0;
-	for(U i = 0; i < kMaxColorRenderTargets; ++i)
-	{
-		if(m_state.maybeEnableBlend(i))
-		{
-			if(m_state.m_colorAtt[i].m_enableBlend)
-			{
-				blendEnableMask |= 1 << i;
-			}
-			else
-			{
-				blendDisableMask |= 1 << i;
-			}
-		}
-	}
-
-	if(blendEnableMask || blendDisableMask)
-	{
-		pushBackNewCommand<BlendCmd>(blendEnableMask, blendDisableMask);
-	}
-}
-
-} // end namespace anki

+ 0 - 132
AnKi/Gr/Gl/CommandBufferImpl.h

@@ -1,132 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/CommandBuffer.h>
-#include <AnKi/Gr/gl/StateTracker.h>
-#include <AnKi/Util/Assert.h>
-
-namespace anki {
-
-// Forward
-class GlState;
-
-/// @addtogroup opengl
-/// @{
-
-template<typename T>
-using CommandBufferAllocator = StackAllocator<T>;
-
-/// The base of all GL commands.
-class GlCommand
-{
-public:
-	GlCommand* m_nextCommand = nullptr;
-
-	virtual ~GlCommand()
-	{
-	}
-
-	/// Execute command
-	virtual ANKI_USE_RESULT Error operator()(GlState& state) = 0;
-};
-
-/// A number of GL commands organized in a chain
-class CommandBufferImpl final : public CommandBuffer
-{
-public:
-	GlCommand* m_firstCommand = nullptr;
-	GlCommand* m_lastCommand = nullptr;
-	CommandBufferAllocator<U8> m_alloc;
-	Bool m_immutable = false;
-	CommandBufferFlag m_flags;
-
-#if ANKI_EXTRA_CHECKS
-	Bool m_executed = false;
-#endif
-
-	StateTracker m_state;
-
-	/// Default constructor
-	CommandBufferImpl(GrManager* manager, CString name)
-		: CommandBuffer(manager, name)
-	{
-	}
-
-	~CommandBufferImpl()
-	{
-		destroy();
-	}
-
-	/// Initialize.
-	void init(const CommandBufferInitInfo& init);
-
-	/// Get the internal allocator.
-	CommandBufferAllocator<U8> getInternalAllocator() const
-	{
-		return m_alloc;
-	}
-
-	/// Create a new command and add it to the chain.
-	template<typename TCommand, typename... TArgs>
-	void pushBackNewCommand(TArgs&&... args);
-
-	/// Execute all commands
-	ANKI_USE_RESULT Error executeAllCommands();
-
-	/// Fake that it's been executed
-	void makeExecuted()
-	{
-#if ANKI_EXTRA_CHECKS
-		m_executed = true;
-#endif
-	}
-
-	/// Make immutable
-	void makeImmutable()
-	{
-		m_immutable = true;
-	}
-
-	Bool isEmpty() const
-	{
-		return m_firstCommand == nullptr;
-	}
-
-	Bool isSecondLevel() const
-	{
-		return !!(m_flags & CommandBufferFlag::kSecondLevel);
-	}
-
-	void flushDrawcall(CommandBuffer& cmdb);
-
-private:
-	void destroy();
-};
-
-template<typename TCommand, typename... TArgs>
-inline void CommandBufferImpl::pushBackNewCommand(TArgs&&... args)
-{
-	ANKI_ASSERT(!m_immutable);
-	TCommand* newCommand = m_alloc.template newInstance<TCommand>(std::forward<TArgs>(args)...);
-
-	if(m_firstCommand != nullptr)
-	{
-		ANKI_ASSERT(m_lastCommand != nullptr);
-		ANKI_ASSERT(m_lastCommand->m_nextCommand == nullptr);
-		m_lastCommand->m_nextCommand = newCommand;
-		m_lastCommand = newCommand;
-	}
-	else
-	{
-		ANKI_ASSERT(m_lastCommand == nullptr);
-		m_firstCommand = newCommand;
-		m_lastCommand = newCommand;
-	}
-}
-/// @}
-
-} // end namespace anki

+ 0 - 468
AnKi/Gr/Gl/Common.cpp

@@ -1,468 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/Common.h>
-
-namespace anki {
-
-GLenum convertCompareOperation(CompareOperation in)
-{
-	GLenum out = GL_NONE;
-
-	switch(in)
-	{
-	case CompareOperation::ALWAYS:
-		out = GL_ALWAYS;
-		break;
-	case CompareOperation::LESS:
-		out = GL_LESS;
-		break;
-	case CompareOperation::EQUAL:
-		out = GL_EQUAL;
-		break;
-	case CompareOperation::LESS_EQUAL:
-		out = GL_LEQUAL;
-		break;
-	case CompareOperation::GREATER:
-		out = GL_GREATER;
-		break;
-	case CompareOperation::GREATER_EQUAL:
-		out = GL_GEQUAL;
-		break;
-	case CompareOperation::NOT_EQUAL:
-		out = GL_NOTEQUAL;
-		break;
-	case CompareOperation::NEVER:
-		out = GL_NEVER;
-		break;
-	default:
-		ANKI_ASSERT(0);
-	}
-
-	return out;
-}
-
-GLenum convertStencilOperation(StencilOperation in)
-{
-	GLenum out = GL_NONE;
-
-	switch(in)
-	{
-	case StencilOperation::KEEP:
-		out = GL_KEEP;
-		break;
-	case StencilOperation::ZERO:
-		out = GL_ZERO;
-		break;
-	case StencilOperation::REPLACE:
-		out = GL_REPLACE;
-		break;
-	case StencilOperation::INCREMENT_AND_CLAMP:
-		out = GL_INCR;
-		break;
-	case StencilOperation::DECREMENT_AND_CLAMP:
-		out = GL_DECR;
-		break;
-	case StencilOperation::INVERT:
-		out = GL_INVERT;
-		break;
-	case StencilOperation::INCREMENT_AND_WRAP:
-		out = GL_INCR_WRAP;
-		break;
-	case StencilOperation::DECREMENT_AND_WRAP:
-		out = GL_DECR_WRAP;
-		break;
-	default:
-		ANKI_ASSERT(0);
-	}
-
-	return out;
-}
-
-void convertFilter(SamplingFilter minMagFilter, SamplingFilter mipFilter, GLenum& minFilter, GLenum& magFilter)
-{
-	switch(minMagFilter)
-	{
-	case SamplingFilter::kNearest:
-		magFilter = GL_NEAREST;
-		switch(mipFilter)
-		{
-		case SamplingFilter::kNearest:
-			minFilter = GL_NEAREST_MIPMAP_NEAREST;
-			break;
-		case SamplingFilter::kLinear:
-			minFilter = GL_NEAREST_MIPMAP_LINEAR;
-			break;
-		case SamplingFilter::kBase:
-			minFilter = GL_NEAREST;
-			break;
-		default:
-			ANKI_ASSERT(0);
-		}
-		break;
-	case SamplingFilter::kLinear:
-		magFilter = GL_LINEAR;
-		switch(mipFilter)
-		{
-		case SamplingFilter::kNearest:
-			minFilter = GL_LINEAR_MIPMAP_NEAREST;
-			break;
-		case SamplingFilter::kLinear:
-			minFilter = GL_LINEAR_MIPMAP_LINEAR;
-			break;
-		case SamplingFilter::kBase:
-			minFilter = GL_LINEAR;
-			break;
-		default:
-			ANKI_ASSERT(0);
-		}
-		break;
-	default:
-		ANKI_ASSERT(0);
-		break;
-	}
-}
-
-void convertVertexFormat(Format fmt, U& compCount, GLenum& type, Bool& normalized)
-{
-	switch(fmt)
-	{
-	case Format::kR32_Sfloat:
-		compCount = 1;
-		type = GL_FLOAT;
-		normalized = false;
-		break;
-	case Format::kR32G32_Sfloat:
-		compCount = 2;
-		type = GL_FLOAT;
-		normalized = false;
-		break;
-	case Format::kR32G32B32_Sfloat:
-		compCount = 3;
-		type = GL_FLOAT;
-		normalized = false;
-		break;
-	case Format::R32G32B32A32_SFLOAT:
-		compCount = 4;
-		type = GL_FLOAT;
-		normalized = false;
-		break;
-	case Format::R16G16_SFLOAT:
-		compCount = 2;
-		type = GL_HALF_FLOAT;
-		normalized = false;
-		break;
-	case Format::R16G16_UNORM:
-		compCount = 2;
-		type = GL_UNSIGNED_SHORT;
-		normalized = true;
-		break;
-	case Format::R16G16B16_SFLOAT:
-		compCount = 3;
-		type = GL_HALF_FLOAT;
-		normalized = false;
-		break;
-	case Format::R16G16B16_UNORM:
-		compCount = 3;
-		type = GL_UNSIGNED_SHORT;
-		normalized = true;
-		break;
-	case Format::R16G16B16A16_SFLOAT:
-		compCount = 4;
-		type = GL_HALF_FLOAT;
-		normalized = false;
-		break;
-	case Format::A2B10G10R10_SNORM_PACK32:
-		compCount = 4;
-		type = GL_INT_2_10_10_10_REV;
-		normalized = true;
-		break;
-	case Format::kR8G8B8A8_Unorm:
-		compCount = 4;
-		type = GL_UNSIGNED_BYTE;
-		normalized = true;
-		break;
-	case Format::R8G8B8_UNORM:
-		compCount = 3;
-		type = GL_UNSIGNED_BYTE;
-		normalized = true;
-		break;
-	case Format::R16G16B16A16_UINT:
-		compCount = 4;
-		type = GL_UNSIGNED_SHORT;
-		normalized = false;
-		break;
-	default:
-		ANKI_ASSERT(!"TODO");
-	}
-}
-
-GLenum convertBlendFactor(BlendFactor in)
-{
-	GLenum out;
-
-	switch(in)
-	{
-	case BlendFactor::ZERO:
-		out = GL_ZERO;
-		break;
-	case BlendFactor::ONE:
-		out = GL_ONE;
-		break;
-	case BlendFactor::SRC_COLOR:
-		out = GL_SRC_COLOR;
-		break;
-	case BlendFactor::ONE_MINUS_SRC_COLOR:
-		out = GL_ONE_MINUS_SRC_COLOR;
-		break;
-	case BlendFactor::DST_COLOR:
-		out = GL_DST_COLOR;
-		break;
-	case BlendFactor::ONE_MINUS_DST_COLOR:
-		out = GL_ONE_MINUS_DST_COLOR;
-		break;
-	case BlendFactor::SRC_ALPHA:
-		out = GL_SRC_ALPHA;
-		break;
-	case BlendFactor::ONE_MINUS_SRC_ALPHA:
-		out = GL_ONE_MINUS_SRC_ALPHA;
-		break;
-	case BlendFactor::DST_ALPHA:
-		out = GL_DST_ALPHA;
-		break;
-	case BlendFactor::ONE_MINUS_DST_ALPHA:
-		out = GL_ONE_MINUS_DST_ALPHA;
-		break;
-	case BlendFactor::CONSTANT_COLOR:
-		out = GL_CONSTANT_COLOR;
-		break;
-	case BlendFactor::ONE_MINUS_CONSTANT_COLOR:
-		out = GL_ONE_MINUS_CONSTANT_COLOR;
-		break;
-	case BlendFactor::CONSTANT_ALPHA:
-		out = GL_CONSTANT_ALPHA;
-		break;
-	case BlendFactor::ONE_MINUS_CONSTANT_ALPHA:
-		out = GL_ONE_MINUS_CONSTANT_ALPHA;
-		break;
-	case BlendFactor::SRC_ALPHA_SATURATE:
-		out = GL_SRC_ALPHA_SATURATE;
-		break;
-	case BlendFactor::SRC1_COLOR:
-		out = GL_SRC1_COLOR;
-		break;
-	case BlendFactor::ONE_MINUS_SRC1_COLOR:
-		out = GL_ONE_MINUS_SRC1_COLOR;
-		break;
-	case BlendFactor::SRC1_ALPHA:
-		out = GL_SRC1_ALPHA;
-		break;
-	case BlendFactor::ONE_MINUS_SRC1_ALPHA:
-		out = GL_ONE_MINUS_SRC1_ALPHA;
-		break;
-	default:
-		ANKI_ASSERT(0);
-		out = 0;
-	}
-
-	return out;
-}
-
-void convertTextureInformation(Format pf, Bool& compressed, GLenum& format, GLenum& internalFormat, GLenum& type, DepthStencilAspectBit& dsAspect)
-{
-	compressed = formatIsCompressed(pf);
-	dsAspect = computeFormatAspect(pf);
-	format = GL_NONE;
-	internalFormat = GL_NONE;
-	type = GL_NONE;
-
-	switch(pf)
-	{
-	case Format::BC1_RGB_UNORM_BLOCK:
-		format = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
-		internalFormat = format;
-		type = GL_UNSIGNED_BYTE;
-		break;
-	case Format::BC3_UNORM_BLOCK:
-		format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
-		internalFormat = format;
-		type = GL_UNSIGNED_BYTE;
-		break;
-	case Format::BC6H_UFLOAT_BLOCK:
-		format = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
-		internalFormat = format;
-		type = GL_FLOAT;
-		break;
-	case Format::R8_UNORM:
-		format = GL_RED;
-		internalFormat = GL_R8;
-		type = GL_UNSIGNED_BYTE;
-		break;
-	case Format::R8_SNORM:
-		format = GL_RED;
-		internalFormat = GL_R8_SNORM;
-		type = GL_BYTE;
-		break;
-	case Format::R8G8_UNORM:
-		format = GL_RG;
-		internalFormat = GL_RG8;
-		type = GL_UNSIGNED_BYTE;
-		break;
-	case Format::R8G8_SNORM:
-		format = GL_RG;
-		internalFormat = GL_RG8_SNORM;
-		type = GL_BYTE;
-		break;
-	case Format::R8G8B8_UNORM:
-		format = GL_RGB;
-		internalFormat = GL_RGB8;
-		type = GL_UNSIGNED_BYTE;
-		break;
-	case Format::R8G8B8_SNORM:
-		format = GL_RGB;
-		internalFormat = GL_RGB8_SNORM;
-		type = GL_BYTE;
-		break;
-	case Format::R8G8B8_UINT:
-		format = GL_RGB;
-		internalFormat = GL_RGB8UI;
-		type = GL_RGB_INTEGER;
-		break;
-	case Format::R8G8B8_SINT:
-		format = GL_RGB;
-		internalFormat = GL_RGB8I;
-		type = GL_RGB_INTEGER;
-		break;
-	case Format::kR8G8B8A8_Unorm:
-		format = GL_RGBA;
-		internalFormat = GL_RGBA8;
-		type = GL_UNSIGNED_BYTE;
-		break;
-	case Format::R8G8B8A8_SNORM:
-		format = GL_RGBA;
-		internalFormat = GL_RGBA8_SNORM;
-		type = GL_BYTE;
-		break;
-	case Format::R16_SFLOAT:
-		format = GL_R;
-		internalFormat = GL_R16F;
-		type = GL_FLOAT;
-		break;
-	case Format::R16_UINT:
-		format = GL_R;
-		internalFormat = GL_R16UI;
-		type = GL_UNSIGNED_SHORT;
-		break;
-	case Format::R16_UNORM:
-		format = GL_R;
-		internalFormat = GL_R16;
-		type = GL_UNSIGNED_SHORT;
-		break;
-	case Format::R16G16_UNORM:
-		format = GL_RG;
-		internalFormat = GL_RG16;
-		type = GL_UNSIGNED_SHORT;
-		break;
-	case Format::R16G16_SNORM:
-		format = GL_RG;
-		internalFormat = GL_RG16_SNORM;
-		type = GL_SHORT;
-		break;
-	case Format::R16G16B16_SFLOAT:
-		format = GL_RGB;
-		internalFormat = GL_RGB16F;
-		type = GL_FLOAT;
-		break;
-	case Format::R16G16B16_UINT:
-		format = GL_RGB_INTEGER;
-		internalFormat = GL_RGB16UI;
-		type = GL_UNSIGNED_INT;
-		break;
-	case Format::R16G16B16A16_SFLOAT:
-		format = GL_RGBA;
-		internalFormat = GL_RGBA16F;
-		type = GL_FLOAT;
-		break;
-	case Format::R16G16B16A16_UINT:
-		format = GL_RGBA;
-		internalFormat = GL_RGBA16UI;
-		type = GL_UNSIGNED_SHORT;
-		break;
-	case Format::kR32_Sfloat:
-		format = GL_R;
-		internalFormat = GL_R32F;
-		type = GL_FLOAT;
-		break;
-	case Format::R32_UINT:
-		format = GL_RG_INTEGER;
-		internalFormat = GL_R32UI;
-		type = GL_UNSIGNED_INT;
-		break;
-	case Format::kR32G32_Sfloat:
-		format = GL_RG;
-		internalFormat = GL_RG32F;
-		type = GL_FLOAT;
-		break;
-	case Format::kR32G32_Uint:
-		format = GL_RG_INTEGER;
-		internalFormat = GL_RG32UI;
-		type = GL_UNSIGNED_INT;
-		break;
-	case Format::kR32G32B32_Sfloat:
-		format = GL_RGB;
-		internalFormat = GL_RGB32F;
-		type = GL_FLOAT;
-		break;
-	case Format::R32G32B32_UINT:
-		format = GL_RGB_INTEGER;
-		internalFormat = GL_RGB32UI;
-		type = GL_UNSIGNED_INT;
-		break;
-	case Format::R32G32B32A32_SFLOAT:
-		format = GL_RGBA;
-		internalFormat = GL_RGBA32F;
-		type = GL_FLOAT;
-		break;
-	case Format::R32G32B32A32_UINT:
-		format = GL_RGBA_INTEGER;
-		internalFormat = GL_RGBA32UI;
-		type = GL_UNSIGNED_INT;
-		break;
-	case Format::B10G11R11_UFLOAT_PACK32:
-		format = GL_RGB;
-		internalFormat = GL_R11F_G11F_B10F;
-		type = GL_FLOAT;
-		break;
-	case Format::A2B10G10R10_UNORM_PACK32:
-		format = GL_RGBA;
-		internalFormat = GL_RGB10_A2;
-		type = GL_UNSIGNED_INT;
-		break;
-	case Format::D24_UNORM_S8_UINT:
-		format = GL_DEPTH_STENCIL;
-		internalFormat = GL_DEPTH24_STENCIL8;
-		type = GL_UNSIGNED_INT;
-		break;
-	case Format::D16_UNORM_S8_UINT:
-		format = GL_DEPTH_COMPONENT;
-		internalFormat = GL_DEPTH_COMPONENT16;
-		type = GL_UNSIGNED_SHORT;
-		break;
-	case Format::D32_SFLOAT:
-		format = GL_DEPTH_COMPONENT;
-		internalFormat = GL_DEPTH_COMPONENT32;
-		type = GL_UNSIGNED_INT;
-		break;
-	case Format::S8_UINT:
-		format = GL_STENCIL_INDEX;
-		internalFormat = GL_STENCIL_INDEX8;
-		type = GL_BYTE;
-		break;
-	default:
-		ANKI_ASSERT(!"TODO");
-	}
-}
-
-} // end namespace anki

+ 0 - 183
AnKi/Gr/Gl/Common.h

@@ -1,183 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/Common.h>
-
-#if ANKI_GL == ANKI_GL_DESKTOP
-#	if ANKI_OS == ANKI_OS_WINDOWS && !defined(GLEW_STATIC)
-#		define GLEW_STATIC
-#	endif
-#	include <GL/glew.h>
-#	if !defined(ANKI_GLEW_H)
-#		error "Wrong GLEW included"
-#	endif
-#elif ANKI_GL == ANKI_GL_ES
-#	include <GLES3/gl3.h>
-#else
-#	error "See file"
-#endif
-
-namespace anki {
-
-// Forward
-class GlState;
-class RenderingThread;
-
-/// @addtogroup opengl
-/// @{
-
-#define ANKI_GL_LOGI(...) ANKI_LOG("GL  ", kNormal, __VA_ARGS__)
-#define ANKI_GL_LOGE(...) ANKI_LOG("GL  ", kError, __VA_ARGS__)
-#define ANKI_GL_LOGW(...) ANKI_LOG("GL  ", kWarning, __VA_ARGS__)
-#define ANKI_GL_LOGF(...) ANKI_LOG("GL  ", kFatal, __VA_ARGS__)
-
-#define ANKI_GL_SELF(class_) class_& self = *static_cast<class_*>(this)
-#define ANKI_GL_SELF_CONST(class_) const class_& self = *static_cast<const class_*>(this)
-
-enum class GlExtensions : U16
-{
-	NONE = 0,
-	ARB_SHADER_BALLOT = 1 << 0,
-};
-ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(GlExtensions, inline)
-
-// Spec limits
-const U MAX_UNIFORM_BLOCK_SIZE = 16384;
-const U MAX_STORAGE_BLOCK_SIZE = 2 << 27;
-
-/// Converter.
-GLenum convertCompareOperation(CompareOperation in);
-
-GLenum convertStencilOperation(StencilOperation in);
-
-inline GLenum convertFaceMode(FaceSelectionBit in)
-{
-	if(in == FaceSelectionBit::FRONT)
-	{
-		return GL_FRONT;
-	}
-	else if(in == FaceSelectionBit::BACK)
-	{
-		return GL_BACK;
-	}
-	else
-	{
-		return GL_FRONT_AND_BACK;
-	}
-}
-
-void convertFilter(SamplingFilter minMagFilter, SamplingFilter mipFilter, GLenum& minFilter, GLenum& magFilter);
-
-void convertVertexFormat(Format fmt, U& compCount, GLenum& type, Bool& normalized);
-
-inline GLenum convertIndexType(IndexType ak)
-{
-	GLenum out;
-	switch(ak)
-	{
-	case IndexType::kU16:
-		out = GL_UNSIGNED_SHORT;
-		break;
-	case IndexType::kU32:
-		out = GL_UNSIGNED_INT;
-		break;
-	default:
-		ANKI_ASSERT(0);
-		out = 0;
-	}
-
-	return out;
-}
-
-inline GLenum convertFillMode(FillMode mode)
-{
-	GLenum out;
-	switch(mode)
-	{
-	case FillMode::POINTS:
-		out = GL_POINT;
-		break;
-	case FillMode::WIREFRAME:
-		out = GL_LINE;
-		break;
-	case FillMode::SOLID:
-		out = GL_FILL;
-		break;
-	default:
-		ANKI_ASSERT(0);
-		out = 0;
-	}
-
-	return out;
-}
-
-GLenum convertBlendFactor(BlendFactor in);
-
-inline GLenum convertBlendOperation(BlendOperation ak)
-{
-	GLenum out;
-
-	switch(ak)
-	{
-	case BlendOperation::ADD:
-		out = GL_FUNC_ADD;
-		break;
-	case BlendOperation::SUBTRACT:
-		out = GL_FUNC_SUBTRACT;
-		break;
-	case BlendOperation::REVERSE_SUBTRACT:
-		out = GL_FUNC_REVERSE_SUBTRACT;
-		break;
-	case BlendOperation::MIN:
-		out = GL_MIN;
-		break;
-	case BlendOperation::MAX:
-		out = GL_MAX;
-		break;
-	default:
-		ANKI_ASSERT(0);
-		out = 0;
-	}
-
-	return out;
-}
-
-inline GLenum convertPrimitiveTopology(PrimitiveTopology ak)
-{
-	GLenum out;
-	switch(ak)
-	{
-	case PrimitiveTopology::POINTS:
-		out = GL_POINTS;
-		break;
-	case PrimitiveTopology::LINES:
-		out = GL_LINES;
-		break;
-	case PrimitiveTopology::LINE_STRIP:
-		out = GL_LINE_STRIP;
-		break;
-	case PrimitiveTopology::kTriangles:
-		out = GL_TRIANGLES;
-		break;
-	case PrimitiveTopology::TRIANGLE_STRIP:
-		out = GL_TRIANGLE_STRIP;
-		break;
-	case PrimitiveTopology::PATCHES:
-		out = GL_PATCHES;
-		break;
-	default:
-		ANKI_ASSERT(0);
-		out = 0;
-	}
-
-	return out;
-}
-
-void convertTextureInformation(Format pf, Bool& compressed, GLenum& format, GLenum& internalFormat, GLenum& type, DepthStencilAspectBit& dsAspect);
-/// @}
-
-} // end namespace anki

+ 0 - 50
AnKi/Gr/Gl/Error.cpp

@@ -1,50 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/Error.h>
-#include <AnKi/Util/Logger.h>
-#include <cstring>
-
-namespace anki {
-
-void glConditionalCheckError(const char* file, int line, const char* func)
-{
-	GLenum errId = glGetError();
-	if(errId == GL_NO_ERROR)
-	{
-		return;
-	}
-
-	const char* glerr;
-	switch(errId)
-	{
-	case GL_INVALID_ENUM:
-		glerr = "GL_INVALID_ENUM";
-		break;
-	case GL_INVALID_VALUE:
-		glerr = "GL_INVALID_VALUE";
-		break;
-	case GL_INVALID_OPERATION:
-		glerr = "GL_INVALID_OPERATION";
-		break;
-	case GL_INVALID_FRAMEBUFFER_OPERATION:
-		glerr = "GL_INVALID_FRAMEBUFFER_OPERATION";
-		break;
-	case GL_OUT_OF_MEMORY:
-		glerr = "GL_OUT_OF_MEMORY";
-		break;
-	default:
-		glerr = "unknown";
-	};
-
-	char errStr[256];
-	const char tmp[] = "OpenGL exception: ";
-	memcpy(errStr, tmp, sizeof(tmp));
-	strcat(errStr, glerr);
-
-	ANKI_GL_LOGF("GL error: %s (%s:%d %s)", errStr, file, line, func);
-}
-
-} // namespace anki

+ 0 - 29
AnKi/Gr/Gl/Error.h

@@ -1,29 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/gl/Common.h>
-
-namespace anki {
-
-/// @addtogroup opengl
-/// @{
-
-// Enable the exception on debug. Calling glGetError calls serialization
-
-#if ANKI_EXTRA_CHECKS
-
-/// The function exits if there is an OpenGL error. Use it with the
-/// ANKI_CHECK_GL_ERROR macro
-void glConditionalCheckError(const char* file, int line, const char* func);
-
-#	define ANKI_CHECK_GL_ERROR() glConditionalCheckError(ANKI_FILE, __LINE__, ANKI_FUNC)
-#else
-#	define ANKI_CHECK_GL_ERROR() ((void)0)
-#endif
-/// @}
-
-} // end namespace anki

+ 0 - 105
AnKi/Gr/Gl/Fence.cpp

@@ -1,105 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/Fence.h>
-#include <AnKi/Gr/gl/FenceImpl.h>
-#include <AnKi/Gr/CommandBuffer.h>
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Util/HighRezTimer.h>
-
-namespace anki {
-
-Bool Fence::clientWait(Second seconds)
-{
-	if(static_cast<FenceImpl&>(*this).m_signaled.load())
-	{
-		return true;
-	}
-
-	class CheckFenceCommand final : public GlCommand
-	{
-	public:
-		FencePtr m_fence;
-		Second m_timeout;
-		Second m_flushTime;
-		Barrier* m_barrier;
-
-		CheckFenceCommand(FencePtr fence, Second timeout, Second flushTime, Barrier* barrier)
-			: m_fence(fence)
-			, m_timeout(timeout)
-			, m_flushTime(flushTime)
-			, m_barrier(barrier)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			// Since there is a delay between flushing the cmdb and returning this result try to adjust the time we
-			// wait
-			Second timeToWait;
-			if(m_timeout != 0.0)
-			{
-				timeToWait = m_timeout - (HighRezTimer::getCurrentTime() - m_flushTime);
-				timeToWait = max(0.0, timeToWait);
-			}
-			else
-			{
-				timeToWait = 0.0;
-			}
-
-			FenceImpl& impl = static_cast<FenceImpl&>(*m_fence);
-			GLenum out = glClientWaitSync(impl.m_fence, GL_SYNC_FLUSH_COMMANDS_BIT, timeToWait * 1e+9);
-
-			if(out == GL_ALREADY_SIGNALED || out == GL_CONDITION_SATISFIED)
-			{
-				impl.m_signaled.store(true);
-			}
-			else if(out == GL_TIMEOUT_EXPIRED)
-			{
-				// Do nothing
-			}
-			else
-			{
-				ANKI_ASSERT(out == GL_WAIT_FAILED);
-				return Error::kFunctionFailed;
-			}
-
-			if(m_barrier)
-			{
-				m_barrier->wait();
-			}
-
-			return Error::kNone;
-		}
-	};
-
-	CommandBufferPtr cmdb = getManager().newCommandBuffer(CommandBufferInitInfo());
-
-	if(seconds == 0.0)
-	{
-		// Send a cmd that will update the fence's status in case someone calls clientWait with seconds==0.0 all the
-		// time
-		static_cast<CommandBufferImpl&>(*cmdb).pushBackNewCommand<CheckFenceCommand>(FencePtr(this), seconds, 0.0, nullptr);
-		static_cast<CommandBufferImpl&>(*cmdb).flush();
-
-		return false;
-	}
-	else
-	{
-		Barrier barrier(2);
-
-		Second flushTime = HighRezTimer::getCurrentTime();
-
-		static_cast<CommandBufferImpl&>(*cmdb).pushBackNewCommand<CheckFenceCommand>(FencePtr(this), seconds, flushTime, &barrier);
-		static_cast<CommandBufferImpl&>(*cmdb).flush();
-
-		barrier.wait();
-
-		return static_cast<FenceImpl&>(*this).m_signaled.load();
-	}
-}
-
-} // end namespace anki

+ 0 - 54
AnKi/Gr/Gl/FenceImpl.cpp

@@ -1,54 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/FenceImpl.h>
-#include <AnKi/Gr/CommandBuffer.h>
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Gr/gl/GrManagerImpl.h>
-#include <AnKi/Gr/gl/RenderingThread.h>
-
-namespace anki {
-
-FenceImpl::~FenceImpl()
-{
-	class DeleteFenceCommand final : public GlCommand
-	{
-	public:
-		GLsync m_fence;
-
-		DeleteFenceCommand(GLsync fence)
-			: m_fence(fence)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			glDeleteSync(m_fence);
-			return Error::kNone;
-		}
-	};
-
-	if(m_fence)
-	{
-		GrManagerImpl& manager = static_cast<GrManagerImpl&>(getManager());
-		RenderingThread& thread = manager.getRenderingThread();
-
-		if(!thread.isServerThread())
-		{
-			CommandBufferPtr commands;
-
-			commands = manager.newCommandBuffer(CommandBufferInitInfo());
-			static_cast<CommandBufferImpl&>(*commands).pushBackNewCommand<DeleteFenceCommand>(m_fence);
-			static_cast<CommandBufferImpl&>(*commands).flush();
-		}
-		else
-		{
-			glDeleteSync(m_fence);
-		}
-	}
-}
-
-} // end namespace anki

+ 0 - 50
AnKi/Gr/Gl/Framebuffer.cpp

@@ -1,50 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/Framebuffer.h>
-#include <AnKi/Gr/gl/FramebufferImpl.h>
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-#include <AnKi/Gr/GrManager.h>
-
-namespace anki {
-
-Framebuffer* Framebuffer::newInstance(GrManager* manager, const FramebufferInitInfo& init)
-{
-	class CreateFramebufferCommand final : public GlCommand
-	{
-	public:
-		FramebufferPtr m_fb;
-		FramebufferInitInfo m_init;
-
-		CreateFramebufferCommand(Framebuffer* handle, const FramebufferInitInfo& init)
-			: m_fb(handle)
-			, m_init(init)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			FramebufferImpl& impl = static_cast<FramebufferImpl&>(*m_fb);
-			Error err = impl.init(m_init);
-
-			GlObject::State oldState = impl.setStateAtomically((err) ? GlObject::State::ERROR : GlObject::State::CREATED);
-			ANKI_ASSERT(oldState == GlObject::State::TO_BE_CREATED);
-			(void)oldState;
-
-			return err;
-		}
-	};
-
-	FramebufferImpl* impl = manager->getAllocator().newInstance<FramebufferImpl>(manager, init.getName());
-	impl->getRefcount().fetchAdd(1); // Hold a reference in case the command finishes and deletes quickly
-
-	CommandBufferPtr cmdb = manager->newCommandBuffer(CommandBufferInitInfo());
-	static_cast<CommandBufferImpl&>(*cmdb).pushBackNewCommand<CreateFramebufferCommand>(impl, init);
-	static_cast<CommandBufferImpl&>(*cmdb).flush();
-
-	return impl;
-}
-
-} // end namespace anki

+ 0 - 256
AnKi/Gr/Gl/FramebufferImpl.cpp

@@ -1,256 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/FramebufferImpl.h>
-#include <AnKi/Gr/Texture.h>
-#include <AnKi/Gr/gl/TextureViewImpl.h>
-#include <AnKi/Gr/gl/GlState.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Gr/gl/GrManagerImpl.h>
-#include <AnKi/Gr/gl/RenderingThread.h>
-#include <AnKi/Util/Logger.h>
-
-namespace anki {
-
-Error FramebufferImpl::init(const FramebufferInitInfo& init)
-{
-	ANKI_ASSERT(!isCreated());
-	m_in = init;
-
-	glGenFramebuffers(1, &m_glName);
-	ANKI_ASSERT(m_glName != 0);
-	const GLenum target = GL_FRAMEBUFFER;
-	glBindFramebuffer(target, m_glName);
-
-	// Attach color
-	for(U i = 0; i < m_in.m_colorAttachmentCount; i++)
-	{
-		const FramebufferAttachmentInfo& att = m_in.m_colorAttachments[i];
-		const TextureViewImpl& viewImpl = static_cast<const TextureViewImpl&>(*att.m_textureView);
-		ANKI_ASSERT(viewImpl.m_tex->isSubresourceGoodForFramebufferAttachment(viewImpl.getSubresource()));
-
-		const GLenum binding = GL_COLOR_ATTACHMENT0 + i;
-
-		attachTextureInternal(binding, viewImpl, att);
-
-		m_drawBuffers[i] = binding;
-
-		if(att.m_loadOperation == AttachmentLoadOperation::kDontCare)
-		{
-			m_invalidateBuffers[m_invalidateBuffersCount++] = binding;
-		}
-
-		if(m_fbSize[0] == 0)
-		{
-			m_fbSize[0] = viewImpl.m_tex->getWidth() >> viewImpl.getSubresource().m_firstMipmap;
-			m_fbSize[1] = viewImpl.m_tex->getHeight() >> viewImpl.getSubresource().m_firstMipmap;
-		}
-		else
-		{
-			ANKI_ASSERT(m_fbSize[0] == (viewImpl.m_tex->getWidth() >> viewImpl.getSubresource().m_firstMipmap));
-			ANKI_ASSERT(m_fbSize[1] == (viewImpl.m_tex->getHeight() >> viewImpl.getSubresource().m_firstMipmap));
-		}
-	}
-
-	// Attach depth/stencil
-	if(m_in.m_depthStencilAttachment.m_textureView.isCreated())
-	{
-		const FramebufferAttachmentInfo& att = m_in.m_depthStencilAttachment;
-		const TextureViewImpl& viewImpl = static_cast<const TextureViewImpl&>(*att.m_textureView);
-		ANKI_ASSERT(viewImpl.m_tex->isSubresourceGoodForFramebufferAttachment(viewImpl.getSubresource()));
-
-		GLenum binding;
-		if(viewImpl.getSubresource().m_depthStencilAspect == DepthStencilAspectBit::kDepth)
-		{
-			binding = GL_DEPTH_ATTACHMENT;
-		}
-		else if(viewImpl.getSubresource().m_depthStencilAspect == DepthStencilAspectBit::STENCIL)
-		{
-			binding = GL_STENCIL_ATTACHMENT;
-		}
-		else
-		{
-			ANKI_ASSERT(viewImpl.getSubresource().m_depthStencilAspect == DepthStencilAspectBit::DEPTH_STENCIL);
-			binding = GL_DEPTH_STENCIL_ATTACHMENT;
-		}
-
-		attachTextureInternal(binding, viewImpl, att);
-
-		if(att.m_loadOperation == AttachmentLoadOperation::kDontCare)
-		{
-			m_invalidateBuffers[m_invalidateBuffersCount++] = binding;
-		}
-
-		if(m_fbSize[0] == 0)
-		{
-			m_fbSize[0] = viewImpl.m_tex->getWidth() >> viewImpl.getSubresource().m_firstMipmap;
-			m_fbSize[1] = viewImpl.m_tex->getHeight() >> viewImpl.getSubresource().m_firstMipmap;
-		}
-		else
-		{
-			ANKI_ASSERT(m_fbSize[0] == (viewImpl.m_tex->getWidth() >> viewImpl.getSubresource().m_firstMipmap));
-			ANKI_ASSERT(m_fbSize[1] == (viewImpl.m_tex->getHeight() >> viewImpl.getSubresource().m_firstMipmap));
-		}
-
-		// Misc
-		m_clearDepth = !!(viewImpl.getSubresource().m_depthStencilAspect & DepthStencilAspectBit::kDepth)
-					   && att.m_loadOperation == AttachmentLoadOperation::kClear;
-
-		m_clearStencil = !!(viewImpl.getSubresource().m_depthStencilAspect & DepthStencilAspectBit::STENCIL)
-						 && att.m_stencilLoadOperation == AttachmentLoadOperation::kClear;
-	}
-
-	// Check completeness
-	GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	if(status != GL_FRAMEBUFFER_COMPLETE)
-	{
-		ANKI_GL_LOGE("FBO is incomplete. Status: 0x%x", status);
-		return Error::kFunctionFailed;
-	}
-
-	glBindFramebuffer(GL_FRAMEBUFFER, 0);
-	return Error::kNone;
-}
-
-void FramebufferImpl::attachTextureInternal(GLenum attachment, const TextureViewImpl& view, const FramebufferAttachmentInfo& info)
-{
-	const GLenum target = GL_FRAMEBUFFER;
-	const TextureImpl& tex = static_cast<const TextureImpl&>(*view.m_tex);
-
-	switch(tex.m_target)
-	{
-	case GL_TEXTURE_2D:
-#if ANKI_GL == ANKI_GL_DESKTOP
-	case GL_TEXTURE_2D_MULTISAMPLE:
-#endif
-		glFramebufferTexture2D(target, attachment, tex.m_target, tex.getGlName(), view.getSubresource().m_firstMipmap);
-		break;
-	case GL_TEXTURE_CUBE_MAP:
-		glFramebufferTexture2D(target, attachment, GL_TEXTURE_CUBE_MAP_POSITIVE_X + view.getSubresource().m_firstFace, tex.getGlName(),
-							   view.getSubresource().m_firstMipmap);
-		break;
-	case GL_TEXTURE_2D_ARRAY:
-		glFramebufferTextureLayer(target, attachment, tex.getGlName(), view.getSubresource().m_firstMipmap, view.getSubresource().m_firstLayer);
-		break;
-	case GL_TEXTURE_3D:
-		ANKI_ASSERT(!"TODO");
-		break;
-	case GL_TEXTURE_CUBE_MAP_ARRAY:
-		glFramebufferTextureLayer(target, attachment, tex.getGlName(), view.getSubresource().m_firstMipmap,
-								  view.getSubresource().m_firstLayer * 6 + view.getSubresource().m_firstFace);
-		break;
-	default:
-		ANKI_ASSERT(0);
-		break;
-	}
-}
-
-void FramebufferImpl::bind(const GlState& state, U32 minx, U32 miny, U32 width, U32 height) const
-{
-	ANKI_ASSERT(width > 0 && height > 0);
-
-	if(m_in.getName() && static_cast<const GrManagerImpl&>(getManager()).debugMarkersEnabled())
-	{
-		glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, m_glName, 0, &m_in.getName()[0]);
-	}
-
-	// Clear in the render area
-	const U maxx = min<U>(minx + width, m_fbSize[0]);
-	const U maxy = min<U>(miny + height, m_fbSize[1]);
-	ANKI_ASSERT(minx < m_fbSize[0] && miny < m_fbSize[1] && maxx <= m_fbSize[0] && maxy <= m_fbSize[1]);
-	width = maxx - minx;
-	height = maxy - miny;
-	glScissor(minx, miny, width, height);
-
-	ANKI_ASSERT(m_glName != 0);
-	glBindFramebuffer(GL_FRAMEBUFFER, m_glName);
-
-	// Set the draw buffers
-	if(m_in.m_colorAttachmentCount)
-	{
-		glDrawBuffers(m_in.m_colorAttachmentCount, &m_drawBuffers[0]);
-	}
-
-	// Invalidate
-	if(m_invalidateBuffersCount)
-	{
-		glInvalidateSubFramebuffer(GL_FRAMEBUFFER, m_invalidateBuffersCount, &m_invalidateBuffers[0], minx, miny, width, height);
-	}
-
-	// Clear buffers
-	for(U i = 0; i < m_in.m_colorAttachmentCount; i++)
-	{
-		const FramebufferAttachmentInfo& att = m_in.m_colorAttachments[i];
-
-		if(att.m_loadOperation == AttachmentLoadOperation::kClear)
-		{
-			// Enable write mask in case a pipeline changed it (else no clear will happen) and then restore state
-			Bool restore = false;
-			if(state.m_colorWriteMasks[i][0] != true || state.m_colorWriteMasks[i][1] != true || state.m_colorWriteMasks[i][2] != true
-			   || state.m_colorWriteMasks[i][3] != true)
-			{
-				glColorMaski(i, true, true, true, true);
-				restore = true;
-			}
-
-			glClearBufferfv(GL_COLOR, i, &att.m_clearValue.m_colorf[0]);
-
-			if(restore)
-			{
-				glColorMaski(i, state.m_colorWriteMasks[i][0], state.m_colorWriteMasks[i][1], state.m_colorWriteMasks[i][2],
-							 state.m_colorWriteMasks[i][3]);
-			}
-		}
-	}
-
-	// Clear depth
-	if(m_clearDepth)
-	{
-		// Enable write mask in case a pipeline changed it (else no clear will happen) and then restore state
-		if(state.m_depthWriteMask == false)
-		{
-			glDepthMask(true);
-		}
-
-		glClearBufferfv(GL_DEPTH, 0, &m_in.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth);
-
-		if(state.m_depthWriteMask == false)
-		{
-			glDepthMask(false);
-		}
-	}
-
-	// Clear stencil
-	if(m_clearStencil)
-	{
-		// Enable write mask in case a pipeline changed it (else no clear will happen) and then restore state
-		// From the spec: The clear operation always uses the front stencil write mask when clearing the stencil
-		// buffer
-		if(state.m_stencilWriteMask[0] != kMaxU32)
-		{
-			glStencilMaskSeparate(GL_FRONT, kMaxU32);
-		}
-
-		GLint clearVal = m_in.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_stencil;
-		glClearBufferiv(GL_STENCIL, 0, &clearVal);
-
-		if(state.m_stencilWriteMask[0] != kMaxU32)
-		{
-			glStencilMaskSeparate(GL_FRONT, state.m_stencilWriteMask[0]);
-		}
-	}
-
-	glScissor(state.m_scissor[0], state.m_scissor[1], state.m_scissor[2], state.m_scissor[3]);
-}
-
-void FramebufferImpl::endRenderPass() const
-{
-	if(m_in.getName() && static_cast<const GrManagerImpl&>(getManager()).debugMarkersEnabled())
-	{
-		glPopDebugGroup();
-	}
-}
-
-} // end namespace anki

+ 0 - 62
AnKi/Gr/Gl/FramebufferImpl.h

@@ -1,62 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/Framebuffer.h>
-#include <AnKi/Gr/gl/GlObject.h>
-
-namespace anki {
-
-/// @addtogroup opengl
-/// @{
-
-/// Framebuffer implementation.
-class FramebufferImpl final : public Framebuffer, public GlObject
-{
-public:
-	FramebufferImpl(GrManager* manager, CString name)
-		: Framebuffer(manager, name)
-	{
-	}
-
-	~FramebufferImpl()
-	{
-		destroyDeferred(getManager(), glDeleteFramebuffers);
-	}
-
-	/// Set all the attachments. It will overwrite the previous state. If the initalizer list is empty the it will bind
-	/// the default framebuffer
-	ANKI_USE_RESULT Error init(const FramebufferInitInfo& init);
-
-	/// Bind it to the state. Call it in rendering thread
-	void bind(const GlState& state, U32 minx, U32 miny, U32 width, U32 height) const;
-
-	void endRenderPass() const;
-
-	U getColorBufferCount() const
-	{
-		return m_in.m_colorAttachmentCount;
-	}
-
-private:
-	FramebufferInitInfo m_in;
-
-	Array<U32, 2> m_fbSize = {};
-	Array<GLenum, kMaxColorRenderTargets> m_drawBuffers;
-	Array<GLenum, kMaxColorRenderTargets + 1> m_invalidateBuffers;
-	U8 m_invalidateBuffersCount = 0;
-	Bool m_clearDepth = false;
-	Bool m_clearStencil = false;
-
-	/// Attach a texture
-	static void attachTextureInternal(GLenum attachment, const TextureViewImpl& view, const FramebufferAttachmentInfo& info);
-
-	/// Create the FBO
-	ANKI_USE_RESULT Error createFbo(const Array<U, kMaxColorRenderTargets + 1>& layers, GLenum depthStencilBindingPoint);
-};
-/// @}
-
-} // end namespace anki

+ 0 - 89
AnKi/Gr/Gl/GlObject.cpp

@@ -1,89 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/GlObject.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Gr/gl/GrManagerImpl.h>
-#include <AnKi/Gr/gl/RenderingThread.h>
-#include <AnKi/Gr/CommandBuffer.h>
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-
-namespace anki {
-
-GlObject::GlObject()
-	: m_glName(0)
-	, m_state(I32(State::TO_BE_CREATED))
-{
-}
-
-Error GlObject::serializeRenderingThread(GrManager& manager)
-{
-	Error err = Error::kNone;
-	State state = State(m_state.load());
-	ANKI_ASSERT(state != State::NEW);
-
-	if(state == State::TO_BE_CREATED)
-	{
-		RenderingThread& thread = static_cast<GrManagerImpl&>(manager).getRenderingThread();
-		thread.syncClientServer();
-
-		state = State(m_state.load());
-
-		if(state == State::ERROR)
-		{
-			err = Error::kUnknown;
-		}
-	}
-
-	ANKI_ASSERT(state > State::TO_BE_CREATED);
-
-	return err;
-}
-
-void GlObject::destroyDeferred(GrManager& manager, GlDeleteFunction deleteCallback)
-{
-	class DeleteGlObjectCommand final : public GlCommand
-	{
-	public:
-		GlObject::GlDeleteFunction m_callback;
-		GLuint m_glName;
-
-		DeleteGlObjectCommand(GlObject::GlDeleteFunction callback, GLuint name)
-			: m_callback(callback)
-			, m_glName(name)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			m_callback(1, &m_glName);
-			return Error::kNone;
-		}
-	};
-
-	if(m_glName == 0)
-	{
-		return;
-	}
-
-	RenderingThread& thread = static_cast<GrManagerImpl&>(manager).getRenderingThread();
-
-	if(!thread.isServerThread())
-	{
-		CommandBufferPtr commands;
-
-		commands = manager.newCommandBuffer(CommandBufferInitInfo());
-		static_cast<CommandBufferImpl&>(*commands).pushBackNewCommand<DeleteGlObjectCommand>(deleteCallback, m_glName);
-		static_cast<CommandBufferImpl&>(*commands).flush();
-	}
-	else
-	{
-		deleteCallback(1, &m_glName);
-	}
-
-	m_glName = 0;
-}
-
-} // end namespace anki

+ 0 - 72
AnKi/Gr/Gl/GlObject.h

@@ -1,72 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/gl/Common.h>
-
-namespace anki {
-
-/// @addtogroup opengl
-/// @{
-
-/// State of the handle
-enum class GlObjectState : U32
-{
-	NEW,
-	TO_BE_CREATED,
-	CREATED,
-	TO_BE_DELETED,
-	DELETED,
-	ERROR
-};
-
-/// A GL object
-class GlObject
-{
-public:
-	using State = GlObjectState;
-	using GlDeleteFunction = void (*)(GLsizei, const GLuint*);
-
-	/// Default
-	GlObject();
-
-	~GlObject()
-	{
-		// The destructor of the derived GL object should pass 0 name
-		ANKI_ASSERT(!isCreated());
-	}
-
-	/// Get the GL name for the current frame
-	GLuint getGlName() const
-	{
-		ANKI_ASSERT(isCreated());
-		return m_glName;
-	}
-
-	/// GL object is created.
-	Bool isCreated() const
-	{
-		return m_glName != 0;
-	}
-
-	State setStateAtomically(State newVal)
-	{
-		return State(m_state.exchange(I32(newVal)));
-	}
-
-	/// Check if the object has been created and if not serialize the thread.
-	ANKI_USE_RESULT Error serializeRenderingThread(GrManager& manager);
-
-	/// Should be called from GL objects for deferred deletion.
-	void destroyDeferred(GrManager& manager, GlDeleteFunction deleteCallback);
-
-protected:
-	GLuint m_glName = 0; ///< OpenGL name
-	mutable Atomic<I32> m_state;
-};
-/// @}
-
-} // end namespace anki

+ 0 - 199
AnKi/Gr/Gl/GlState.cpp

@@ -1,199 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/GlState.h>
-#include <AnKi/Gr/gl/BufferImpl.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Util/Logger.h>
-#include <AnKi/Core/Trace.h>
-#include <AnKi/Core/CVarSet.h>
-#include <algorithm>
-#include <cstring>
-
-namespace anki {
-
-#if ANKI_GL == ANKI_GL_DESKTOP
-struct GlDbg
-{
-	GLenum token;
-	const char* str;
-};
-
-static const GlDbg gldbgsource[] = {{GL_DEBUG_SOURCE_API, "GL_DEBUG_SOURCE_API"},
-									{GL_DEBUG_SOURCE_WINDOW_SYSTEM, "GL_DEBUG_SOURCE_WINDOW_SYSTEM"},
-									{GL_DEBUG_SOURCE_SHADER_COMPILER, "GL_DEBUG_SOURCE_SHADER_COMPILER"},
-									{GL_DEBUG_SOURCE_THIRD_PARTY, "GL_DEBUG_SOURCE_THIRD_PARTY"},
-									{GL_DEBUG_SOURCE_APPLICATION, "GL_DEBUG_SOURCE_APPLICATION"},
-									{GL_DEBUG_SOURCE_OTHER, "GL_DEBUG_SOURCE_OTHER"}};
-
-static const GlDbg gldbgtype[] = {{GL_DEBUG_TYPE_ERROR, "GL_DEBUG_TYPE_ERROR"},
-								  {GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, "GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR"},
-								  {GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, "GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR"},
-								  {GL_DEBUG_TYPE_PORTABILITY, "GL_DEBUG_TYPE_PORTABILITY"},
-								  {GL_DEBUG_TYPE_PERFORMANCE, "GL_DEBUG_TYPE_PERFORMANCE"},
-								  {GL_DEBUG_TYPE_OTHER, "GL_DEBUG_TYPE_OTHER"}};
-
-static const GlDbg gldbgseverity[] = {{GL_DEBUG_SEVERITY_LOW, "GL_DEBUG_SEVERITY_LOW"},
-									  {GL_DEBUG_SEVERITY_MEDIUM, "GL_DEBUG_SEVERITY_MEDIUM"},
-									  {GL_DEBUG_SEVERITY_HIGH, "GL_DEBUG_SEVERITY_HIGH"}};
-
-#	if ANKI_OS == ANKI_OS_WINDOWS && ANKI_COMPILER != ANKI_COMPILER_MSVC
-__stdcall
-#	endif
-	void
-	oglMessagesCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, const GLvoid* userParam)
-{
-	using namespace anki;
-
-	const GlDbg* sourced = &gldbgsource[0];
-	while(source != sourced->token)
-	{
-		++sourced;
-	}
-
-	const GlDbg* typed = &gldbgtype[0];
-	while(type != typed->token)
-	{
-		++typed;
-	}
-
-	switch(severity)
-	{
-	case GL_DEBUG_SEVERITY_LOW:
-		ANKI_GL_LOGI("GL: %s, %s: %s", sourced->str, typed->str, message);
-		break;
-	case GL_DEBUG_SEVERITY_MEDIUM:
-		ANKI_GL_LOGW("GL: %s, %s: %s", sourced->str, typed->str, message);
-		break;
-	case GL_DEBUG_SEVERITY_HIGH:
-		ANKI_GL_LOGE("GL: %s, %s: %s", sourced->str, typed->str, message);
-		break;
-	}
-}
-#endif
-
-void GlState::initMainThread(const ConfigSet& config)
-{
-	m_registerMessages = config.getNumber("gr_debugContext");
-}
-
-void GlState::initRenderThread()
-{
-	// GL version
-	GLint major, minor;
-	glGetIntegerv(GL_MAJOR_VERSION, &major);
-	glGetIntegerv(GL_MINOR_VERSION, &minor);
-	m_version = major * 100 + minor * 10;
-
-	// Vendor
-	CString glstr = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
-
-	if(glstr.find("ARM") != CString::kNpos)
-	{
-		m_gpu = GpuVendor::ARM;
-	}
-	else if(glstr.find("NVIDIA") != CString::kNpos)
-	{
-		m_gpu = GpuVendor::NVIDIA;
-	}
-	else if(glstr.find("AMD") != CString::kNpos || glstr.find("ATI") != CString::kNpos)
-	{
-		m_gpu = GpuVendor::AMD;
-	}
-	else if(glstr.find("Intel") != CString::kNpos)
-	{
-		m_gpu = GpuVendor::INTEL;
-	}
-
-	ANKI_GL_LOGI("GPU vendor is %s", &kGPUVendorStrings[m_gpu][0]);
-
-// Enable debug messages
-#if ANKI_GL == ANKI_GL_DESKTOP
-	if(m_registerMessages)
-	{
-		glDebugMessageCallback(oglMessagesCallback, nullptr);
-
-		for(U s = 0; s < sizeof(gldbgsource) / sizeof(GlDbg); s++)
-		{
-			for(U t = 0; t < sizeof(gldbgtype) / sizeof(GlDbg); t++)
-			{
-				for(U sv = 0; sv < sizeof(gldbgseverity) / sizeof(GlDbg); sv++)
-				{
-					glDebugMessageControl(gldbgsource[s].token, gldbgtype[t].token, gldbgseverity[sv].token, 0, nullptr, GL_TRUE);
-				}
-			}
-		}
-	}
-#endif
-	// Set some GL state
-	glEnable(GL_PROGRAM_POINT_SIZE);
-	glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
-	glEnable(GL_CULL_FACE);
-	glEnable(GL_SCISSOR_TEST);
-	glScissor(0, 0, kMaxI16, kMaxI16);
-	glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
-
-	// Create default VAO
-	glGenVertexArrays(1, &m_defaultVao);
-	glBindVertexArray(m_defaultVao);
-
-	// Enable all attributes
-	for(U i = 0; i < kMaxVertexAttributes; ++i)
-	{
-		glEnableVertexAttribArray(i);
-	}
-
-	I64 val;
-	glGetInteger64v(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &val);
-	m_uboAlignment = max<U32>(ANKI_SAFE_ALIGNMENT, val); // Some GPU have really low requirements
-
-	glGetInteger64v(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &val);
-	m_ssboAlignment = max<U32>(ANKI_SAFE_ALIGNMENT, val); // Some GPU have really low requirements
-
-	glGetInteger64v(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &val);
-	m_tboAlignment = max<U32>(ANKI_SAFE_ALIGNMENT, val); // Some GPU have really low requirements
-
-	glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &val);
-	m_uniBlockMaxSize = val;
-
-	glGetInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &val);
-	m_storageBlockMaxSize = val;
-
-	m_tboMaxRange = kMaxU32;
-
-	// Texture buffer textures
-	glGenTextures(kMaxDescriptorSets * MAX_TEXTURE_BUFFER_BINDINGS, &m_texBuffTextures[0][0]);
-	for(U i = 0; i < kMaxDescriptorSets; ++i)
-	{
-		for(U j = 0; j < MAX_TEXTURE_BUFFER_BINDINGS; ++j)
-		{
-			U unit = MAX_TEXTURE_BINDINGS * kMaxDescriptorSets + MAX_TEXTURE_BUFFER_BINDINGS * i + j;
-			glActiveTexture(GL_TEXTURE0 + unit);
-
-			glBindTexture(GL_TEXTURE_BUFFER, m_texBuffTextures[i][j]);
-		}
-	}
-
-	// Get extensions
-	GLint extCount = 0;
-	glGetIntegerv(GL_NUM_EXTENSIONS, &extCount);
-	while(extCount--)
-	{
-		const char* ext = reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, extCount));
-		if(CString(ext) == "GL_ARB_shader_ballot")
-		{
-			ANKI_GL_LOGI("Found GL_ARB_shader_ballot");
-			m_extensions |= GlExtensions::ARB_SHADER_BALLOT;
-		}
-	}
-}
-
-void GlState::destroy()
-{
-	glDeleteVertexArrays(1, &m_defaultVao);
-	m_crntProg.reset(nullptr);
-}
-
-} // end namespace anki

+ 0 - 73
AnKi/Gr/Gl/GlState.h

@@ -1,73 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/gl/Common.h>
-#include <AnKi/Util/DynamicArray.h>
-#include <AnKi/Gr/ShaderProgram.h>
-#include <AnKi/Gr/Texture.h>
-#include <AnKi/Gr/Framebuffer.h>
-
-namespace anki {
-
-// Forward
-class ConfigSet;
-
-/// @addtogroup opengl
-/// @{
-
-/// Part of the global state. It's essentialy a cache of the state mainly used for optimizations and other stuff
-class GlState
-{
-public:
-	GrManager* m_manager;
-	GlExtensions m_extensions = GlExtensions::NONE;
-	I32 m_version = -1; ///< Minor major GL version. Something like 430
-	GpuVendor m_gpu = GpuVendor::UNKNOWN;
-	Bool m_registerMessages = false;
-
-	ShaderProgramPtr m_crntProg;
-
-	GLuint m_defaultVao = 0;
-
-	U32 m_uboAlignment = 0;
-	U32 m_ssboAlignment = 0;
-	U32 m_uniBlockMaxSize = 0;
-	U32 m_storageBlockMaxSize = 0;
-	U32 m_tboAlignment = 0;
-	U32 m_tboMaxRange = 0;
-
-	/// @name FB
-	/// @{
-	Array2d<Bool, kMaxColorRenderTargets, 4> m_colorWriteMasks = {
-		{{{true, true, true, true}}, {{true, true, true, true}}, {{true, true, true, true}}, {{true, true, true, true}}}};
-
-	Bool m_depthWriteMask = true;
-
-	Array<U32, 2> m_stencilWriteMask = {{kMaxU32, kMaxU32}};
-	/// @}
-
-	Array2d<GLuint, kMaxDescriptorSets, MAX_TEXTURE_BUFFER_BINDINGS> m_texBuffTextures = {};
-
-	Array<GLsizei, 4> m_scissor = {{0, 0, kMaxI32, kMaxI32}};
-
-	GlState(GrManager* manager)
-		: m_manager(manager)
-	{
-	}
-
-	/// Call this from the main thread.
-	void initMainThread(const ConfigSet& config);
-
-	/// Call this from the rendering thread.
-	void initRenderThread();
-
-	/// Call this from the rendering thread.
-	void destroy();
-};
-/// @}
-
-} // end namespace anki

+ 0 - 152
AnKi/Gr/Gl/GrManager.cpp

@@ -1,152 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Gr/gl/GrManagerImpl.h>
-#include <AnKi/Gr/gl/RenderingThread.h>
-#include <AnKi/Gr/gl/TextureImpl.h>
-#include <AnKi/Gr/gl/GlState.h>
-
-#include <AnKi/Gr/Buffer.h>
-#include <AnKi/Gr/Texture.h>
-#include <AnKi/Gr/Sampler.h>
-#include <AnKi/Gr/Shader.h>
-#include <AnKi/Gr/ShaderProgram.h>
-#include <AnKi/Gr/CommandBuffer.h>
-#include <AnKi/Gr/Framebuffer.h>
-#include <AnKi/Gr/OcclusionQuery.h>
-#include <AnKi/Gr/RenderGraph.h>
-
-#include <cstring>
-
-namespace anki {
-
-GrManager::GrManager()
-{
-}
-
-GrManager::~GrManager()
-{
-	// Destroy in reverse order
-	m_cacheDir.destroy(m_alloc);
-}
-
-Error GrManager::newInstance(GrManagerInitInfo& init, GrManager*& gr)
-{
-	auto alloc = GrAllocator<U8>(init.m_allocCallback, init.m_allocCallbackUserData);
-
-	GrManagerImpl* impl = alloc.newInstance<GrManagerImpl>();
-	Error err = impl->init(init, alloc);
-
-	if(err)
-	{
-		alloc.deleteInstance(impl);
-		gr = nullptr;
-	}
-	else
-	{
-		gr = impl;
-	}
-
-	return err;
-}
-
-void GrManager::deleteInstance(GrManager* gr)
-{
-	if(gr == nullptr)
-	{
-		return;
-	}
-
-	auto alloc = gr->m_alloc;
-	gr->~GrManager();
-	alloc.deallocate(gr, 1);
-}
-
-TexturePtr GrManager::acquireNextPresentableTexture()
-{
-	ANKI_GL_SELF(GrManagerImpl);
-	return self.m_fakeFbTex;
-}
-
-void GrManager::swapBuffers()
-{
-	ANKI_GL_SELF(GrManagerImpl);
-	self.getRenderingThread().swapBuffers();
-}
-
-void GrManager::finish()
-{
-	ANKI_GL_SELF(GrManagerImpl);
-	self.getRenderingThread().syncClientServer();
-}
-
-#define ANKI_SAFE_CONSTRUCT(class_) \
-	class_* out = class_::newInstance(this, init); \
-	class_##Ptr ptr(out); \
-	out->getRefcount().fetchSub(1); \
-	return ptr
-
-BufferPtr GrManager::newBuffer(const BufferInitInfo& init)
-{
-	ANKI_SAFE_CONSTRUCT(Buffer);
-}
-
-TexturePtr GrManager::newTexture(const TextureInitInfo& init)
-{
-	ANKI_SAFE_CONSTRUCT(Texture);
-}
-
-TextureViewPtr GrManager::newTextureView(const TextureViewInitInfo& init)
-{
-	ANKI_SAFE_CONSTRUCT(TextureView);
-}
-
-SamplerPtr GrManager::newSampler(const SamplerInitInfo& init)
-{
-	ANKI_SAFE_CONSTRUCT(Sampler);
-}
-
-ShaderPtr GrManager::newShader(const ShaderInitInfo& init)
-{
-	ANKI_SAFE_CONSTRUCT(Shader);
-}
-
-ShaderProgramPtr GrManager::newShaderProgram(const ShaderProgramInitInfo& init)
-{
-	ANKI_SAFE_CONSTRUCT(ShaderProgram);
-}
-
-CommandBufferPtr GrManager::newCommandBuffer(const CommandBufferInitInfo& init)
-{
-	return CommandBufferPtr(CommandBuffer::newInstance(this, init));
-}
-
-FramebufferPtr GrManager::newFramebuffer(const FramebufferInitInfo& init)
-{
-	ANKI_SAFE_CONSTRUCT(Framebuffer);
-}
-
-OcclusionQueryPtr GrManager::newOcclusionQuery()
-{
-	OcclusionQuery* out = OcclusionQuery::newInstance(this);
-	OcclusionQueryPtr ptr(out);
-	out->getRefcount().fetchSub(1);
-	return ptr;
-}
-
-RenderGraphPtr GrManager::newRenderGraph()
-{
-	return RenderGraphPtr(RenderGraph::newInstance(this));
-}
-
-#undef ANKI_SAFE_CONSTRUCT
-
-GrManagerStats GrManager::getStats() const
-{
-	return GrManagerStats();
-}
-
-} // end namespace anki

+ 0 - 96
AnKi/Gr/Gl/GrManagerImpl.cpp

@@ -1,96 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/GrManagerImpl.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Gr/gl/RenderingThread.h>
-#include <AnKi/Gr/gl/GlState.h>
-#include <AnKi/Core/Config.h>
-#include <AnKi/Window/NativeWindow.h>
-
-namespace anki {
-
-GrManagerImpl::GrManagerImpl()
-{
-}
-
-GrManagerImpl::~GrManagerImpl()
-{
-	m_fakeDefaultFb.reset(nullptr);
-	m_fakeFbTex.reset(nullptr);
-
-	if(m_thread)
-	{
-		m_thread->stop();
-		m_alloc.deleteInstance(m_thread);
-		m_thread = nullptr;
-	}
-
-	if(m_state)
-	{
-		m_alloc.deleteInstance(m_state);
-	}
-
-	destroyBackend();
-}
-
-Error GrManagerImpl::init(GrManagerInitInfo& init, GrAllocator<U8> alloc)
-{
-	m_alloc = alloc;
-	m_cacheDir.create(m_alloc, init.m_cacheDirectory);
-
-	m_debugMarkers = init.m_config->getNumber("gr_debugMarkers");
-
-	// Init the backend of the backend
-	ANKI_CHECK(createBackend(init));
-
-	// First create the state
-	m_state = m_alloc.newInstance<GlState>(this);
-	m_state->initMainThread(*init.m_config);
-
-	// Create thread
-	m_thread = m_alloc.newInstance<RenderingThread>(this);
-
-	// Start it
-	m_thread->start();
-	m_thread->syncClientServer();
-
-	// Misc
-	m_capabilities.m_gpuVendor = m_state->m_gpu;
-	m_capabilities.m_constantBufferBindOffsetAlignment = m_state->m_uboAlignment;
-	m_capabilities.m_constantBufferMaxRange = m_state->m_uniBlockMaxSize;
-	m_capabilities.m_uavBufferBindOffsetAlignment = m_state->m_ssboAlignment;
-	m_capabilities.m_uavBufferMaxRange = m_state->m_storageBlockMaxSize;
-	m_capabilities.m_textureBufferBindOffsetAlignment = m_state->m_tboAlignment;
-	m_capabilities.m_textureBufferMaxRange = m_state->m_tboMaxRange;
-	m_capabilities.m_majorApiVersion = U(init.m_config->getNumber("gr.glmajor"));
-	m_capabilities.m_minorApiVersion = U(init.m_config->getNumber("gr.glmajor"));
-
-	initFakeDefaultFb(init);
-
-	return Error::kNone;
-}
-
-void GrManagerImpl::initFakeDefaultFb(GrManagerInitInfo& init)
-{
-	U32 defaultFbWidth = init.m_window->getWidth();
-	U32 defaultFbHeight = init.m_window->getHeight();
-
-	TextureInitInfo texinit("FB Tex");
-	texinit.m_width = defaultFbWidth;
-	texinit.m_height = defaultFbHeight;
-	texinit.m_format = Format::kR8G8B8A8_Unorm;
-	texinit.m_usage = TextureUsageBit::kFramebufferWrite | TextureUsageBit::kUavComputeWrite | TextureUsageBit::kPresent;
-	m_fakeFbTex = newTexture(texinit);
-
-	TextureViewPtr view = newTextureView(TextureViewInitInfo(m_fakeFbTex, "FB view"));
-
-	FramebufferInitInfo fbinit("Dflt FB");
-	fbinit.m_colorAttachmentCount = 1;
-	fbinit.m_colorAttachments[0].m_textureView = view;
-	m_fakeDefaultFb = newFramebuffer(fbinit);
-}
-
-} // end namespace anki

+ 0 - 81
AnKi/Gr/Gl/GrManagerImpl.h

@@ -1,81 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Gr/gl/Common.h>
-
-namespace anki {
-
-// Forward
-class RenderingThread;
-class WindowingBackend;
-class GlState;
-
-/// @addtogroup opengl
-/// @{
-
-/// Graphics manager backend specific.
-class GrManagerImpl final : public GrManager
-{
-public:
-	/// Dummy framebuffer texture that emulates functionality vulkan can but GL can't
-	TexturePtr m_fakeFbTex;
-	FramebufferPtr m_fakeDefaultFb;
-
-	GrManagerImpl();
-
-	~GrManagerImpl();
-
-	ANKI_USE_RESULT Error init(GrManagerInitInfo& init, GrAllocator<U8> alloc);
-
-	const RenderingThread& getRenderingThread() const
-	{
-		ANKI_ASSERT(m_thread);
-		return *m_thread;
-	}
-
-	RenderingThread& getRenderingThread()
-	{
-		ANKI_ASSERT(m_thread);
-		return *m_thread;
-	}
-
-	GlState& getState()
-	{
-		ANKI_ASSERT(m_state);
-		return *m_state;
-	}
-
-	const GlState& getState() const
-	{
-		ANKI_ASSERT(m_state);
-		return *m_state;
-	}
-
-	void swapBuffers();
-
-	void pinContextToCurrentThread(Bool pin);
-
-	Bool debugMarkersEnabled() const
-	{
-		return m_debugMarkers;
-	}
-
-private:
-	GlState* m_state = nullptr;
-	RenderingThread* m_thread = nullptr;
-	WindowingBackend* m_backend = nullptr; ///< The backend of the backend.
-	Bool m_debugMarkers = false;
-
-	ANKI_USE_RESULT Error createBackend(GrManagerInitInfo& init);
-	void destroyBackend();
-
-	void initFakeDefaultFb(GrManagerInitInfo& init);
-};
-/// @}
-
-} // end namespace anki

+ 0 - 116
AnKi/Gr/Gl/GrManagerImplSdl.cpp

@@ -1,116 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-/// @file Contains the SDL specific bits of the GL implamentation
-
-#include <AnKi/Gr/gl/GrManagerImpl.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Window/NativeWindow.h>
-#include <AnKi/Window/NativeWindowSdl.h>
-#include <AnKi/Core/Config.h>
-#include <SDL.h>
-#include <GL/glew.h>
-
-namespace anki {
-
-/// SDL implementation of WindowingBackend
-class WindowingBackend
-{
-public:
-	SDL_GLContext m_context = nullptr;
-	SDL_Window* m_window = nullptr;
-
-	~WindowingBackend()
-	{
-		if(m_context)
-		{
-			SDL_GL_DeleteContext(m_context);
-		}
-	}
-
-	Error createContext(GrManagerInitInfo& init)
-	{
-		m_window = init.m_window->getNative().m_window;
-
-		ANKI_GL_LOGI("Creating GL %u.%u context...", U(init.m_config->getNumber("gr.glmajor")), U(init.m_config->getNumber("gr.glminor")));
-
-		if(init.m_config->getNumber("gr_debugContext"))
-		{
-			if(SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG))
-			{
-				ANKI_GL_LOGE("SDL_GL_SetAttribute() failed");
-				return Error::kFunctionFailed;
-			}
-		}
-
-		if(SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, init.m_config->getNumber("gr.glmajor"))
-		   || SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, init.m_config->getNumber("gr.glminor"))
-		   || SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE))
-		{
-			ANKI_GL_LOGE("SDL_GL_SetAttribute() failed");
-			return Error::kFunctionFailed;
-		}
-
-		// Create context
-		m_context = SDL_GL_CreateContext(m_window);
-		if(m_context == nullptr)
-		{
-			ANKI_GL_LOGE("SDL_GL_CreateContext() failed: %s", SDL_GetError());
-			return Error::kFunctionFailed;
-		}
-
-		// GLEW
-		glewExperimental = GL_TRUE;
-		if(glewInit() != GLEW_OK)
-		{
-			ANKI_GL_LOGE("GLEW initialization failed");
-			return Error::kFunctionFailed;
-		}
-		glGetError();
-
-		return Error::kNone;
-	}
-
-	void pinContextToCurrentThread(Bool pin)
-	{
-		SDL_GLContext pinCtx = (pin) ? m_context : nullptr;
-		SDL_GL_MakeCurrent(m_window, pinCtx);
-	}
-
-	void swapBuffers()
-	{
-		SDL_GL_SwapWindow(m_window);
-	}
-};
-
-Error GrManagerImpl::createBackend(GrManagerInitInfo& init)
-{
-	ANKI_ASSERT(m_backend == nullptr);
-
-	m_backend = getAllocator().newInstance<WindowingBackend>();
-	return m_backend->createContext(init);
-}
-
-void GrManagerImpl::destroyBackend()
-{
-	if(m_backend)
-	{
-		getAllocator().deleteInstance(m_backend);
-	}
-}
-
-void GrManagerImpl::swapBuffers()
-{
-	ANKI_ASSERT(m_backend);
-	m_backend->swapBuffers();
-}
-
-void GrManagerImpl::pinContextToCurrentThread(Bool pin)
-{
-	ANKI_ASSERT(m_backend);
-	m_backend->pinContextToCurrentThread(pin);
-}
-
-} // end namespace anki

+ 0 - 50
AnKi/Gr/Gl/OcclusionQuery.cpp

@@ -1,50 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/OcclusionQuery.h>
-#include <AnKi/Gr/gl/OcclusionQueryImpl.h>
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-#include <AnKi/Gr/GrManager.h>
-
-namespace anki {
-
-OcclusionQuery* OcclusionQuery::newInstance(GrManager* manager)
-{
-	class CreateOqCommand final : public GlCommand
-	{
-	public:
-		OcclusionQueryPtr m_q;
-
-		CreateOqCommand(OcclusionQuery* q)
-			: m_q(q)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			OcclusionQueryImpl& impl = static_cast<OcclusionQueryImpl&>(*m_q);
-
-			impl.init();
-
-			GlObject::State oldState = impl.setStateAtomically(GlObject::State::CREATED);
-
-			(void)oldState;
-			ANKI_ASSERT(oldState == GlObject::State::TO_BE_CREATED);
-
-			return Error::kNone;
-		}
-	};
-
-	OcclusionQueryImpl* impl = manager->getAllocator().newInstance<OcclusionQueryImpl>(manager, "N/A");
-	impl->getRefcount().fetchAdd(1); // Hold a reference in case the command finishes and deletes quickly
-
-	CommandBufferPtr cmdb = manager->newCommandBuffer(CommandBufferInitInfo());
-	static_cast<CommandBufferImpl&>(*cmdb).pushBackNewCommand<CreateOqCommand>(impl);
-	static_cast<CommandBufferImpl&>(*cmdb).flush();
-
-	return impl;
-}
-
-} // end namespace anki

+ 0 - 44
AnKi/Gr/Gl/OcclusionQueryImpl.cpp

@@ -1,44 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/OcclusionQueryImpl.h>
-
-namespace anki {
-
-void OcclusionQueryImpl::init()
-{
-	glGenQueries(1, &m_glName);
-	ANKI_ASSERT(m_glName != 0);
-}
-
-void OcclusionQueryImpl::begin()
-{
-	ANKI_ASSERT(isCreated());
-	glBeginQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, m_glName);
-}
-
-void OcclusionQueryImpl::end()
-{
-	ANKI_ASSERT(isCreated());
-	glEndQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE);
-}
-
-OcclusionQueryResult OcclusionQueryImpl::getResult() const
-{
-	ANKI_ASSERT(isCreated());
-	OcclusionQueryResult result = OcclusionQueryResult::kNotAvailable;
-	GLuint params;
-	glGetQueryObjectuiv(m_glName, GL_QUERY_RESULT_AVAILABLE, &params);
-
-	if(params != 0)
-	{
-		glGetQueryObjectuiv(m_glName, GL_QUERY_RESULT, &params);
-		result = (params == 1) ? OcclusionQueryResult::kVisible : OcclusionQueryResult::kNotVisible;
-	}
-
-	return result;
-}
-
-} // end namespace anki

+ 0 - 44
AnKi/Gr/Gl/OcclusionQueryImpl.h

@@ -1,44 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/OcclusionQuery.h>
-#include <AnKi/Gr/gl/GlObject.h>
-
-namespace anki {
-
-/// @addtogroup opengl
-/// @{
-
-/// Occlusion query.
-class OcclusionQueryImpl final : public OcclusionQuery, public GlObject
-{
-public:
-	OcclusionQueryImpl(GrManager* manager, CString name)
-		: OcclusionQuery(manager, name)
-	{
-	}
-
-	~OcclusionQueryImpl()
-	{
-		destroyDeferred(getManager(), glDeleteQueries);
-	}
-
-	/// Create the query.
-	void init();
-
-	/// Begin query.
-	void begin();
-
-	/// End query.
-	void end();
-
-	/// Get query result.
-	OcclusionQueryResult getResult() const;
-};
-/// @}
-
-} // end namespace anki

+ 0 - 317
AnKi/Gr/Gl/RenderingThread.cpp

@@ -1,317 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/RenderingThread.h>
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Gr/gl/GrManagerImpl.h>
-#include <AnKi/Gr/gl/GlState.h>
-#include <AnKi/Gr/Fence.h>
-#include <AnKi/Gr/gl/FenceImpl.h>
-#include <AnKi/Util/Logger.h>
-#include <AnKi/Core/Trace.h>
-#include <cstdlib>
-
-namespace anki {
-
-/// Sync rendering thread command.
-class SyncCommand final : public GlCommand
-{
-public:
-	RenderingThread* m_renderingThread;
-
-	SyncCommand(RenderingThread* renderingThread)
-		: m_renderingThread(renderingThread)
-	{
-	}
-
-	ANKI_USE_RESULT Error operator()(GlState&)
-	{
-		// Make sure that all GPU and CPU work is done
-		glFlush();
-		glFinish();
-		m_renderingThread->m_syncBarrier.wait();
-		return Error::kNone;
-	}
-};
-
-/// Swap buffers command.
-class SwapBuffersCommand final : public GlCommand
-{
-public:
-	RenderingThread* m_renderingThread;
-
-	SwapBuffersCommand(RenderingThread* renderingThread)
-		: m_renderingThread(renderingThread)
-	{
-	}
-
-	ANKI_USE_RESULT Error operator()(GlState& state)
-	{
-		// Blit from the fake FB to the real default FB
-		const GrManagerImpl& gr = *static_cast<const GrManagerImpl*>(state.m_manager);
-		const FramebufferImpl& fb = static_cast<FramebufferImpl&>(*gr.m_fakeDefaultFb);
-		const U width = gr.m_fakeFbTex->getWidth();
-		const U height = gr.m_fakeFbTex->getHeight();
-		glBlitNamedFramebuffer(fb.getGlName(), 0, 0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
-
-		// Swap buffers
-		m_renderingThread->swapBuffersInternal();
-		return Error::kNone;
-	}
-};
-
-/// Empty command
-class EmptyCommand final : public GlCommand
-{
-public:
-	ANKI_USE_RESULT Error operator()(GlState&)
-	{
-		return Error::kNone;
-	}
-};
-
-RenderingThread::RenderingThread(GrManagerImpl* manager)
-	: m_manager(manager)
-	, m_tail(0)
-	, m_head(0)
-	, m_renderingThreadSignal(0)
-	, m_thread("anki_gl")
-{
-	ANKI_ASSERT(m_manager);
-}
-
-RenderingThread::~RenderingThread()
-{
-	m_queue.destroy(m_manager->getAllocator());
-}
-
-void RenderingThread::flushCommandBuffer(CommandBufferPtr cmdb, FencePtr* fence)
-{
-	// Create a fence
-	if(fence)
-	{
-		FencePtr& f = *fence;
-		FenceImpl* fenceImpl = m_manager->getAllocator().newInstance<FenceImpl>(m_manager.get(), "N/A");
-		f.reset(fenceImpl);
-
-		class CreateFenceCmd final : public GlCommand
-		{
-		public:
-			FencePtr m_fence;
-
-			CreateFenceCmd(FencePtr fence)
-				: m_fence(fence)
-			{
-			}
-
-			Error operator()(GlState&)
-			{
-				static_cast<FenceImpl&>(*m_fence).m_fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-				return Error::kNone;
-			}
-		};
-
-		static_cast<CommandBufferImpl&>(*cmdb).pushBackNewCommand<CreateFenceCmd>(f);
-	}
-
-	static_cast<CommandBufferImpl&>(*cmdb).makeImmutable();
-
-	{
-		LockGuard<Mutex> lock(m_mtx);
-
-		// Set commands
-		U64 diff = m_tail - m_head;
-
-		if(diff < m_queue.getSize())
-		{
-			U64 idx = m_tail % m_queue.getSize();
-
-			m_queue[idx] = cmdb;
-			++m_tail;
-		}
-		else
-		{
-			ANKI_GL_LOGW("Rendering queue too small");
-		}
-
-		m_condVar.notifyOne(); // Wake the thread
-	}
-}
-
-void RenderingThread::start()
-{
-	ANKI_ASSERT(m_tail == 0 && m_head == 0);
-	m_queue.create(m_manager->getAllocator(), QUEUE_SIZE);
-
-	// Swap buffers stuff
-	m_swapBuffersCommands = m_manager->newCommandBuffer(CommandBufferInitInfo());
-
-	static_cast<CommandBufferImpl&>(*m_swapBuffersCommands).pushBackNewCommand<SwapBuffersCommand>(this);
-	// Just in case noone swaps
-	static_cast<CommandBufferImpl&>(*m_swapBuffersCommands).makeExecuted();
-
-	m_manager->pinContextToCurrentThread(false);
-
-	// Start thread
-	m_thread.start(this, threadCallback);
-
-	// Create sync command buffer
-	m_syncCommands = m_manager->newCommandBuffer(CommandBufferInitInfo());
-	static_cast<CommandBufferImpl&>(*m_syncCommands).pushBackNewCommand<SyncCommand>(this);
-
-	m_emptyCmdb = m_manager->newCommandBuffer(CommandBufferInitInfo());
-	static_cast<CommandBufferImpl&>(*m_emptyCmdb).pushBackNewCommand<EmptyCommand>();
-}
-
-void RenderingThread::stop()
-{
-	syncClientServer();
-	m_renderingThreadSignal = 1;
-	flushCommandBuffer(m_emptyCmdb, nullptr);
-
-	Error err = m_thread.join();
-	(void)err;
-}
-
-void RenderingThread::prepare()
-{
-	m_manager->pinContextToCurrentThread(true);
-
-	// Ignore the first error
-	glGetError();
-
-	ANKI_GL_LOGI("OpenGL async thread started: OpenGL version \"%s\", GLSL version \"%s\"", reinterpret_cast<const char*>(glGetString(GL_VERSION)),
-				 reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION)));
-
-	// Get thread id
-	m_serverThreadId = Thread::getCurrentThreadId();
-
-	// Init state
-	m_manager->getState().initRenderThread();
-}
-
-void RenderingThread::finish()
-{
-	// Iterate the queue and release the refcounts
-	for(U i = 0; i < m_queue.getSize(); i++)
-	{
-		if(m_queue[i].isCreated())
-		{
-			// Fake that it's executed to avoid warnings
-			static_cast<CommandBufferImpl&>(*m_queue[i]).makeExecuted();
-
-			// Release
-			m_queue[i] = CommandBufferPtr();
-		}
-	}
-
-	// Cleanup GL
-	m_manager->getState().destroy();
-
-	// Cleanup
-	glFinish();
-	m_manager->pinContextToCurrentThread(false);
-}
-
-Error RenderingThread::threadCallback(ThreadCallbackInfo& info)
-{
-	RenderingThread* thread = static_cast<RenderingThread*>(info.m_userData);
-	thread->threadLoop();
-	return Error::kNone;
-}
-
-void RenderingThread::threadLoop()
-{
-	prepare();
-
-	while(1)
-	{
-		CommandBufferPtr cmd;
-
-		// Wait for something
-		{
-			LockGuard<Mutex> lock(m_mtx);
-			while(m_tail == m_head)
-			{
-				m_condVar.wait(m_mtx);
-			}
-
-			// Check signals
-			if(m_renderingThreadSignal == 1)
-			{
-				// Requested to stop
-				break;
-			}
-
-			U64 idx = m_head % m_queue.getSize();
-			// Pop a command
-			cmd = m_queue[idx];
-			m_queue[idx] = CommandBufferPtr(); // Insert empty cmd buffer
-
-			++m_head;
-		}
-
-		Error err = Error::kNone;
-		{
-			ANKI_TRACE_SCOPED_EVENT(GL_THREAD);
-			err = static_cast<CommandBufferImpl&>(*cmd).executeAllCommands();
-		}
-
-		if(err)
-		{
-			ANKI_GL_LOGE("Error in rendering thread. Aborting");
-			abort();
-		}
-	}
-
-	finish();
-}
-
-void RenderingThread::syncClientServer()
-{
-	// Lock because there is only one barrier. If multiple threads call
-	// syncClientServer all of them will hit the same barrier.
-	LockGuard<SpinLock> lock(m_syncLock);
-
-	flushCommandBuffer(m_syncCommands, nullptr);
-	m_syncBarrier.wait();
-}
-
-void RenderingThread::swapBuffersInternal()
-{
-	ANKI_TRACE_SCOPED_EVENT(SWAP_BUFFERS);
-
-	// Do the swap buffers
-	m_manager->swapBuffers();
-
-	// Notify the main thread that we are done
-	{
-		LockGuard<Mutex> lock(m_frameMtx);
-		m_frameWait = false;
-
-		m_frameCondVar.notifyOne();
-	}
-}
-
-void RenderingThread::swapBuffers()
-{
-	ANKI_TRACE_SCOPED_EVENT(SWAP_BUFFERS);
-	// Wait for the rendering thread to finish swap buffers...
-	{
-		LockGuard<Mutex> lock(m_frameMtx);
-		while(m_frameWait)
-		{
-			m_frameCondVar.wait(m_frameMtx);
-		}
-
-		m_frameWait = true;
-	}
-
-	// ...and then flush a new swap buffers
-	flushCommandBuffer(m_swapBuffersCommands, nullptr);
-}
-
-} // end namespace anki

+ 0 - 92
AnKi/Gr/Gl/RenderingThread.h

@@ -1,92 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/CommandBuffer.h>
-#include <AnKi/Util/Thread.h>
-
-namespace anki {
-
-/// @addtogroup opengl
-/// @{
-
-/// Command queue. It's essentialy a queue of command buffers waiting for execution and a server
-class RenderingThread
-{
-	friend class SyncCommand;
-	friend class SwapBuffersCommand;
-
-public:
-	RenderingThread(GrManagerImpl* device);
-
-	~RenderingThread();
-
-	/// Start the working thread
-	/// @note Don't free the context before calling #stop
-	void start();
-
-	/// Stop the working thread
-	void stop();
-
-	/// Push a command buffer to the queue for deferred execution
-	void flushCommandBuffer(CommandBufferPtr commands, FencePtr* fence);
-
-	/// Push a command buffer to the queue and wait for it
-	void finishCommandBuffer(CommandBufferPtr commands);
-
-	/// Sync the client and server
-	void syncClientServer();
-
-	/// Return true if this is the main thread
-	Bool isServerThread() const
-	{
-		return m_serverThreadId == Thread::getCurrentThreadId();
-	}
-
-	/// Swap buffers
-	void swapBuffers();
-
-private:
-	WeakPtr<GrManagerImpl> m_manager;
-
-	static constexpr U QUEUE_SIZE = 1024 * 2;
-	DynamicArray<CommandBufferPtr> m_queue; ///< Command queue
-	U64 m_tail; ///< Tail of queue
-	U64 m_head; ///< Head of queue. Points to the end
-	U8 m_renderingThreadSignal; ///< Signal to the thread
-	Mutex m_mtx; ///< Wake the thread
-	ConditionVariable m_condVar; ///< To wake up the thread
-	Thread m_thread;
-
-	/// @name Swap_buffers_vars
-	/// @{
-	CommandBufferPtr m_swapBuffersCommands;
-	ConditionVariable m_frameCondVar;
-	Mutex m_frameMtx;
-	Bool m_frameWait = false;
-	/// @}
-
-	ThreadId m_serverThreadId;
-
-	/// A special command buffer that is called every time we want to wait for the server
-	CommandBufferPtr m_syncCommands;
-	Barrier m_syncBarrier{2};
-	SpinLock m_syncLock;
-
-	/// Command buffer with an empty command.
-	CommandBufferPtr m_emptyCmdb;
-
-	/// The function that the thread runs
-	static ANKI_USE_RESULT Error threadCallback(ThreadCallbackInfo&);
-	void threadLoop();
-	void prepare();
-	void finish();
-
-	void swapBuffersInternal();
-};
-/// @}
-
-} // end namespace anki

+ 0 - 51
AnKi/Gr/Gl/Sampler.cpp

@@ -1,51 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/Sampler.h>
-#include <AnKi/Gr/gl/SamplerImpl.h>
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-#include <AnKi/Gr/GrManager.h>
-
-namespace anki {
-
-Sampler* Sampler::newInstance(GrManager* manager, const SamplerInitInfo& init)
-{
-	class CreateSamplerCommand : public GlCommand
-	{
-	public:
-		SamplerPtr m_sampler;
-		SamplerInitInfo m_init;
-
-		CreateSamplerCommand(Sampler* sampler, const SamplerInitInfo& init)
-			: m_sampler(sampler)
-			, m_init(init)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			SamplerImpl& impl = static_cast<SamplerImpl&>(*m_sampler);
-
-			impl.init(m_init);
-
-			GlObject::State oldState = impl.setStateAtomically(GlObject::State::CREATED);
-			(void)oldState;
-			ANKI_ASSERT(oldState == GlObject::State::TO_BE_CREATED);
-
-			return Error::kNone;
-		}
-	};
-
-	SamplerImpl* impl = manager->getAllocator().newInstance<SamplerImpl>(manager, init.getName());
-	impl->getRefcount().fetchAdd(1); // Hold a reference in case the command finishes and deletes quickly
-
-	CommandBufferPtr cmdb = manager->newCommandBuffer(CommandBufferInitInfo());
-	static_cast<CommandBufferImpl&>(*cmdb).pushBackNewCommand<CreateSamplerCommand>(impl, init);
-	static_cast<CommandBufferImpl&>(*cmdb).flush();
-
-	return impl;
-}
-
-} // end namespace anki

+ 0 - 57
AnKi/Gr/Gl/SamplerImpl.cpp

@@ -1,57 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/SamplerImpl.h>
-#include <AnKi/Gr/Texture.h>
-
-namespace anki {
-
-void SamplerImpl::init(const SamplerInitInfo& sinit)
-{
-	glGenSamplers(1, &m_glName);
-	ANKI_ASSERT(m_glName);
-
-	if(sinit.m_addressing == SamplingAddressing::kRepeat)
-	{
-		glSamplerParameteri(m_glName, GL_TEXTURE_WRAP_S, GL_REPEAT);
-		glSamplerParameteri(m_glName, GL_TEXTURE_WRAP_T, GL_REPEAT);
-		glSamplerParameteri(m_glName, GL_TEXTURE_WRAP_R, GL_REPEAT);
-	}
-	else if(sinit.m_addressing == SamplingAddressing::kClamp)
-	{
-		glSamplerParameteri(m_glName, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-		glSamplerParameteri(m_glName, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-		glSamplerParameteri(m_glName, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
-	}
-	else
-	{
-		ANKI_ASSERT(!"TODO");
-	}
-
-	// Set filtering type
-	GLenum minFilter = GL_NONE;
-	GLenum magFilter = GL_NONE;
-	convertFilter(sinit.m_minMagFilter, sinit.m_mipmapFilter, minFilter, magFilter);
-	glSamplerParameteri(m_glName, GL_TEXTURE_MIN_FILTER, minFilter);
-	glSamplerParameteri(m_glName, GL_TEXTURE_MAG_FILTER, magFilter);
-
-#if ANKI_GL == ANKI_GL_DESKTOP
-	if(sinit.m_anisotropyLevel > 1)
-	{
-		glSamplerParameteri(m_glName, GL_TEXTURE_MAX_ANISOTROPY_EXT, GLint(sinit.m_anisotropyLevel));
-	}
-#endif
-
-	if(sinit.m_compareOperation != CompareOperation::ALWAYS)
-	{
-		glSamplerParameteri(m_glName, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
-		glSamplerParameteri(m_glName, GL_TEXTURE_COMPARE_FUNC, convertCompareOperation(sinit.m_compareOperation));
-	}
-
-	glSamplerParameteri(m_glName, GL_TEXTURE_MIN_LOD, sinit.m_minLod);
-	glSamplerParameteri(m_glName, GL_TEXTURE_MAX_LOD, sinit.m_maxLod);
-}
-
-} // end namespace anki

+ 0 - 34
AnKi/Gr/Gl/SamplerImpl.h

@@ -1,34 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/Sampler.h>
-#include <AnKi/Gr/gl/GlObject.h>
-
-namespace anki {
-
-/// @addtogroup opengl
-/// @{
-
-/// Sampler GL object.
-class SamplerImpl final : public Sampler, public GlObject
-{
-public:
-	SamplerImpl(GrManager* manager, CString name)
-		: Sampler(manager, name)
-	{
-	}
-
-	~SamplerImpl()
-	{
-		destroyDeferred(getManager(), glDeleteSamplers);
-	}
-
-	void init(const SamplerInitInfo& sinit);
-};
-/// @}
-
-} // end namespace anki

+ 0 - 70
AnKi/Gr/Gl/Shader.cpp

@@ -1,70 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/Shader.h>
-#include <AnKi/Gr/gl/ShaderImpl.h>
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-#include <AnKi/Gr/GrManager.h>
-
-namespace anki {
-
-Shader* Shader::newInstance(GrManager* manager, const ShaderInitInfo& init)
-{
-	class ShaderCreateCommand final : public GlCommand
-	{
-	public:
-		ShaderPtr m_shader;
-		StringRaii m_source;
-		DynamicArrayRaii<ShaderSpecializationConstValue> m_constValues;
-
-		ShaderCreateCommand(Shader* shader, ConstWeakArray<U8> bin, ConstWeakArray<ShaderSpecializationConstValue> constValues,
-							const CommandBufferAllocator<U8>& alloc)
-			: m_shader(shader)
-			, m_source(alloc)
-			, m_constValues(alloc)
-		{
-			m_source.create(reinterpret_cast<const char*>(&bin[0]));
-
-			if(constValues.getSize())
-			{
-				m_constValues.create(constValues.getSize());
-				memcpy(&m_constValues[0], &constValues[0], m_constValues.getByteSize());
-			}
-		}
-
-		Error operator()(GlState&)
-		{
-			ShaderImpl& impl = static_cast<ShaderImpl&>(*m_shader);
-
-			Error err = impl.init(m_source.toCString(), m_constValues);
-
-			GlObject::State oldState = impl.setStateAtomically((err) ? GlObject::State::ERROR : GlObject::State::CREATED);
-			ANKI_ASSERT(oldState == GlObject::State::TO_BE_CREATED);
-			(void)oldState;
-
-			return err;
-		}
-	};
-
-	ANKI_ASSERT(!init.m_binary.isEmpty());
-
-	ShaderImpl* impl = manager->getAllocator().newInstance<ShaderImpl>(manager, init.getName());
-	impl->getRefcount().fetchAdd(1); // Hold a reference in case the command finishes and deletes quickly
-
-	// Need to pre-init because some funcs ask for members and we don't want to serialize
-	impl->preInit(init);
-
-	// Copy source to the command buffer
-	CommandBufferPtr cmdb = manager->newCommandBuffer(CommandBufferInitInfo());
-	CommandBufferImpl& cmdbimpl = static_cast<CommandBufferImpl&>(*cmdb);
-	CommandBufferAllocator<U8> alloc = cmdbimpl.getInternalAllocator();
-
-	cmdbimpl.pushBackNewCommand<ShaderCreateCommand>(impl, init.m_binary, init.m_constValues, alloc);
-	cmdbimpl.flush();
-
-	return impl;
-}
-
-} // end namespace anki

+ 0 - 153
AnKi/Gr/Gl/ShaderImpl.cpp

@@ -1,153 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/ShaderImpl.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Gr/gl/GrManagerImpl.h>
-#include <AnKi/Gr/gl/GlState.h>
-#include <AnKi/Gr/ShaderCompiler.h>
-#include <AnKi/Util/StringList.h>
-#include <AnKi/Util/Logger.h>
-
-#define ANKI_DUMP_SHADERS ANKI_EXTRA_CHECKS
-
-#if ANKI_DUMP_SHADERS
-#	include <anki/util/File.h>
-#endif
-
-namespace anki {
-
-/// Fake glDeleteShaders because some jenius created a conflicting interface
-static void deleteShaders(GLsizei n, const GLuint* names)
-{
-	ANKI_ASSERT(n == 1);
-	ANKI_ASSERT(names);
-	glDeleteShader(*names);
-}
-
-ShaderImpl::~ShaderImpl()
-{
-	destroyDeferred(getManager(), deleteShaders);
-}
-
-Error ShaderImpl::init(CString source, ConstWeakArray<ShaderSpecializationConstValue> constValues)
-{
-	ANKI_ASSERT(source);
-	ANKI_ASSERT(!isCreated());
-
-	static const Array<GLenum, 6> gltype = {
-		{GL_VERTEX_SHADER, GL_TESS_CONTROL_SHADER, GL_TESS_EVALUATION_SHADER, GL_GEOMETRY_SHADER, GL_FRAGMENT_SHADER, GL_COMPUTE_SHADER}};
-
-	m_glType = gltype[U(m_shaderType)];
-
-	// Create a new shader with spec consts if needed
-	StringRaii newSrc(getAllocator());
-	if(constValues.getSize())
-	{
-		// Create const str
-		StringListRaii constStrLines(getAllocator());
-		U count = 0;
-		for(const ShaderSpecializationConstValue& constVal : constValues)
-		{
-			if(constVal.m_dataType == ShaderVariableDataType::INT)
-			{
-				constStrLines.pushBackSprintf("#define _anki_spec_const_%u %i", count, constVal.m_int);
-			}
-			else
-			{
-				ANKI_ASSERT(constVal.m_dataType == ShaderVariableDataType::FLOAT);
-				constStrLines.pushBackSprintf("#define _anki_spec_const_%u %f", count, constVal.m_float);
-			}
-
-			++count;
-		}
-		StringRaii constStr(getAllocator());
-		constStrLines.join("\n", constStr);
-
-		// Break the old source
-		StringListRaii lines(getAllocator());
-		lines.splitString(source, '\n');
-		ANKI_ASSERT(lines.getFront().find("#version") == 0);
-		lines.popFront();
-
-		// Append the const values
-		lines.pushFront(constStr.toCString());
-		lines.pushFront("#version 450 core");
-
-		// Create the new string
-		lines.join("\n", newSrc);
-		source = newSrc.toCString();
-	}
-
-	// Gen name, create and compile
-	const char* sourceStrs[1] = {nullptr};
-	sourceStrs[0] = &source[0];
-	m_glName = glCreateShader(m_glType);
-	glShaderSource(m_glName, 1, sourceStrs, NULL);
-	glCompileShader(m_glName);
-
-#if ANKI_DUMP_SHADERS
-	{
-		const char* ext;
-
-		switch(m_glType)
-		{
-		case GL_VERTEX_SHADER:
-			ext = "vert";
-			break;
-		case GL_TESS_CONTROL_SHADER:
-			ext = "tesc";
-			break;
-		case GL_TESS_EVALUATION_SHADER:
-			ext = "tese";
-			break;
-		case GL_GEOMETRY_SHADER:
-			ext = "geom";
-			break;
-		case GL_FRAGMENT_SHADER:
-			ext = "frag";
-			break;
-		case GL_COMPUTE_SHADER:
-			ext = "comp";
-			break;
-		default:
-			ext = nullptr;
-			ANKI_ASSERT(0);
-		}
-
-		StringRaii fname(getAllocator());
-		CString cacheDir = getManager().getCacheDirectory();
-		fname.sprintf("%s/%05u.%s", &cacheDir[0], static_cast<U32>(m_glName), ext);
-
-		File file;
-		ANKI_CHECK(file.open(fname.toCString(), FileOpenFlag::kWrite));
-		ANKI_CHECK(file.writeText("%s", source.cstr()));
-	}
-#endif
-
-	GLint status = GL_FALSE;
-	glGetShaderiv(m_glName, GL_COMPILE_STATUS, &status);
-	if(status == GL_FALSE)
-	{
-		auto alloc = getAllocator();
-		StringRaii compilerLog(alloc);
-		GLint compilerLogLen = 0;
-		GLint charsWritten = 0;
-
-		glGetShaderiv(m_glName, GL_INFO_LOG_LENGTH, &compilerLogLen);
-		compilerLog.create(' ', compilerLogLen + 1);
-
-		glGetShaderInfoLog(m_glName, compilerLogLen, &charsWritten, &compilerLog[0]);
-
-		ShaderCompiler::logShaderErrorCode(compilerLog.toCString(), source, alloc);
-
-		// Compilation failed, set error anyway
-		return Error::kUserData;
-	}
-
-	return Error::kNone;
-}
-
-} // end namespace anki

+ 0 - 41
AnKi/Gr/Gl/ShaderImpl.h

@@ -1,41 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/Shader.h>
-#include <AnKi/Gr/gl/GlObject.h>
-
-namespace anki {
-
-// Forward
-class CString;
-
-/// @addtogroup opengl
-/// @{
-
-/// Shader program implementation.
-class ShaderImpl final : public Shader, public GlObject
-{
-public:
-	GLenum m_glType = 0;
-
-	ShaderImpl(GrManager* manager, CString name)
-		: Shader(manager, name)
-	{
-	}
-
-	~ShaderImpl();
-
-	void preInit(const ShaderInitInfo& init)
-	{
-		m_shaderType = init.m_shaderType;
-	}
-
-	ANKI_USE_RESULT Error init(CString source, ConstWeakArray<ShaderSpecializationConstValue> constValues);
-};
-/// @}
-
-} // end namespace anki

+ 0 - 66
AnKi/Gr/Gl/ShaderProgram.cpp

@@ -1,66 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/ShaderProgram.h>
-#include <AnKi/Gr/gl/ShaderProgramImpl.h>
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Gr/Shader.h>
-
-namespace anki {
-
-ShaderProgram* ShaderProgram::newInstance(GrManager* manager, const ShaderProgramInitInfo& init)
-{
-	class CreateCommand final : public GlCommand
-	{
-	public:
-		ShaderProgramPtr m_prog;
-		ShaderPtr m_vert;
-		ShaderPtr m_tessc;
-		ShaderPtr m_tesse;
-		ShaderPtr m_geom;
-		ShaderPtr m_frag;
-		ShaderPtr m_comp;
-
-		CreateCommand(ShaderProgram* prog, ShaderPtr vert, ShaderPtr tessc, ShaderPtr tesse, ShaderPtr geom, ShaderPtr frag, ShaderPtr comp)
-			: m_prog(prog)
-			, m_vert(vert)
-			, m_tessc(tessc)
-			, m_tesse(tesse)
-			, m_geom(geom)
-			, m_frag(frag)
-			, m_comp(comp)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			if(m_comp)
-			{
-				return static_cast<ShaderProgramImpl&>(*m_prog).initCompute(m_comp);
-			}
-			else
-			{
-				return static_cast<ShaderProgramImpl&>(*m_prog).initGraphics(m_vert, m_tessc, m_tesse, m_geom, m_frag);
-			}
-		}
-	};
-
-	ANKI_ASSERT(init.isValid());
-
-	ShaderProgramImpl* impl = manager->getAllocator().newInstance<ShaderProgramImpl>(manager, init.getName());
-	impl->getRefcount().fetchAdd(1); // Hold a reference in case the command finishes and deletes quickly
-
-	CommandBufferPtr cmdb = manager->newCommandBuffer(CommandBufferInitInfo());
-	static_cast<CommandBufferImpl&>(*cmdb).pushBackNewCommand<CreateCommand>(
-		impl, init.m_shaders[ShaderType::kVertex], init.m_shaders[ShaderType::kTessellationControl],
-		init.m_shaders[ShaderType::kTessellationEvaluation], init.m_shaders[ShaderType::kGeometry], init.m_shaders[ShaderType::kFragment],
-		init.m_shaders[ShaderType::kCompute]);
-	static_cast<CommandBufferImpl&>(*cmdb).flush();
-
-	return impl;
-}
-
-} // end namespace anki

+ 0 - 201
AnKi/Gr/Gl/ShaderProgramImpl.cpp

@@ -1,201 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/ShaderProgramImpl.h>
-#include <AnKi/Gr/Shader.h>
-#include <AnKi/Gr/gl/ShaderImpl.h>
-
-namespace anki {
-
-static void deletePrograms(GLsizei n, const GLuint* progs)
-{
-	ANKI_ASSERT(n == 1);
-	ANKI_ASSERT(progs);
-	glDeleteProgram(*progs);
-}
-
-ShaderProgramImpl::~ShaderProgramImpl()
-{
-	destroyDeferred(getManager(), deletePrograms);
-	m_refl.m_uniforms.destroy(getAllocator());
-}
-
-Error ShaderProgramImpl::initGraphics(ShaderPtr vert, ShaderPtr tessc, ShaderPtr tesse, ShaderPtr geom, ShaderPtr frag)
-{
-	m_glName = glCreateProgram();
-	ANKI_ASSERT(m_glName != 0);
-
-	glAttachShader(m_glName, static_cast<const ShaderImpl&>(*vert).getGlName());
-	m_shaders[ShaderType::kVertex] = vert;
-
-	if(tessc)
-	{
-		glAttachShader(m_glName, static_cast<const ShaderImpl&>(*tessc).getGlName());
-		m_shaders[ShaderType::kTessellationControl] = tessc;
-	}
-
-	if(tesse)
-	{
-		glAttachShader(m_glName, static_cast<const ShaderImpl&>(*tesse).getGlName());
-		m_shaders[ShaderType::kTessellationEvaluation] = tesse;
-	}
-
-	if(geom)
-	{
-		glAttachShader(m_glName, static_cast<const ShaderImpl&>(*geom).getGlName());
-		m_shaders[ShaderType::kGeometry] = geom;
-	}
-
-	glAttachShader(m_glName, static_cast<const ShaderImpl&>(*frag).getGlName());
-	m_shaders[ShaderType::kFragment] = frag;
-
-	return link(static_cast<const ShaderImpl&>(*vert).getGlName(), static_cast<const ShaderImpl&>(*frag).getGlName());
-}
-
-Error ShaderProgramImpl::initCompute(ShaderPtr comp)
-{
-	m_glName = glCreateProgram();
-	ANKI_ASSERT(m_glName != 0);
-
-	glAttachShader(m_glName, static_cast<const ShaderImpl&>(*comp).getGlName());
-	m_shaders[ShaderType::kCompute] = comp;
-
-	return link(0, 0);
-}
-
-Error ShaderProgramImpl::link(GLuint vert, GLuint frag)
-{
-	Error err = Error::kNone;
-
-	glLinkProgram(m_glName);
-	GLint status = 0;
-	glGetProgramiv(m_glName, GL_LINK_STATUS, &status);
-
-	if(!status)
-	{
-		GLint infoLen = 0;
-		GLint charsWritten = 0;
-		DynamicArrayRaii<char> infoLogTxt(getAllocator());
-
-		glGetProgramiv(m_glName, GL_INFO_LOG_LENGTH, &infoLen);
-
-		infoLogTxt.create(infoLen + 1);
-
-		glGetProgramInfoLog(m_glName, infoLen, &charsWritten, &infoLogTxt[0]);
-
-		ANKI_GL_LOGE("Link error log follows (vs:%u, fs:%u):\n%s", vert, frag, &infoLogTxt[0]);
-
-		err = Error::kUserData;
-	}
-
-	return err;
-}
-
-const ShaderProgramImplReflection& ShaderProgramImpl::getReflection()
-{
-	if(m_reflInitialized)
-	{
-		return m_refl;
-	}
-
-	GLint uniformCount = 0;
-	glGetProgramiv(getGlName(), GL_ACTIVE_UNIFORMS, &uniformCount);
-
-	if(uniformCount)
-	{
-		for(U i = 0; i < U(uniformCount); ++i)
-		{
-			// Get uniform info
-			GLsizei len;
-			GLenum type;
-			GLint size;
-			Array<char, 128> name;
-			glGetActiveUniform(getGlName(), i, sizeof(name), &len, &size, &type, &name[0]);
-			name[len] = '\0';
-
-			if(CString(&name[0]).find("gl_") == 0)
-			{
-				// Builtin, skip
-				continue;
-			}
-
-			// Set type
-			ShaderVariableDataType akType = ShaderVariableDataType::kNone;
-			switch(type)
-			{
-			case GL_FLOAT_VEC4:
-				akType = ShaderVariableDataType::VEC4;
-				break;
-			case GL_INT_VEC4:
-				akType = ShaderVariableDataType::IVEC4;
-				break;
-			case GL_UNSIGNED_INT_VEC4:
-				akType = ShaderVariableDataType::UVEC4;
-				break;
-			case GL_FLOAT_MAT4:
-				akType = ShaderVariableDataType::MAT4;
-				break;
-			case GL_FLOAT_MAT3:
-				akType = ShaderVariableDataType::MAT3;
-				break;
-			default:
-				// Unsupported type, skip as well
-				continue;
-			}
-
-			const GLint location = glGetUniformLocation(getGlName(), &name[0]);
-			if(location < 0)
-			{
-				// Uniform block maybe, skip
-				continue;
-			}
-
-			// Store
-			ShaderProgramImplReflection::Uniform uni;
-			uni.m_location = location;
-			uni.m_type = akType;
-			uni.m_arrSize = size;
-
-			m_refl.m_uniforms.emplaceBack(getAllocator(), uni);
-		}
-
-		// Sort the uniforms
-		std::sort(m_refl.m_uniforms.getBegin(), m_refl.m_uniforms.getEnd(),
-				  [](const ShaderProgramImplReflection::Uniform& a, const ShaderProgramImplReflection::Uniform& b) {
-					  return a.m_location < b.m_location;
-				  });
-
-		// Now calculate the offset inside the push constant buffer
-		m_refl.m_uniformDataSize = 0;
-		for(ShaderProgramImplReflection::Uniform& uni : m_refl.m_uniforms)
-		{
-			U32 dataSize = 0;
-			switch(uni.m_type)
-			{
-			case ShaderVariableDataType::VEC4:
-			case ShaderVariableDataType::IVEC4:
-			case ShaderVariableDataType::UVEC4:
-				dataSize = sizeof(F32) * 4;
-				break;
-			case ShaderVariableDataType::MAT4:
-				dataSize = sizeof(F32) * 16;
-				break;
-			case ShaderVariableDataType::MAT3:
-				dataSize = sizeof(F32) * 12;
-				break;
-			default:
-				ANKI_ASSERT(!"Unsupported type");
-			}
-
-			uni.m_pushConstantOffset = m_refl.m_uniformDataSize;
-			m_refl.m_uniformDataSize += dataSize * uni.m_arrSize;
-		}
-	}
-
-	m_reflInitialized = true;
-	return m_refl;
-}
-
-} // end namespace anki

+ 0 - 57
AnKi/Gr/Gl/ShaderProgramImpl.h

@@ -1,57 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/ShaderProgram.h>
-#include <AnKi/Gr/gl/GlObject.h>
-
-namespace anki {
-
-/// @addtogroup opengl
-/// @{
-
-class ShaderProgramImplReflection
-{
-public:
-	struct Uniform
-	{
-		I32 m_location;
-		U32 m_pushConstantOffset;
-		ShaderVariableDataType m_type;
-		U8 m_arrSize;
-	};
-
-	DynamicArray<Uniform> m_uniforms;
-	U32 m_uniformDataSize = 0;
-};
-
-/// Shader program implementation.
-class ShaderProgramImpl final : public ShaderProgram, public GlObject
-{
-public:
-	ShaderProgramImpl(GrManager* manager, CString name)
-		: ShaderProgram(manager, name)
-	{
-	}
-
-	~ShaderProgramImpl();
-
-	ANKI_USE_RESULT Error initGraphics(ShaderPtr vert, ShaderPtr tessc, ShaderPtr tesse, ShaderPtr geom, ShaderPtr frag);
-	ANKI_USE_RESULT Error initCompute(ShaderPtr comp);
-
-	// Do that only when is needed to avoid serializing the thread the driver is using for compilation.
-	const ShaderProgramImplReflection& getReflection();
-
-private:
-	Array<ShaderPtr, U(ShaderType::kCount)> m_shaders;
-	ShaderProgramImplReflection m_refl;
-	Bool m_reflInitialized = false;
-
-	ANKI_USE_RESULT Error link(GLuint vert, GLuint frag);
-};
-/// @}
-
-} // end namespace anki

+ 0 - 585
AnKi/Gr/Gl/StateTracker.h

@@ -1,585 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/gl/Common.h>
-#include <AnKi/Gr/ShaderProgram.h>
-#include <AnKi/Gr/Framebuffer.h>
-#include <AnKi/Gr/gl/FramebufferImpl.h>
-#include <AnKi/Gr/Buffer.h>
-#include <AnKi/Gr/gl/BufferImpl.h>
-#include <AnKi/Gr/Texture.h>
-#include <AnKi/Gr/gl/TextureImpl.h>
-#include <AnKi/Gr/Sampler.h>
-#include <AnKi/Gr/gl/SamplerImpl.h>
-#include <AnKi/Gr/ShaderProgram.h>
-#include <AnKi/Gr/gl/ShaderProgramImpl.h>
-#include <AnKi/Gr/Framebuffer.h>
-#include <AnKi/Gr/gl/FramebufferImpl.h>
-#include <AnKi/Gr/Utils/Functions.h>
-
-namespace anki {
-
-/// @addtogroup opengl
-/// @{
-
-/// Local state tracker. Used to avoid creating command buffer commands.
-class StateTracker
-{
-public:
-	/// If it's false then there might be unset state.
-	Bool m_mayContainUnsetState = true;
-
-#if ANKI_EXTRA_CHECKS
-	Bool m_secondLevel = false;
-#endif
-
-	/// @name vert_state
-	/// @{
-	class VertexAttribute
-	{
-	public:
-		U32 m_buffBinding = kMaxU32;
-		Format m_fmt = Format::kNone;
-		PtrSize m_relativeOffset = kMaxPtrSize;
-	};
-
-	Array<VertexAttribute, kMaxVertexAttributes> m_attribs;
-
-	Bool setVertexAttribute(U32 location, U32 buffBinding, Format fmt, PtrSize relativeOffset)
-	{
-		VertexAttribute& attrib = m_attribs[location];
-		if(attrib.m_buffBinding != buffBinding || attrib.m_fmt != fmt || attrib.m_relativeOffset != relativeOffset)
-		{
-			attrib.m_buffBinding = buffBinding;
-			attrib.m_fmt = fmt;
-			attrib.m_relativeOffset = relativeOffset;
-			return true;
-		}
-
-		return false;
-	}
-
-	class VertexBuffer
-	{
-	public:
-		BufferImpl* m_buff = nullptr;
-		PtrSize m_offset = 0;
-		PtrSize m_stride = 0;
-		VertexStepRate m_stepRate = VertexStepRate::COUNT;
-	};
-
-	Array<VertexBuffer, kMaxVertexAttributes> m_vertBuffs;
-
-	Bool bindVertexBuffer(U32 binding, BufferPtr buff, PtrSize offset, PtrSize stride, VertexStepRate stepRate)
-	{
-		VertexBuffer& b = m_vertBuffs[binding];
-		b.m_buff = static_cast<BufferImpl*>(buff.get());
-		b.m_offset = offset;
-		b.m_stride = stride;
-		b.m_stepRate = stepRate;
-		return true;
-	}
-
-	class Index
-	{
-	public:
-		BufferImpl* m_buff = nullptr;
-		PtrSize m_offset = kMaxPtrSize;
-		GLenum m_indexType = 0;
-	} m_idx;
-
-	Bool bindIndexBuffer(BufferPtr buff, PtrSize offset, IndexType type)
-	{
-		m_idx.m_buff = static_cast<BufferImpl*>(buff.get());
-		m_idx.m_offset = offset;
-		m_idx.m_indexType = convertIndexType(type);
-		return true;
-	}
-	/// @}
-
-	/// @name input_assembly
-	/// @{
-	Bool m_primitiveRestart = 2;
-
-	Bool setPrimitiveRestart(Bool enable)
-	{
-		if(enable != m_primitiveRestart)
-		{
-			m_primitiveRestart = enable;
-			return true;
-		}
-		return false;
-	}
-	/// @}
-
-	/// @name viewport_state
-	/// @{
-	Array<U32, 4> m_viewport = {{kMaxU32, kMaxU32, kMaxU32, kMaxU32}};
-
-	Bool setViewport(U32 minx, U32 miny, U32 width, U32 height)
-	{
-		ANKI_ASSERT(minx != kMaxU32 && miny != kMaxU32 && width != kMaxU32 && height != kMaxU32);
-		if(m_viewport[0] != minx || m_viewport[1] != miny || m_viewport[2] != width || m_viewport[3] != height)
-		{
-			m_viewport = {{minx, miny, width, height}};
-			return true;
-		}
-		return false;
-	}
-	/// @}
-
-	/// @name scissor_state
-	/// @{
-	Array<GLsizei, 4> m_scissor = {{0, 0, kMaxI32, kMaxI32}};
-	Bool m_scissorSet = false;
-
-	Bool setScissor(GLsizei minx, GLsizei miny, GLsizei width, GLsizei height)
-	{
-		if(!m_scissorSet || (m_scissor[0] != minx || m_scissor[1] != miny || m_scissor[2] != width || m_scissor[3] != height))
-		{
-			m_scissor = {{minx, miny, width, height}};
-			m_scissorSet = true;
-			return true;
-		}
-		return false;
-	}
-	/// @}
-
-	/// @name rasterizer
-	/// @{
-	FillMode m_fillMode = FillMode::COUNT;
-
-	Bool setFillMode(FillMode mode)
-	{
-		if(m_fillMode != mode)
-		{
-			m_fillMode = mode;
-			return true;
-		}
-		return false;
-	}
-
-	FaceSelectionBit m_cullMode = static_cast<FaceSelectionBit>(0);
-
-	Bool setCullMode(FaceSelectionBit mode)
-	{
-		if(m_cullMode != mode)
-		{
-			m_cullMode = mode;
-			return true;
-		}
-		return false;
-	}
-
-	F32 m_polyOffsetFactor = -1.0;
-	F32 m_polyOffsetUnits = -1.0;
-
-	Bool setPolygonOffset(F32 factor, F32 units)
-	{
-		if(factor != m_polyOffsetFactor || units != m_polyOffsetUnits)
-		{
-			m_polyOffsetFactor = factor;
-			m_polyOffsetUnits = units;
-			return true;
-		}
-		return false;
-	}
-	/// @}
-
-	/// @name depth_stencil
-	/// @{
-	Bool m_stencilTestEnabled = 2;
-
-	Bool maybeEnableStencilTest()
-	{
-		Bool enable = !stencilTestDisabled(m_stencilFail[0], m_stencilPassDepthFail[0], m_stencilPassDepthPass[0], m_stencilCompare[0]);
-		enable = enable || !stencilTestDisabled(m_stencilFail[1], m_stencilPassDepthFail[1], m_stencilPassDepthPass[1], m_stencilCompare[1]);
-
-		if(enable != m_stencilTestEnabled)
-		{
-			m_stencilTestEnabled = enable;
-			return true;
-		}
-		return false;
-	}
-
-	Array<StencilOperation, 2> m_stencilFail = {{StencilOperation::COUNT, StencilOperation::COUNT}};
-	Array<StencilOperation, 2> m_stencilPassDepthFail = {{StencilOperation::COUNT, StencilOperation::COUNT}};
-	Array<StencilOperation, 2> m_stencilPassDepthPass = {{StencilOperation::COUNT, StencilOperation::COUNT}};
-
-	Bool setStencilOperations(FaceSelectionBit face, StencilOperation stencilFail, StencilOperation stencilPassDepthFail,
-							  StencilOperation stencilPassDepthPass)
-	{
-		Bool changed = false;
-		if(!!(face & FaceSelectionBit::FRONT)
-		   && (m_stencilFail[0] != stencilFail || m_stencilPassDepthFail[0] != stencilPassDepthFail
-			   || m_stencilPassDepthPass[0] != stencilPassDepthPass))
-		{
-			m_stencilFail[0] = stencilFail;
-			m_stencilPassDepthFail[0] = stencilPassDepthFail;
-			m_stencilPassDepthPass[0] = stencilPassDepthPass;
-			changed = true;
-		}
-
-		if(!!(face & FaceSelectionBit::BACK)
-		   && (m_stencilFail[1] != stencilFail || m_stencilPassDepthFail[1] != stencilPassDepthFail
-			   || m_stencilPassDepthPass[1] != stencilPassDepthPass))
-		{
-			m_stencilFail[1] = stencilFail;
-			m_stencilPassDepthFail[1] = stencilPassDepthFail;
-			m_stencilPassDepthPass[1] = stencilPassDepthPass;
-			changed = true;
-		}
-
-		return changed;
-	}
-
-	Array<Bool, 2> m_glStencilFuncSeparateDirty = {{false, false}};
-	Array<CompareOperation, 2> m_stencilCompare = {{CompareOperation::COUNT, CompareOperation::COUNT}};
-
-	void setStencilCompareOperation(FaceSelectionBit face, CompareOperation comp)
-	{
-		if(!!(face & FaceSelectionBit::FRONT) && m_stencilCompare[0] != comp)
-		{
-			m_stencilCompare[0] = comp;
-			m_glStencilFuncSeparateDirty[0] = true;
-		}
-
-		if(!!(face & FaceSelectionBit::BACK) && m_stencilCompare[1] != comp)
-		{
-			m_stencilCompare[1] = comp;
-			m_glStencilFuncSeparateDirty[1] = true;
-		}
-	}
-
-	static const U32 DUMMY_STENCIL_MASK = 0x969696;
-
-	Array<U32, 2> m_stencilCompareMask = {{DUMMY_STENCIL_MASK, DUMMY_STENCIL_MASK}};
-
-	void setStencilCompareMask(FaceSelectionBit face, U32 mask)
-	{
-		ANKI_ASSERT(mask != DUMMY_STENCIL_MASK && "Oops");
-
-		if(!!(face & FaceSelectionBit::FRONT) && m_stencilCompareMask[0] != mask)
-		{
-			m_stencilCompareMask[0] = mask;
-			m_glStencilFuncSeparateDirty[0] = true;
-		}
-
-		if(!!(face & FaceSelectionBit::BACK) && m_stencilCompareMask[1] != mask)
-		{
-			m_stencilCompareMask[1] = mask;
-			m_glStencilFuncSeparateDirty[1] = true;
-		}
-	}
-
-	Array<U32, 2> m_stencilWriteMask = {{DUMMY_STENCIL_MASK, DUMMY_STENCIL_MASK}};
-
-	Bool setStencilWriteMask(FaceSelectionBit face, U32 mask)
-	{
-		ANKI_ASSERT(mask != DUMMY_STENCIL_MASK && "Oops");
-
-		Bool changed = false;
-		if(!!(face & FaceSelectionBit::FRONT) && m_stencilWriteMask[0] != mask)
-		{
-			m_stencilWriteMask[0] = mask;
-			changed = true;
-		}
-
-		if(!!(face & FaceSelectionBit::BACK) && m_stencilWriteMask[1] != mask)
-		{
-			m_stencilWriteMask[1] = mask;
-			changed = true;
-		}
-
-		return changed;
-	}
-
-	Array<U32, 2> m_stencilRef = {{DUMMY_STENCIL_MASK, DUMMY_STENCIL_MASK}};
-
-	void setStencilReference(FaceSelectionBit face, U32 mask)
-	{
-		ANKI_ASSERT(mask != DUMMY_STENCIL_MASK && "Oops");
-
-		if(!!(face & FaceSelectionBit::FRONT) && m_stencilRef[0] != mask)
-		{
-			m_stencilRef[0] = mask;
-			m_glStencilFuncSeparateDirty[0] = true;
-		}
-
-		if(!!(face & FaceSelectionBit::BACK) && m_stencilRef[1] != mask)
-		{
-			m_stencilRef[1] = mask;
-			m_glStencilFuncSeparateDirty[1] = true;
-		}
-	}
-
-	Bool m_depthTestEnabled = 2; ///< 2 means don't know
-
-	Bool maybeEnableDepthTest()
-	{
-		ANKI_ASSERT(m_depthWrite <= 1 && m_depthOp != CompareOperation::COUNT);
-		Bool enable = m_depthWrite || m_depthOp != CompareOperation::ALWAYS;
-
-		if(enable != m_depthTestEnabled)
-		{
-			m_depthTestEnabled = enable;
-			return true;
-		}
-
-		return false;
-	}
-
-	Bool m_depthWrite = 2;
-
-	Bool setDepthWrite(Bool enable)
-	{
-		if(m_depthWrite != enable)
-		{
-			m_depthWrite = enable;
-			return true;
-		}
-		return false;
-	}
-
-	CompareOperation m_depthOp = CompareOperation::COUNT;
-
-	Bool setDepthCompareOperation(CompareOperation op)
-	{
-		if(op != m_depthOp)
-		{
-			m_depthOp = op;
-			return true;
-		}
-		return false;
-	}
-	/// @}
-
-	/// @name color
-	/// @{
-	static const ColorBit INVALID_COLOR_MASK = static_cast<ColorBit>(kMaxU8);
-
-	class ColorAttachment
-	{
-	public:
-		ColorBit m_writeMask = INVALID_COLOR_MASK;
-		Bool m_enableBlend = 2;
-		BlendFactor m_blendSrcFactorRgb = BlendFactor::COUNT;
-		BlendFactor m_blendDstFactorRgb = BlendFactor::COUNT;
-		BlendFactor m_blendSrcFactorA = BlendFactor::COUNT;
-		BlendFactor m_blendDstFactorA = BlendFactor::COUNT;
-		BlendOperation m_blendOpRgb = BlendOperation::COUNT;
-		BlendOperation m_blendOpA = BlendOperation::COUNT;
-	};
-
-	Array<ColorAttachment, kMaxColorRenderTargets> m_colorAtt;
-
-	Bool setColorChannelWriteMask(U32 attachment, ColorBit mask)
-	{
-		if(m_colorAtt[attachment].m_writeMask != mask)
-		{
-			m_colorAtt[attachment].m_writeMask = mask;
-			return true;
-		}
-		return false;
-	}
-
-	Bool maybeEnableBlend(U attidx)
-	{
-		ColorAttachment& att = m_colorAtt[attidx];
-		Bool wantBlend = !blendingDisabled(att.m_blendSrcFactorRgb, att.m_blendDstFactorRgb, att.m_blendSrcFactorA, att.m_blendDstFactorA,
-										   att.m_blendOpRgb, att.m_blendOpA);
-
-		if(wantBlend != att.m_enableBlend)
-		{
-			att.m_enableBlend = wantBlend;
-			return true;
-		}
-		return false;
-	}
-
-	Bool setBlendFactors(U32 attachment, BlendFactor srcRgb, BlendFactor dstRgb, BlendFactor srcA, BlendFactor dstA)
-	{
-		auto& att = m_colorAtt[attachment];
-		if(att.m_blendSrcFactorRgb != srcRgb || att.m_blendDstFactorRgb != dstRgb || att.m_blendSrcFactorA != srcA || att.m_blendDstFactorA != dstA)
-		{
-			att.m_blendSrcFactorRgb = srcRgb;
-			att.m_blendDstFactorRgb = dstRgb;
-			att.m_blendSrcFactorA = srcA;
-			att.m_blendDstFactorA = dstA;
-			return true;
-		}
-		return false;
-	}
-
-	Bool setBlendOperation(U32 attachment, BlendOperation funcRgb, BlendOperation funcA)
-	{
-		auto& att = m_colorAtt[attachment];
-
-		if(att.m_blendOpRgb != funcRgb || att.m_blendOpA != funcA)
-		{
-			att.m_blendOpRgb = funcRgb;
-			att.m_blendOpA = funcA;
-			return true;
-		}
-		return false;
-	}
-	/// @}
-
-	/// @name resources
-	/// @{
-	class TextureBinding
-	{
-	public:
-		U64 m_texViewUuid = 0;
-		U64 m_samplerUuid = 0;
-	};
-
-	Array2d<TextureBinding, kMaxDescriptorSets, MAX_TEXTURE_BINDINGS> m_textures;
-
-	Bool bindTextureViewAndSampler(U32 set, U32 binding, const TextureViewPtr& texView, const SamplerPtr& sampler)
-	{
-		TextureBinding& b = m_textures[set][binding];
-
-		Bool dirty;
-		if(b.m_texViewUuid != texView->getUuid() || b.m_samplerUuid != sampler->getUuid())
-		{
-			b.m_texViewUuid = texView->getUuid();
-			b.m_samplerUuid = sampler->getUuid();
-			dirty = true;
-		}
-		else
-		{
-			dirty = false;
-		}
-
-		return dirty;
-	}
-
-	class ShaderBufferBinding
-	{
-	public:
-		BufferImpl* m_buff = nullptr;
-		PtrSize m_offset;
-		PtrSize m_range;
-	};
-
-	Array2d<ShaderBufferBinding, kMaxDescriptorSets, MAX_UNIFORM_BUFFER_BINDINGS> m_ubos;
-
-	Bool bindConstantBuffer(U32 set, U32 binding, BufferPtr buff, PtrSize offset, PtrSize range)
-	{
-		ShaderBufferBinding& b = m_ubos[set][binding];
-		b.m_buff = static_cast<BufferImpl*>(buff.get());
-		b.m_offset = offset;
-		b.m_range = range;
-		return true;
-	}
-
-	Array2d<ShaderBufferBinding, kMaxDescriptorSets, MAX_STORAGE_BUFFER_BINDINGS> m_ssbos;
-
-	Bool bindUavBuffer(U32 set, U32 binding, BufferPtr buff, PtrSize offset, PtrSize range)
-	{
-		ShaderBufferBinding& b = m_ssbos[set][binding];
-		b.m_buff = static_cast<BufferImpl*>(buff.get());
-		b.m_offset = offset;
-		b.m_range = range;
-		return true;
-	}
-
-	class ImageBinding
-	{
-	public:
-		U64 m_texViewUuid = 0;
-	};
-
-	Array2d<ImageBinding, kMaxDescriptorSets, MAX_IMAGE_BINDINGS> m_images;
-
-	Bool bindUavTexture(U32 set, U32 binding, const TextureViewPtr& img)
-	{
-		ImageBinding& b = m_images[set][binding];
-		b.m_texViewUuid = img->getUuid();
-		return true;
-	}
-
-	ShaderProgramImpl* m_prog = nullptr;
-
-	Bool bindShaderProgram(ShaderProgramPtr prog)
-	{
-		ShaderProgramImpl* const progimpl = static_cast<ShaderProgramImpl*>(prog.get());
-		if(progimpl != m_prog)
-		{
-			m_prog = progimpl;
-			return true;
-		}
-		return false;
-	}
-	/// @}
-
-	/// @name other
-	/// @{
-	const FramebufferImpl* m_fb = nullptr;
-
-	Bool beginRenderPass(const FramebufferPtr& fb)
-	{
-		ANKI_ASSERT(!insideRenderPass() && "Already inside a renderpass");
-		m_fb = static_cast<const FramebufferImpl*>(fb.get());
-		m_lastSecondLevelCmdb = nullptr;
-		return true;
-	}
-
-	void endRenderPass()
-	{
-		ANKI_ASSERT(insideRenderPass() && "Not inside a renderpass");
-		if(m_lastSecondLevelCmdb)
-		{
-			// Renderpass had 2nd level cmdbs, need to restore the state back to default
-			::new(this) StateTracker();
-		}
-		else
-		{
-			m_fb = nullptr;
-		}
-	}
-
-	Bool insideRenderPass() const
-	{
-		return m_fb != nullptr;
-	}
-
-	CommandBufferImpl* m_lastSecondLevelCmdb = nullptr;
-	/// @}
-
-	/// @name drawcalls
-	/// @{
-	void checkIndexedDracall() const
-	{
-		ANKI_ASSERT(m_idx.m_indexType != 0 && "Forgot to bind index buffer");
-		checkDrawcall();
-	}
-
-	void checkNonIndexedDrawcall() const
-	{
-		checkDrawcall();
-	}
-
-	void checkDrawcall() const
-	{
-		ANKI_ASSERT(m_viewport[1] != kMaxU16 && "Forgot to set the viewport");
-		ANKI_ASSERT(m_prog && "Forgot to bound a program");
-		ANKI_ASSERT((insideRenderPass() || m_secondLevel) && "Forgot to begin a render pass");
-	}
-
-	void checkDispatch() const
-	{
-		ANKI_ASSERT(m_prog && "Forgot to bound a program");
-		ANKI_ASSERT(!insideRenderPass() && "Forgot to end the render pass");
-	}
-	/// @}
-};
-/// @}
-
-} // end namespace anki

+ 0 - 54
AnKi/Gr/Gl/Texture.cpp

@@ -1,54 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/Texture.h>
-#include <AnKi/Gr/gl/TextureImpl.h>
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-#include <AnKi/Gr/GrManager.h>
-
-namespace anki {
-
-Texture* Texture::newInstance(GrManager* manager, const TextureInitInfo& init)
-{
-	class CreateTextureCommand final : public GlCommand
-	{
-	public:
-		TexturePtr m_tex;
-		TextureInitInfo m_init;
-
-		CreateTextureCommand(Texture* tex, const TextureInitInfo& init)
-			: m_tex(tex)
-			, m_init(init)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			TextureImpl& impl = static_cast<TextureImpl&>(*m_tex);
-
-			impl.init(m_init);
-
-			GlObject::State oldState = impl.setStateAtomically(GlObject::State::CREATED);
-			ANKI_ASSERT(oldState == GlObject::State::TO_BE_CREATED);
-			(void)oldState;
-
-			return Error::kNone;
-		}
-	};
-
-	TextureImpl* impl = manager->getAllocator().newInstance<TextureImpl>(manager, init.getName());
-	impl->getRefcount().fetchAdd(1); // Hold a reference in case the command finishes and deletes quickly
-
-	// Need to pre-init because some funcs ask for members and we don't want to serialize
-	impl->preInit(init);
-
-	CommandBufferPtr cmdb = manager->newCommandBuffer(CommandBufferInitInfo());
-	static_cast<CommandBufferImpl&>(*cmdb).pushBackNewCommand<CreateTextureCommand>(impl, init);
-	static_cast<CommandBufferImpl&>(*cmdb).flush();
-
-	return impl;
-}
-
-} // end namespace anki

+ 0 - 417
AnKi/Gr/Gl/TextureImpl.cpp

@@ -1,417 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/TextureImpl.h>
-#include <AnKi/Gr/Texture.h>
-#include <AnKi/Gr/gl/Error.h>
-#include <AnKi/Util/Functions.h>
-#include <AnKi/Gr/GrManager.h>
-#include <AnKi/Gr/gl/GrManagerImpl.h>
-#include <AnKi/Gr/gl/TextureViewImpl.h>
-#include <AnKi/Gr/gl/RenderingThread.h>
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-
-namespace anki {
-
-static GLenum convertTextureType(TextureType type)
-{
-	GLenum out = GL_NONE;
-	switch(type)
-	{
-	case TextureType::_1D:
-		out = GL_TEXTURE_1D;
-		break;
-	case TextureType::k2D:
-		out = GL_TEXTURE_2D;
-		break;
-	case TextureType::k3D:
-		out = GL_TEXTURE_3D;
-		break;
-	case TextureType::k2DArray:
-		out = GL_TEXTURE_2D_ARRAY;
-		break;
-	case TextureType::kCube:
-		out = GL_TEXTURE_CUBE_MAP;
-		break;
-	case TextureType::kCubeArray:
-		out = GL_TEXTURE_CUBE_MAP_ARRAY;
-		break;
-	default:
-		ANKI_ASSERT(0);
-	};
-
-	return out;
-}
-
-class DeleteTextureCommand final : public GlCommand
-{
-public:
-	GLuint m_tex;
-	HashMap<TextureSubresourceInfo, MicroTextureView> m_views;
-	GrAllocator<U8> m_alloc;
-
-	DeleteTextureCommand(GLuint tex, HashMap<TextureSubresourceInfo, MicroTextureView>& views, GrAllocator<U8> alloc)
-		: m_tex(tex)
-		, m_views(std::move(views))
-		, m_alloc(alloc)
-	{
-	}
-
-	Error operator()(GlState& state)
-	{
-		// Delete views
-		auto it = m_views.getBegin();
-		auto end = m_views.getEnd();
-		while(it != end)
-		{
-			const MicroTextureView& view = *it;
-			glDeleteTextures(1, &view.m_glName);
-			++it;
-		}
-
-		m_views.destroy(m_alloc);
-
-		// Delete texture
-		if(m_tex != 0)
-		{
-			glDeleteTextures(1, &m_tex);
-		}
-
-		return Error::kNone;
-	}
-};
-
-TextureImpl::~TextureImpl()
-{
-	GrManager& manager = getManager();
-	RenderingThread& thread = static_cast<GrManagerImpl&>(manager).getRenderingThread();
-
-	if(!thread.isServerThread())
-	{
-		CommandBufferPtr commands;
-
-		commands = manager.newCommandBuffer(CommandBufferInitInfo());
-		static_cast<CommandBufferImpl&>(*commands).pushBackNewCommand<DeleteTextureCommand>(m_glName, m_viewsMap, getAllocator());
-		static_cast<CommandBufferImpl&>(*commands).flush();
-	}
-	else
-	{
-		DeleteTextureCommand cmd(m_glName, m_viewsMap, getAllocator());
-		cmd(static_cast<GrManagerImpl&>(manager).getState());
-	}
-
-	m_glName = 0;
-}
-
-void TextureImpl::bind() const
-{
-	glActiveTexture(GL_TEXTURE0);
-	glBindTexture(m_target, m_glName);
-}
-
-void TextureImpl::preInit(const TextureInitInfo& init)
-{
-	ANKI_ASSERT(init.isValid());
-
-	m_width = init.m_width;
-	m_height = init.m_height;
-	m_depth = init.m_depth;
-	m_layerCount = init.m_layerCount;
-	m_target = convertTextureType(init.m_type);
-	m_texType = init.m_type;
-	m_format = init.m_format;
-	m_usage = init.m_usage;
-
-	convertTextureInformation(init.m_format, m_compressed, m_glFormat, m_internalFormat, m_glType, m_aspect);
-
-	if(m_target != GL_TEXTURE_3D)
-	{
-		m_mipCount = min<U>(init.m_mipmapCount, computeMaxMipmapCount2d(m_width, m_height));
-	}
-	else
-	{
-		m_mipCount = min<U>(init.m_mipmapCount, computeMaxMipmapCount3d(m_width, m_height, m_depth));
-	}
-
-	// Surface count
-	switch(m_target)
-	{
-	case GL_TEXTURE_1D:
-	case GL_TEXTURE_2D:
-	case GL_TEXTURE_2D_MULTISAMPLE:
-		m_surfaceCountPerLevel = 1;
-		m_faceCount = 1;
-		break;
-	case GL_TEXTURE_CUBE_MAP:
-		m_surfaceCountPerLevel = 6;
-		m_faceCount = 6;
-		break;
-	case GL_TEXTURE_CUBE_MAP_ARRAY:
-		m_surfaceCountPerLevel = m_layerCount * 6;
-		m_faceCount = 6;
-		break;
-	case GL_TEXTURE_2D_ARRAY:
-		m_surfaceCountPerLevel = m_layerCount;
-		m_faceCount = 1;
-		break;
-	case GL_TEXTURE_3D:
-		m_surfaceCountPerLevel = m_depth;
-		m_faceCount = 1;
-		break;
-	default:
-		ANKI_ASSERT(0);
-	}
-}
-
-void TextureImpl::init(const TextureInitInfo& init)
-{
-	ANKI_ASSERT(!isCreated());
-
-	GrAllocator<U8> alloc = getAllocator();
-
-	// Create
-	//
-	glGenTextures(1, &m_glName);
-	ANKI_ASSERT(m_glName != 0);
-
-	bind();
-
-	// Create storage
-	switch(m_target)
-	{
-	case GL_TEXTURE_2D:
-	case GL_TEXTURE_CUBE_MAP:
-		glTexStorage2D(m_target, m_mipCount, m_internalFormat, m_width, m_height);
-		break;
-	case GL_TEXTURE_CUBE_MAP_ARRAY:
-		glTexStorage3D(m_target, m_mipCount, m_internalFormat, m_width, m_height, m_layerCount * 6);
-		break;
-	case GL_TEXTURE_2D_ARRAY:
-		glTexStorage3D(m_target, m_mipCount, m_internalFormat, m_width, m_height, m_layerCount);
-		break;
-	case GL_TEXTURE_3D:
-		glTexStorage3D(m_target, m_mipCount, m_internalFormat, m_width, m_height, m_depth);
-		break;
-	case GL_TEXTURE_2D_MULTISAMPLE:
-		glTexStorage2DMultisample(m_target, init.m_samples, m_internalFormat, m_width, m_height, GL_FALSE);
-		break;
-	default:
-		ANKI_ASSERT(0);
-	}
-
-	// Make sure that the texture is complete
-	glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, m_mipCount - 1);
-
-	ANKI_CHECK_GL_ERROR();
-}
-
-void TextureImpl::copyFromBuffer(const TextureSubresourceInfo& subresource, GLuint pbo, PtrSize offset, PtrSize dataSize) const
-{
-	ANKI_ASSERT(isSubresourceGoodForCopyFromBuffer(subresource));
-	ANKI_ASSERT(dataSize > 0);
-
-	const U mipmap = subresource.m_firstMipmap;
-	const U w = m_width >> mipmap;
-	const U h = m_height >> mipmap;
-	const U d = m_depth >> mipmap;
-	ANKI_ASSERT(w > 0);
-	ANKI_ASSERT(h > 0);
-
-	bind();
-	glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
-	const void* ptrOffset = numberToPtr<const void*>(offset);
-
-	switch(m_target)
-	{
-	case GL_TEXTURE_2D:
-		if(!m_compressed)
-		{
-			glTexSubImage2D(m_target, mipmap, 0, 0, w, h, m_glFormat, m_glType, ptrOffset);
-		}
-		else
-		{
-			glCompressedTexSubImage2D(m_target, mipmap, 0, 0, w, h, m_glFormat, dataSize, ptrOffset);
-		}
-		break;
-	case GL_TEXTURE_CUBE_MAP:
-	{
-		const U surfIdx = computeSurfaceIdx(TextureSurfaceInfo(mipmap, 0, subresource.m_firstFace, 0));
-		if(!m_compressed)
-		{
-			glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + surfIdx, mipmap, 0, 0, w, h, m_glFormat, m_glType, ptrOffset);
-		}
-		else
-		{
-			glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + surfIdx, mipmap, 0, 0, w, h, m_glFormat, dataSize, ptrOffset);
-		}
-		break;
-	}
-	case GL_TEXTURE_2D_ARRAY:
-	{
-		const U surfIdx = computeSurfaceIdx(TextureSurfaceInfo(mipmap, 0, 0, subresource.m_firstLayer));
-		if(!m_compressed)
-		{
-			glTexSubImage3D(m_target, mipmap, 0, 0, surfIdx, w, h, 1, m_glFormat, m_glType, ptrOffset);
-		}
-		else
-		{
-			glCompressedTexSubImage3D(m_target, mipmap, 0, 0, surfIdx, w, h, 1, m_glFormat, dataSize, ptrOffset);
-		}
-		break;
-	}
-	case GL_TEXTURE_3D:
-		ANKI_ASSERT(d > 0);
-		if(!m_compressed)
-		{
-			glTexSubImage3D(m_target, mipmap, 0, 0, 0, w, h, d, m_glFormat, m_glType, ptrOffset);
-		}
-		else
-		{
-			glCompressedTexSubImage3D(m_target, mipmap, 0, 0, 0, w, h, d, m_glFormat, dataSize, ptrOffset);
-		}
-		break;
-	default:
-		ANKI_ASSERT(0);
-	}
-
-	glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-	ANKI_CHECK_GL_ERROR();
-}
-
-void TextureImpl::generateMipmaps2d(const TextureViewImpl& view) const
-{
-	ANKI_ASSERT(view.m_tex.get() == this);
-	ANKI_ASSERT(isSubresourceGoodForMipmapGeneration(view.getSubresource()));
-	ANKI_ASSERT(!m_compressed);
-
-	if(m_surfaceCountPerLevel > 1)
-	{
-		glGenerateTextureMipmap(view.m_view.m_glName);
-	}
-	else
-	{
-		glGenerateTextureMipmap(m_glName);
-	}
-}
-
-void TextureImpl::clear(const TextureSubresourceInfo& subresource, const ClearValue& clearValue) const
-{
-	ANKI_ASSERT(isCreated());
-	ANKI_ASSERT(isSubresourceValid(subresource));
-	ANKI_ASSERT(m_texType != TextureType::k3D && "TODO");
-
-	// Find the aspect to clear
-	const DepthStencilAspectBit aspect = subresource.m_depthStencilAspect;
-	GLenum format;
-	if(aspect == DepthStencilAspectBit::kDepth)
-	{
-		ANKI_ASSERT(m_glFormat == GL_DEPTH_COMPONENT || m_glFormat == GL_DEPTH_STENCIL);
-		format = GL_DEPTH_COMPONENT;
-	}
-	else if(aspect == DepthStencilAspectBit::STENCIL)
-	{
-		ANKI_ASSERT(m_glFormat == GL_STENCIL_INDEX || m_glFormat == GL_DEPTH_STENCIL);
-		format = GL_STENCIL_INDEX;
-	}
-	else if(aspect == DepthStencilAspectBit::DEPTH_STENCIL)
-	{
-		ANKI_ASSERT(m_glFormat == GL_DEPTH_STENCIL);
-		format = GL_DEPTH_STENCIL;
-	}
-	else
-	{
-		format = m_glFormat;
-	}
-
-	for(U mip = subresource.m_firstMipmap; mip < subresource.m_firstMipmap + subresource.m_mipmapCount; ++mip)
-	{
-		for(U face = subresource.m_firstFace; face < subresource.m_firstFace + subresource.m_faceCount; ++face)
-		{
-			for(U layer = subresource.m_firstLayer; layer < subresource.m_firstLayer + subresource.m_layerCount; ++layer)
-			{
-				const U surfaceIdx = computeSurfaceIdx(TextureSurfaceInfo(mip, 0, face, layer));
-				const U width = m_width >> mip;
-				const U height = m_height >> mip;
-
-				glClearTexSubImage(m_glName, mip, 0, 0, surfaceIdx, width, height, 1, format, GL_FLOAT, &clearValue.m_colorf[0]);
-			}
-		}
-	}
-}
-
-U TextureImpl::computeSurfaceIdx(const TextureSurfaceInfo& surf) const
-{
-	U out;
-
-	if(m_target == GL_TEXTURE_3D)
-	{
-		// Check depth for this level
-		ANKI_ASSERT(surf.m_depth < (m_depth >> surf.m_level));
-		out = surf.m_depth;
-	}
-	else
-	{
-		out = m_faceCount * surf.m_layer + surf.m_face;
-	}
-
-	ANKI_ASSERT(out < m_surfaceCountPerLevel);
-	return out;
-}
-
-MicroTextureView TextureImpl::getOrCreateView(const TextureSubresourceInfo& subresource) const
-{
-	// Quick opt: Check if the subresource refers to the whole tex
-	TextureSubresourceInfo wholeTexSubresource;
-	wholeTexSubresource.m_mipmapCount = getMipmapCount();
-	wholeTexSubresource.m_faceCount = textureTypeIsCube(getTextureType()) ? 6 : 1;
-	wholeTexSubresource.m_layerCount = getLayerCount();
-	wholeTexSubresource.m_depthStencilAspect = getDepthStencilAspect();
-
-	if(subresource == wholeTexSubresource)
-	{
-		MicroTextureView view{getGlName(), wholeTexSubresource.m_depthStencilAspect};
-		return view;
-	}
-
-	// Continue with the regular init
-	LockGuard<Mutex> lock(m_viewsMapMtx);
-	auto it = m_viewsMap.find(subresource);
-
-	if(it != m_viewsMap.getEnd())
-	{
-		return *it;
-	}
-	else
-	{
-		// Create a new view
-
-		// Compute the new target if needed
-		const TextureType newTexType = computeNewTexTypeOfSubresource(subresource);
-		GLenum glTarget = m_target;
-		if(newTexType == TextureType::k2D)
-		{
-			// Change that anyway
-			glTarget = GL_TEXTURE_2D;
-		}
-
-		const U firstSurf = computeSurfaceIdx(TextureSurfaceInfo(subresource.m_firstMipmap, 0, subresource.m_firstFace, subresource.m_firstLayer));
-		const U lastSurf = computeSurfaceIdx(TextureSurfaceInfo(subresource.m_firstMipmap, 0, subresource.m_firstFace + subresource.m_faceCount - 1,
-																subresource.m_firstLayer + subresource.m_layerCount - 1));
-		ANKI_ASSERT(firstSurf <= lastSurf);
-
-		MicroTextureView view;
-		view.m_aspect = subresource.m_depthStencilAspect;
-
-		glGenTextures(1, &view.m_glName);
-		glTextureView(view.m_glName, glTarget, m_glName, m_internalFormat, subresource.m_firstMipmap, subresource.m_mipmapCount, firstSurf,
-					  lastSurf - firstSurf + 1);
-
-		m_viewsMap.emplace(getAllocator(), subresource, view);
-
-		return view;
-	}
-}
-
-} // end namespace anki

+ 0 - 76
AnKi/Gr/Gl/TextureImpl.h

@@ -1,76 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/Texture.h>
-#include <AnKi/Gr/gl/GlObject.h>
-#include <AnKi/Gr/Utils/Functions.h>
-#include <AnKi/Util/HashMap.h>
-
-namespace anki {
-
-/// @addtogroup opengl
-/// @{
-
-/// Small wrapper on top of a texture view and its aspect.
-struct MicroTextureView
-{
-	GLuint m_glName;
-	DepthStencilAspectBit m_aspect;
-};
-
-/// Texture container.
-class TextureImpl final : public Texture, public GlObject
-{
-public:
-	GLenum m_target = GL_NONE; ///< GL_TEXTURE_2D, GL_TEXTURE_3D... etc.
-	GLenum m_internalFormat = GL_NONE; ///< GL_COMPRESSED_RED, GL_RGB16 etc.
-	GLenum m_glFormat = GL_NONE;
-	GLenum m_glType = GL_NONE;
-	U32 m_surfaceCountPerLevel = 0;
-	U8 m_faceCount = 0; ///< 6 for cubes and 1 for the rest.
-	Bool m_compressed = false;
-
-	TextureImpl(GrManager* manager, CString name)
-		: Texture(manager, name)
-	{
-	}
-
-	~TextureImpl();
-
-	/// Init some stuff.
-	void preInit(const TextureInitInfo& init);
-
-	/// Create the texture storage.
-	void init(const TextureInitInfo& init);
-
-	/// Write texture data.
-	void copyFromBuffer(const TextureSubresourceInfo& subresource, GLuint pbo, PtrSize offset, PtrSize dataSize) const;
-
-	/// Generate mipmaps.
-	void generateMipmaps2d(const TextureViewImpl& view) const;
-
-	void bind() const;
-
-	void clear(const TextureSubresourceInfo& subresource, const ClearValue& clearValue) const;
-
-	U computeSurfaceIdx(const TextureSurfaceInfo& surf) const;
-
-	MicroTextureView getOrCreateView(const TextureSubresourceInfo& subresource) const;
-
-	TextureType computeNewTexTypeOfSubresource(const TextureSubresourceInfo& subresource) const
-	{
-		ANKI_ASSERT(isSubresourceValid(subresource));
-		return (textureTypeIsCube(m_texType) && subresource.m_faceCount != 6) ? TextureType::k2D : m_texType;
-	}
-
-private:
-	mutable HashMap<TextureSubresourceInfo, MicroTextureView> m_viewsMap;
-	mutable Mutex m_viewsMapMtx;
-};
-/// @}
-
-} // end namespace anki

+ 0 - 52
AnKi/Gr/Gl/TextureView.cpp

@@ -1,52 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/TextureView.h>
-#include <AnKi/Gr/gl/TextureViewImpl.h>
-#include <AnKi/Gr/gl/CommandBufferImpl.h>
-#include <AnKi/Gr/GrManager.h>
-
-namespace anki {
-
-TextureView* TextureView::newInstance(GrManager* manager, const TextureViewInitInfo& init)
-{
-	class CreateTextureViewCommand final : public GlCommand
-	{
-	public:
-		TextureViewPtr m_view;
-
-		CreateTextureViewCommand(TextureView* view)
-			: m_view(view)
-		{
-		}
-
-		Error operator()(GlState&)
-		{
-			TextureViewImpl& impl = static_cast<TextureViewImpl&>(*m_view);
-
-			impl.init();
-
-			GlObject::State oldState = impl.setStateAtomically(GlObject::State::CREATED);
-			ANKI_ASSERT(oldState == GlObject::State::TO_BE_CREATED);
-			(void)oldState;
-
-			return Error::kNone;
-		}
-	};
-
-	TextureViewImpl* impl = manager->getAllocator().newInstance<TextureViewImpl>(manager, init.getName());
-	impl->getRefcount().fetchAdd(1); // Hold a reference in case the command finishes and deletes quickly
-
-	// Need to pre-init because some funcs ask for members and we don't want to serialize
-	impl->preInit(init);
-
-	CommandBufferPtr cmdb = manager->newCommandBuffer(CommandBufferInitInfo());
-	static_cast<CommandBufferImpl&>(*cmdb).pushBackNewCommand<CreateTextureViewCommand>(impl);
-	static_cast<CommandBufferImpl&>(*cmdb).flush();
-
-	return impl;
-}
-
-} // end namespace anki

+ 0 - 24
AnKi/Gr/Gl/TextureViewImpl.cpp

@@ -1,24 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <AnKi/Gr/gl/TextureViewImpl.h>
-
-namespace anki {
-
-void TextureViewImpl::preInit(const TextureViewInitInfo& inf)
-{
-	ANKI_ASSERT(inf.isValid());
-
-	// Store some stuff
-	m_subresource = inf;
-
-	m_tex = inf.m_texture;
-	const TextureImpl& tex = static_cast<const TextureImpl&>(*m_tex);
-	ANKI_ASSERT(tex.isSubresourceValid(inf));
-
-	m_texType = tex.computeNewTexTypeOfSubresource(inf);
-}
-
-} // end namespace anki

+ 0 - 44
AnKi/Gr/Gl/TextureViewImpl.h

@@ -1,44 +0,0 @@
-// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <AnKi/Gr/TextureView.h>
-#include <AnKi/Gr/gl/GlObject.h>
-#include <AnKi/Gr/gl/TextureImpl.h>
-
-namespace anki {
-
-/// @addtogroup opengl
-/// @{
-
-/// Texture view implementation.
-class TextureViewImpl final : public TextureView, public GlObject
-{
-public:
-	MicroTextureView m_view = {};
-	TexturePtr m_tex; ///< Hold a reference.
-
-	TextureViewImpl(GrManager* manager, CString name)
-		: TextureView(manager, name)
-	{
-	}
-
-	~TextureViewImpl()
-	{
-		m_glName = 0;
-	}
-
-	void preInit(const TextureViewInitInfo& inf);
-
-	void init()
-	{
-		m_view = static_cast<const TextureImpl&>(*m_tex).getOrCreateView(getSubresource());
-		m_glName = m_view.m_glName;
-	}
-};
-/// @}
-
-} // end namespace anki

+ 2 - 2
AnKi/Shaders/Functions.hlsl

@@ -317,7 +317,7 @@ vector<T, 3> gammaCorrection(vector<T, 3> gamma, vector<T, 3> col)
 
 // Can use 0.15 for sharpenFactor
 template<typename T>
-vector<T, 3> readSharpen(Texture2D<vector<T, 4>> tex, SamplerState sampl, Vec2 uv, T sharpenFactor, Bool detailed)
+vector<T, 3> readSharpen(Texture2D<vector<T, 4> > tex, SamplerState sampl, Vec2 uv, T sharpenFactor, Bool detailed)
 {
 	vector<T, 3> col = tex.SampleLevel(sampl, uv, 0.0).rgb;
 
@@ -342,7 +342,7 @@ vector<T, 3> readSharpen(Texture2D<vector<T, 4>> tex, SamplerState sampl, Vec2 u
 }
 
 template<typename T>
-vector<T, 3> readErosion(Texture2D<vector<T, 4>> tex, SamplerState sampl, const Vec2 uv)
+vector<T, 3> readErosion(Texture2D<vector<T, 4> > tex, SamplerState sampl, const Vec2 uv)
 {
 	vector<T, 3> minValue = tex.SampleLevel(sampl, uv, 0.0).rgb;
 

+ 7 - 5
CMakeLists.txt

@@ -171,15 +171,17 @@ else()
 	message(FATAL_ERROR "Couldn't determine the window backend. You need to specify it manually.")
 endif()
 
-set(ANKI_GR_BACKEND "VULKAN" CACHE STRING "The graphics API to use (VULKAN or GL)")
+set(ANKI_GR_BACKEND "VULKAN" CACHE STRING "The graphics API to use (VULKAN or DIRECTX)")
 
-if(${ANKI_GR_BACKEND} STREQUAL "GL")
-	set(GL TRUE)
+if(${ANKI_GR_BACKEND} STREQUAL "DIRECTX")
+	set(DIRECTX TRUE)
 	set(VULKAN FALSE)
 	set(VIDEO_VULKAN TRUE) # Set for the SDL2 to pick up
-else()
-	set(GL FALSE)
+elseif(${ANKI_GR_BACKEND} STREQUAL "VULKAN")
+	set(DIRECTX FALSE)
 	set(VULKAN TRUE)
+else()
+	message(FATAL_ERROR "Wrong ANKI_GR_BACKEND")
 endif()
 
 if(NOT DEFINED CMAKE_BUILD_TYPE)