blob: ae0dc50a62eb02c451f7e3e183ceb08540ccf1d2 [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 Gebben84b838b2021-08-23 08:41:39 -060034static bool HasWriteableDescriptor(const std::vector<PipelineStageState::DescriptorUse> &descriptor_uses) {
35 return std::any_of(descriptor_uses.begin(), descriptor_uses.end(),
ziga-lunarg1a535052022-03-10 01:04:28 +010036 [](const PipelineStageState::DescriptorUse &use) { return use.second.is_writable; });
Jeremy Gebben84b838b2021-08-23 08:41:39 -060037}
38
39static bool HasAtomicDescriptor(const std::vector<PipelineStageState::DescriptorUse> &descriptor_uses) {
40 return std::any_of(descriptor_uses.begin(), descriptor_uses.end(),
ziga-lunarg1a535052022-03-10 01:04:28 +010041 [](const PipelineStageState::DescriptorUse &use) { return use.second.is_atomic_operation; });
Jeremy Gebben84b838b2021-08-23 08:41:39 -060042}
43
Jeremy Gebben3dfeacf2021-12-02 08:46:39 -070044static bool WrotePrimitiveShadingRate(VkShaderStageFlagBits stage_flag, spirv_inst_iter entrypoint,
sfricke-samsungef15e482022-01-26 11:32:49 -080045 const SHADER_MODULE_STATE *module_state) {
Jeremy Gebben3dfeacf2021-12-02 08:46:39 -070046 bool primitiverate_written = false;
47 if (stage_flag == VK_SHADER_STAGE_VERTEX_BIT || stage_flag == VK_SHADER_STAGE_GEOMETRY_BIT ||
48 stage_flag == VK_SHADER_STAGE_MESH_BIT_NV) {
sfricke-samsungef15e482022-01-26 11:32:49 -080049 for (const auto &set : module_state->GetBuiltinDecorationList()) {
50 auto insn = module_state->at(set.offset);
Jeremy Gebben3dfeacf2021-12-02 08:46:39 -070051 if (set.builtin == spv::BuiltInPrimitiveShadingRateKHR) {
sfricke-samsungef15e482022-01-26 11:32:49 -080052 primitiverate_written = module_state->IsBuiltInWritten(insn, entrypoint);
Jeremy Gebben3dfeacf2021-12-02 08:46:39 -070053 }
54 if (primitiverate_written) {
55 break;
56 }
57 }
58 }
59 return primitiverate_written;
60}
61
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -070062PipelineStageState::PipelineStageState(const safe_VkPipelineShaderStageCreateInfo *stage,
sfricke-samsungef15e482022-01-26 11:32:49 -080063 std::shared_ptr<const SHADER_MODULE_STATE> &module_state)
64 : module_state(module_state),
Jeremy Gebben84b838b2021-08-23 08:41:39 -060065 create_info(stage),
66 stage_flag(stage->stage),
sfricke-samsungef15e482022-01-26 11:32:49 -080067 entrypoint(module_state->FindEntrypoint(stage->pName, stage->stage)),
68 accessible_ids(module_state->MarkAccessibleIds(entrypoint)),
69 descriptor_uses(module_state->CollectInterfaceByDescriptorSlot(accessible_ids)),
Jeremy Gebben84b838b2021-08-23 08:41:39 -060070 has_writable_descriptor(HasWriteableDescriptor(descriptor_uses)),
Jeremy Gebben3dfeacf2021-12-02 08:46:39 -070071 has_atomic_descriptor(HasAtomicDescriptor(descriptor_uses)),
sfricke-samsungef15e482022-01-26 11:32:49 -080072 wrote_primitive_shading_rate(WrotePrimitiveShadingRate(stage_flag, entrypoint, module_state.get())) {}
Jeremy Gebben84b838b2021-08-23 08:41:39 -060073
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -070074// static
75PIPELINE_STATE::StageStateVec PIPELINE_STATE::GetStageStates(const ValidationStateTracker &state_data,
76 const PIPELINE_STATE &pipe_state) {
Jeremy Gebben84b838b2021-08-23 08:41:39 -060077 PIPELINE_STATE::StageStateVec stage_states;
Jeremy Gebben84b838b2021-08-23 08:41:39 -060078 // shader stages need to be recorded in pipeline order
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -070079 const auto stages = pipe_state.GetShaderStages();
80
Jeremy Gebben84b838b2021-08-23 08:41:39 -060081 for (uint32_t stage_idx = 0; stage_idx < 32; ++stage_idx) {
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -070082 bool stage_found = false;
83 const auto stage = static_cast<VkShaderStageFlagBits>(1 << stage_idx);
84 for (const auto &shader_stage : stages) {
85 if (shader_stage.stage == stage) {
86 auto module = state_data.Get<SHADER_MODULE_STATE>(shader_stage.module);
87 if (!module) {
88 // If module is null and there is a VkShaderModuleCreateInfo in the pNext chain of the stage info, then this
89 // module is part of a library and the state must be created
90 const auto shader_ci = LvlFindInChain<VkShaderModuleCreateInfo>(shader_stage.pNext);
91 if (shader_ci) {
92 const uint32_t unique_shader_id = 0; // TODO GPU-AV rework required to get this value properly
93 module = state_data.CreateShaderModuleState(*shader_ci, unique_shader_id);
94 } else {
95 // TODO This should be an error of some sort. Just assert for now
96 assert(false);
97 }
98 }
99 stage_states.emplace_back(&shader_stage, module);
100 stage_found = true;
101 }
102 }
103 if (!stage_found) {
104 // Check if stage has been supplied by a library
105 switch (stage) {
106 case VK_SHADER_STAGE_VERTEX_BIT:
107 if (pipe_state.pre_raster_state && pipe_state.pre_raster_state->vertex_shader) {
108 stage_states.emplace_back(pipe_state.pre_raster_state->vertex_shader_ci,
109 pipe_state.pre_raster_state->vertex_shader);
110 }
111 break;
112 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
113 if (pipe_state.pre_raster_state && pipe_state.pre_raster_state->tessc_shader) {
114 stage_states.emplace_back(pipe_state.pre_raster_state->tessc_shader_ci,
115 pipe_state.pre_raster_state->tessc_shader);
116 }
117 break;
118 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
119 if (pipe_state.pre_raster_state && pipe_state.pre_raster_state->tesse_shader) {
120 stage_states.emplace_back(pipe_state.pre_raster_state->tesse_shader_ci,
121 pipe_state.pre_raster_state->tesse_shader);
122 }
123 break;
124 case VK_SHADER_STAGE_GEOMETRY_BIT:
125 if (pipe_state.pre_raster_state && pipe_state.pre_raster_state->geometry_shader) {
126 stage_states.emplace_back(pipe_state.pre_raster_state->geometry_shader_ci,
127 pipe_state.pre_raster_state->geometry_shader);
128 }
129 break;
130 case VK_SHADER_STAGE_FRAGMENT_BIT:
131 if (pipe_state.fragment_shader_state && pipe_state.fragment_shader_state->fragment_shader) {
132 stage_states.emplace_back(pipe_state.fragment_shader_state->fragment_shader_ci.get(),
133 pipe_state.fragment_shader_state->fragment_shader);
134 }
135 break;
136 default:
137 // no-op
138 break;
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600139 }
140 }
141 }
142 return stage_states;
143}
144
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700145// static
146PIPELINE_STATE::ActiveSlotMap PIPELINE_STATE::GetActiveSlots(const StageStateVec &stage_states) {
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600147 PIPELINE_STATE::ActiveSlotMap active_slots;
148 for (const auto &stage : stage_states) {
sfricke-samsungef15e482022-01-26 11:32:49 -0800149 if (stage.entrypoint == stage.module_state->end()) {
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600150 continue;
151 }
152 // Capture descriptor uses for the pipeline
153 for (const auto &use : stage.descriptor_uses) {
154 // While validating shaders capture which slots are used by the pipeline
155 auto &entry = active_slots[use.first.set][use.first.binding];
156 entry.is_writable |= use.second.is_writable;
157
158 auto &reqs = entry.reqs;
sfricke-samsungef15e482022-01-26 11:32:49 -0800159 reqs |= stage.module_state->DescriptorTypeToReqs(use.second.type_id);
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600160 if (use.second.is_atomic_operation) reqs |= DESCRIPTOR_REQ_VIEW_ATOMIC_OPERATION;
161 if (use.second.is_sampler_implicitLod_dref_proj) reqs |= DESCRIPTOR_REQ_SAMPLER_IMPLICITLOD_DREF_PROJ;
162 if (use.second.is_sampler_bias_offset) reqs |= DESCRIPTOR_REQ_SAMPLER_BIAS_OFFSET;
Lionel Landwerlinbc7401b2021-12-07 15:43:05 +0200163 if (use.second.is_read_without_format) reqs |= DESCRIPTOR_REQ_IMAGE_READ_WITHOUT_FORMAT;
164 if (use.second.is_write_without_format) reqs |= DESCRIPTOR_REQ_IMAGE_WRITE_WITHOUT_FORMAT;
Lionel Landwerlincdbe8682021-12-08 15:10:37 +0200165 if (use.second.is_dref_operation) reqs |= DESCRIPTOR_REQ_IMAGE_DREF;
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600166
167 if (use.second.samplers_used_by_image.size()) {
168 if (use.second.samplers_used_by_image.size() > entry.samplers_used_by_image.size()) {
169 entry.samplers_used_by_image.resize(use.second.samplers_used_by_image.size());
170 }
171 uint32_t image_index = 0;
172 for (const auto &samplers : use.second.samplers_used_by_image) {
173 for (const auto &sampler : samplers) {
Jeremy Gebben856b8c62021-12-01 15:20:07 -0700174 entry.samplers_used_by_image[image_index].emplace(sampler);
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600175 }
176 ++image_index;
177 }
178 }
179 }
180 }
181 return active_slots;
182}
183
184static uint32_t GetMaxActiveSlot(const PIPELINE_STATE::ActiveSlotMap &active_slots) {
185 uint32_t max_active_slot = 0;
186 for (const auto &entry : active_slots) {
187 max_active_slot = std::max(max_active_slot, entry.first);
188 }
189 return max_active_slot;
190}
191
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700192static uint32_t GetActiveShaders(const PIPELINE_STATE::StageStateVec &stages) {
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600193 uint32_t result = 0;
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700194 for (const auto &stage : stages) {
195 result |= stage.stage_flag;
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600196 }
197 return result;
198}
199
200static layer_data::unordered_set<uint32_t> GetFSOutputLocations(const PIPELINE_STATE::StageStateVec &stage_states) {
201 layer_data::unordered_set<uint32_t> result;
202 for (const auto &stage : stage_states) {
sfricke-samsungef15e482022-01-26 11:32:49 -0800203 if (stage.entrypoint == stage.module_state->end()) {
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600204 continue;
205 }
206 if (stage.stage_flag == VK_SHADER_STAGE_FRAGMENT_BIT) {
sfricke-samsungef15e482022-01-26 11:32:49 -0800207 result = stage.module_state->CollectWritableOutputLocationinFS(stage.entrypoint);
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600208 break;
209 }
210 }
211 return result;
212}
213
214static VkPrimitiveTopology GetTopologyAtRasterizer(const PIPELINE_STATE::StageStateVec &stage_states,
215 const safe_VkPipelineInputAssemblyStateCreateInfo *assembly_state) {
216 VkPrimitiveTopology result = assembly_state ? assembly_state->topology : static_cast<VkPrimitiveTopology>(0);
217 for (const auto &stage : stage_states) {
sfricke-samsungef15e482022-01-26 11:32:49 -0800218 if (stage.entrypoint == stage.module_state->end()) {
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600219 continue;
220 }
sfricke-samsungef15e482022-01-26 11:32:49 -0800221 auto stage_topo = stage.module_state->GetTopology(stage.entrypoint);
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600222 if (stage_topo) {
223 result = *stage_topo;
224 }
225 }
226 return result;
227}
228
Nathaniel Cesario52398442022-02-15 16:33:46 -0700229// static
230std::shared_ptr<VertexInputState> PIPELINE_STATE::CreateVertexInputState(const ValidationStateTracker &state,
231 const safe_VkGraphicsPipelineCreateInfo &create_info) {
232 const auto lib_type = GetGraphicsLibType(create_info);
233 if (lib_type & VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT) { // Vertex input graphics library
234 return std::make_shared<VertexInputState>(create_info);
235 }
236
237 const auto link_info = LvlFindInChain<VkPipelineLibraryCreateInfoKHR>(create_info.pNext);
238 if (link_info) {
Nathaniel Cesario0f5906a2022-04-05 11:10:18 -0600239 auto ss = GetLibSubState<VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT>(state, *link_info);
Nathaniel Cesario52398442022-02-15 16:33:46 -0700240 if (ss) {
241 return ss;
242 }
Nathaniel Cesariofe8d7862022-02-16 17:27:29 -0700243 } else {
244 if (lib_type == static_cast<VkGraphicsPipelineLibraryFlagsEXT>(0)) { // Not a graphics library
245 return std::make_shared<VertexInputState>(create_info);
246 }
Nathaniel Cesario52398442022-02-15 16:33:46 -0700247 }
248
249 // We shouldn't get here...
250 return {};
251}
252
253// static
254std::shared_ptr<PreRasterState> PIPELINE_STATE::CreatePreRasterState(const ValidationStateTracker &state,
255 const safe_VkGraphicsPipelineCreateInfo &create_info) {
256 const auto lib_type = GetGraphicsLibType(create_info);
257 if (lib_type & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) { // Pre-raster graphics library
258 return std::make_shared<PreRasterState>(state, create_info);
259 }
260
261 const auto link_info = LvlFindInChain<VkPipelineLibraryCreateInfoKHR>(create_info.pNext);
262 if (link_info) {
Nathaniel Cesario0f5906a2022-04-05 11:10:18 -0600263 auto ss = GetLibSubState<VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT>(state, *link_info);
Nathaniel Cesario52398442022-02-15 16:33:46 -0700264 if (ss) {
265 return ss;
266 }
Nathaniel Cesariofe8d7862022-02-16 17:27:29 -0700267 } else {
268 if (lib_type == static_cast<VkGraphicsPipelineLibraryFlagsEXT>(0)) { // Not a graphics library
269 return std::make_shared<PreRasterState>(state, create_info);
270 }
Nathaniel Cesario52398442022-02-15 16:33:46 -0700271 }
272
273 // We shouldn't get here...
274 return {};
275}
276
277// static
278std::shared_ptr<FragmentShaderState> PIPELINE_STATE::CreateFragmentShaderState(
279 const ValidationStateTracker &state, const VkGraphicsPipelineCreateInfo &create_info,
280 const safe_VkGraphicsPipelineCreateInfo &safe_create_info) {
281 const auto lib_type = GetGraphicsLibType(create_info);
282 if (lib_type & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) { // Fragment shader graphics library
283 return std::make_shared<FragmentShaderState>(state, create_info);
284 }
285
286 const auto link_info = LvlFindInChain<VkPipelineLibraryCreateInfoKHR>(create_info.pNext);
287 if (link_info) {
Nathaniel Cesario0f5906a2022-04-05 11:10:18 -0600288 auto ss = GetLibSubState<VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT>(state, *link_info);
Nathaniel Cesario52398442022-02-15 16:33:46 -0700289 if (ss) {
290 return ss;
291 }
Nathaniel Cesariofe8d7862022-02-16 17:27:29 -0700292 } else {
293 if (lib_type == static_cast<VkGraphicsPipelineLibraryFlagsEXT>(0)) { // Not a graphics library
294 return std::make_shared<FragmentShaderState>(state, safe_create_info);
295 }
Nathaniel Cesario52398442022-02-15 16:33:46 -0700296 }
297
298 // We shouldn't get here...
299 return {};
300}
301
302// static
303// Pointers that should be ignored have been set to null in safe_create_info, but if this is a graphics library we need the "raw"
304// create_info.
305std::shared_ptr<FragmentOutputState> PIPELINE_STATE::CreateFragmentOutputState(
306 const ValidationStateTracker &state, const VkGraphicsPipelineCreateInfo &create_info,
307 const safe_VkGraphicsPipelineCreateInfo &safe_create_info) {
308 const auto lib_type = GetGraphicsLibType(create_info);
309 if (lib_type & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) { // Fragment output graphics library
310 return std::make_shared<FragmentOutputState>(state, create_info);
311 }
312
313 const auto link_info = LvlFindInChain<VkPipelineLibraryCreateInfoKHR>(create_info.pNext);
314 if (link_info) {
Nathaniel Cesario0f5906a2022-04-05 11:10:18 -0600315 auto ss = GetLibSubState<VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT>(state, *link_info);
Nathaniel Cesario52398442022-02-15 16:33:46 -0700316 if (ss) {
317 return ss;
318 }
Nathaniel Cesariofe8d7862022-02-16 17:27:29 -0700319 } else {
320 if (lib_type == static_cast<VkGraphicsPipelineLibraryFlagsEXT>(0)) { // Not a graphics library
321 return std::make_shared<FragmentOutputState>(state, safe_create_info);
322 }
Nathaniel Cesario52398442022-02-15 16:33:46 -0700323 }
324
325 // We shouldn't get here...
326 return {};
327}
328
Jeremy Gebben11af9792021-08-20 10:20:09 -0600329PIPELINE_STATE::PIPELINE_STATE(const ValidationStateTracker *state_data, const VkGraphicsPipelineCreateInfo *pCreateInfo,
330 std::shared_ptr<const RENDER_PASS_STATE> &&rpstate,
331 std::shared_ptr<const PIPELINE_LAYOUT_STATE> &&layout)
332 : BASE_NODE(static_cast<VkPipeline>(VK_NULL_HANDLE), kVulkanObjectTypePipeline),
amhagana448ea52021-11-02 14:09:14 -0400333 create_info(pCreateInfo, rpstate),
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700334 graphics_lib_type(GetGraphicsLibType(create_info.graphics)),
335 vertex_input_state(CreateVertexInputState(*state_data, create_info.graphics)),
336 pre_raster_state(CreatePreRasterState(*state_data, create_info.graphics)),
337 fragment_shader_state(CreateFragmentShaderState(*state_data, *pCreateInfo, create_info.graphics)),
338 fragment_output_state(CreateFragmentOutputState(*state_data, *pCreateInfo, create_info.graphics)),
339 stage_state(GetStageStates(*state_data, *this)),
340 fragmentShader_writable_output_location_list(GetFSOutputLocations(stage_state)),
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600341 active_slots(GetActiveSlots(stage_state)),
342 max_active_slot(GetMaxActiveSlot(active_slots)),
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700343 active_shaders(GetActiveShaders(stage_state)),
344 topology_at_rasterizer(GetTopologyAtRasterizer(stage_state, create_info.graphics.pInputAssemblyState)),
Nathaniel Cesario81257cb2022-02-16 17:15:58 -0700345 rp_state(rpstate) {
346 const auto link_info = LvlFindInChain<VkPipelineLibraryCreateInfoKHR>(PNext());
347 if (link_info) {
348 const auto &exe_layout_state = state_data->Get<PIPELINE_LAYOUT_STATE>(create_info.graphics.layout);
349 const auto *exe_layout = exe_layout_state.get();
350 const auto *pre_raster_layout =
351 (pre_raster_state && pre_raster_state->pipeline_layout) ? pre_raster_state->pipeline_layout.get() : nullptr;
352 const auto *fragment_shader_layout = (fragment_shader_state && fragment_shader_state->pipeline_layout)
353 ? fragment_shader_state->pipeline_layout.get()
354 : nullptr;
355 std::array<decltype(exe_layout), 3> layouts;
356 layouts[0] = pre_raster_layout;
357 layouts[1] = fragment_shader_layout;
358 layouts[2] = exe_layout;
359 merged_graphics_layout = std::make_shared<PIPELINE_LAYOUT_STATE>(layouts);
Nathaniel Cesariofe8d7862022-02-16 17:27:29 -0700360
361 // TODO Could store the graphics_lib_type in the sub-state rather than searching for it again here.
362 // Or, could store a pointer back to the owning PIPELINE_STATE.
363 for (uint32_t i = 0; i < link_info->libraryCount; ++i) {
364 const auto &state = state_data->Get<PIPELINE_STATE>(link_info->pLibraries[i]);
365 if (state) {
366 graphics_lib_type |= state->graphics_lib_type;
367 }
368 }
Nathaniel Cesario81257cb2022-02-16 17:15:58 -0700369 }
370}
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600371
Jeremy Gebben11af9792021-08-20 10:20:09 -0600372PIPELINE_STATE::PIPELINE_STATE(const ValidationStateTracker *state_data, const VkComputePipelineCreateInfo *pCreateInfo,
373 std::shared_ptr<const PIPELINE_LAYOUT_STATE> &&layout)
374 : BASE_NODE(static_cast<VkPipeline>(VK_NULL_HANDLE), kVulkanObjectTypePipeline),
375 create_info(pCreateInfo),
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700376 stage_state(GetStageStates(*state_data, *this)),
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600377 active_slots(GetActiveSlots(stage_state)),
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700378 active_shaders(GetActiveShaders(stage_state)),
379 topology_at_rasterizer{},
380 merged_graphics_layout(layout) {
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600381 assert(active_shaders == VK_SHADER_STAGE_COMPUTE_BIT);
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600382}
383
Nathaniel Cesarioc8c11c12022-02-16 17:23:50 -0700384PIPELINE_STATE::PIPELINE_STATE(const ValidationStateTracker *state_data, const VkRayTracingPipelineCreateInfoKHR *pCreateInfo,
385 std::shared_ptr<const PIPELINE_LAYOUT_STATE> &&layout)
386 : BASE_NODE(static_cast<VkPipeline>(VK_NULL_HANDLE), kVulkanObjectTypePipeline),
387 create_info(pCreateInfo),
388 stage_state(GetStageStates(*state_data, *this)),
389 active_slots(GetActiveSlots(stage_state)),
390 active_shaders(GetActiveShaders(stage_state)),
391 topology_at_rasterizer{},
392 merged_graphics_layout(std::move(layout)) {
393 assert(0 == (active_shaders &
394 ~(VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |
395 VK_SHADER_STAGE_MISS_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_CALLABLE_BIT_KHR)));
396}
397
Jeremy Gebben20da7a12022-02-25 14:07:46 -0700398PIPELINE_STATE::PIPELINE_STATE(const ValidationStateTracker *state_data, const VkRayTracingPipelineCreateInfoNV *pCreateInfo,
Jeremy Gebben11af9792021-08-20 10:20:09 -0600399 std::shared_ptr<const PIPELINE_LAYOUT_STATE> &&layout)
400 : BASE_NODE(static_cast<VkPipeline>(VK_NULL_HANDLE), kVulkanObjectTypePipeline),
401 create_info(pCreateInfo),
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700402 stage_state(GetStageStates(*state_data, *this)),
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600403 active_slots(GetActiveSlots(stage_state)),
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700404 active_shaders(GetActiveShaders(stage_state)),
405 topology_at_rasterizer{},
406 merged_graphics_layout(std::move(layout)) {
Jeremy Gebben84b838b2021-08-23 08:41:39 -0600407 assert(0 == (active_shaders &
408 ~(VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |
409 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 -0600410}
411
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700412void LAST_BOUND_STATE::UnbindAndResetPushDescriptorSet(CMD_BUFFER_STATE *cb_state,
413 std::shared_ptr<cvdescriptorset::DescriptorSet> &&ds) {
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600414 if (push_descriptor_set) {
415 for (auto &ps : per_set) {
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700416 if (ps.bound_descriptor_set == push_descriptor_set) {
Jeremy Gebben610d3a62022-01-01 12:53:17 -0700417 cb_state->RemoveChild(ps.bound_descriptor_set);
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700418 ps.bound_descriptor_set.reset();
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600419 }
420 }
421 }
422 cb_state->AddChild(ds);
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700423 push_descriptor_set = std::move(ds);
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600424}
425
426void LAST_BOUND_STATE::Reset() {
427 pipeline_state = nullptr;
428 pipeline_layout = VK_NULL_HANDLE;
429 if (push_descriptor_set) {
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700430 push_descriptor_set->Destroy();
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600431 }
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700432 push_descriptor_set.reset();
Jeremy Gebbenadb3eb02021-06-15 12:55:19 -0600433 per_set.clear();
434}