Flutter Engine
The Flutter Engine
VulkanRenderPass.cpp
Go to the documentation of this file.
1/*
2* Copyright 2023 Google LLC
3*
4* Use of this source code is governed by a BSD-style license that can be
5* found in the LICENSE file.
6*/
7
9
16
17#include <limits>
18
19namespace skgpu::graphite {
20
21namespace { // anonymous namespace
22
23int determine_uint32_count(int rpAttachmentCount, int subpassCount, int subpassDependencyCount ) {
24 // The key will be formed such that bigger-picture items (such as the total attachment count)
25 // will be near the front of the key to more quickly eliminate incompatible keys. Each
26 // renderpass key will start with the total number of attachments associated with it
27 // followed by how many subpasses and subpass dependencies the renderpass has.Packed together,
28 // these will use one uint32.
29 int num32DataCnt = 1;
30 SkASSERT(static_cast<uint32_t>(rpAttachmentCount) <= (1u << 8));
31 SkASSERT(static_cast<uint32_t>(subpassCount) <= (1u << 8));
32 SkASSERT(static_cast<uint32_t>(subpassDependencyCount) <= (1u << 8));
33
34 // The key will then contain key information for each attachment. This includes format, sample
35 // count, and load/store operation information.
36 num32DataCnt += 3 * rpAttachmentCount;
37 // Then, subpass information will be added in the form of attachment reference indices. Reserve
38 // one int32 for each possible attachment reference type, of which there are 4.
39 // There are 4 possible attachment reference types. Pack all 4 attachment reference indices into
40 // one uint32.
41 num32DataCnt += subpassCount;
42 // Each subpass dependency will be allotted 6 int32s to store all its pertinent information.
43 num32DataCnt += 6 * subpassDependencyCount;
44
45 return num32DataCnt;
46}
47
48void add_attachment_description_info_to_key(ResourceKey::Builder& builder,
49 const TextureInfo& textureInfo,
50 int& builderIdx,
51 LoadOp loadOp,
52 StoreOp storeOp) {
53 VulkanTextureInfo vkTexInfo;
54 if (textureInfo.isValid() && textureInfo.getVulkanTextureInfo(&vkTexInfo)) {
55 builder[builderIdx++] = vkTexInfo.fFormat;
56 builder[builderIdx++] = vkTexInfo.fSampleCount;
57 SkASSERT(sizeof(loadOp) < (1u << 8));
58 SkASSERT(sizeof(storeOp) < (1u << 8));
59 builder[builderIdx++] = static_cast<uint8_t>(loadOp) << 8 | static_cast<uint8_t>(storeOp);
60 }
61 // We only count attachments that are valid textures when calculating the total number of
62 // render pass attachments, so if a texture is invalid, simply skip it rather than using
63 // VK_ATTACHMENT_UNUSED and incrementing the builderIdx. Attachments can be differentiated from
64 // one another by their sample count and format (i.e. depth/stencil attachments will have a
65 // depth/stencil format).
66}
67
68void add_subpass_info_to_key(ResourceKey::Builder& builder,
69 int& builderIdx,
70 bool hasColorAttachment,
71 bool hasColorResolveAttachment,
72 bool hasDepthStencilAttachment,
73 bool loadMSAAFromResolve,
74 int subpassCount,
75 int subpassDependencyCount) {
76 // TODO: Fetch actual attachment reference and index information for each
77 // subpass from RenderPassDesc. For now, determine subpass data based upon whether we are
78 // loading from MSAA or not.
79 const int mainSubpassIdx = loadMSAAFromResolve ? 1 : 0;
80 // Assign a smaller value to represent VK_ATTACHMENT_UNUSED.
81 static constexpr int kAttachmentUnused = std::numeric_limits<uint8_t>::max();
82
83 // The following key structure assumes that we only have up to one reference of each type per
84 // subpass and that attachments are indexed in order of color, resolve, depth/stencil, then
85 // input attachments. These indices are statically defined in the VulkanRenderPass header file.
86 for (int j = 0; j < subpassCount; j++) {
87 if (j == mainSubpassIdx) {
88 uint32_t attachmentIdxKeyInfo;
89 attachmentIdxKeyInfo = hasColorAttachment ? VulkanRenderPass::kColorAttachmentIdx
90 : kAttachmentUnused;
91 attachmentIdxKeyInfo |=
92 (hasColorResolveAttachment ? VulkanRenderPass::kColorResolveAttachmentIdx
93 : kAttachmentUnused) << 8;
94 attachmentIdxKeyInfo |=
95 (hasDepthStencilAttachment ? VulkanRenderPass::kDepthStencilAttachmentIdx
96 : kAttachmentUnused) << 16;
97 // TODO: Add input attachment info to key once supported for use in main subpass
98 attachmentIdxKeyInfo |= kAttachmentUnused << 24;
99
100 builder[builderIdx++] = attachmentIdxKeyInfo;
101 } else { // Loading MSAA from resolve subpass
102 SkASSERT(hasColorAttachment);
103 builder[builderIdx++] =
104 VulkanRenderPass::kColorAttachmentIdx | // color attachment
105 (kAttachmentUnused << 8) | // No color resolve attachment
106 (kAttachmentUnused << 16) | // No depth/stencil attachment
107 // The input attachment for the load subpass is the color resolve texture.
109 }
110 }
111
112 // TODO: Query RenderPassDesc for subpass dependency information & populate the key accordingly.
113 // For now, we know that the only subpass dependency will be that expected for loading MSAA from
114 // resolve.
115 for (int i = 0; i < subpassDependencyCount; i++) {
116 builder[builderIdx++] = 0 | (mainSubpassIdx << 8); // srcSubpass, dstSubpass
117 builder[builderIdx++] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // srcStageMask
118 builder[builderIdx++] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // dstStageMask
119 builder[builderIdx++] = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; // srcAccessMask
120 builder[builderIdx++] = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | // dstAccessMask
122 builder[builderIdx++] = VK_DEPENDENCY_BY_REGION_BIT; // dependencyFlags
123 }
124}
125
126void populate_key(VulkanRenderPass::VulkanRenderPassMetaData& rpMetaData,
128 int& builderIdx,
129 bool compatibleOnly) {
130 builder[builderIdx++] = rpMetaData.fAttachments.size() |
131 (rpMetaData.fSubpassCount << 8) |
132 (rpMetaData.fSubpassDependencyCount << 16);
133
134 // Iterate through each renderpass attachment to add its information
135 for (int i = 0; i < rpMetaData.fAttachments.size(); i++) {
136 add_attachment_description_info_to_key(
137 builder,
138 rpMetaData.fAttachments[i]->fTextureInfo,
139 builderIdx,
140 // Assign LoadOp::kLoad and StoreOp::kStore as default load/store operations for
141 // compatible render passes where load/store ops don't need to match.
142 compatibleOnly ? LoadOp::kLoad : rpMetaData.fAttachments[i]->fLoadOp,
143 compatibleOnly ? StoreOp::kStore : rpMetaData.fAttachments[i]->fStoreOp);
144 }
145
146 add_subpass_info_to_key(builder,
147 builderIdx,
148 rpMetaData.fHasColorAttachment,
149 rpMetaData.fHasColorResolveAttachment,
150 rpMetaData.fHasDepthStencilAttachment,
151 rpMetaData.fLoadMSAAFromResolve,
152 rpMetaData.fSubpassCount,
153 rpMetaData.fSubpassDependencyCount);
154}
155
156} // anonymous namespace
157
159 const RenderPassDesc& renderPassDesc) {
167
168 // TODO: Query for more attachments once the RenderPassDesc struct contains that information.
169 // For now, we only ever expect to see 0 or 1 of each attachment type (color, resolve, and
170 // depth/stencil), so the count of each of those can simply be determined with a bool.
174
175 // Accumulate attachments into a container to mimic future structure in RenderPassDesc
180 fAttachments.push_back(&renderPassDesc.fColorAttachment);
181 }
183 fAttachments.push_back(&renderPassDesc.fColorResolveAttachment);
184 }
186 fAttachments.push_back(&renderPassDesc.fDepthStencilAttachment);
187 }
188
189 // TODO: Reference RenderPassDesc to determine number and makeup of subpasses and their
190 // dependencies. For now, we only ever expect 1 (in most cases) or 2 (when loading MSAA).
193 fUint32DataCnt = determine_uint32_count(
195}
196
198 const RenderPassDesc& renderPassDesc, bool compatibleOnly) {
199
200 VulkanRenderPassMetaData rpMetaData = VulkanRenderPassMetaData(renderPassDesc);
201
205
206 int startingIdx = 0;
207 populate_key(rpMetaData, builder, startingIdx, compatibleOnly);
208
209 builder.finish();
210 return key;
211}
212
215 int& builderIdx,
216 bool compatibleOnly) {
217 populate_key(rpMetaData, builder, builderIdx, /*compatibleOnly=*/true);
218}
219
220namespace { // anonymous namespace
222 const VulkanTextureInfo& textureInfo,
223 const AttachmentDesc& desc,
224 const LoadOp loadOp,
225 const StoreOp storeOp,
226 const VkImageLayout initialLayout,
227 const VkImageLayout finalLayout) {
228 static_assert((int)LoadOp::kLoad == 0);
229 static_assert((int)LoadOp::kClear == 1);
230 static_assert((int)LoadOp::kDiscard == 2);
231 static_assert(std::size(vkLoadOp) == kLoadOpCount);
232 static_assert((int)StoreOp::kStore == 0);
233 static_assert((int)StoreOp::kDiscard == 1);
234 static_assert(std::size(vkStoreOp) == kStoreOpCount);
235
236 outAttachment->flags = 0;
237 outAttachment->format = textureInfo.fFormat;
238 VkSampleCountFlagBits sampleCount;
240 skgpu::SampleCountToVkSampleCount(textureInfo.fSampleCount, &sampleCount));
241 outAttachment->samples = sampleCount;
242 switch (initialLayout) {
246 outAttachment->loadOp = vkLoadOp[static_cast<int>(loadOp)];
247 outAttachment->storeOp = vkStoreOp[static_cast<int>(storeOp)];
250 break;
252 // The loadOp and storeOp refer to the depth part of the attachment and the stencil*Ops
253 // refer to the stencil bits in the attachment.
254 outAttachment->loadOp = vkLoadOp[static_cast<int>(loadOp)];
255 outAttachment->storeOp = vkStoreOp[static_cast<int>(storeOp)];
256 outAttachment->stencilLoadOp = vkLoadOp[static_cast<int>(loadOp)];
257 outAttachment->stencilStoreOp = vkStoreOp[static_cast<int>(storeOp)];
258 break;
259 default:
260 SK_ABORT("Unexpected attachment layout");
261 }
262 outAttachment->initialLayout = initialLayout;
263 outAttachment->finalLayout = finalLayout == VK_IMAGE_LAYOUT_UNDEFINED ? initialLayout
264 : finalLayout;
265}
266} // anonymous namespace
267
269 const RenderPassDesc& renderPassDesc,
270 bool compatibleOnly) {
271 VkRenderPass renderPass;
273 auto& colorAttachmentTextureInfo = renderPassDesc.fColorAttachment.fTextureInfo;
274 auto& colorResolveAttachmentTextureInfo = renderPassDesc.fColorResolveAttachment.fTextureInfo;
275 auto& depthStencilAttachmentTextureInfo = renderPassDesc.fDepthStencilAttachment.fTextureInfo;
276 bool hasColorAttachment = colorAttachmentTextureInfo.isValid();
277 bool hasColorResolveAttachment = colorResolveAttachmentTextureInfo.isValid();
278 bool hasDepthStencilAttachment = depthStencilAttachmentTextureInfo.isValid();
279
281 // Create and track attachment references for the subpass.
282 VkAttachmentReference colorRef;
283 VkAttachmentReference resolveRef;
284 VkAttachmentReference resolveLoadInputRef;
285 VkAttachmentReference depthStencilRef;
286
287 bool loadMSAAFromResolve = false;
288 if (hasColorAttachment) {
289 VulkanTextureInfo colorAttachTexInfo;
290 colorAttachmentTextureInfo.getVulkanTextureInfo(&colorAttachTexInfo);
291 auto& colorAttachDesc = renderPassDesc.fColorAttachment;
292
293 colorRef.attachment = attachmentDescs.size();
294 VkAttachmentDescription& vkColorAttachDesc = attachmentDescs.push_back();
295 memset(&vkColorAttachDesc, 0, sizeof(VkAttachmentDescription));
297 &vkColorAttachDesc,
298 colorAttachTexInfo,
299 colorAttachDesc,
300 compatibleOnly ? LoadOp::kDiscard : colorAttachDesc.fLoadOp,
301 compatibleOnly ? StoreOp::kDiscard : colorAttachDesc.fStoreOp,
305
306 if (hasColorResolveAttachment) {
307 loadMSAAFromResolve = renderPassDesc.fColorResolveAttachment.fLoadOp == LoadOp::kLoad;
309 VulkanTextureInfo resolveAttachTexInfo;
310 colorResolveAttachmentTextureInfo.getVulkanTextureInfo(&resolveAttachTexInfo);
311 auto& resolveAttachDesc = renderPassDesc.fColorResolveAttachment;
312
313 resolveRef.attachment = attachmentDescs.size();
314 VkAttachmentDescription& vkResolveAttachDesc = attachmentDescs.push_back();
315 memset(&vkResolveAttachDesc, 0, sizeof(VkAttachmentDescription));
317 &vkResolveAttachDesc,
318 resolveAttachTexInfo,
319 resolveAttachDesc,
320 compatibleOnly ? LoadOp::kDiscard : resolveAttachDesc.fLoadOp,
321 compatibleOnly ? StoreOp::kDiscard : resolveAttachDesc.fStoreOp,
322 loadMSAAFromResolve ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
326 } else {
327 resolveRef.attachment = VK_ATTACHMENT_UNUSED;
329 }
330 } else {
331 SkASSERT(false);
334 resolveRef.attachment = VK_ATTACHMENT_UNUSED;
336 }
337
338 if (hasDepthStencilAttachment) {
339 VulkanTextureInfo depthStencilTexInfo;
340 depthStencilAttachmentTextureInfo.getVulkanTextureInfo(&depthStencilTexInfo);
341 auto& depthStencilAttachDesc = renderPassDesc.fDepthStencilAttachment;
342
343 depthStencilRef.attachment = attachmentDescs.size();
344 VkAttachmentDescription& vkDepthStencilAttachDesc = attachmentDescs.push_back();
346 &vkDepthStencilAttachDesc,
347 depthStencilTexInfo,
348 depthStencilAttachDesc,
349 compatibleOnly ? LoadOp::kDiscard : depthStencilAttachDesc.fLoadOp,
350 compatibleOnly ? StoreOp::kDiscard : depthStencilAttachDesc.fStoreOp,
354 } else {
355 depthStencilRef.attachment = VK_ATTACHMENT_UNUSED;
356 depthStencilRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
357 }
358
359 // Create VkRenderPass
360 VkRenderPassCreateInfo renderPassInfo;
361 memset(&renderPassInfo, 0, sizeof(VkRenderPassCreateInfo));
363 renderPassInfo.pNext = nullptr;
364 renderPassInfo.flags = 0;
365 renderPassInfo.subpassCount = loadMSAAFromResolve ? 2 : 1;
366
367 skia_private::TArray<VkSubpassDescription> subpassDescs(renderPassInfo.subpassCount);
368 memset(subpassDescs.begin(), 0, renderPassInfo.subpassCount * sizeof(VkSubpassDescription));
369
370 // If we are loading MSAA from resolve, that subpass must always be first.
372 if (loadMSAAFromResolve) {
373 resolveLoadInputRef.attachment = resolveRef.attachment;
375
376 VkSubpassDescription& loadSubpassDesc = subpassDescs.push_back();
377 memset(&loadSubpassDesc, 0, sizeof(VkSubpassDescription));
378 loadSubpassDesc.flags = 0;
380 loadSubpassDesc.inputAttachmentCount = 1;
381 loadSubpassDesc.pInputAttachments = &resolveLoadInputRef;
382 loadSubpassDesc.colorAttachmentCount = 1;
383 loadSubpassDesc.pColorAttachments = &colorRef;
384 loadSubpassDesc.pResolveAttachments = nullptr;
385 loadSubpassDesc.pDepthStencilAttachment = nullptr;
386 loadSubpassDesc.preserveAttachmentCount = 0;
387 loadSubpassDesc.pPreserveAttachments = nullptr;
388
389 // Set up the subpass dependency
390 const int mainSubpassIdx = loadMSAAFromResolve ? 1 : 0;
391 dependency.srcSubpass = 0;
392 dependency.dstSubpass = mainSubpassIdx;
393 dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
397 dependency.dstAccessMask =
399 }
400
401 VkSubpassDescription& mainSubpassDesc = subpassDescs.push_back();
402 memset(&mainSubpassDesc, 0, sizeof(VkSubpassDescription));
403 mainSubpassDesc.flags = 0;
405 mainSubpassDesc.inputAttachmentCount = 0; // TODO: Add input attachment support in main subpass
406 mainSubpassDesc.pInputAttachments = nullptr;
407 mainSubpassDesc.colorAttachmentCount = 1;
408 mainSubpassDesc.pColorAttachments = &colorRef;
409 mainSubpassDesc.pResolveAttachments = &resolveRef;
410 mainSubpassDesc.pDepthStencilAttachment = &depthStencilRef;
411 mainSubpassDesc.preserveAttachmentCount = 0;
412 mainSubpassDesc.pPreserveAttachments = nullptr;
413
414 renderPassInfo.pSubpasses = subpassDescs.begin();
415 renderPassInfo.dependencyCount = loadMSAAFromResolve ? 1 : 0;
416 renderPassInfo.pDependencies = loadMSAAFromResolve ? &dependency : VK_NULL_HANDLE;
417 renderPassInfo.attachmentCount = attachmentDescs.size();
418 renderPassInfo.pAttachments = attachmentDescs.begin();
419
421 VULKAN_CALL_RESULT(context,
422 result,
423 CreateRenderPass(context->device(), &renderPassInfo, nullptr, &renderPass));
424 if (result != VK_SUCCESS) {
425 return nullptr;
426 }
428 VULKAN_CALL(context->interface(), GetRenderAreaGranularity(context->device(),
430 &granularity));
432}
433
434VulkanRenderPass::VulkanRenderPass(const VulkanSharedContext* context,
435 VkRenderPass renderPass,
437 : Resource(context,
440 /*gpuMemorySize=*/0)
441 , fSharedContext(context)
442 , fRenderPass(renderPass)
443 , fGranularity(granularity) {}
444
445void VulkanRenderPass::freeGpuData() {
446 VULKAN_CALL(fSharedContext->interface(),
447 DestroyRenderPass(fSharedContext->device(), fRenderPass, nullptr));
448}
449
450} // namespace skgpu::graphite
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
void setup_vk_attachment_description(VkAttachmentDescription *attachment, const AttachmentDesc &desc, VkImageLayout startLayout, VkImageLayout endLayout)
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kYes
Do pre-clip the geometry before applying the (perspective) matrix.
#define VULKAN_CALL(IFACE, X)
#define VULKAN_CALL_RESULT(SHARED_CONTEXT, RESULT, X)
const GraphiteResourceKey & key() const
Definition: Resource.h:156
static constexpr int kColorAttachmentIdx
static void AddRenderPassInfoToKey(VulkanRenderPassMetaData &rpMetaData, ResourceKey::Builder &builder, int &builderIdx, bool compatibleOnly)
static sk_sp< VulkanRenderPass > MakeRenderPass(const VulkanSharedContext *, const RenderPassDesc &, bool compatibleOnly)
static constexpr int kColorResolveAttachmentIdx
static constexpr int kDepthStencilAttachmentIdx
static GraphiteResourceKey MakeRenderPassKey(const RenderPassDesc &, bool compatibleOnly)
const skgpu::VulkanInterface * interface() const
int size() const
Definition: SkTArray.h:421
GAsyncResult * result
static float max(float r, float g, float b)
Definition: hsl.cpp:49
DlVertices::Builder Builder
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
uint32_t ResourceType
static constexpr int kLoadOpCount
Definition: ResourceTypes.h:41
static const VkAttachmentLoadOp vkLoadOp[]
static constexpr int kStoreOpCount
Definition: ResourceTypes.h:52
static const VkAttachmentStoreOp vkStoreOp[]
Definition: GpuTools.h:21
Budgeted
Definition: GpuTypes.h:35
static constexpr bool SampleCountToVkSampleCount(uint32_t samples, VkSampleCountFlagBits *vkSamples)
VkAttachmentLoadOp loadOp
Definition: vulkan_core.h:3804
VkAttachmentStoreOp stencilStoreOp
Definition: vulkan_core.h:3807
VkSampleCountFlagBits samples
Definition: vulkan_core.h:3803
VkAttachmentDescriptionFlags flags
Definition: vulkan_core.h:3801
VkAttachmentStoreOp storeOp
Definition: vulkan_core.h:3805
VkImageLayout initialLayout
Definition: vulkan_core.h:3808
VkImageLayout finalLayout
Definition: vulkan_core.h:3809
VkAttachmentLoadOp stencilLoadOp
Definition: vulkan_core.h:3806
VkImageLayout layout
Definition: vulkan_core.h:3814
VkStructureType sType
Definition: vulkan_core.h:3853
const VkSubpassDescription * pSubpasses
Definition: vulkan_core.h:3859
const VkSubpassDependency * pDependencies
Definition: vulkan_core.h:3861
const VkAttachmentDescription * pAttachments
Definition: vulkan_core.h:3857
VkRenderPassCreateFlags flags
Definition: vulkan_core.h:3855
const VkAttachmentReference * pDepthStencilAttachment
Definition: vulkan_core.h:3837
VkSubpassDescriptionFlags flags
Definition: vulkan_core.h:3830
uint32_t inputAttachmentCount
Definition: vulkan_core.h:3832
const VkAttachmentReference * pResolveAttachments
Definition: vulkan_core.h:3836
const uint32_t * pPreserveAttachments
Definition: vulkan_core.h:3839
const VkAttachmentReference * pInputAttachments
Definition: vulkan_core.h:3833
uint32_t colorAttachmentCount
Definition: vulkan_core.h:3834
const VkAttachmentReference * pColorAttachments
Definition: vulkan_core.h:3835
VkPipelineBindPoint pipelineBindPoint
Definition: vulkan_core.h:3831
uint32_t preserveAttachmentCount
Definition: vulkan_core.h:3838
AttachmentDesc fDepthStencilAttachment
AttachmentDesc fColorResolveAttachment
skia_private::TArray< const AttachmentDesc * > fAttachments
VulkanRenderPassMetaData(const RenderPassDesc &renderPassDesc)
VkImageLayout
Definition: vulkan_core.h:1330
@ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
Definition: vulkan_core.h:1334
@ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
Definition: vulkan_core.h:1336
@ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
Definition: vulkan_core.h:1333
@ VK_IMAGE_LAYOUT_UNDEFINED
Definition: vulkan_core.h:1331
@ VK_IMAGE_LAYOUT_GENERAL
Definition: vulkan_core.h:1332
@ VK_DEPENDENCY_BY_REGION_BIT
Definition: vulkan_core.h:2776
@ VK_PIPELINE_BIND_POINT_GRAPHICS
Definition: vulkan_core.h:2166
#define VK_ATTACHMENT_UNUSED
Definition: vulkan_core.h:124
VkSampleCountFlagBits
Definition: vulkan_core.h:2339
VkResult
Definition: vulkan_core.h:140
@ VK_SUCCESS
Definition: vulkan_core.h:141
@ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
Definition: vulkan_core.h:2208
@ VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
Definition: vulkan_core.h:2207
#define VK_NULL_HANDLE
Definition: vulkan_core.h:46
@ VK_ATTACHMENT_LOAD_OP_DONT_CARE
Definition: vulkan_core.h:2150
@ VK_ATTACHMENT_STORE_OP_DONT_CARE
Definition: vulkan_core.h:2157
@ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
Definition: vulkan_core.h:2445
@ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
Definition: vulkan_core.h:240