blob: 50b9bb9dda0e2c0d527507b36831349cb7a3a219 [file] [log] [blame]
Lionel Landwerlin2d9f5632022-01-08 01:12:47 +02001/* Copyright (c) 2015-2022 The Khronos Group Inc.
2 * Copyright (c) 2015-2022 Valve Corporation
3 * Copyright (c) 2015-2022 LunarG, Inc.
4 * Copyright (C) 2015-2022 Google Inc.
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -06005 * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * Author: Courtney Goeltzenleuchter <courtneygo@google.com>
20 * Author: Tobin Ehlis <tobine@google.com>
21 * Author: Chris Forbes <chrisf@ijw.co.nz>
22 * Author: Mark Lobodzinski <mark@lunarg.com>
23 * Author: Dave Houlton <daveh@lunarg.com>
24 * Author: John Zulauf <jzulauf@lunarg.com>
25 * Author: Tobias Hector <tobias.hector@amd.com>
Jeremy Gebben11af9792021-08-20 10:20:09 -060026 * Author: Jeremy Gebben <jeremyg@lunarg.com>
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -060027 */
28#include "pipeline_state.h"
29#include "descriptor_sets.h"
30#include "cmd_buffer_state.h"
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -060031#include "state_tracker.h"
Jeremy Gebben84b838b2021-08-23 08:41:39 -060032#include "shader_module.h"
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -060033
Jeremy Gebbene6e45542021-08-05 16:39:49 -060034// Dictionary of canonical form of the pipeline set layout of descriptor set layouts
35static PipelineLayoutSetLayoutsDict pipeline_layout_set_layouts_dict;
36
37// Dictionary of canonical form of the "compatible for set" records
38static PipelineLayoutCompatDict pipeline_layout_compat_dict;
39
40static PushConstantRangesDict push_constant_ranges_dict;
41
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -060042size_t PipelineLayoutCompatDef::hash() const {
43 hash_util::HashCombiner hc;
44 // The set number is integral to the CompatDef's distinctiveness
45 hc << set << push_constant_ranges.get();
46 const auto &descriptor_set_layouts = *set_layouts_id.get();
47 for (uint32_t i = 0; i <= set; i++) {
48 hc << descriptor_set_layouts[i].get();
49 }
50 return hc.Value();
51}
52
53bool PipelineLayoutCompatDef::operator==(const PipelineLayoutCompatDef &other) const {
54 if ((set != other.set) || (push_constant_ranges != other.push_constant_ranges)) {
55 return false;
56 }
57
58 if (set_layouts_id == other.set_layouts_id) {
59 // if it's the same set_layouts_id, then *any* subset will match
60 return true;
61 }
62
63 // They aren't exactly the same PipelineLayoutSetLayouts, so we need to check if the required subsets match
64 const auto &descriptor_set_layouts = *set_layouts_id.get();
65 assert(set < descriptor_set_layouts.size());
66 const auto &other_ds_layouts = *other.set_layouts_id.get();
67 assert(set < other_ds_layouts.size());
68 for (uint32_t i = 0; i <= set; i++) {
69 if (descriptor_set_layouts[i] != other_ds_layouts[i]) {
70 return false;
71 }
72 }
73 return true;
74}
75
Jeremy Gebbene6e45542021-08-05 16:39:49 -060076static PipelineLayoutCompatId GetCanonicalId(const uint32_t set_index, const PushConstantRangesId pcr_id,
77 const PipelineLayoutSetLayoutsId set_layouts_id) {
78 return pipeline_layout_compat_dict.look_up(PipelineLayoutCompatDef(set_index, pcr_id, set_layouts_id));
79}
80
81// For repeatable sorting, not very useful for "memory in range" search
82struct PushConstantRangeCompare {
83 bool operator()(const VkPushConstantRange *lhs, const VkPushConstantRange *rhs) const {
84 if (lhs->offset == rhs->offset) {
85 if (lhs->size == rhs->size) {
86 // The comparison is arbitrary, but avoids false aliasing by comparing all fields.
87 return lhs->stageFlags < rhs->stageFlags;
88 }
89 // If the offsets are the same then sorting by the end of range is useful for validation
90 return lhs->size < rhs->size;
91 }
92 return lhs->offset < rhs->offset;
93 }
94};
95
96static PushConstantRangesId GetCanonicalId(const VkPipelineLayoutCreateInfo *info) {
97 if (!info->pPushConstantRanges) {
98 // Hand back the empty entry (creating as needed)...
99 return push_constant_ranges_dict.look_up(PushConstantRanges());
100 }
101
102 // Sort the input ranges to ensure equivalent ranges map to the same id
103 std::set<const VkPushConstantRange *, PushConstantRangeCompare> sorted;
104 for (uint32_t i = 0; i < info->pushConstantRangeCount; i++) {
105 sorted.insert(info->pPushConstantRanges + i);
106 }
107
108 PushConstantRanges ranges;
109 ranges.reserve(sorted.size());
110 for (const auto *range : sorted) {
111 ranges.emplace_back(*range);
112 }
113 return push_constant_ranges_dict.look_up(std::move(ranges));
114}
115
116static PIPELINE_LAYOUT_STATE::SetLayoutVector GetSetLayouts(ValidationStateTracker *dev_data,
117 const VkPipelineLayoutCreateInfo *pCreateInfo) {
118 PIPELINE_LAYOUT_STATE::SetLayoutVector set_layouts(pCreateInfo->setLayoutCount);
119
120 for (uint32_t i = 0; i < pCreateInfo->setLayoutCount; ++i) {
Jeremy Gebben9f537102021-10-05 16:37:12 -0600121 set_layouts[i] = dev_data->Get<cvdescriptorset::DescriptorSetLayout>(pCreateInfo->pSetLayouts[i]);
Jeremy Gebbene6e45542021-08-05 16:39:49 -0600122 }
123 return set_layouts;
124}
125
126static std::vector<PipelineLayoutCompatId> GetCompatForSet(const PIPELINE_LAYOUT_STATE::SetLayoutVector &set_layouts,
127 const PushConstantRangesId &push_constant_ranges) {
128 PipelineLayoutSetLayoutsDef set_layout_ids(set_layouts.size());
129 for (size_t i = 0; i < set_layouts.size(); i++) {
130 set_layout_ids[i] = set_layouts[i]->GetLayoutId();
131 }
132 auto set_layouts_id = pipeline_layout_set_layouts_dict.look_up(set_layout_ids);
133
134 std::vector<PipelineLayoutCompatId> compat_for_set;
135 compat_for_set.reserve(set_layouts.size());
136
137 for (uint32_t i = 0; i < set_layouts.size(); i++) {
138 compat_for_set.emplace_back(GetCanonicalId(i, push_constant_ranges, set_layouts_id));
139 }
140 return compat_for_set;
141}
142
143PIPELINE_LAYOUT_STATE::PIPELINE_LAYOUT_STATE(ValidationStateTracker *dev_data, VkPipelineLayout l,
144 const VkPipelineLayoutCreateInfo *pCreateInfo)
145 : BASE_NODE(l, kVulkanObjectTypePipelineLayout),
146 set_layouts(GetSetLayouts(dev_data, pCreateInfo)),
147 push_constant_ranges(GetCanonicalId(pCreateInfo)),
148 compat_for_set(GetCompatForSet(set_layouts, push_constant_ranges)) {}
149
Jeremy Gebben11af9792021-08-20 10:20:09 -0600150static PIPELINE_STATE::VertexBindingVector GetVertexBindingDescriptions(const safe_VkGraphicsPipelineCreateInfo &create_info) {
151 PIPELINE_STATE::VertexBindingVector result;
152 if (create_info.pVertexInputState) {
153 const auto vici = create_info.pVertexInputState;
154 if (vici->vertexBindingDescriptionCount) {
155 result.reserve(vici->vertexBindingDescriptionCount);
156 std::copy(vici->pVertexBindingDescriptions, vici->pVertexBindingDescriptions + vici->vertexBindingDescriptionCount,
157 std::back_inserter(result));
158 }
159 }
160 return result;
161}
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600162
Jeremy Gebben11af9792021-08-20 10:20:09 -0600163static PIPELINE_STATE::VertexBindingIndexMap GetVertexBindingMap(const PIPELINE_STATE::VertexBindingVector &bindings) {
164 PIPELINE_STATE::VertexBindingIndexMap result;
165 for (uint32_t i = 0; i < bindings.size(); i++) {
166 result[bindings[i].binding] = i;
167 }
168 return result;
169}
170
171static PIPELINE_STATE::VertexAttrVector GetVertexAttributeDescriptions(const safe_VkGraphicsPipelineCreateInfo &create_info) {
172 PIPELINE_STATE::VertexAttrVector result;
173 if (create_info.pVertexInputState) {
174 const auto vici = create_info.pVertexInputState;
175 if (vici->vertexAttributeDescriptionCount) {
176 result.reserve(vici->vertexAttributeDescriptionCount);
177 std::copy(vici->pVertexAttributeDescriptions,
178 vici->pVertexAttributeDescriptions + vici->vertexAttributeDescriptionCount, std::back_inserter(result));
179 }
180 }
181 return result;
182}
183
184static PIPELINE_STATE::VertexAttrAlignmentVector GetAttributeAlignments(const PIPELINE_STATE::VertexAttrVector &attributes) {
185 PIPELINE_STATE::VertexAttrAlignmentVector result;
186 result.reserve(attributes.size());
187 for (const auto &attr : attributes) {
188 VkDeviceSize vtx_attrib_req_alignment = FormatElementSize(attr.format);
189 if (FormatElementIsTexel(attr.format)) {
sfricke-samsunged028b02021-09-06 23:14:51 -0700190 vtx_attrib_req_alignment = SafeDivision(vtx_attrib_req_alignment, FormatComponentCount(attr.format));
Jeremy Gebben11af9792021-08-20 10:20:09 -0600191 }
192 result.push_back(vtx_attrib_req_alignment);
193 }
194 return result;
195}
196
197static PIPELINE_STATE::AttachmentVector GetAttachments(const safe_VkGraphicsPipelineCreateInfo &create_info) {
198 PIPELINE_STATE::AttachmentVector result;
199 if (create_info.pColorBlendState) {
200 const auto cbci = create_info.pColorBlendState;
201 if (cbci->attachmentCount) {
202 result.reserve(cbci->attachmentCount);
203 std::copy(cbci->pAttachments, cbci->pAttachments + cbci->attachmentCount, std::back_inserter(result));
204 }
205 }
206 return result;
207}
208
209static bool IsBlendConstantsEnabled(const PIPELINE_STATE::AttachmentVector &attachments) {
210 bool result = false;
211 for (const auto &attachment : attachments) {
212 if (VK_TRUE == attachment.blendEnable) {
213 if (((attachment.dstAlphaBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
214 (attachment.dstAlphaBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) ||
215 ((attachment.dstColorBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
216 (attachment.dstColorBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) ||
217 ((attachment.srcAlphaBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
218 (attachment.srcAlphaBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) ||
219 ((attachment.srcColorBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) &&
220 (attachment.srcColorBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA))) {
221 result = true;
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600222 break;
223 }
224 }
Jeremy Gebben11af9792021-08-20 10:20:09 -0600225 }
226 return result;
227}
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600228
Jeremy Gebben11af9792021-08-20 10:20:09 -0600229static bool IsSampleLocationEnabled(const safe_VkGraphicsPipelineCreateInfo &create_info) {
230 bool result = false;
231 if (create_info.pMultisampleState) {
232 const auto *sample_location_state =
233 LvlFindInChain<VkPipelineSampleLocationsStateCreateInfoEXT>(create_info.pMultisampleState->pNext);
234 if (sample_location_state != nullptr) {
235 result = (sample_location_state->sampleLocationsEnable != 0);
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600236 }
237 }
Jeremy Gebben11af9792021-08-20 10:20:09 -0600238 return result;
239}
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600240
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600241static bool HasWriteableDescriptor(const std::vector<PipelineStageState::DescriptorUse> &descriptor_uses) {
242 return std::any_of(descriptor_uses.begin(), descriptor_uses.end(),
ziga-lunarg1a535052022-03-10 01:04:28 +0100243 [](const PipelineStageState::DescriptorUse &use) { return use.second.is_writable; });
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600244}
245
246static bool HasAtomicDescriptor(const std::vector<PipelineStageState::DescriptorUse> &descriptor_uses) {
247 return std::any_of(descriptor_uses.begin(), descriptor_uses.end(),
ziga-lunarg1a535052022-03-10 01:04:28 +0100248 [](const PipelineStageState::DescriptorUse &use) { return use.second.is_atomic_operation; });
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600249}
250
Jeremy Gebben3dfeacf2021-12-02 08:46:39 -0700251static bool WrotePrimitiveShadingRate(VkShaderStageFlagBits stage_flag, spirv_inst_iter entrypoint,
sfricke-samsungef15e482022-01-26 11:32:49 -0800252 const SHADER_MODULE_STATE *module_state) {
Jeremy Gebben3dfeacf2021-12-02 08:46:39 -0700253 bool primitiverate_written = false;
254 if (stage_flag == VK_SHADER_STAGE_VERTEX_BIT || stage_flag == VK_SHADER_STAGE_GEOMETRY_BIT ||
255 stage_flag == VK_SHADER_STAGE_MESH_BIT_NV) {
sfricke-samsungef15e482022-01-26 11:32:49 -0800256 for (const auto &set : module_state->GetBuiltinDecorationList()) {
257 auto insn = module_state->at(set.offset);
Jeremy Gebben3dfeacf2021-12-02 08:46:39 -0700258 if (set.builtin == spv::BuiltInPrimitiveShadingRateKHR) {
sfricke-samsungef15e482022-01-26 11:32:49 -0800259 primitiverate_written = module_state->IsBuiltInWritten(insn, entrypoint);
Jeremy Gebben3dfeacf2021-12-02 08:46:39 -0700260 }
261 if (primitiverate_written) {
262 break;
263 }
264 }
265 }
266 return primitiverate_written;
267}
268
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600269PipelineStageState::PipelineStageState(const VkPipelineShaderStageCreateInfo *stage,
sfricke-samsungef15e482022-01-26 11:32:49 -0800270 std::shared_ptr<const SHADER_MODULE_STATE> &module_state)
271 : module_state(module_state),
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600272 create_info(stage),
273 stage_flag(stage->stage),
sfricke-samsungef15e482022-01-26 11:32:49 -0800274 entrypoint(module_state->FindEntrypoint(stage->pName, stage->stage)),
275 accessible_ids(module_state->MarkAccessibleIds(entrypoint)),
276 descriptor_uses(module_state->CollectInterfaceByDescriptorSlot(accessible_ids)),
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600277 has_writable_descriptor(HasWriteableDescriptor(descriptor_uses)),
Jeremy Gebben3dfeacf2021-12-02 08:46:39 -0700278 has_atomic_descriptor(HasAtomicDescriptor(descriptor_uses)),
sfricke-samsungef15e482022-01-26 11:32:49 -0800279 wrote_primitive_shading_rate(WrotePrimitiveShadingRate(stage_flag, entrypoint, module_state.get())) {}
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600280
281static PIPELINE_STATE::StageStateVec GetStageStates(const ValidationStateTracker *state_data,
282 const safe_VkPipelineShaderStageCreateInfo *stages, uint32_t stage_count) {
283 PIPELINE_STATE::StageStateVec stage_states;
284 stage_states.reserve(stage_count);
285 // shader stages need to be recorded in pipeline order
286 for (uint32_t stage_idx = 0; stage_idx < 32; ++stage_idx) {
287 for (uint32_t i = 0; i < stage_count; i++) {
288 if (stages[i].stage == (1 << stage_idx)) {
sfricke-samsungef15e482022-01-26 11:32:49 -0800289 auto module_state = state_data->Get<SHADER_MODULE_STATE>(stages[i].module);
290 stage_states.emplace_back(stages[i].ptr(), module_state);
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600291 }
292 }
293 }
294 return stage_states;
295}
296
297static PIPELINE_STATE::ActiveSlotMap GetActiveSlots(const PIPELINE_STATE::StageStateVec &stage_states) {
298 PIPELINE_STATE::ActiveSlotMap active_slots;
299 for (const auto &stage : stage_states) {
sfricke-samsungef15e482022-01-26 11:32:49 -0800300 if (stage.entrypoint == stage.module_state->end()) {
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600301 continue;
302 }
303 // Capture descriptor uses for the pipeline
304 for (const auto &use : stage.descriptor_uses) {
305 // While validating shaders capture which slots are used by the pipeline
306 auto &entry = active_slots[use.first.set][use.first.binding];
307 entry.is_writable |= use.second.is_writable;
308
309 auto &reqs = entry.reqs;
sfricke-samsungef15e482022-01-26 11:32:49 -0800310 reqs |= stage.module_state->DescriptorTypeToReqs(use.second.type_id);
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600311 if (use.second.is_atomic_operation) reqs |= DESCRIPTOR_REQ_VIEW_ATOMIC_OPERATION;
312 if (use.second.is_sampler_implicitLod_dref_proj) reqs |= DESCRIPTOR_REQ_SAMPLER_IMPLICITLOD_DREF_PROJ;
313 if (use.second.is_sampler_bias_offset) reqs |= DESCRIPTOR_REQ_SAMPLER_BIAS_OFFSET;
Lionel Landwerlinbc7401b2021-12-07 15:43:05 +0200314 if (use.second.is_read_without_format) reqs |= DESCRIPTOR_REQ_IMAGE_READ_WITHOUT_FORMAT;
315 if (use.second.is_write_without_format) reqs |= DESCRIPTOR_REQ_IMAGE_WRITE_WITHOUT_FORMAT;
Lionel Landwerlincdbe8682021-12-08 15:10:37 +0200316 if (use.second.is_dref_operation) reqs |= DESCRIPTOR_REQ_IMAGE_DREF;
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600317
318 if (use.second.samplers_used_by_image.size()) {
319 if (use.second.samplers_used_by_image.size() > entry.samplers_used_by_image.size()) {
320 entry.samplers_used_by_image.resize(use.second.samplers_used_by_image.size());
321 }
322 uint32_t image_index = 0;
323 for (const auto &samplers : use.second.samplers_used_by_image) {
324 for (const auto &sampler : samplers) {
Jeremy Gebben856b8c62021-12-01 15:20:07 -0700325 entry.samplers_used_by_image[image_index].emplace(sampler);
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600326 }
327 ++image_index;
328 }
329 }
330 }
331 }
332 return active_slots;
333}
334
335static uint32_t GetMaxActiveSlot(const PIPELINE_STATE::ActiveSlotMap &active_slots) {
336 uint32_t max_active_slot = 0;
337 for (const auto &entry : active_slots) {
338 max_active_slot = std::max(max_active_slot, entry.first);
339 }
340 return max_active_slot;
341}
342
343static uint32_t GetActiveShaders(const VkPipelineShaderStageCreateInfo *stages, uint32_t stage_count) {
344 uint32_t result = 0;
345 for (uint32_t i = 0; i < stage_count; i++) {
346 result |= stages[i].stage;
347 }
348 return result;
349}
350
351static layer_data::unordered_set<uint32_t> GetFSOutputLocations(const PIPELINE_STATE::StageStateVec &stage_states) {
352 layer_data::unordered_set<uint32_t> result;
353 for (const auto &stage : stage_states) {
sfricke-samsungef15e482022-01-26 11:32:49 -0800354 if (stage.entrypoint == stage.module_state->end()) {
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600355 continue;
356 }
357 if (stage.stage_flag == VK_SHADER_STAGE_FRAGMENT_BIT) {
sfricke-samsungef15e482022-01-26 11:32:49 -0800358 result = stage.module_state->CollectWritableOutputLocationinFS(stage.entrypoint);
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600359 break;
360 }
361 }
362 return result;
363}
364
365static VkPrimitiveTopology GetTopologyAtRasterizer(const PIPELINE_STATE::StageStateVec &stage_states,
366 const safe_VkPipelineInputAssemblyStateCreateInfo *assembly_state) {
367 VkPrimitiveTopology result = assembly_state ? assembly_state->topology : static_cast<VkPrimitiveTopology>(0);
368 for (const auto &stage : stage_states) {
sfricke-samsungef15e482022-01-26 11:32:49 -0800369 if (stage.entrypoint == stage.module_state->end()) {
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600370 continue;
371 }
sfricke-samsungef15e482022-01-26 11:32:49 -0800372 auto stage_topo = stage.module_state->GetTopology(stage.entrypoint);
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600373 if (stage_topo) {
374 result = *stage_topo;
375 }
376 }
377 return result;
378}
379
Jeremy Gebben11af9792021-08-20 10:20:09 -0600380PIPELINE_STATE::PIPELINE_STATE(const ValidationStateTracker *state_data, const VkGraphicsPipelineCreateInfo *pCreateInfo,
381 std::shared_ptr<const RENDER_PASS_STATE> &&rpstate,
382 std::shared_ptr<const PIPELINE_LAYOUT_STATE> &&layout)
383 : BASE_NODE(static_cast<VkPipeline>(VK_NULL_HANDLE), kVulkanObjectTypePipeline),
amhagana448ea52021-11-02 14:09:14 -0400384 create_info(pCreateInfo, rpstate),
Jeremy Gebben11af9792021-08-20 10:20:09 -0600385 pipeline_layout(std::move(layout)),
386 rp_state(rpstate),
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600387 stage_state(GetStageStates(state_data, create_info.graphics.pStages, create_info.graphics.stageCount)),
388 active_slots(GetActiveSlots(stage_state)),
389 max_active_slot(GetMaxActiveSlot(active_slots)),
390 fragmentShader_writable_output_location_list(GetFSOutputLocations(stage_state)),
Jeremy Gebben11af9792021-08-20 10:20:09 -0600391 vertex_binding_descriptions_(GetVertexBindingDescriptions(create_info.graphics)),
392 vertex_attribute_descriptions_(GetVertexAttributeDescriptions(create_info.graphics)),
393 vertex_attribute_alignments_(GetAttributeAlignments(vertex_attribute_descriptions_)),
394 vertex_binding_to_index_map_(GetVertexBindingMap(vertex_binding_descriptions_)),
395 attachments(GetAttachments(create_info.graphics)),
396 blend_constants_enabled(IsBlendConstantsEnabled(attachments)),
397 sample_location_enabled(IsSampleLocationEnabled(create_info.graphics)),
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600398 active_shaders(GetActiveShaders(pCreateInfo->pStages, pCreateInfo->stageCount)),
399 topology_at_rasterizer(GetTopologyAtRasterizer(stage_state, create_info.graphics.pInputAssemblyState)) {}
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600400
Jeremy Gebben11af9792021-08-20 10:20:09 -0600401PIPELINE_STATE::PIPELINE_STATE(const ValidationStateTracker *state_data, const VkComputePipelineCreateInfo *pCreateInfo,
402 std::shared_ptr<const PIPELINE_LAYOUT_STATE> &&layout)
403 : BASE_NODE(static_cast<VkPipeline>(VK_NULL_HANDLE), kVulkanObjectTypePipeline),
404 create_info(pCreateInfo),
405 pipeline_layout(std::move(layout)),
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600406 stage_state(GetStageStates(state_data, &create_info.compute.stage, 1)),
407 active_slots(GetActiveSlots(stage_state)),
Jeremy Gebben11af9792021-08-20 10:20:09 -0600408 blend_constants_enabled(false),
409 sample_location_enabled(false),
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600410 active_shaders(GetActiveShaders(&pCreateInfo->stage, 1)),
Jeremy Gebben11af9792021-08-20 10:20:09 -0600411 topology_at_rasterizer{} {
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600412 assert(active_shaders == VK_SHADER_STAGE_COMPUTE_BIT);
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600413}
414
Jeremy Gebben20da7a12022-02-25 14:07:46 -0700415PIPELINE_STATE::PIPELINE_STATE(const ValidationStateTracker *state_data, const VkRayTracingPipelineCreateInfoNV *pCreateInfo,
Jeremy Gebben11af9792021-08-20 10:20:09 -0600416 std::shared_ptr<const PIPELINE_LAYOUT_STATE> &&layout)
417 : BASE_NODE(static_cast<VkPipeline>(VK_NULL_HANDLE), kVulkanObjectTypePipeline),
418 create_info(pCreateInfo),
419 pipeline_layout(std::move(layout)),
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600420 stage_state(GetStageStates(state_data, create_info.raytracing.pStages, create_info.raytracing.stageCount)),
421 active_slots(GetActiveSlots(stage_state)),
Jeremy Gebben11af9792021-08-20 10:20:09 -0600422 blend_constants_enabled(false),
423 sample_location_enabled(false),
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600424 active_shaders(GetActiveShaders(pCreateInfo->pStages, pCreateInfo->stageCount)),
Jeremy Gebben11af9792021-08-20 10:20:09 -0600425 topology_at_rasterizer{} {
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600426 assert(0 == (active_shaders &
427 ~(VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |
428 VK_SHADER_STAGE_MISS_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_CALLABLE_BIT_KHR)));
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600429}
430
Jeremy Gebben20da7a12022-02-25 14:07:46 -0700431PIPELINE_STATE::PIPELINE_STATE(const ValidationStateTracker *state_data, const VkRayTracingPipelineCreateInfoKHR *pCreateInfo,
432 std::shared_ptr<const PIPELINE_LAYOUT_STATE> &&layout)
433 : BASE_NODE(static_cast<VkPipeline>(VK_NULL_HANDLE), kVulkanObjectTypePipeline),
434 create_info(pCreateInfo),
435 pipeline_layout(std::move(layout)),
436 stage_state(GetStageStates(state_data, create_info.raytracing.pStages, create_info.raytracing.stageCount)),
437 active_slots(GetActiveSlots(stage_state)),
438 blend_constants_enabled(false),
439 sample_location_enabled(false),
440 active_shaders(GetActiveShaders(pCreateInfo->pStages, pCreateInfo->stageCount)),
441 topology_at_rasterizer{} {
442 assert(0 == (active_shaders &
443 ~(VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |
444 VK_SHADER_STAGE_MISS_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_CALLABLE_BIT_KHR)));
445}
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600446
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700447void LAST_BOUND_STATE::UnbindAndResetPushDescriptorSet(CMD_BUFFER_STATE *cb_state,
448 std::shared_ptr<cvdescriptorset::DescriptorSet> &&ds) {
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600449 if (push_descriptor_set) {
450 for (auto &ps : per_set) {
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700451 if (ps.bound_descriptor_set == push_descriptor_set) {
Jeremy Gebben610d3a62022-01-01 12:53:17 -0700452 cb_state->RemoveChild(ps.bound_descriptor_set);
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700453 ps.bound_descriptor_set.reset();
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600454 }
455 }
456 }
457 cb_state->AddChild(ds);
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700458 push_descriptor_set = std::move(ds);
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600459}
460
461void LAST_BOUND_STATE::Reset() {
462 pipeline_state = nullptr;
463 pipeline_layout = VK_NULL_HANDLE;
464 if (push_descriptor_set) {
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700465 push_descriptor_set->Destroy();
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600466 }
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700467 push_descriptor_set.reset();
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600468 per_set.clear();
469}