Skip to content

Commit

Permalink
Refactor render pass & framebuffer (#23)
Browse files Browse the repository at this point in the history
* wip

* remove framebuffer objects

* update metal backend

* cleanup

* refactor render pass descriptor

* fix metal

* refactor render pipeline desc

* metal fixes

---------

Co-authored-by: Simon Kallweit <skallweit@nvidia.com>
  • Loading branch information
westlicht and skallweitNV authored Sep 7, 2024
1 parent db1adf3 commit 895bec8
Show file tree
Hide file tree
Showing 84 changed files with 906 additions and 1,864 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
- implement dynamic rendering in Vulkan
- remove IFramebuffer and IFramebufferLayout
- rename IFramebufferLayout::Desc -> FramebufferLayoutDesc
- rename IInputLayout::Desc -> InputLayoutDesc
- introduce ICommandEncoder, which is the new base interface for all command encoders (encoders don't inherit the IResourceCommandEncoder anymore)
Expand Down
168 changes: 61 additions & 107 deletions include/slang-rhi.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ enum class AccessFlag
Write,
};

// TODO: Needed? Shouldn't be hard-coded if so
const GfxCount kMaxRenderTargetCount = 8;

class ITransientResourceHeap;
class IPersistentShaderCache;

Expand Down Expand Up @@ -1068,8 +1065,10 @@ struct DepthStencilOpDesc
ComparisonFunc stencilFunc = ComparisonFunc::Always;
};

struct DepthStencilDesc
struct DepthStencilState
{
Format format = Format::Unknown;

bool depthTestEnable = false;
bool depthWriteEnable = true;
ComparisonFunc depthFunc = ComparisonFunc::Less;
Expand Down Expand Up @@ -1155,49 +1154,35 @@ struct AspectBlendDesc
BlendOp op = BlendOp::Add;
};

struct TargetBlendDesc
struct ColorTargetState
{
Format format = Format::Unknown;
AspectBlendDesc color;
AspectBlendDesc alpha;
bool enableBlend = false;
LogicOp logicOp = LogicOp::NoOp;
RenderTargetWriteMaskT writeMask = RenderTargetWriteMask::EnableAll;
};

struct BlendDesc
{
TargetBlendDesc targets[kMaxRenderTargetCount];
bool alphaToCoverageEnable = false;
};

struct TargetLayoutDesc
struct MultisampleState
{
Format format = Format::Unknown;
GfxCount sampleCount = 1;
};

struct FramebufferLayoutDesc
{
GfxCount renderTargetCount;
TargetLayoutDesc renderTargets[kMaxRenderTargetCount];
TargetLayoutDesc depthStencil;
};

class IFramebufferLayout : public ISlangUnknown
{
SLANG_COM_INTERFACE(0xe5facc0a, 0x3d48, 0x4459, {0x8e, 0xa5, 0x7d, 0xbe, 0x81, 0xba, 0x91, 0xc2});
uint32_t sampleMask = 0xFFFFFFFF;
bool alphaToCoverageEnable = false;
bool alphaToOneEnable = false;
};

struct RenderPipelineDesc
{
IShaderProgram* program = nullptr;

IInputLayout* inputLayout = nullptr;
IFramebufferLayout* framebufferLayout = nullptr;
PrimitiveType primitiveType = PrimitiveType::Triangle;
DepthStencilDesc depthStencil;
ColorTargetState* targets = nullptr;
GfxCount targetCount = 0;
DepthStencilState depthStencil;
RasterizerDesc rasterizer;
BlendDesc blend;
MultisampleState multisample;
};

struct ComputePipelineDesc
Expand Down Expand Up @@ -1228,7 +1213,7 @@ struct RayTracingPipelineDesc
{
IShaderProgram* program = nullptr;
GfxCount hitGroupCount = 0;
const HitGroupDesc* hitGroups = nullptr;
HitGroupDesc* hitGroups = nullptr;
int maxRecursion = 0;
Size maxRayPayloadSize = 0;
Size maxAttributeSizeInBytes = 8;
Expand Down Expand Up @@ -1296,20 +1281,6 @@ struct Viewport
float maxZ = 1.0f;
};

