Rendering

Fwog forgoes framebuffers in favor of specifying a list of render targets at draw time, taking inspiration from VK_KHR_dynamic_rendering.

Color attachments are bound in the order in which they’re provided, which means your fragment shader outputs should use sequential explicit locations starting at zero.

Fwog::RenderColorAttachments colorAttachments[] = {aAlbedo, aNormal, aMaterial};

and the corresponding fragment shader outputs:

layout(location = 0) out vec3 o_albedo;
layout(location = 1) out vec3 o_normal;
layout(location = 2) out vec3 o_material;

To bind the render targets and begin a rendering pass, call Fwog::Render().

Fwog::Render({
    .colorAttachments = colorAttachments,
    .depthAttachment = &depthAttachment,
}
[&] {
    // Bind pipelines, resources, and make draw calls here
});

Then, you can bind pipelines and resources and issue draw calls inside of the callable that is passed.

If you wish to render to the screen, call Fwog::RenderToSwapchain().

Compute

Compute piplines are similar to graphics pipelines, except they only encapsulate a compute shader. To issue dispatches, call Fwog::BeginCompute() to begin a compute scope.

Color Spaces

Fwog enables GL_FRAMEBUFFER_SRGB by default. Fwog::TextureView can be used to view an image in a different color space if desired. This follows the same rules as glTextureView.

Synchronization

Like in plain OpenGL, most operations are automatically synchronized with respect to each other. However, there are certain instances where the driver may not automatically resolve a hazard. These can be dealt with by calling Fwog::MemoryBarrier() and Fwog::TextureBarrier(). Consult the OpenGL specification for more information.

#include “Fwog/Rendering.h”

namespace Fwog

Enums

enum AttachmentLoadOp

Tells Fwog what to do with a render target at the beginning of a pass.

Values:

enumerator LOAD

The previous contents of the image will be preserved.

enumerator CLEAR

The contents of the image will be cleared to a uniform value.

enumerator DONT_CARE

The previous contents of the image need not be preserved (they may be discarded)

Functions

template<std::invocable Func>
void RenderToSwapchain(const SwapchainRenderInfo &renderInfo, Func func)

Renders to the swapchain.

The swapchain can be thought of as “the window”. This function is provided because OpenGL nor windowing libraries provide a simple mechanism to access the swapchain as a set of images without interop with an explicit API like Vulkan or D3D12.

Parameters:
  • renderInfo – Rendering parameters

  • func – A callback that invokes rendering commands

template<std::invocable Func>
void Render(const RenderInfo &renderInfo, Func func)

Renders to a set of textures.

Parameters:
  • renderInfo – Rendering parameters

  • func – A callback that invokes rendering commands

template<std::invocable Func>
void Compute(std::string_view name, Func func)

Begins a compute scope.

Parameters:

func – A callback that invokes dispatch commands

void BlitTexture(const Texture &source, const Texture &target, Offset3D sourceOffset, Offset3D targetOffset, Extent3D sourceExtent, Extent3D targetExtent, Filter filter, AspectMask aspect = AspectMaskBit::COLOR_BUFFER_BIT)

Blits a texture to another texture. Supports minification and magnification.

void BlitTextureToSwapchain(const Texture &source, Offset3D sourceOffset, Offset3D targetOffset, Extent3D sourceExtent, Extent3D targetExtent, Filter filter, AspectMask aspect = AspectMaskBit::COLOR_BUFFER_BIT)

Blits a texture to the swapchain. Supports minification and magnification.

void CopyTexture(const CopyTextureInfo &copy)

Copies data between textures.

No format conversion is applied, as in memcpy.

void MemoryBarrier(MemoryBarrierBits accessBits)

Defines a barrier ordering memory transactions.

This call is used to ensure that incoherent writes (SSBO writes and image stores) from a shader are reflected in subsequent accesses.

Parameters:

accessBits – The barriers to insert

void TextureBarrier()

Allows subsequent draw commands to read the result of texels written in a previous draw operation.

See the ARB_texture_barrier spec for potential uses.

void CopyBuffer(const CopyBufferInfo &copy)

Copies data between buffers.

void CopyTextureToBuffer(const CopyTextureToBufferInfo &copy)

