Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor render pass & framebuffer #23

Merged
merged 8 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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