// immediate-renderer-base.h #pragma once // Provides shared implementation of public API objects for targets with // an immediate mode execution context. #include "renderer-shared.h" namespace gfx { enum class MapFlavor { Unknown, ///< Unknown mapping type HostRead, HostWrite, WriteDiscard, }; class ImmediateCommandQueueBase : public ICommandQueue , public Slang::ComObject { public: // Immediate device also holds a strong reference to an instance of `ImmediateCommandQueue`, // forming a cyclic reference. Therefore we need a free-op here to break the cycle when // the public reference count of the queue drops to 0. SLANG_COM_OBJECT_IUNKNOWN_ALL ICommandQueue* getInterface(const Slang::Guid& guid) { if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_ICommandQueue) return static_cast(this); return nullptr; } virtual void comFree() override { breakStrongReferenceToDevice(); } public: BreakableReference m_renderer; void breakStrongReferenceToDevice() { m_renderer.breakStrongReference(); } void establishStrongReferenceToDevice() { m_renderer.establishStrongReference(); } }; struct CommandBufferInfo { bool hasWriteTimestamps; }; class ImmediateRendererBase : public RendererBase { public: // Immediate commands to be implemented by each target. virtual Result createRootShaderObject( IShaderProgram* program, ShaderObjectBase** outObject) = 0; virtual void bindRootShaderObject(IShaderObject* rootObject) = 0; virtual void setPipelineState(IPipelineState* state) = 0; virtual void setFramebuffer(IFramebuffer* frameBuffer) = 0; virtual void clearFrame(uint32_t colorBufferMask, bool clearDepth, bool clearStencil) = 0; virtual void setViewports(UInt count, const Viewport* viewports) = 0; virtual void setScissorRects(UInt count, const ScissorRect* scissors) = 0; virtual void setPrimitiveTopology(PrimitiveTopology topology) = 0; virtual void setVertexBuffers( uint32_t startSlot, uint32_t slotCount, IBufferResource* const* buffers, const uint32_t* offsets) = 0; virtual void setIndexBuffer( IBufferResource* buffer, Format indexFormat, uint32_t offset = 0) = 0; virtual void draw(uint32_t vertexCount, uint32_t startVertex = 0) = 0; virtual void drawIndexed( uint32_t indexCount, uint32_t startIndex = 0, uint32_t baseVertex = 0) = 0; virtual void drawInstanced( uint32_t vertexCount, uint32_t instanceCount, uint32_t startVertex, uint32_t startInstanceLocation) = 0; virtual void drawIndexedInstanced( uint32_t indexCount, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) = 0; virtual void setStencilReference(uint32_t referenceValue) = 0; virtual void dispatchCompute(int x, int y, int z) = 0; virtual void copyBuffer( IBufferResource* dst, size_t dstOffset, IBufferResource* src, size_t srcOffset, size_t size) = 0; virtual void submitGpuWork() = 0; virtual void waitForGpu() = 0; virtual void* map(IBufferResource* buffer, MapFlavor flavor) = 0; virtual void unmap(IBufferResource* buffer, size_t offsetWritten, size_t sizeWritten) = 0; virtual void writeTimestamp(IQueryPool* pool, SlangInt index) = 0; virtual void beginCommandBuffer(const CommandBufferInfo&) {} virtual void endCommandBuffer(const CommandBufferInfo&) {} public: Slang::RefPtr m_queue; uint32_t m_queueCreateCount = 0; ImmediateRendererBase(); virtual SLANG_NO_THROW Result SLANG_MCALL createCommandQueue(const ICommandQueue::Desc& desc, ICommandQueue** outQueue) override; virtual SLANG_NO_THROW Result SLANG_MCALL createTransientResourceHeap( const ITransientResourceHeap::Desc& desc, ITransientResourceHeap** outHeap) override; virtual SLANG_NO_THROW Result SLANG_MCALL createRenderPassLayout( const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) override; void uploadBufferData( IBufferResource* dst, size_t offset, size_t size, void* data); virtual SLANG_NO_THROW SlangResult SLANG_MCALL readBufferResource( IBufferResource* buffer, size_t offset, size_t size, ISlangBlob** outBlob) override; }; class ImmediateComputeDeviceBase : public ImmediateRendererBase { public: // Provide empty implementation for devices without graphics support. virtual void setFramebuffer(IFramebuffer* frameBuffer) override { SLANG_UNUSED(frameBuffer); } virtual void clearFrame(uint32_t colorBufferMask, bool clearDepth, bool clearStencil) override { SLANG_UNUSED(colorBufferMask); SLANG_UNUSED(clearDepth); SLANG_UNUSED(clearStencil); } virtual void setViewports(UInt count, const Viewport* viewports) override { SLANG_UNUSED(count); SLANG_UNUSED(viewports); } virtual void setScissorRects(UInt count, const ScissorRect* scissors) override { SLANG_UNUSED(count); SLANG_UNUSED(scissors); } virtual void setPrimitiveTopology(PrimitiveTopology topology) override { SLANG_UNUSED(topology); } virtual void setVertexBuffers( uint32_t startSlot, uint32_t slotCount, IBufferResource* const* buffers, const uint32_t* offsets) override { SLANG_UNUSED(startSlot); SLANG_UNUSED(slotCount); SLANG_UNUSED(buffers); SLANG_UNUSED(offsets); } virtual void setIndexBuffer( IBufferResource* buffer, Format indexFormat, uint32_t offset = 0) override { SLANG_UNUSED(buffer); SLANG_UNUSED(indexFormat); SLANG_UNUSED(offset); } virtual void draw(uint32_t vertexCount, uint32_t startVertex = 0) override { SLANG_UNUSED(vertexCount); SLANG_UNUSED(startVertex); } virtual void drawIndexed( uint32_t indexCount, uint32_t startIndex = 0, uint32_t baseVertex = 0) override { SLANG_UNUSED(indexCount); SLANG_UNUSED(startIndex); SLANG_UNUSED(baseVertex); } virtual void drawInstanced( uint32_t vertexCount, uint32_t instanceCount, uint32_t startVertex, uint32_t startInstanceLocation) override { SLANG_UNUSED(vertexCount); SLANG_UNUSED(instanceCount); SLANG_UNUSED(startVertex); SLANG_UNUSED(startInstanceLocation); } virtual void drawIndexedInstanced( uint32_t indexCount, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) override { SLANG_UNUSED(indexCount); SLANG_UNUSED(instanceCount); SLANG_UNUSED(startIndexLocation); SLANG_UNUSED(baseVertexLocation); SLANG_UNUSED(startInstanceLocation); } virtual void setStencilReference(uint32_t referenceValue) override { SLANG_UNUSED(referenceValue); } virtual SLANG_NO_THROW Result SLANG_MCALL createSwapchain( const ISwapchain::Desc& desc, WindowHandle window, ISwapchain** outSwapchain) override { SLANG_UNUSED(desc); SLANG_UNUSED(window); SLANG_UNUSED(outSwapchain); return SLANG_FAIL; } virtual SLANG_NO_THROW Result SLANG_MCALL createFramebufferLayout( const IFramebufferLayout::Desc& desc, IFramebufferLayout** outLayout) override { SLANG_UNUSED(desc); SLANG_UNUSED(outLayout); return SLANG_FAIL; } virtual SLANG_NO_THROW Result SLANG_MCALL createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) override { SLANG_UNUSED(desc); SLANG_UNUSED(outFramebuffer); return SLANG_FAIL; } virtual SLANG_NO_THROW Result SLANG_MCALL createRenderPassLayout( const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) override { SLANG_UNUSED(desc); SLANG_UNUSED(outRenderPassLayout); return SLANG_FAIL; } virtual SLANG_NO_THROW Result SLANG_MCALL createInputLayout( IInputLayout::Desc const& desc, IInputLayout** outLayout) override { SLANG_UNUSED(desc); SLANG_UNUSED(outLayout); return SLANG_E_NOT_AVAILABLE; } virtual SLANG_NO_THROW Result SLANG_MCALL createGraphicsPipelineState( const GraphicsPipelineStateDesc& desc, IPipelineState** outState) override { SLANG_UNUSED(desc); SLANG_UNUSED(outState); return SLANG_E_NOT_AVAILABLE; } virtual SLANG_NO_THROW SlangResult SLANG_MCALL readTextureResource( ITextureResource* texture, ResourceState state, ISlangBlob** outBlob, size_t* outRowPitch, size_t* outPixelSize) override { SLANG_UNUSED(texture); SLANG_UNUSED(outBlob); SLANG_UNUSED(outRowPitch); SLANG_UNUSED(outPixelSize); return SLANG_E_NOT_AVAILABLE; } }; }