Copies texture data into a buffer.

void CopyBufferToTexture(const CopyBufferToTextureInfo &copy)

Copies buffer data into a texture.

struct ClearColorValue
#include <Rendering.h>

Describes a clear color value.

The clear color value can be up to four of float, uint32_t, or int32_t. Use of a type that does not match the render target format may result in undefined behavior.

Public Functions

ClearColorValue() = default
template<typename... Args> inline  requires (sizeof...(Args)<=4) ClearColorValue(const Args &... args)

Public Members

std::variant<std::array<float, 4>, std::array<uint32_t, 4>, std::array<int32_t, 4>> data
struct ClearDepthStencilValue

Public Members

float depth = {}
int32_t stencil = {}
struct CopyBufferInfo
#include <Rendering.h>

Parameters for CopyBuffer()

Public Members

const Buffer &source
Buffer &target
uint64_t sourceOffset = 0
uint64_t targetOffset = 0
uint64_t size = WHOLE_BUFFER

The amount of data to copy, in bytes. If size is WHOLE_BUFFER, the size of the source buffer is used.

struct CopyBufferToTextureInfo

Public Members

const Buffer &sourceBuffer
Texture &targetTexture
uint32_t level = 0
uint64_t sourceOffset = {}
Offset3D targetOffset = {}
Extent3D extent = {}
UploadFormat format = UploadFormat::INFER_FORMAT

The arrangement of components of texels in the source buffer. DEPTH_STENCIL is not allowed here.

UploadType type = UploadType::INFER_TYPE

The data type of the texel data.

uint32_t bufferRowLength = 0

Specifies, in texels, the size of rows in the buffer (for 2D and 3D images). If zero, it is assumed to be tightly packed according to extent.

uint32_t bufferImageHeight = 0

Specifies, in texels, the number of rows in the buffer (for 3D images. If zero, it is assumed to be tightly packed according to extent.

struct CopyTextureInfo

Public Members

const Texture &source
Texture &target
uint32_t sourceLevel = 0
uint32_t targetLevel = 0
Offset3D sourceOffset = {}
Offset3D targetOffset = {}
Extent3D extent = {}
struct CopyTextureToBufferInfo
#include <Rendering.h>

Parameters for CopyTextureToBuffer.

Public Members

const Texture &sourceTexture
Buffer &targetBuffer
uint32_t level = 0
Offset3D sourceOffset = {}
uint64_t targetOffset = {}
Extent3D extent = {}
UploadFormat format = UploadFormat::INFER_FORMAT
UploadType type = UploadType::INFER_TYPE
uint32_t bufferRowLength = 0

Specifies, in texels, the size of rows in the buffer (for 2D and 3D images). If zero, it is assumed to be tightly packed according to extent.

uint32_t bufferImageHeight = 0

Specifies, in texels, the number of rows in the buffer (for 3D images. If zero, it is assumed to be tightly packed according to extent.

template<class T>
class ReferenceWrapper

Public Types

using type = T

Public Functions

template<class U>
inline constexpr ReferenceWrapper(U &&val) noexcept
inline constexpr operator T&() const noexcept
inline constexpr T &get() const noexcept

Private Members

T *ptr = {}
struct RenderColorAttachment

Public Members

ReferenceWrapper<const Texture> texture
AttachmentLoadOp loadOp = AttachmentLoadOp::LOAD
ClearColorValue clearValue
struct RenderDepthStencilAttachment
struct RenderInfo

Public Members

std::string_view name

An optional name to demarcate the pass in a graphics debugger.

std::optional<Viewport> viewport = std::nullopt

A pointer to a viewport.

If empty, the viewport size will be the minimum the render targets’ size and the offset will be 0.

std::span<const RenderColorAttachment> colorAttachments
std::optional<RenderDepthStencilAttachment> depthAttachment = std::nullopt
std::optional<RenderDepthStencilAttachment> stencilAttachment = std::nullopt
struct SwapchainRenderInfo

Public Members

std::string_view name

An optional name to demarcate the pass in a graphics debugger.

Viewport viewport = {}
AttachmentLoadOp colorLoadOp = AttachmentLoadOp::LOAD
ClearColorValue clearColorValue
AttachmentLoadOp depthLoadOp = AttachmentLoadOp::LOAD
float clearDepthValue = 0.0f
AttachmentLoadOp stencilLoadOp = AttachmentLoadOp::LOAD
int32_t clearStencilValue = 0
bool enableSrgb = true

If true, the linear->nonlinear sRGB OETF will be applied to pixels when rendering to the swapchain.

This facility is provided because OpenGL does not expose the swapchain as an image we can interact with in the usual manner.

struct Viewport

Public Functions

bool operator==(const Viewport&) const noexcept = default

Public Members

Rect2D drawRect = {}
float minDepth = 0.0f
float maxDepth = 1.0f
ClipDepthRange depthRange = Fwog::ClipDepthRange::ZERO_TO_ONE
namespace Cmd

Functions that set pipeline state, binds resources, or issues draws or dispatches.

These functions are analogous to Vulkan vkCmd* calls, which can only be made inside of an active command buffer.

Note

Calling functions in this namespace outside of a rendering or compute scope will result in undefined behavior

Functions

void BindGraphicsPipeline(const GraphicsPipeline &pipeline)

Binds a graphics pipeline to be used for future draw operations.

Valid in rendering scopes.

Parameters:

pipeline – The pipeline to bind

void BindComputePipeline(const ComputePipeline &pipeline)

Binds a compute pipeline to be used for future dispatch operations.

Valid in compute scopes.

Parameters:

pipeline – The pipeline to bind

void SetViewport(const Viewport &viewport)

Dynamically sets the viewport.

Similar to glViewport. Valid in rendering scopes.

Parameters:

viewport – The new viewport

void SetScissor(const Rect2D &scissor)

Dynamically sets the scissor rect.

Similar to glScissor. Valid in rendering scopes.

Parameters:

scissor – The new scissor rect

void Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)

Equivalent to glDrawArraysInstancedBaseInstance or vkCmdDraw.

Valid in rendering scopes.

Parameters:
  • vertexCount – The number of vertices to draw

  • instanceCount – The number of instances to draw

  • firstVertex – The index of the first vertex to draw

  • firstInstance – The instance ID of the first instance to draw

void DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)