class IFramebuffer : public ISlangUnknown
{
SLANG_COM_INTERFACE(0x19ed79f3, 0xcea8, 0x4a3d, {0xae, 0xf5, 0x03, 0xa7, 0xe4, 0xda, 0xc6, 0x11});

public:
struct Desc
{
GfxCount renderTargetCount;
IResourceView* const* renderTargetViews;
IResourceView* depthStencilView;
IFramebufferLayout* layout;
};
};

struct WindowHandle
{
enum class Type
Expand Down Expand Up @@ -1354,38 +1325,51 @@ struct FaceMask
};
};

class IRenderPassLayout : public ISlangUnknown
enum class LoadOp
{
SLANG_COM_INTERFACE(0x923d7ba6, 0xee84, 0x434f, {0x91, 0x85, 0x67, 0xda, 0x6f, 0x93, 0x9c, 0x58});
Load,
Clear,
DontCare
};

public:
enum class TargetLoadOp
{
Load,
Clear,
DontCare
};
enum class TargetStoreOp
{
Store,
DontCare
};
struct TargetAccessDesc
{
TargetLoadOp loadOp;
TargetLoadOp stencilLoadOp;
TargetStoreOp storeOp;
TargetStoreOp stencilStoreOp;
ResourceState initialState;
ResourceState finalState;
};
struct Desc
{
IFramebufferLayout* framebufferLayout = nullptr;
GfxCount renderTargetCount;
TargetAccessDesc* renderTargetAccess = nullptr;
TargetAccessDesc* depthStencilAccess = nullptr;
};
enum class StoreOp
{
Store,
DontCare
};

struct RenderPassColorAttachment
{
IResourceView* view = nullptr;
LoadOp loadOp = LoadOp::DontCare;
StoreOp storeOp = StoreOp::Store;
float clearValue[4] = {0.0f, 0.0f, 0.0f, 0.0f};
// TODO: remove with automatic resource tracking
ResourceState initialState = ResourceState::Undefined;
ResourceState finalState = ResourceState::Undefined;
};

struct RenderPassDepthStencilAttachment
{
IResourceView* view = nullptr;
LoadOp depthLoadOp = LoadOp::DontCare;
StoreOp depthStoreOp = StoreOp::Store;
float depthClearValue = 1.f;
bool depthReadOnly = false;
LoadOp stencilLoadOp = LoadOp::DontCare;
StoreOp stencilStoreOp = StoreOp::DontCare;
uint8_t stencilClearValue = 0;
bool stencilReadOnly = false;
// TODO: remove with automatic resource tracking
ResourceState initialState = ResourceState::Undefined;
ResourceState finalState = ResourceState::Undefined;
};

struct RenderPassDesc
{
RenderPassColorAttachment* colorAttachments = nullptr;
GfxCount colorAttachmentCount = 0;
RenderPassDepthStencilAttachment* depthStencilAttachment = nullptr;
};

enum class QueryType
Expand Down Expand Up @@ -1754,16 +1738,13 @@ class ICommandBuffer : public ISlangUnknown
return encoder;
}

virtual SLANG_NO_THROW Result SLANG_MCALL encodeRenderCommands(
IRenderPassLayout* renderPass,
IFramebuffer* framebuffer,
IRenderCommandEncoder** outEncoder
) = 0;
virtual SLANG_NO_THROW Result SLANG_MCALL
encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) = 0;

inline IRenderCommandEncoder* encodeRenderCommands(IRenderPassLayout* renderPass, IFramebuffer* framebuffer)
inline IRenderCommandEncoder* encodeRenderCommands(const RenderPassDesc& desc)
{
IRenderCommandEncoder* encoder;
SLANG_RETURN_NULL_ON_FAIL(encodeRenderCommands(renderPass, framebuffer, &encoder));
SLANG_RETURN_NULL_ON_FAIL(encodeRenderCommands(desc, &encoder));
return encoder;
}

Expand Down Expand Up @@ -2250,33 +2231,6 @@ class IDevice : public ISlangUnknown
return view;
}

virtual SLANG_NO_THROW Result SLANG_MCALL
createFramebufferLayout(FramebufferLayoutDesc const& desc, IFramebufferLayout** outFrameBuffer) = 0;
inline ComPtr<IFramebufferLayout> createFramebufferLayout(FramebufferLayoutDesc const& desc)
{
ComPtr<IFramebufferLayout> fb;
SLANG_RETURN_NULL_ON_FAIL(createFramebufferLayout(desc, fb.writeRef()));
return fb;
}

