"""Shared render pass definitions."""
import logging
from typing import Any
import vulkan as vk
__all__ = [
"create_render_pass",
"create_offscreen_pass",
"create_overlay_pass",
"create_hdr_reload_pass",
"create_pick_pass",
]
log = logging.getLogger(__name__)
[docs]
def create_render_pass(
device: Any, colour_format: int, depth_format: int = 0,
) -> Any:
"""Create a render pass with colour and optional depth attachment."""
attachments = []
colour_attachment = vk.VkAttachmentDescription(
format=colour_format,
samples=vk.VK_SAMPLE_COUNT_1_BIT,
loadOp=vk.VK_ATTACHMENT_LOAD_OP_CLEAR,
storeOp=vk.VK_ATTACHMENT_STORE_OP_STORE,
stencilLoadOp=vk.VK_ATTACHMENT_LOAD_OP_DONT_CARE,
stencilStoreOp=vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
initialLayout=vk.VK_IMAGE_LAYOUT_UNDEFINED,
finalLayout=vk.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
)
attachments.append(colour_attachment)
colour_ref = vk.VkAttachmentReference(
attachment=0,
layout=vk.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
)
depth_ref = None
if depth_format:
depth_attachment = vk.VkAttachmentDescription(
format=depth_format,
samples=vk.VK_SAMPLE_COUNT_1_BIT,
loadOp=vk.VK_ATTACHMENT_LOAD_OP_CLEAR,
storeOp=vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
stencilLoadOp=vk.VK_ATTACHMENT_LOAD_OP_DONT_CARE,
stencilStoreOp=vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
initialLayout=vk.VK_IMAGE_LAYOUT_UNDEFINED,
finalLayout=vk.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
)
attachments.append(depth_attachment)
depth_ref = vk.VkAttachmentReference(
attachment=1,
layout=vk.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
)
subpass = vk.VkSubpassDescription(
pipelineBindPoint=vk.VK_PIPELINE_BIND_POINT_GRAPHICS,
colorAttachmentCount=1,
pColorAttachments=[colour_ref],
pDepthStencilAttachment=depth_ref,
)
src_stages = vk.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
dst_stages = vk.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
dst_access = vk.VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
if depth_format:
src_stages |= vk.VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
dst_stages |= vk.VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
dst_access |= vk.VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
dependency = vk.VkSubpassDependency(
srcSubpass=vk.VK_SUBPASS_EXTERNAL,
dstSubpass=0,
srcStageMask=src_stages,
srcAccessMask=0,
dstStageMask=dst_stages,
dstAccessMask=dst_access,
)
create_info = vk.VkRenderPassCreateInfo(
attachmentCount=len(attachments),
pAttachments=attachments,
subpassCount=1,
pSubpasses=[subpass],
dependencyCount=1,
pDependencies=[dependency],
)
render_pass = vk.vkCreateRenderPass(device, create_info, None)
log.debug("Render pass created (depth=%s)", bool(depth_format))
return render_pass
[docs]
def create_offscreen_pass(
device: Any, colour_format: int, depth_format: int = vk.VK_FORMAT_D32_SFLOAT,
*, samplable_depth: bool = False, gbuffer_format: int = 0,
) -> Any:
"""Create a render pass for offscreen rendering (colour -> SHADER_READ_ONLY).
When *samplable_depth* is True, the depth attachment transitions to
SHADER_READ_ONLY_OPTIMAL so it can be sampled in a later pass (e.g. motion blur).
When *gbuffer_format* is non-zero, a second colour attachment (the thin
G-buffer) is added between the scene colour and depth. It clears
and stores like the scene colour and ends in SHADER_READ_ONLY so a later
compute/fragment pass can sample it. Attachment indices become
colour=0, gbuffer=1, depth=2; with no G-buffer they stay colour=0, depth=1
(byte-identical to the historical pass).
"""
attachments = [
vk.VkAttachmentDescription(
format=colour_format,
samples=vk.VK_SAMPLE_COUNT_1_BIT,
loadOp=vk.VK_ATTACHMENT_LOAD_OP_CLEAR,
storeOp=vk.VK_ATTACHMENT_STORE_OP_STORE,
stencilLoadOp=vk.VK_ATTACHMENT_LOAD_OP_DONT_CARE,
stencilStoreOp=vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
initialLayout=vk.VK_IMAGE_LAYOUT_UNDEFINED,
finalLayout=vk.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
),
]
colour_refs = [vk.VkAttachmentReference(
attachment=0,
layout=vk.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
)]
if gbuffer_format:
attachments.append(vk.VkAttachmentDescription(
format=gbuffer_format,
samples=vk.VK_SAMPLE_COUNT_1_BIT,
loadOp=vk.VK_ATTACHMENT_LOAD_OP_CLEAR,
storeOp=vk.VK_ATTACHMENT_STORE_OP_STORE,
stencilLoadOp=vk.VK_ATTACHMENT_LOAD_OP_DONT_CARE,
stencilStoreOp=vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
initialLayout=vk.VK_IMAGE_LAYOUT_UNDEFINED,
finalLayout=vk.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
))
colour_refs.append(vk.VkAttachmentReference(
attachment=1,
layout=vk.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
))
depth_ref = None
if depth_format:
depth_final = (
vk.VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL if samplable_depth
else vk.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
)
depth_store = (
vk.VK_ATTACHMENT_STORE_OP_STORE if samplable_depth
else vk.VK_ATTACHMENT_STORE_OP_DONT_CARE
)
attachments.append(vk.VkAttachmentDescription(
format=depth_format,
samples=vk.VK_SAMPLE_COUNT_1_BIT,
loadOp=vk.VK_ATTACHMENT_LOAD_OP_CLEAR,
storeOp=depth_store,
stencilLoadOp=vk.VK_ATTACHMENT_LOAD_OP_DONT_CARE,
stencilStoreOp=vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
initialLayout=vk.VK_IMAGE_LAYOUT_UNDEFINED,
finalLayout=depth_final,
))
depth_ref = vk.VkAttachmentReference(
attachment=len(colour_refs),
layout=vk.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
)
subpass = vk.VkSubpassDescription(
pipelineBindPoint=vk.VK_PIPELINE_BIND_POINT_GRAPHICS,
colorAttachmentCount=len(colour_refs),
pColorAttachments=colour_refs,
pDepthStencilAttachment=depth_ref,
)
src_stages = vk.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
dst_stages = vk.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
dst_access = vk.VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
if depth_format:
src_stages |= vk.VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
dst_stages |= vk.VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
dst_access |= vk.VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
dependencies = [
vk.VkSubpassDependency(
srcSubpass=vk.VK_SUBPASS_EXTERNAL,
dstSubpass=0,
srcStageMask=src_stages,
srcAccessMask=0,
dstStageMask=dst_stages,
dstAccessMask=dst_access,
),
# Outgoing colour dependency: the colour write + the render pass's implicit
# transition to SHADER_READ_ONLY must be made available to a later
# fragment-shader sample in the SAME command buffer. Required by the
# single-submit multi-scene model (SubViewport / reflection-probe SRUs are
# written and then sampled by the main pass with no queue wait between).
vk.VkSubpassDependency(
srcSubpass=0,
dstSubpass=vk.VK_SUBPASS_EXTERNAL,
srcStageMask=vk.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
srcAccessMask=vk.VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
dstStageMask=vk.VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
dstAccessMask=vk.VK_ACCESS_SHADER_READ_BIT,
),
]
# When depth is samplable, add a dependency so the fragment shader can read it
if samplable_depth and depth_format:
dependencies.append(vk.VkSubpassDependency(
srcSubpass=0,
dstSubpass=vk.VK_SUBPASS_EXTERNAL,
srcStageMask=vk.VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
srcAccessMask=vk.VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
dstStageMask=vk.VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
dstAccessMask=vk.VK_ACCESS_SHADER_READ_BIT,
))
create_info = vk.VkRenderPassCreateInfo(
attachmentCount=len(attachments),
pAttachments=attachments,
subpassCount=1,
pSubpasses=[subpass],
dependencyCount=len(dependencies),
pDependencies=dependencies,
)
render_pass = vk.vkCreateRenderPass(device, create_info, None)
log.debug("Offscreen render pass created (samplable_depth=%s)", samplable_depth)
return render_pass
[docs]
def create_overlay_pass(device: Any, colour_format: int) -> Any:
"""Create a colour-only render pass that loads existing content (no clear).
Used for drawing 2D overlays on top of a previously rendered target.
Colour attachment uses LOAD_OP_LOAD and transitions to SHADER_READ_ONLY.
No depth attachment.
"""
colour_attachment = vk.VkAttachmentDescription(
format=colour_format,
samples=vk.VK_SAMPLE_COUNT_1_BIT,
loadOp=vk.VK_ATTACHMENT_LOAD_OP_LOAD,
storeOp=vk.VK_ATTACHMENT_STORE_OP_STORE,
stencilLoadOp=vk.VK_ATTACHMENT_LOAD_OP_DONT_CARE,
stencilStoreOp=vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
initialLayout=vk.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
finalLayout=vk.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
)
colour_ref = vk.VkAttachmentReference(
attachment=0,
layout=vk.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
)
subpass = vk.VkSubpassDescription(
pipelineBindPoint=vk.VK_PIPELINE_BIND_POINT_GRAPHICS,
colorAttachmentCount=1,
pColorAttachments=[colour_ref],
)
dependency = vk.VkSubpassDependency(
srcSubpass=vk.VK_SUBPASS_EXTERNAL,
dstSubpass=0,
srcStageMask=vk.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
srcAccessMask=0,
dstStageMask=vk.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
dstAccessMask=vk.VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
)
render_pass = vk.vkCreateRenderPass(device, vk.VkRenderPassCreateInfo(
attachmentCount=1,
pAttachments=[colour_attachment],
subpassCount=1,
pSubpasses=[subpass],
dependencyCount=1,
pDependencies=[dependency],
), None)
log.debug("Overlay render pass created")
return render_pass
[docs]
def create_hdr_reload_pass(
device: Any, colour_format: int, depth_format: int = vk.VK_FORMAT_D32_SFLOAT,
*, gbuffer_format: int = 0,
) -> Any:
"""Colour + depth LOAD render pass for the scene-read pass split.
After the opaque family draws, the forward renderer ends the HDR pass, copies
the HDR colour + depth into sampleable scene textures, then re-begins with
THIS pass to draw the transparent phase. Both attachments load their existing
content (opaque colour + depth) rather than clearing, so transparent geometry
blends over the opaque scene and depth-tests against it. The final layouts
match the offscreen HDR pass (colour -> SHADER_READ_ONLY for tonemap, depth ->
DEPTH_STENCIL_READ_ONLY for the velocity / SSAO samplers), so downstream passes
are byte-identical to the non-split path.
When *gbuffer_format* is set (thin G-buffer), the second colour
attachment is LOADED too (the opaque normal target is preserved; the
transparent phase masks its writes to it), keeping this pass render-pass-
compatible with the 2-attachment forward pipelines.
"""
colour_attachments = [vk.VkAttachmentDescription(
format=colour_format,
samples=vk.VK_SAMPLE_COUNT_1_BIT,
loadOp=vk.VK_ATTACHMENT_LOAD_OP_LOAD,
storeOp=vk.VK_ATTACHMENT_STORE_OP_STORE,
stencilLoadOp=vk.VK_ATTACHMENT_LOAD_OP_DONT_CARE,
stencilStoreOp=vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
initialLayout=vk.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
finalLayout=vk.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
)]
colour_refs = [vk.VkAttachmentReference(
attachment=0, layout=vk.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
)]
if gbuffer_format:
colour_attachments.append(vk.VkAttachmentDescription(
format=gbuffer_format,
samples=vk.VK_SAMPLE_COUNT_1_BIT,
loadOp=vk.VK_ATTACHMENT_LOAD_OP_LOAD,
storeOp=vk.VK_ATTACHMENT_STORE_OP_STORE,
stencilLoadOp=vk.VK_ATTACHMENT_LOAD_OP_DONT_CARE,
stencilStoreOp=vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
initialLayout=vk.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
finalLayout=vk.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
))
colour_refs.append(vk.VkAttachmentReference(
attachment=1, layout=vk.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
))
depth_attachment = vk.VkAttachmentDescription(
format=depth_format,
samples=vk.VK_SAMPLE_COUNT_1_BIT,
loadOp=vk.VK_ATTACHMENT_LOAD_OP_LOAD,
storeOp=vk.VK_ATTACHMENT_STORE_OP_STORE,
stencilLoadOp=vk.VK_ATTACHMENT_LOAD_OP_DONT_CARE,
stencilStoreOp=vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
initialLayout=vk.VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
finalLayout=vk.VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
)
depth_ref = vk.VkAttachmentReference(
attachment=len(colour_refs), layout=vk.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
)
subpass = vk.VkSubpassDescription(
pipelineBindPoint=vk.VK_PIPELINE_BIND_POINT_GRAPHICS,
colorAttachmentCount=len(colour_refs),
pColorAttachments=colour_refs,
pDepthStencilAttachment=depth_ref,
)
# Subpass dependencies mirror the samplable-depth offscreen pass EXACTLY so
# this pass is render-pass-compatible with the forward pipelines (which are
# built against the offscreen HDR pass). The scene-read copy already inserts
# explicit image barriers around the copy; these render-pass dependencies only
# order the LOAD transition + the outgoing colour/depth samples.
dependencies = [
vk.VkSubpassDependency(
srcSubpass=vk.VK_SUBPASS_EXTERNAL,
dstSubpass=0,
srcStageMask=(
vk.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
| vk.VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
),
srcAccessMask=0,
dstStageMask=(
vk.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
| vk.VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
),
dstAccessMask=(
vk.VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
| vk.VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
),
),
# Outgoing colour: tonemap / bloom sample the colour after the pass.
vk.VkSubpassDependency(
srcSubpass=0,
dstSubpass=vk.VK_SUBPASS_EXTERNAL,
srcStageMask=vk.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
srcAccessMask=vk.VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
dstStageMask=vk.VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
dstAccessMask=vk.VK_ACCESS_SHADER_READ_BIT,
),
# Outgoing depth: velocity / SSAO sample the depth after the pass.
vk.VkSubpassDependency(
srcSubpass=0,
dstSubpass=vk.VK_SUBPASS_EXTERNAL,
srcStageMask=vk.VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
srcAccessMask=vk.VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
dstStageMask=vk.VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
dstAccessMask=vk.VK_ACCESS_SHADER_READ_BIT,
),
]
all_attachments = [*colour_attachments, depth_attachment]
render_pass = vk.vkCreateRenderPass(device, vk.VkRenderPassCreateInfo(
attachmentCount=len(all_attachments),
pAttachments=all_attachments,
subpassCount=1,
pSubpasses=[subpass],
dependencyCount=len(dependencies),
pDependencies=dependencies,
), None)
log.debug("HDR reload render pass created (gbuffer=%s)", bool(gbuffer_format))
return render_pass
[docs]
def create_shadow_pass(device: Any, depth_format: int = vk.VK_FORMAT_D32_SFLOAT) -> Any:
"""Create a depth-only render pass for shadow mapping."""
depth_attachment = vk.VkAttachmentDescription(
format=depth_format,
samples=vk.VK_SAMPLE_COUNT_1_BIT,
loadOp=vk.VK_ATTACHMENT_LOAD_OP_CLEAR,
storeOp=vk.VK_ATTACHMENT_STORE_OP_STORE,
stencilLoadOp=vk.VK_ATTACHMENT_LOAD_OP_DONT_CARE,
stencilStoreOp=vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
initialLayout=vk.VK_IMAGE_LAYOUT_UNDEFINED,
finalLayout=vk.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
)
depth_ref = vk.VkAttachmentReference(
attachment=0,
layout=vk.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
)
subpass = vk.VkSubpassDescription(
pipelineBindPoint=vk.VK_PIPELINE_BIND_POINT_GRAPHICS,
colorAttachmentCount=0,
pDepthStencilAttachment=depth_ref,
)
# Two dependencies: write → read transition
dependencies = [
vk.VkSubpassDependency(
srcSubpass=vk.VK_SUBPASS_EXTERNAL,
dstSubpass=0,
srcStageMask=vk.VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
srcAccessMask=vk.VK_ACCESS_SHADER_READ_BIT,
dstStageMask=vk.VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
dstAccessMask=vk.VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
),
vk.VkSubpassDependency(
srcSubpass=0,
dstSubpass=vk.VK_SUBPASS_EXTERNAL,
srcStageMask=vk.VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
srcAccessMask=vk.VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
dstStageMask=vk.VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
dstAccessMask=vk.VK_ACCESS_SHADER_READ_BIT,
),
]
create_info = vk.VkRenderPassCreateInfo(
attachmentCount=1,
pAttachments=[depth_attachment],
subpassCount=1,
pSubpasses=[subpass],
dependencyCount=2,
pDependencies=dependencies,
)
render_pass = vk.vkCreateRenderPass(device, create_info, None)
log.debug("Shadow render pass created")
return render_pass
[docs]
def create_pick_pass(device: Any, depth_format: int = 0) -> Any:
"""Create the picking render pass (R32_UINT colour + optional depth)."""
attachments = [
vk.VkAttachmentDescription(
format=vk.VK_FORMAT_R32_UINT,
samples=vk.VK_SAMPLE_COUNT_1_BIT,
loadOp=vk.VK_ATTACHMENT_LOAD_OP_CLEAR,
storeOp=vk.VK_ATTACHMENT_STORE_OP_STORE,
stencilLoadOp=vk.VK_ATTACHMENT_LOAD_OP_DONT_CARE,
stencilStoreOp=vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
initialLayout=vk.VK_IMAGE_LAYOUT_UNDEFINED,
finalLayout=vk.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
),
]
colour_ref = vk.VkAttachmentReference(
attachment=0,
layout=vk.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
)
depth_ref = None
if depth_format:
attachments.append(vk.VkAttachmentDescription(
format=depth_format,
samples=vk.VK_SAMPLE_COUNT_1_BIT,
loadOp=vk.VK_ATTACHMENT_LOAD_OP_CLEAR,
storeOp=vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
stencilLoadOp=vk.VK_ATTACHMENT_LOAD_OP_DONT_CARE,
stencilStoreOp=vk.VK_ATTACHMENT_STORE_OP_DONT_CARE,
initialLayout=vk.VK_IMAGE_LAYOUT_UNDEFINED,
finalLayout=vk.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
))
depth_ref = vk.VkAttachmentReference(
attachment=1,
layout=vk.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
)
subpass = vk.VkSubpassDescription(
pipelineBindPoint=vk.VK_PIPELINE_BIND_POINT_GRAPHICS,
colorAttachmentCount=1,
pColorAttachments=[colour_ref],
pDepthStencilAttachment=depth_ref,
)
src_stages = vk.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
dst_stages = vk.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
dst_access = vk.VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
if depth_format:
src_stages |= vk.VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
dst_stages |= vk.VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
dst_access |= vk.VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
dependency = vk.VkSubpassDependency(
srcSubpass=vk.VK_SUBPASS_EXTERNAL,
dstSubpass=0,
srcStageMask=src_stages,
srcAccessMask=0,
dstStageMask=dst_stages,
dstAccessMask=dst_access,
)
create_info = vk.VkRenderPassCreateInfo(
attachmentCount=len(attachments),
pAttachments=attachments,
subpassCount=1,
pSubpasses=[subpass],
dependencyCount=1,
pDependencies=[dependency],
)
render_pass = vk.vkCreateRenderPass(device, create_info, None)
log.debug("Pick render pass created (depth=%s)", bool(depth_format))
return render_pass