Equivalent to glDrawElementsInstancedBaseVertexBaseInstance or vkCmdDrawIndexed.

Valid in rendering scopes.

Parameters:
  • indexCount – The number of vertices to draw

  • instanceCount – The number of instances to draw

  • firstIndex – The base index within the index buffer

  • vertexOffset – The value added to the vertex index before indexing into the vertex buffer

  • firstInstance – The instance ID of the first instance to draw

void DrawIndirect(const Buffer &commandBuffer, uint64_t commandBufferOffset, uint32_t drawCount, uint32_t stride)

Equivalent to glMultiDrawArraysIndirect or vkCmdDrawDrawIndirect.

Valid in rendering scopes.

Parameters:
  • commandBuffer – The buffer containing draw parameters

  • commandBufferOffset – The byte offset into commandBuffer where parameters begin

  • drawCount – The number of draws to execute

  • stride – The byte stride between successive sets of draw parameters

void DrawIndirectCount(const Buffer &commandBuffer, uint64_t commandBufferOffset, const Buffer &countBuffer, uint64_t countBufferOffset, uint32_t maxDrawCount, uint32_t stride)

Equivalent to glMultiDrawArraysIndirectCount or vkCmdDrawIndirectCount.

Valid in rendering scopes.

Parameters:
  • commandBuffer – The buffer containing draw parameters

  • commandBufferOffset – The byte offset into commandBuffer where parameters begin

  • countBuffer – The buffer containing the draw count

  • countBufferOffset – The byte offset into countBuffer where the draw count begins

  • maxDrawCount – The maximum number of draws that will be executed

  • stride – The byte stride between successive sets of draw parameters

void DrawIndexedIndirect(const Buffer &commandBuffer, uint64_t commandBufferOffset, uint32_t drawCount, uint32_t stride)

Equivalent to glMultiDrawElementsIndirect or vkCmdDrawIndexedIndirect.

Valid in rendering scopes.

