blob: 3bd5a5101f8eb7a18851569fd15ec94a60d7f523 [file] [log] [blame]
Jasper St. Pierre512613a2019-04-08 16:25:23 -07001/* Copyright (c) 2015-2019 The Khronos Group Inc.
2 * Copyright (c) 2015-2019 Valve Corporation
3 * Copyright (c) 2015-2019 LunarG, Inc.
4 * Copyright (C) 2015-2019 Google Inc.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Cody Northrop <cnorthrop@google.com>
19 * Author: Michael Lentine <mlentine@google.com>
20 * Author: Tobin Ehlis <tobine@google.com>
21 * Author: Chia-I Wu <olv@google.com>
22 * Author: Chris Forbes <chrisf@ijw.co.nz>
23 * Author: Mark Lobodzinski <mark@lunarg.com>
24 * Author: Ian Elliott <ianelliott@google.com>
25 * Author: Dave Houlton <daveh@lunarg.com>
26 * Author: Dustin Graves <dustin@lunarg.com>
27 * Author: Jeremy Hayes <jeremy@lunarg.com>
28 * Author: Jon Ashburn <jon@lunarg.com>
29 * Author: Karl Schultz <karl@lunarg.com>
30 * Author: Mark Young <marky@lunarg.com>
31 * Author: Mike Schuchardt <mikes@lunarg.com>
32 * Author: Mike Weiblen <mikew@lunarg.com>
33 * Author: Tony Barbour <tony@LunarG.com>
34 * Author: John Zulauf <jzulauf@lunarg.com>
35 * Author: Shannon McPherson <shannon@lunarg.com>
36 */
37
38// Allow use of STL min and max functions in Windows
39#define NOMINMAX
40
41#include "chassis.h"
42#include "core_validation.h"
43
44static inline void UpdateResourceTrackingOnDraw(GLOBAL_CB_NODE *pCB) { pCB->draw_data.push_back(pCB->current_draw_data); }
45
46// Generic function to handle validation for all CmdDraw* type functions
47bool CoreChecks::ValidateCmdDrawType(VkCommandBuffer cmd_buffer, bool indexed, VkPipelineBindPoint bind_point, CMD_TYPE cmd_type,
48 const char *caller, VkQueueFlags queue_flags, const char *queue_flag_code,
49 const char *renderpass_msg_code, const char *pipebound_msg_code,
50 const char *dynamic_state_msg_code) {
51 bool skip = false;
52 GLOBAL_CB_NODE *cb_state = GetCBNode(cmd_buffer);
53 if (cb_state) {
54 skip |= ValidateCmdQueueFlags(cb_state, caller, queue_flags, queue_flag_code);
55 skip |= ValidateCmd(cb_state, cmd_type, caller);
56 skip |=
57 ValidateCmdBufDrawState(cb_state, cmd_type, indexed, bind_point, caller, pipebound_msg_code, dynamic_state_msg_code);
58 skip |= (VK_PIPELINE_BIND_POINT_GRAPHICS == bind_point) ? OutsideRenderPass(cb_state, caller, renderpass_msg_code)
59 : InsideRenderPass(cb_state, caller, renderpass_msg_code);
60 }
61 return skip;
62}
63
64// Generic function to handle state update for all CmdDraw* and CmdDispatch* type functions
65void CoreChecks::UpdateStateCmdDrawDispatchType(GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) {
66 UpdateDrawState(cb_state, bind_point);
67}
68
69// Generic function to handle state update for all CmdDraw* type functions
70void CoreChecks::UpdateStateCmdDrawType(GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) {
71 UpdateStateCmdDrawDispatchType(cb_state, bind_point);
72 UpdateResourceTrackingOnDraw(cb_state);
73 cb_state->hasDrawCmd = true;
74}
75
76bool CoreChecks::PreCallValidateCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
77 uint32_t firstVertex, uint32_t firstInstance) {
78 return ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAW, "vkCmdDraw()",
79 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDraw-commandBuffer-cmdpool", "VUID-vkCmdDraw-renderpass",
80 "VUID-vkCmdDraw-None-00442", "VUID-vkCmdDraw-None-00443");
81}
82
83void CoreChecks::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
84 uint32_t firstVertex, uint32_t firstInstance) {
85 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
86}
87
88void CoreChecks::PostCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
89 uint32_t firstVertex, uint32_t firstInstance) {
90 GLOBAL_CB_NODE *cb_state = GetCBNode(commandBuffer);
91 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
92}
93
94bool CoreChecks::PreCallValidateCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
95 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
96 bool skip = ValidateCmdDrawType(commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXED, "vkCmdDrawIndexed()",
97 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDrawIndexed-commandBuffer-cmdpool",
98 "VUID-vkCmdDrawIndexed-renderpass", "VUID-vkCmdDrawIndexed-None-00461",
99 "VUID-vkCmdDrawIndexed-None-00462");
100 GLOBAL_CB_NODE *cb_state = GetCBNode(commandBuffer);
101 if (!skip && (cb_state->status & CBSTATUS_INDEX_BUFFER_BOUND)) {
102 unsigned int index_size = 0;
103 const auto &index_buffer_binding = cb_state->index_buffer_binding;
104 if (index_buffer_binding.index_type == VK_INDEX_TYPE_UINT16) {
105 index_size = 2;
106 } else if (index_buffer_binding.index_type == VK_INDEX_TYPE_UINT32) {
107 index_size = 4;
108 }
109 VkDeviceSize end_offset = (index_size * ((VkDeviceSize)firstIndex + indexCount)) + index_buffer_binding.offset;
110 if (end_offset > index_buffer_binding.size) {
111 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
112 HandleToUint64(index_buffer_binding.buffer), "VUID-vkCmdDrawIndexed-indexSize-00463",
113 "vkCmdDrawIndexed() index size (%d) * (firstIndex (%d) + indexCount (%d)) "
114 "+ binding offset (%" PRIuLEAST64 ") = an ending offset of %" PRIuLEAST64
115 " bytes, "
116 "which is greater than the index buffer size (%" PRIuLEAST64 ").",
117 index_size, firstIndex, indexCount, index_buffer_binding.offset, end_offset, index_buffer_binding.size);
118 }
119 }
120 return skip;
121}
122
123void CoreChecks::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
124 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
125 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
126}
127
128void CoreChecks::PostCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
129 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
130 GLOBAL_CB_NODE *cb_state = GetCBNode(commandBuffer);
131 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
132}
133
134bool CoreChecks::PreCallValidateCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
135 uint32_t stride) {
136 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECT, "vkCmdDrawIndirect()",
137 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDrawIndirect-commandBuffer-cmdpool",
138 "VUID-vkCmdDrawIndirect-renderpass", "VUID-vkCmdDrawIndirect-None-00485",
139 "VUID-vkCmdDrawIndirect-None-00486");
140 BUFFER_STATE *buffer_state = GetBufferState(buffer);
141 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndirect()", "VUID-vkCmdDrawIndirect-buffer-00474");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700142 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true, "VUID-vkCmdDrawIndirect-buffer-01660",
143 "vkCmdDrawIndirect()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700144 // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the
145 // VkDrawIndirectCommand structures accessed by this command must be 0, which will require access to the contents of 'buffer'.
146 return skip;
147}
148
149void CoreChecks::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
150 uint32_t stride) {
151 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
152}
153
154void CoreChecks::PostCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
155 uint32_t stride) {
156 GLOBAL_CB_NODE *cb_state = GetCBNode(commandBuffer);
157 BUFFER_STATE *buffer_state = GetBufferState(buffer);
158 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
159 AddCommandBufferBindingBuffer(cb_state, buffer_state);
160}
161
162bool CoreChecks::PreCallValidateCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
163 uint32_t count, uint32_t stride) {
164 bool skip = ValidateCmdDrawType(
165 commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECT, "vkCmdDrawIndexedIndirect()",
166 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDrawIndexedIndirect-commandBuffer-cmdpool", "VUID-vkCmdDrawIndexedIndirect-renderpass",
167 "VUID-vkCmdDrawIndexedIndirect-None-00537", "VUID-vkCmdDrawIndexedIndirect-None-00538");
168 BUFFER_STATE *buffer_state = GetBufferState(buffer);
169 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndexedIndirect()", "VUID-vkCmdDrawIndexedIndirect-buffer-00526");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700170 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
171 "VUID-vkCmdDrawIndexedIndirect-buffer-01665", "vkCmdDrawIndexedIndirect()",
172 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700173 // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the
174 // VkDrawIndexedIndirectCommand structures accessed by this command must be 0, which will require access to the contents of
175 // 'buffer'.
176 return skip;
177}
178
179void CoreChecks::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
180 uint32_t count, uint32_t stride) {
181 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
182}
183
184void CoreChecks::PostCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
185 uint32_t count, uint32_t stride) {
186 GLOBAL_CB_NODE *cb_state = GetCBNode(commandBuffer);
187 BUFFER_STATE *buffer_state = GetBufferState(buffer);
188 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
189 AddCommandBufferBindingBuffer(cb_state, buffer_state);
190}
191
192bool CoreChecks::PreCallValidateCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
193 return ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH, "vkCmdDispatch()",
194 VK_QUEUE_COMPUTE_BIT, "VUID-vkCmdDispatch-commandBuffer-cmdpool", "VUID-vkCmdDispatch-renderpass",
195 "VUID-vkCmdDispatch-None-00391", kVUIDUndefined);
196}
197
198void CoreChecks::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
199 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
200}
201
202void CoreChecks::PostCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
203 GLOBAL_CB_NODE *cb_state = GetCBNode(commandBuffer);
204 UpdateStateCmdDrawDispatchType(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
205}
206
207bool CoreChecks::PreCallValidateCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
208 bool skip =
209 ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT, "vkCmdDispatchIndirect()",
210 VK_QUEUE_COMPUTE_BIT, "VUID-vkCmdDispatchIndirect-commandBuffer-cmdpool",
211 "VUID-vkCmdDispatchIndirect-renderpass", "VUID-vkCmdDispatchIndirect-None-00404", kVUIDUndefined);
212 BUFFER_STATE *buffer_state = GetBufferState(buffer);
213 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDispatchIndirect()", "VUID-vkCmdDispatchIndirect-buffer-00401");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700214 skip |=
215 ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true, "VUID-vkCmdDispatchIndirect-buffer-00405",
216 "vkCmdDispatchIndirect()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700217 return skip;
218}
219
220void CoreChecks::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
221 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
222}
223
224void CoreChecks::PostCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
225 GLOBAL_CB_NODE *cb_state = GetCBNode(commandBuffer);
226 UpdateStateCmdDrawDispatchType(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
227 BUFFER_STATE *buffer_state = GetBufferState(buffer);
228 AddCommandBufferBindingBuffer(cb_state, buffer_state);
229}
230
231bool CoreChecks::PreCallValidateCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
232 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
233 uint32_t stride) {
234 bool skip = false;
235 if (offset & 3) {
236 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
237 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndirectCountKHR-offset-03108",
238 "vkCmdDrawIndirectCountKHR() parameter, VkDeviceSize offset (0x%" PRIxLEAST64 "), is not a multiple of 4.",
239 offset);
240 }
241
242 if (countBufferOffset & 3) {
243 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
244 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndirectCountKHR-countBufferOffset-03109",
245 "vkCmdDrawIndirectCountKHR() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64
246 "), is not a multiple of 4.",
247 countBufferOffset);
248 }
249
250 if ((stride & 3) || stride < sizeof(VkDrawIndirectCommand)) {
251 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
252 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndirectCountKHR-stride-03110",
253 "vkCmdDrawIndirectCountKHR() parameter, uint32_t stride (0x%" PRIxLEAST32
254 "), is not a multiple of 4 or smaller than sizeof (VkDrawIndirectCommand).",
255 stride);
256 }
257
258 skip |= ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNTKHR,
259 "vkCmdDrawIndirectCountKHR()", VK_QUEUE_GRAPHICS_BIT,
260 "VUID-vkCmdDrawIndirectCountKHR-commandBuffer-cmdpool", "VUID-vkCmdDrawIndirectCountKHR-renderpass",
261 "VUID-vkCmdDrawIndirectCountKHR-None-03119", "VUID-vkCmdDrawIndirectCountKHR-None-03120");
262 BUFFER_STATE *buffer_state = GetBufferState(buffer);
263 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
264 skip |=
265 ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndirectCountKHR()", "VUID-vkCmdDrawIndirectCountKHR-buffer-03104");
266 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawIndirectCountKHR()",
267 "VUID-vkCmdDrawIndirectCountKHR-countBuffer-03106");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700268 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
269 "VUID-vkCmdDrawIndirectCountKHR-buffer-03105", "vkCmdDrawIndirectCountKHR()",
270 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
271 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
272 "VUID-vkCmdDrawIndirectCountKHR-countBuffer-03107", "vkCmdDrawIndirectCountKHR()",
273 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700274 return skip;
275}
276
277void CoreChecks::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
278 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
279 uint32_t stride) {
280 GLOBAL_CB_NODE *cb_state = GetCBNode(commandBuffer);
281 BUFFER_STATE *buffer_state = GetBufferState(buffer);
282 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
283 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
284 AddCommandBufferBindingBuffer(cb_state, buffer_state);
285 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
286}
287
288bool CoreChecks::PreCallValidateCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
289 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
290 uint32_t maxDrawCount, uint32_t stride) {
291 bool skip = false;
292 if (offset & 3) {
293 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
294 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndexedIndirectCountKHR-offset-03140",
295 "vkCmdDrawIndexedIndirectCountKHR() parameter, VkDeviceSize offset (0x%" PRIxLEAST64
296 "), is not a multiple of 4.",
297 offset);
298 }
299
300 if (countBufferOffset & 3) {
301 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
302 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndexedIndirectCountKHR-countBufferOffset-03141",
303 "vkCmdDrawIndexedIndirectCountKHR() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64
304 "), is not a multiple of 4.",
305 countBufferOffset);
306 }
307
308 if ((stride & 3) || stride < sizeof(VkDrawIndexedIndirectCommand)) {
309 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
310 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndexedIndirectCountKHR-stride-03142",
311 "vkCmdDrawIndexedIndirectCountKHR() parameter, uint32_t stride (0x%" PRIxLEAST32
312 "), is not a multiple of 4 or smaller than sizeof (VkDrawIndexedIndirectCommand).",
313 stride);
314 }
315
316 skip |= ValidateCmdDrawType(
317 commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNTKHR, "vkCmdDrawIndexedIndirectCountKHR()",
318 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDrawIndexedIndirectCountKHR-commandBuffer-cmdpool",
319 "VUID-vkCmdDrawIndexedIndirectCountKHR-renderpass", "VUID-vkCmdDrawIndexedIndirectCountKHR-None-03151",
320 "VUID-vkCmdDrawIndexedIndirectCountKHR-None-03152");
321 BUFFER_STATE *buffer_state = GetBufferState(buffer);
322 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
323 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndexedIndirectCountKHR()",
324 "VUID-vkCmdDrawIndexedIndirectCountKHR-buffer-03136");
325 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawIndexedIndirectCountKHR()",
326 "VUID-vkCmdDrawIndexedIndirectCountKHR-countBuffer-03138");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700327 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
328 "VUID-vkCmdDrawIndexedIndirectCountKHR-buffer-03137", "vkCmdDrawIndexedIndirectCountKHR()",
329 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
330 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
331 "VUID-vkCmdDrawIndexedIndirectCountKHR-countBuffer-03139",
332 "vkCmdDrawIndexedIndirectCountKHR()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700333 return skip;
334}
335
336void CoreChecks::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
337 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
338 uint32_t maxDrawCount, uint32_t stride) {
339 GLOBAL_CB_NODE *cb_state = GetCBNode(commandBuffer);
340 BUFFER_STATE *buffer_state = GetBufferState(buffer);
341 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
342 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
343 AddCommandBufferBindingBuffer(cb_state, buffer_state);
344 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
345}
346
347bool CoreChecks::PreCallValidateCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
348 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV,
349 "vkCmdDrawMeshTasksNV()", VK_QUEUE_GRAPHICS_BIT,
350 "VUID-vkCmdDrawMeshTasksNV-commandBuffer-cmdpool", "VUID-vkCmdDrawMeshTasksNV-renderpass",
351 "VUID-vkCmdDrawMeshTasksNV-None-02125", "VUID-vkCmdDrawMeshTasksNV-None-02126");
352 return skip;
353}
354
355void CoreChecks::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
356 GLOBAL_CB_NODE *cb_state = GetCBNode(commandBuffer);
357 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
358}
359
360bool CoreChecks::PreCallValidateCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
361 uint32_t drawCount, uint32_t stride) {
362 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV,
363 "vkCmdDrawMeshTasksIndirectNV()", VK_QUEUE_GRAPHICS_BIT,
364 "VUID-vkCmdDrawMeshTasksIndirectNV-commandBuffer-cmdpool",
365 "VUID-vkCmdDrawMeshTasksIndirectNV-renderpass", "VUID-vkCmdDrawMeshTasksIndirectNV-None-02154",
366 "VUID-vkCmdDrawMeshTasksIndirectNV-None-02155");
367 BUFFER_STATE *buffer_state = GetBufferState(buffer);
368 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawMeshTasksIndirectNV()",
369 "VUID-vkCmdDrawMeshTasksIndirectNV-buffer-02143");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700370 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
371 "VUID-vkCmdDrawMeshTasksIndirectNV-buffer-02144", "vkCmdDrawMeshTasksIndirectNV()",
372 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700373 return skip;
374}
375
376void CoreChecks::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
377 uint32_t drawCount, uint32_t stride) {
378 GLOBAL_CB_NODE *cb_state = GetCBNode(commandBuffer);
379 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
380 BUFFER_STATE *buffer_state = GetBufferState(buffer);
381 if (buffer_state) {
382 AddCommandBufferBindingBuffer(cb_state, buffer_state);
383 }
384}
385
386bool CoreChecks::PreCallValidateCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
387 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
388 uint32_t maxDrawCount, uint32_t stride) {
389 bool skip = ValidateCmdDrawType(
390 commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV,
391 "vkCmdDrawMeshTasksIndirectCountNV()", VK_QUEUE_GRAPHICS_BIT,
392 "VUID-vkCmdDrawMeshTasksIndirectCountNV-commandBuffer-cmdpool", "VUID-vkCmdDrawMeshTasksIndirectCountNV-renderpass",
393 "VUID-vkCmdDrawMeshTasksIndirectCountNV-None-02189", "VUID-vkCmdDrawMeshTasksIndirectCountNV-None-02190");
394 BUFFER_STATE *buffer_state = GetBufferState(buffer);
395 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
396 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawMeshTasksIndirectCountNV()",
397 "VUID-vkCmdDrawMeshTasksIndirectCountNV-buffer-02176");
398 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawMeshTasksIndirectCountNV()",
399 "VUID-vkCmdDrawMeshTasksIndirectCountNV-countBuffer-02178");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700400 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
401 "VUID-vkCmdDrawMeshTasksIndirectCountNV-buffer-02177", "vkCmdDrawIndexedIndirectCountKHR()",
402 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
403 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
404 "VUID-vkCmdDrawMeshTasksIndirectCountNV-countBuffer-02179",
405 "vkCmdDrawIndexedIndirectCountKHR()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700406 return skip;
407}
408
409void CoreChecks::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
410 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
411 uint32_t maxDrawCount, uint32_t stride) {
412 GLOBAL_CB_NODE *cb_state = GetCBNode(commandBuffer);
413 BUFFER_STATE *buffer_state = GetBufferState(buffer);
414 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
415 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
416 if (buffer_state) {
417 AddCommandBufferBindingBuffer(cb_state, buffer_state);
418 }
419 if (count_buffer_state) {
420 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
421 }
422}