virtual SLANG_NO_THROW Result SLANG_MCALL
createFramebuffer(IFramebuffer::Desc const& desc, IFramebuffer** outFrameBuffer) = 0;
inline ComPtr<IFramebuffer> createFramebuffer(IFramebuffer::Desc const& desc)
{
ComPtr<IFramebuffer> fb;
SLANG_RETURN_NULL_ON_FAIL(createFramebuffer(desc, fb.writeRef()));
return fb;
}

virtual SLANG_NO_THROW Result SLANG_MCALL
createRenderPassLayout(const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) = 0;
inline ComPtr<IRenderPassLayout> createRenderPassLayout(const IRenderPassLayout::Desc& desc)
{
ComPtr<IRenderPassLayout> rs;
SLANG_RETURN_NULL_ON_FAIL(createRenderPassLayout(desc, rs.writeRef()));
return rs;
}

virtual SLANG_NO_THROW Result SLANG_MCALL
createSwapchain(ISwapchain::Desc const& desc, WindowHandle window, ISwapchain** outSwapchain) = 0;
inline ComPtr<ISwapchain> createSwapchain(ISwapchain::Desc const& desc, WindowHandle window)
Expand Down
45 changes: 35 additions & 10 deletions src/command-writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ enum class CommandName
{
SetPipeline,
BindRootShaderObject,
SetFramebuffer,
ClearFrame,
BeginRenderPass,
EndRenderPass,
SetViewports,
SetScissorRects,
SetPrimitiveTopology,
Expand All @@ -39,6 +39,10 @@ struct Command
CommandName name;
uint32_t operands[kMaxCommandOperands];
Command() = default;
Command(CommandName inName)
: name(inName)
{
}
Command(CommandName inName, uint32_t op)
: name(inName)
{
Expand Down Expand Up @@ -162,18 +166,39 @@ class CommandWriter
));
}

void setFramebuffer(IFramebuffer* frameBuffer)
void beginRenderPass(const RenderPassDesc& desc)
{
auto framebufferOffset = encodeObject(static_cast<FramebufferBase*>(frameBuffer));
m_commands.push_back(Command(CommandName::SetFramebuffer, (uint32_t)framebufferOffset));
}

void clearFrame(uint32_t colorBufferMask, bool clearDepth, bool clearStencil)
{
m_commands.push_back(Command(CommandName::ClearFrame, colorBufferMask, clearDepth ? 1 : 0, clearStencil ? 1 : 0)
Offset colorAttachmentsOffset =
encodeData(desc.colorAttachments, sizeof(RenderPassColorAttachment) * desc.colorAttachmentCount);
Offset depthStencilAttachmentOffset = encodeData(
desc.depthStencilAttachment,
desc.depthStencilAttachment ? sizeof(RenderPassDepthStencilAttachment) : 0
);
Offset viewsOffset = 0;
for (uint32_t i = 0; i < desc.colorAttachmentCount; i++)
{
auto offset = encodeObject(static_cast<ResourceViewBase*>(desc.colorAttachments[i].view));
if (i == 0)
viewsOffset = offset;
}
if (desc.depthStencilAttachment)
{
auto offset = encodeObject(static_cast<ResourceViewBase*>(desc.depthStencilAttachment->view));
if (desc.colorAttachmentCount == 0)
viewsOffset = offset;
}
m_commands.push_back(Command(
CommandName::BeginRenderPass,
(uint32_t)desc.colorAttachmentCount,
(uint32_t)(desc.depthStencilAttachment ? 1 : 0),
(uint32_t)colorAttachmentsOffset,
(uint32_t)depthStencilAttachmentOffset,
(uint32_t)viewsOffset
));
}

void endRenderPass() { m_commands.push_back(Command(CommandName::EndRenderPass)); }

void setViewports(GfxCount count, const Viewport* viewports)
{
auto offset = encodeData(viewports, sizeof(Viewport) * count);
Expand Down
1 change: 1 addition & 0 deletions src/core/platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Result loadSharedLibrary(const char* path, SharedLibraryHandle& handleOut)
{
return SLANG_FAIL;
}
return SLANG_OK;
#else
SLANG_RHI_ASSERT_FAILURE("Not implemented");
#endif
Expand Down
Loading

0 comments on commit 895bec8

Please sign in to comment.