Parameters:
  • commandBuffer – The buffer containing draw parameters

  • commandBufferOffset – The byte offset into commandBuffer where parameters begin

  • drawCount – The number of draws to execute

  • stride – The byte stride between successive sets of draw parameters

void DrawIndexedIndirectCount(const Buffer &commandBuffer, uint64_t commandBufferOffset, const Buffer &countBuffer, uint64_t countBufferOffset, uint32_t maxDrawCount, uint32_t stride)

Equivalent to glMultiDrawElementsIndirectCount or vkCmdDrawIndexedIndirectCount.

Valid in rendering scopes.

Parameters:
  • commandBuffer – The buffer containing draw parameters

  • commandBufferOffset – The byte offset into commandBuffer where parameters begin

  • countBuffer – The buffer containing the draw count

  • countBufferOffset – The byte offset into countBuffer where the draw count begins

  • maxDrawCount – The maximum number of draws that will be executed

  • stride – The byte stride between successive sets of draw parameters

void BindVertexBuffer(uint32_t bindingIndex, const Buffer &buffer, uint64_t offset, uint64_t stride)

Binds a buffer to a vertex buffer binding point.

Similar to glVertexArrayVertexBuffer. Valid in rendering scopes.

void BindIndexBuffer(const Buffer &buffer, IndexType indexType)

Binds an index buffer.

Similar to glVertexArrayElementBuffer. Valid in rendering scopes.

void BindUniformBuffer(uint32_t index, const Buffer &buffer, uint64_t offset = 0, uint64_t size = WHOLE_BUFFER)

Binds a range within a buffer as a uniform buffer.

Similar to glBindBufferRange(GL_UNIFORM_BUFFER, …)

void BindStorageBuffer(uint32_t index, const Buffer &buffer, uint64_t offset = 0, uint64_t size = WHOLE_BUFFER)

Binds a range within a buffer as a storage buffer.

Similar to glBindBufferRange(GL_SHADER_STORAGE_BUFFER, …)

void BindSampledImage(uint32_t index, const Texture &texture, const Sampler &sampler)

Binds a texture and a sampler to a texture unit.

Similar to glBindTextureUnit + glBindSampler

void BindImage(uint32_t index, const Texture &texture, uint32_t level)

Binds a texture to an image unit.

Similar to glBindImageTexture{s}

void Dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)

Invokes a compute shader.

Valid in compute scopes.

Parameters:
  • groupCountX – The number of local workgroups to dispatch in the X dimension

  • groupCountY – The number of local workgroups to dispatch in the Y dimension

  • groupCountZ – The number of local workgroups to dispatch in the Z dimension

void Dispatch(Extent3D groupCount)

Invokes a compute shader.

Valid in compute scopes.

Parameters:

groupCount – The number of local workgroups to dispatch

void DispatchInvocations(uint32_t invocationCountX, uint32_t invocationCountY, uint32_t invocationCountZ)

Invokes a compute shader a specified number of times.

Automatically computes the number of workgroups to invoke based on the formula groupCount = (invocationCount + workgroupSize - 1) / workgroupSize. Valid in compute scopes.

Parameters:
  • invocationCountX – The minimum number of invocations in the X dimension

  • invocationCountY – The minimum number of invocations in the Y dimension

  • invocationCountZ – The minimum number of invocations in the Z dimension

void DispatchInvocations(Extent3D invocationCount)

Invokes a compute shader a specified number of times.

Automatically computes the number of workgroups to invoke based on the formula groupCount = (invocationCount + workgroupSize - 1) / workgroupSize. Valid in compute scopes.

Parameters:

invocationCount – The minimum number of invocations

void DispatchIndirect(const Buffer &commandBuffer, uint64_t commandBufferOffset)

Invokes a compute shader with the group count provided by a buffer.

Valid in compute scopes.

Parameters:
  • commandBuffer – The buffer containing dispatch parameters

  • commandBufferOffset – The byte offset into commandBuffer where the parameters begin

namespace detail

Functions

void BeginSwapchainRendering(const SwapchainRenderInfo &renderInfo)
void BeginRendering(const RenderInfo &renderInfo)
void EndRendering()
void BeginCompute(std::string_view name)
void EndCompute()