3#include "graphics/shaders/color_vert_spv.inc"
4#include "graphics/shaders/color_frag_spv.inc"
6#include "graphics/shaders/textured_vert_spv.inc"
7#include "graphics/shaders/textured_frag_spv.inc"
8#include "graphics/shaders/lit2d_vert_spv.inc"
9#include "graphics/shaders/lit2d_frag_spv.inc"
10#include "graphics/shaders/particle_distortion_frag_spv.inc"
11#include "graphics/shaders/scene_tonemap_frag_spv.inc"
21 std::vector<vk::PipelineColorBlendAttachmentState> attachments(1,
22 makeBlendAttachment(mode));
23 vk::PipelineColorBlendStateCreateInfo cbs{};
24 cbs.logicOpEnable =
false;
25 cbs.attachmentCount = 1;
26 cbs.pAttachments = attachments.data();
27 return device.createPipeline()
28 .useClassicPipeline(embeddedSpirv(color_vert_spv), embeddedSpirv(color_frag_spv))
30 .setVertexInputState(vkb::VertexInputStateBuilder()
31 .addInputBinding<ColorVertex>()
32 .addAttributeDescription<ColorVertex>())
33 .setDynamicStatesViewportScissor()
34 .setRasterizer(vk::PolygonMode::eFill,
false,
false, 1.0f,
35 vk::CullModeFlagBits::eNone, vk::FrontFace::eCounterClockwise)
36 .setDepthStencil(
false,
false)
37 .setColorBlending(cbs)
41 return device.createPipeline()
42 .useClassicPipeline(embeddedSpirv(color_vert_spv), embeddedSpirv(color_frag_spv))
44 .setVertexInputState(vkb::VertexInputStateBuilder()
45 .addInputBinding<ColorVertex>()
46 .addAttributeDescription<ColorVertex>())
47 .setDynamicStatesViewportScissor()
48 .setRasterizer(vk::PolygonMode::eFill,
false,
false, 1.0f,
49 vk::CullModeFlagBits::eNone, vk::FrontFace::eCounterClockwise)
50 .setDepthStencil(
false,
false)
55 return device.createPipeline()
56 .useClassicPipeline(embeddedSpirv(color_vert_spv), embeddedSpirv(color_frag_spv))
58 .setVertexInputState(vkb::VertexInputStateBuilder()
59 .addInputBinding<ColorVertex>()
60 .addAttributeDescription<ColorVertex>())
61 .setDynamicStatesViewportScissor()
62 .setRasterizer(vk::PolygonMode::eFill,
false,
false, 1.0f, vk::CullModeFlagBits::eNone,
63 vk::FrontFace::eCounterClockwise)
64 .setDepthStencil(
false,
false)
70vkb::BuiltRenderPass persistentColorPass(vkb::Device&
device, vk::Format format) {
71 vk::AttachmentDescription
color{};
72 color.format = format;
73 color.samples = vk::SampleCountFlagBits::e1;
74 color.loadOp = vk::AttachmentLoadOp::eLoad;
75 color.storeOp = vk::AttachmentStoreOp::eStore;
76 color.stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
77 color.stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
78 color.initialLayout = vk::ImageLayout::eColorAttachmentOptimal;
79 color.finalLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
80 auto pass =
device.createRenderPass().addAttachment(
color)
81 .addSubpass(vkb::SubpassBuilder().addAttachmentRef(0, vk::ImageLayout::eColorAttachmentOptimal))
82 .addDependency(VK_SUBPASS_EXTERNAL, 0,
83 vk::PipelineStageFlagBits::eFragmentShader | vk::PipelineStageFlagBits::eColorAttachmentOutput,
84 vk::PipelineStageFlagBits::eColorAttachmentOutput,
85 vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eColorAttachmentWrite,
86 vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite)
87 .addDependency(0, VK_SUBPASS_EXTERNAL, vk::PipelineStageFlagBits::eColorAttachmentOutput,
88 vk::PipelineStageFlagBits::eFragmentShader, vk::AccessFlagBits::eColorAttachmentWrite,
89 vk::AccessFlagBits::eShaderRead).build();
91 pass.colorAttachmentCount = 1;
92 pass.colorsSampledAfter =
true;
93 pass.colorFinalLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
97void Graphics::ensureOffscreenPipelines() {
98 if (offscreenRenderPass)
return;
100 offscreenRenderPass = persistentColorPass(device, vk::Format::eR8G8B8A8Unorm);
102 offscreenSolidPipeline =
104 offscreenSolidAlphaPipeline =
106 offscreenAdditiveSolidPipeline =
114 auto tvert = embeddedSpirv(textured_vert_spv);
115 auto tfrag = embeddedSpirv(textured_frag_spv);
116 offscreenTexPipeline =
117 createTexturedStylePipeline(tvert, tfrag, offscreenRenderPass, texPipelineLayout);
118 offscreenAdditiveTexPipeline =
119 createTexturedStylePipeline(tvert, tfrag, offscreenRenderPass, texPipelineLayout,
121 offscreenPremultipliedTexPipeline = createTexturedStylePipeline(
123 offscreenMultiplyTexPipeline = createTexturedStylePipeline(
125 offscreenOpaqueTexPipeline =
126 createTexturedStylePipeline(tvert, tfrag, offscreenRenderPass, texPipelineLayout,
129 if (lit2dPipelineLayout) {
130 auto lvert = embeddedSpirv(lit2d_vert_spv);
131 auto lfrag = embeddedSpirv(lit2d_frag_spv);
132 offscreenLitPipeline =
133 createTexturedStylePipeline(lvert, lfrag, offscreenRenderPass, lit2dPipelineLayout);
134 offscreenLitAdditivePipeline =
135 createTexturedStylePipeline(lvert, lfrag, offscreenRenderPass, lit2dPipelineLayout,
BlendMode::Additive);
136 offscreenLitPremultipliedPipeline = createTexturedStylePipeline(lvert, lfrag, offscreenRenderPass,
138 offscreenLitMultiplyPipeline =
139 createTexturedStylePipeline(lvert, lfrag, offscreenRenderPass, lit2dPipelineLayout,
BlendMode::Multiply);
140 offscreenLitOpaquePipeline =
141 createTexturedStylePipeline(lvert, lfrag, offscreenRenderPass, lit2dPipelineLayout,
BlendMode::Opaque);
145 for (
auto &sh : ownedShaders) ensureShaderOffscreenPipeline(sh.get());
148void Graphics::ensureShaderOffscreenPipeline(Shader *
shader) {
149 if (!
shader || !
shader->gpuHandle || !offscreenRenderPass)
return;
152 auto *gpu =
static_cast<GpuShader *
>(
shader->gpuHandle);
153 if (gpu->isMesh3D || gpu->offscreenPipeline)
return;
154 gpu->offscreenPipeline = createTexturedStylePipeline(
shader->vertexSpirv(),
shader->fragmentSpirv(),
155 offscreenRenderPass, shaderPipelineLayout);
156 gpu->offscreenOpaquePipeline = createTexturedStylePipeline(
157 shader->vertexSpirv(),
shader->fragmentSpirv(), offscreenRenderPass,
161void Graphics::ensureHdrOffscreenPipelines() {
162 if (!hdrOffscreenRenderPass) {
163 hdrOffscreenRenderPass =
165 .addSampledColorAttachment(vk::Format::eR16G16B16A16Sfloat)
166 .addSubpass(vkb::SubpassBuilder().addAttachmentRef(
167 0, vk::ImageLayout::eColorAttachmentOptimal))
168 .addExternalShaderReadDependencies()
171 if (!pipelineLayout) pipelineLayout = createPipelineLayout(device);
172 if (!hdrOffscreenSolidPipeline) {
173 hdrOffscreenSolidPipeline =
175 hdrOffscreenSolidAlphaPipeline =
184 if (!hdrOffscreenTexPipeline && texPipelineLayout) {
185 auto vert = embeddedSpirv(textured_vert_spv);
186 auto frag = embeddedSpirv(textured_frag_spv);
187 hdrOffscreenTexPipeline = createTexturedStylePipeline(
188 vert,
frag, hdrOffscreenRenderPass, texPipelineLayout);
189 hdrOffscreenOpaqueTexPipeline = createTexturedStylePipeline(
191 hdrOffscreenAdditiveTexPipeline = createTexturedStylePipeline(
193 hdrOffscreenPremultipliedTexPipeline = createTexturedStylePipeline(
195 hdrOffscreenMultiplyTexPipeline = createTexturedStylePipeline(
197 hdrOffscreenParticleDistortionPipeline = createTexturedStylePipeline(
198 vert, embeddedSpirv(particle_distortion_frag_spv), hdrOffscreenRenderPass, texPipelineLayout,
200 hdrOffscreenTonemapPipeline = createTexturedStylePipeline(
201 vert, embeddedSpirv(scene_tonemap_frag_spv), hdrOffscreenRenderPass, texPipelineLayout,
204 if (!hdrOffscreenLitPipeline && lit2dPipelineLayout) {
205 auto lvert = embeddedSpirv(lit2d_vert_spv);
206 auto lfrag = embeddedSpirv(lit2d_frag_spv);
207 hdrOffscreenLitPipeline =
208 createTexturedStylePipeline(lvert, lfrag, hdrOffscreenRenderPass, lit2dPipelineLayout);
209 hdrOffscreenLitAdditivePipeline =
210 createTexturedStylePipeline(lvert, lfrag, hdrOffscreenRenderPass, lit2dPipelineLayout,
BlendMode::Additive);
211 hdrOffscreenLitPremultipliedPipeline = createTexturedStylePipeline(
213 hdrOffscreenLitMultiplyPipeline =
214 createTexturedStylePipeline(lvert, lfrag, hdrOffscreenRenderPass, lit2dPipelineLayout,
BlendMode::Multiply);
215 hdrOffscreenLitOpaquePipeline =
216 createTexturedStylePipeline(lvert, lfrag, hdrOffscreenRenderPass, lit2dPipelineLayout,
BlendMode::Opaque);
218 ensureHdrGpuParticleDrawPipelines();
219 for (
auto &
shader : ownedShaders) ensureShaderHdrOffscreenPipeline(
shader.get());
222void Graphics::ensureShaderHdrOffscreenPipeline(Shader *
shader) {
223 if (!
shader || !
shader->gpuHandle || !hdrOffscreenRenderPass)
return;
225 auto *gpu =
static_cast<GpuShader *
>(
shader->gpuHandle);
226 if (gpu->isMesh3D || gpu->hdrOffscreenPipeline)
return;
227 gpu->hdrOffscreenPipeline = createTexturedStylePipeline(
228 shader->vertexSpirv(),
shader->fragmentSpirv(), hdrOffscreenRenderPass,
229 shaderPipelineLayout);
230 gpu->hdrOffscreenOpaquePipeline = createTexturedStylePipeline(
231 shader->vertexSpirv(),
shader->fragmentSpirv(), hdrOffscreenRenderPass,
vk::Pipeline createSolidColorPipeline(vkb::Device &device, const vkb::BuiltRenderPass &renderPass, vk::PipelineLayout layout, BlendMode mode)
Internal synchronous pipeline factory; caller destroys the returned Vulkan pipeline.
BlendMode
Render-neutral 2D blend mode shared by graphics-facing modules.