summaryrefslogtreecommitdiffstats
path: root/tools/gfx/cpu
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2021-04-05 13:31:05 -0700
committerGitHub <noreply@github.com>2021-04-05 13:31:05 -0700
commit086ecf41fa21138899960bb9805bc8ced91690f0 (patch)
treec98af81ffc28371a9334e71987a85f9e88bce678 /tools/gfx/cpu
parentdd662f5cda97e7a6720ef526509a772a06112d4a (diff)
Transient root shader object. (#1782)
Diffstat (limited to 'tools/gfx/cpu')
-rw-r--r--tools/gfx/cpu/render-cpu.cpp438
1 files changed, 57 insertions, 381 deletions
diff --git a/tools/gfx/cpu/render-cpu.cpp b/tools/gfx/cpu/render-cpu.cpp
index f0b612e2f..8dbe5460a 100644
--- a/tools/gfx/cpu/render-cpu.cpp
+++ b/tools/gfx/cpu/render-cpu.cpp
@@ -7,9 +7,7 @@
#include "core/slang-basic.h"
#include "core/slang-blob.h"
-#include "../command-writer.h"
-#include "../renderer-shared.h"
-#include "../simple-transient-resource-heap.h"
+#include "../immediate-renderer-base.h"
#include "../slang-context.h"
#define SLANG_PRELUDE_NAMESPACE slang_prelude
@@ -1014,7 +1012,6 @@ public:
// type, we need to make sure to use that type as the specialization argument.
// TODO: need to implement the case where the field is an array of existential values.
- SLANG_ASSERT(bindingRange.count == 1);
ExtendedShaderObjectType specializedSubObjType;
SLANG_RETURN_ON_FAIL(m_objects[subObjIndex]->getSpecializedShaderObjectType(&specializedSubObjType));
args.add(specializedSubObjType);
@@ -1097,308 +1094,72 @@ public:
}
};
-class CPUDevice : public RendererBase
+class CPUDevice : public ImmediateComputeDeviceBase
{
private:
RefPtr<CPUPipelineState> m_currentPipeline = nullptr;
RefPtr<CPURootShaderObject> m_currentRootObject = nullptr;
DeviceInfo m_info;
- class CommandQueueImpl;
-
- class CommandBufferImpl
- : public ICommandBuffer
- , public CommandWriter
- , public RefObject
+ virtual void setPipelineState(IPipelineState* state) override
{
- public:
- SLANG_REF_OBJECT_IUNKNOWN_ALL
- ICommandBuffer* getInterface(const Guid& guid)
- {
- if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_ICommandBuffer)
- return static_cast<ICommandBuffer*>(this);
- return nullptr;
- }
- public:
- void init(CPUDevice* device)
- {
- SLANG_UNUSED(device);
- }
- virtual SLANG_NO_THROW void SLANG_MCALL encodeRenderCommands(
- IRenderPassLayout* renderPass,
- IFramebuffer* framebuffer,
- IRenderCommandEncoder** outEncoder) override
- {
- SLANG_UNUSED(renderPass);
- SLANG_UNUSED(framebuffer);
- *outEncoder = nullptr;
- }
-
- class ComputeCommandEncoderImpl
- : public IComputeCommandEncoder
- {
- public:
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL
- queryInterface(SlangUUID const& uuid, void** outObject) override
- {
- if (uuid == GfxGUID::IID_ISlangUnknown ||
- uuid == GfxGUID::IID_IComputeCommandEncoder)
- {
- *outObject = static_cast<IComputeCommandEncoder*>(this);
- return SLANG_OK;
- }
- *outObject = nullptr;
- return SLANG_E_NO_INTERFACE;
- }
- virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; }
- virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; }
-
- public:
- CommandWriter* m_writer;
-
- virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override {}
- void init(CommandBufferImpl* cmdBuffer)
- {
- m_writer = cmdBuffer;
- }
-
- virtual SLANG_NO_THROW void SLANG_MCALL setPipelineState(IPipelineState* state) override
- {
- m_writer->setPipelineState(state);
- }
- virtual SLANG_NO_THROW void SLANG_MCALL
- bindRootShaderObject(IShaderObject* object) override
- {
- m_writer->bindRootShaderObject(PipelineType::Compute, object);
- }
-
- virtual SLANG_NO_THROW void SLANG_MCALL dispatchCompute(int x, int y, int z) override
- {
- m_writer->dispatchCompute(x, y, z);
- }
- };
-
- ComputeCommandEncoderImpl m_computeCommandEncoder;
- virtual SLANG_NO_THROW void SLANG_MCALL
- encodeComputeCommands(IComputeCommandEncoder** outEncoder) override
- {
- m_computeCommandEncoder.init(this);
- *outEncoder = &m_computeCommandEncoder;
- }
-
- class ResourceCommandEncoderImpl
- : public IResourceCommandEncoder
- {
- public:
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL
- queryInterface(SlangUUID const& uuid, void** outObject) override
- {
- if (uuid == GfxGUID::IID_ISlangUnknown ||
- uuid == GfxGUID::IID_IResourceCommandEncoder)
- {
- *outObject = static_cast<IResourceCommandEncoder*>(this);
- return SLANG_OK;
- }
- *outObject = nullptr;
- return SLANG_E_NO_INTERFACE;
- }
- virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; }
- virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; }
-
- public:
- CommandWriter* m_writer;
-
- void init(CommandBufferImpl* cmdBuffer)
- {
- m_writer = cmdBuffer;
- }
-
- virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override {}
- virtual SLANG_NO_THROW void SLANG_MCALL copyBuffer(
- IBufferResource* dst,
- size_t dstOffset,
- IBufferResource* src,
- size_t srcOffset,
- size_t size) override
- {
- m_writer->copyBuffer(dst, dstOffset, src, srcOffset, size);
- }
-
- virtual SLANG_NO_THROW void SLANG_MCALL
- uploadBufferData(IBufferResource* dst, size_t offset, size_t size, void* data) override
- {
- m_writer->uploadBufferData(dst, offset, size, data);
- }
- };
-
- ResourceCommandEncoderImpl m_resourceCommandEncoder;
-
- virtual SLANG_NO_THROW void SLANG_MCALL
- encodeResourceCommands(IResourceCommandEncoder** outEncoder) override
- {
- m_resourceCommandEncoder.init(this);
- *outEncoder = &m_resourceCommandEncoder;
- }
-
- virtual SLANG_NO_THROW void SLANG_MCALL close() override {}
- };
+ m_currentPipeline = static_cast<CPUPipelineState*>(state);
+ }
- class CommandQueueImpl
- : public ICommandQueue
- , public RefObject
+ virtual void bindRootShaderObject(IShaderObject* object) override
{
- public:
- SLANG_REF_OBJECT_IUNKNOWN_ALL
- ICommandQueue* getInterface(const Guid& guid)
- {
- if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_ICommandQueue)
- return static_cast<ICommandQueue*>(this);
- return nullptr;
- }
-
- public:
- RefPtr<CPUPipelineState> currentPipeline;
- RefPtr<CPURootShaderObject> currentRootObject;
- RefPtr<CPUDevice> renderer;
- Desc m_desc;
- public:
- void init(CPUDevice* inRenderer)
- {
- renderer = inRenderer;
- m_desc.type = ICommandQueue::QueueType::Graphics;
- }
- ~CommandQueueImpl()
- {
- currentPipeline = nullptr;
- currentRootObject = nullptr;
- }
-
- public:
- virtual SLANG_NO_THROW const Desc& SLANG_MCALL getDesc() override
- {
- return m_desc;
- }
-
- virtual SLANG_NO_THROW void SLANG_MCALL
- executeCommandBuffers(uint32_t count, ICommandBuffer* const* commandBuffers) override
- {
- for (uint32_t i = 0; i < count; i++)
- {
- execute(static_cast<CommandBufferImpl*>(commandBuffers[i]));
- }
- }
-
- virtual SLANG_NO_THROW void SLANG_MCALL wait() override
- {}
-
- public:
- void setPipelineState(IPipelineState* state)
- {
- currentPipeline = static_cast<CPUPipelineState*>(state);
- }
-
- Result bindRootShaderObject(PipelineType pipelineType, IShaderObject* object)
- {
- currentRootObject = static_cast<CPURootShaderObject*>(object);
- if (currentRootObject)
- return SLANG_OK;
- return SLANG_E_INVALID_ARG;
- }
-
- void dispatchCompute(int x, int y, int z)
- {
- int entryPointIndex = 0;
- int targetIndex = 0;
-
- // Specialize the compute kernel based on the shader object bindings.
- RefPtr<PipelineStateBase> newPipeline;
- renderer->maybeSpecializePipeline(currentPipeline, currentRootObject, newPipeline);
- currentPipeline = static_cast<CPUPipelineState*>(newPipeline.Ptr());
-
- auto program = currentPipeline->getProgram();
- auto entryPointLayout = currentRootObject->getLayout()->getEntryPoint(entryPointIndex);
- auto entryPointName = entryPointLayout->getEntryPointName();
+ m_currentRootObject = static_cast<CPURootShaderObject*>(object);
+ }
- auto entryPointObject = currentRootObject->getEntryPoint(entryPointIndex);
+ virtual void dispatchCompute(int x, int y, int z) override
+ {
+ int entryPointIndex = 0;
+ int targetIndex = 0;
- ComPtr<ISlangSharedLibrary> sharedLibrary;
- program->slangProgram->getEntryPointHostCallable(entryPointIndex, targetIndex, sharedLibrary.writeRef());
+ // Specialize the compute kernel based on the shader object bindings.
+ RefPtr<PipelineStateBase> newPipeline;
+ maybeSpecializePipeline(m_currentPipeline, m_currentRootObject, newPipeline);
+ m_currentPipeline = static_cast<CPUPipelineState*>(newPipeline.Ptr());
- auto func = (slang_prelude::ComputeFunc) sharedLibrary->findSymbolAddressByName(entryPointName);
+ auto program = m_currentPipeline->getProgram();
+ auto entryPointLayout =
+ m_currentRootObject->getLayout()->getEntryPoint(entryPointIndex);
+ auto entryPointName = entryPointLayout->getEntryPointName();
- slang_prelude::ComputeVaryingInput varyingInput;
- varyingInput.startGroupID.x = 0;
- varyingInput.startGroupID.y = 0;
- varyingInput.startGroupID.z = 0;
- varyingInput.endGroupID.x = x;
- varyingInput.endGroupID.y = y;
- varyingInput.endGroupID.z = z;
+ auto entryPointObject = m_currentRootObject->getEntryPoint(entryPointIndex);
- auto globalParamsData = currentRootObject->m_data;
- auto entryPointParamsData = entryPointObject->m_data;
- func(&varyingInput, entryPointParamsData, globalParamsData);
- }
+ ComPtr<ISlangSharedLibrary> sharedLibrary;
+ program->slangProgram->getEntryPointHostCallable(entryPointIndex, targetIndex, sharedLibrary.writeRef());
- void copyBuffer(
- IBufferResource* dst,
- size_t dstOffset,
- IBufferResource* src,
- size_t srcOffset,
- size_t size)
- {
- auto dstImpl = static_cast<CPUBufferResource*>(dst);
- auto srcImpl = static_cast<CPUBufferResource*>(src);
- memcpy(
- (uint8_t*)dstImpl->m_data + dstOffset,
- (uint8_t*)srcImpl->m_data + srcOffset,
- size);
- }
+ auto func = (slang_prelude::ComputeFunc) sharedLibrary->findSymbolAddressByName(entryPointName);
- void uploadBufferData(IBufferResource* dst, size_t offset, size_t size, void* data)
- {
- auto dstImpl = static_cast<CPUBufferResource*>(dst);
- memcpy((uint8_t*)dstImpl->m_data + offset, data, size);
- }
+ slang_prelude::ComputeVaryingInput varyingInput;
+ varyingInput.startGroupID.x = 0;
+ varyingInput.startGroupID.y = 0;
+ varyingInput.startGroupID.z = 0;
+ varyingInput.endGroupID.x = x;
+ varyingInput.endGroupID.y = y;
+ varyingInput.endGroupID.z = z;
- void execute(CommandBufferImpl* commandBuffer)
- {
- for (auto& cmd : commandBuffer->m_commands)
- {
- switch (cmd.name)
- {
- case CommandName::SetPipelineState:
- setPipelineState(commandBuffer->getObject<IPipelineState>(cmd.operands[0]));
- break;
- case CommandName::BindRootShaderObject:
- bindRootShaderObject(
- (PipelineType)cmd.operands[0],
- commandBuffer->getObject<IShaderObject>(cmd.operands[1]));
- break;
- case CommandName::DispatchCompute:
- dispatchCompute(
- int(cmd.operands[0]), int(cmd.operands[1]), int(cmd.operands[2]));
- break;
- case CommandName::CopyBuffer:
- copyBuffer(
- commandBuffer->getObject<IBufferResource>(cmd.operands[0]),
- cmd.operands[1],
- commandBuffer->getObject<IBufferResource>(cmd.operands[2]),
- cmd.operands[3],
- cmd.operands[4]);
- break;
- case CommandName::UploadBufferData:
- uploadBufferData(
- commandBuffer->getObject<IBufferResource>(cmd.operands[0]),
- cmd.operands[1],
- cmd.operands[2],
- commandBuffer->getData<uint8_t>(cmd.operands[3]));
- break;
- }
- }
- }
- };
+ auto globalParamsData = m_currentRootObject->m_data;
+ auto entryPointParamsData = entryPointObject->m_data;
+ func(&varyingInput, entryPointParamsData, globalParamsData);
+ }
- using TransientResourceHeapImpl = SimpleTransientResourceHeap<CPUDevice, CommandBufferImpl>;
+ virtual void copyBuffer(
+ IBufferResource* dst,
+ size_t dstOffset,
+ IBufferResource* src,
+ size_t srcOffset,
+ size_t size) override
+ {
+ auto dstImpl = static_cast<CPUBufferResource*>(dst);
+ auto srcImpl = static_cast<CPUBufferResource*>(src);
+ memcpy(
+ (uint8_t*)dstImpl->m_data + dstOffset,
+ (uint8_t*)srcImpl->m_data + srcOffset,
+ size);
+ }
public:
~CPUDevice()
@@ -1498,8 +1259,7 @@ public:
return SLANG_OK;
}
- virtual SLANG_NO_THROW Result SLANG_MCALL
- createRootShaderObject(IShaderProgram* program, IShaderObject** outObject) override
+ virtual Result createRootShaderObject(IShaderProgram* program, IShaderObject** outObject) override
{
auto cpuProgram = static_cast<CPUShaderProgram*>(program);
auto cpuProgramLayout = cpuProgram->layout;
@@ -1551,53 +1311,7 @@ public:
}
public:
- virtual SLANG_NO_THROW Result SLANG_MCALL
- createCommandQueue(const ICommandQueue::Desc& desc, ICommandQueue** outQueue) override
- {
- RefPtr<CommandQueueImpl> queue = new CommandQueueImpl();
- queue->init(this);
- *outQueue = queue.detach();
- return SLANG_OK;
- }
- virtual SLANG_NO_THROW Result SLANG_MCALL createTransientResourceHeap(
- const ITransientResourceHeap::Desc& desc,
- ITransientResourceHeap** outHeap) override
- {
- RefPtr<TransientResourceHeapImpl> result = new TransientResourceHeapImpl();
- SLANG_RETURN_ON_FAIL(result->init(this, desc));
- *outHeap = result.detach();
- return SLANG_OK;
- }
- 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
createSamplerState(ISamplerState::Desc const& desc, ISamplerState** outSampler) override
{
@@ -1605,54 +1319,16 @@ public:
*outSampler = nullptr;
return SLANG_OK;
}
-
- virtual SLANG_NO_THROW Result SLANG_MCALL createInputLayout(
- const InputElementDesc* inputElements,
- UInt inputElementCount,
- IInputLayout** outLayout) override
- {
- SLANG_UNUSED(inputElements);
- SLANG_UNUSED(inputElementCount);
- 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;
- }
- virtual SLANG_NO_THROW Result SLANG_MCALL readBufferResource(
- IBufferResource* buffer,
- size_t offset,
- size_t size,
- ISlangBlob** outBlob) override
+ virtual void submitGpuWork() override {}
+ virtual void waitForGpu() override {}
+ virtual void* map(IBufferResource* buffer, MapFlavor flavor) override
{
+ SLANG_UNUSED(flavor);
auto bufferImpl = static_cast<CPUBufferResource*>(buffer);
- RefPtr<ListBlob> blob = new ListBlob();
- blob->m_data.setCount((Index)size);
- memcpy(
- blob->m_data.getBuffer(),
- (uint8_t*)bufferImpl->m_data + offset,
- size);
- *outBlob = blob.detach();
- return SLANG_OK;
+ return bufferImpl->m_data;
}
+ virtual void unmap(IBufferResource* buffer) override { SLANG_UNUSED(buffer); }
};
SlangResult CPUShaderObject::init(IDevice* device, CPUShaderObjectLayout* typeLayout)