blob: ecdda5b20d6675abbd2a1c951e810ae0310d3984 [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
Mark Lobodzinski33a34b82019-04-25 11:38:36 -060044static inline void UpdateResourceTrackingOnDraw(CMD_BUFFER_STATE *pCB) { pCB->draw_data.push_back(pCB->current_draw_data); }
Jasper St. Pierre512613a2019-04-08 16:25:23 -070045
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;
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -060052 CMD_BUFFER_STATE *cb_state = GetCBState(cmd_buffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -070053 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
Mark Lobodzinski33a34b82019-04-25 11:38:36 -060065void CoreChecks::UpdateStateCmdDrawDispatchType(CMD_BUFFER_STATE *cb_state, VkPipelineBindPoint bind_point) {
Jasper St. Pierre512613a2019-04-08 16:25:23 -070066 UpdateDrawState(cb_state, bind_point);
67}
68
69// Generic function to handle state update for all CmdDraw* type functions
Mark Lobodzinski33a34b82019-04-25 11:38:36 -060070void CoreChecks::UpdateStateCmdDrawType(CMD_BUFFER_STATE *cb_state, VkPipelineBindPoint bind_point) {
Jasper St. Pierre512613a2019-04-08 16:25:23 -070071 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",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -060080 "VUID-vkCmdDraw-None-02700", "VUID-vkCmdDraw-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -070081}
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) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -060090 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -070091 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",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -060098 "VUID-vkCmdDrawIndexed-renderpass", "VUID-vkCmdDrawIndexed-None-02700",
99 "VUID-vkCmdDrawIndexed-commandBuffer-02701");
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600100 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700101 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) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600130 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700131 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",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600138 "VUID-vkCmdDrawIndirect-renderpass", "VUID-vkCmdDrawIndirect-None-02700",
139 "VUID-vkCmdDrawIndirect-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700140 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600141 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndirect()", "VUID-vkCmdDrawIndirect-buffer-02708");
142 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true, "VUID-vkCmdDrawIndirect-buffer-02709",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700143 "vkCmdDrawIndirect()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600144 if (count > 1) {
145 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndirect-drawCount-00476", stride,
146 "VkDrawIndirectCommand", sizeof(VkDrawIndirectCommand));
147 skip |=
148 ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndirect-drawCount-00488", stride,
149 "VkDrawIndirectCommand", sizeof(VkDrawIndirectCommand), count, offset, buffer_state);
150 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700151 // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the
152 // VkDrawIndirectCommand structures accessed by this command must be 0, which will require access to the contents of 'buffer'.
153 return skip;
154}
155
156void CoreChecks::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
157 uint32_t stride) {
158 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
159}
160
161void CoreChecks::PostCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
162 uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600163 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700164 BUFFER_STATE *buffer_state = GetBufferState(buffer);
165 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
166 AddCommandBufferBindingBuffer(cb_state, buffer_state);
167}
168
169bool CoreChecks::PreCallValidateCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
170 uint32_t count, uint32_t stride) {
171 bool skip = ValidateCmdDrawType(
172 commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECT, "vkCmdDrawIndexedIndirect()",
173 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDrawIndexedIndirect-commandBuffer-cmdpool", "VUID-vkCmdDrawIndexedIndirect-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600174 "VUID-vkCmdDrawIndexedIndirect-None-02700", "VUID-vkCmdDrawIndexedIndirect-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700175 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600176 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndexedIndirect()", "VUID-vkCmdDrawIndexedIndirect-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700177 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600178 "VUID-vkCmdDrawIndexedIndirect-buffer-02709", "vkCmdDrawIndexedIndirect()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700179 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600180 if (count > 1) {
181 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndexedIndirect-drawCount-00528", stride,
182 "VkDrawIndexedIndirectCommand", sizeof(VkDrawIndexedIndirectCommand));
183 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndexedIndirect-drawCount-00540", stride,
184 "VkDrawIndexedIndirectCommand", sizeof(VkDrawIndexedIndirectCommand), count, offset,
185 buffer_state);
186 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700187 // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the
188 // VkDrawIndexedIndirectCommand structures accessed by this command must be 0, which will require access to the contents of
189 // 'buffer'.
190 return skip;
191}
192
193void CoreChecks::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
194 uint32_t count, uint32_t stride) {
195 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
196}
197
198void CoreChecks::PostCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
199 uint32_t count, uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600200 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700201 BUFFER_STATE *buffer_state = GetBufferState(buffer);
202 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
203 AddCommandBufferBindingBuffer(cb_state, buffer_state);
204}
205
206bool CoreChecks::PreCallValidateCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Lockef39c0772019-04-03 14:40:02 -0600207 bool skip = false;
Lockef39c0772019-04-03 14:40:02 -0600208 skip |= ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH, "vkCmdDispatch()",
209 VK_QUEUE_COMPUTE_BIT, "VUID-vkCmdDispatch-commandBuffer-cmdpool", "VUID-vkCmdDispatch-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600210 "VUID-vkCmdDispatch-None-02700", kVUIDUndefined);
Lockef39c0772019-04-03 14:40:02 -0600211 return skip;
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700212}
213
214void CoreChecks::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
215 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
216}
217
218void CoreChecks::PostCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600219 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700220 UpdateStateCmdDrawDispatchType(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
221}
222
223bool CoreChecks::PreCallValidateCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
224 bool skip =
225 ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT, "vkCmdDispatchIndirect()",
226 VK_QUEUE_COMPUTE_BIT, "VUID-vkCmdDispatchIndirect-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600227 "VUID-vkCmdDispatchIndirect-renderpass", "VUID-vkCmdDispatchIndirect-None-02700", kVUIDUndefined);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700228 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600229 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDispatchIndirect()", "VUID-vkCmdDispatchIndirect-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700230 skip |=
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600231 ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true, "VUID-vkCmdDispatchIndirect-buffer-02709",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700232 "vkCmdDispatchIndirect()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700233 return skip;
234}
235
236void CoreChecks::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
237 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
238}
239
240void CoreChecks::PostCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600241 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700242 UpdateStateCmdDrawDispatchType(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
243 BUFFER_STATE *buffer_state = GetBufferState(buffer);
244 AddCommandBufferBindingBuffer(cb_state, buffer_state);
245}
246
247bool CoreChecks::PreCallValidateCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
248 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
249 uint32_t stride) {
250 bool skip = false;
251 if (offset & 3) {
252 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600253 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndirectCountKHR-offset-02710",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700254 "vkCmdDrawIndirectCountKHR() parameter, VkDeviceSize offset (0x%" PRIxLEAST64 "), is not a multiple of 4.",
255 offset);
256 }
257
258 if (countBufferOffset & 3) {
259 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600260 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndirectCountKHR-countBufferOffset-02716",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700261 "vkCmdDrawIndirectCountKHR() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64
262 "), is not a multiple of 4.",
263 countBufferOffset);
264 }
Lockee68ac652019-05-06 10:17:33 -0600265 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndirectCountKHR-stride-03110", stride,
266 "VkDrawIndirectCommand", sizeof(VkDrawIndirectCommand));
267 if (maxDrawCount > 1) {
268 BUFFER_STATE *buffer_state = GetBufferState(buffer);
269 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndirectCountKHR-maxDrawCount-03111", stride,
270 "VkDrawIndirectCommand", sizeof(VkDrawIndirectCommand), maxDrawCount, offset,
271 buffer_state);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700272 }
273
274 skip |= ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNTKHR,
275 "vkCmdDrawIndirectCountKHR()", VK_QUEUE_GRAPHICS_BIT,
276 "VUID-vkCmdDrawIndirectCountKHR-commandBuffer-cmdpool", "VUID-vkCmdDrawIndirectCountKHR-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600277 "VUID-vkCmdDrawIndirectCountKHR-None-02700", "VUID-vkCmdDrawIndirectCountKHR-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700278 BUFFER_STATE *buffer_state = GetBufferState(buffer);
279 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
280 skip |=
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600281 ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndirectCountKHR()", "VUID-vkCmdDrawIndirectCountKHR-buffer-02708");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700282 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawIndirectCountKHR()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600283 "VUID-vkCmdDrawIndirectCountKHR-countBuffer-02714");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700284 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600285 "VUID-vkCmdDrawIndirectCountKHR-buffer-02709", "vkCmdDrawIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700286 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
287 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600288 "VUID-vkCmdDrawIndirectCountKHR-countBuffer-02715", "vkCmdDrawIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700289 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700290 return skip;
291}
292
293void CoreChecks::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
294 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
295 uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600296 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700297 BUFFER_STATE *buffer_state = GetBufferState(buffer);
298 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
299 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
300 AddCommandBufferBindingBuffer(cb_state, buffer_state);
301 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
302}
303
304bool CoreChecks::PreCallValidateCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
305 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
306 uint32_t maxDrawCount, uint32_t stride) {
307 bool skip = false;
308 if (offset & 3) {
309 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600310 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndexedIndirectCountKHR-offset-02710",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700311 "vkCmdDrawIndexedIndirectCountKHR() parameter, VkDeviceSize offset (0x%" PRIxLEAST64
312 "), is not a multiple of 4.",
313 offset);
314 }
315
316 if (countBufferOffset & 3) {
317 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600318 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndexedIndirectCountKHR-countBufferOffset-02716",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700319 "vkCmdDrawIndexedIndirectCountKHR() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64
320 "), is not a multiple of 4.",
321 countBufferOffset);
322 }
323
Lockee68ac652019-05-06 10:17:33 -0600324 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndexedIndirectCountKHR-stride-03142", stride,
325 "VkDrawIndirectCommand", sizeof(VkDrawIndexedIndirectCommand));
326 if (maxDrawCount > 1) {
327 BUFFER_STATE *buffer_state = GetBufferState(buffer);
328 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndexedIndirectCountKHR-maxDrawCount-03143", stride,
329 "VkDrawIndirectCommand", sizeof(VkDrawIndexedIndirectCommand), maxDrawCount, offset,
330 buffer_state);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700331 }
332
333 skip |= ValidateCmdDrawType(
334 commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNTKHR, "vkCmdDrawIndexedIndirectCountKHR()",
335 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDrawIndexedIndirectCountKHR-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600336 "VUID-vkCmdDrawIndexedIndirectCountKHR-renderpass", "VUID-vkCmdDrawIndexedIndirectCountKHR-None-02700",
337 "VUID-vkCmdDrawIndexedIndirectCountKHR-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700338 BUFFER_STATE *buffer_state = GetBufferState(buffer);
339 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
340 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndexedIndirectCountKHR()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600341 "VUID-vkCmdDrawIndexedIndirectCountKHR-buffer-02708");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700342 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawIndexedIndirectCountKHR()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600343 "VUID-vkCmdDrawIndexedIndirectCountKHR-countBuffer-02714");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700344 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600345 "VUID-vkCmdDrawIndexedIndirectCountKHR-buffer-02709", "vkCmdDrawIndexedIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700346 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
347 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600348 "VUID-vkCmdDrawIndexedIndirectCountKHR-countBuffer-02715",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700349 "vkCmdDrawIndexedIndirectCountKHR()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700350 return skip;
351}
352
353void CoreChecks::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
354 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
355 uint32_t maxDrawCount, uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600356 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700357 BUFFER_STATE *buffer_state = GetBufferState(buffer);
358 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
359 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
360 AddCommandBufferBindingBuffer(cb_state, buffer_state);
361 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
362}
363
364bool CoreChecks::PreCallValidateCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
365 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV,
366 "vkCmdDrawMeshTasksNV()", VK_QUEUE_GRAPHICS_BIT,
367 "VUID-vkCmdDrawMeshTasksNV-commandBuffer-cmdpool", "VUID-vkCmdDrawMeshTasksNV-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600368 "VUID-vkCmdDrawMeshTasksNV-None-02700", "VUID-vkCmdDrawMeshTasksNV-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700369 return skip;
370}
371
372void CoreChecks::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600373 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700374 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
375}
376
377bool CoreChecks::PreCallValidateCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
378 uint32_t drawCount, uint32_t stride) {
379 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV,
380 "vkCmdDrawMeshTasksIndirectNV()", VK_QUEUE_GRAPHICS_BIT,
381 "VUID-vkCmdDrawMeshTasksIndirectNV-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600382 "VUID-vkCmdDrawMeshTasksIndirectNV-renderpass", "VUID-vkCmdDrawMeshTasksIndirectNV-None-02700",
383 "VUID-vkCmdDrawMeshTasksIndirectNV-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700384 BUFFER_STATE *buffer_state = GetBufferState(buffer);
385 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawMeshTasksIndirectNV()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600386 "VUID-vkCmdDrawMeshTasksIndirectNV-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700387 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600388 "VUID-vkCmdDrawMeshTasksIndirectNV-buffer-02709", "vkCmdDrawMeshTasksIndirectNV()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700389 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600390 if (drawCount > 1) {
391 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02146", stride,
392 "VkDrawMeshTasksIndirectCommandNV", sizeof(VkDrawMeshTasksIndirectCommandNV));
393 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02157", stride,
394 "VkDrawMeshTasksIndirectCommandNV", sizeof(VkDrawMeshTasksIndirectCommandNV),
395 drawCount, offset, buffer_state);
396 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700397 return skip;
398}
399
400void CoreChecks::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
401 uint32_t drawCount, uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600402 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700403 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
404 BUFFER_STATE *buffer_state = GetBufferState(buffer);
405 if (buffer_state) {
406 AddCommandBufferBindingBuffer(cb_state, buffer_state);
407 }
408}
409
410bool CoreChecks::PreCallValidateCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
411 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
412 uint32_t maxDrawCount, uint32_t stride) {
413 bool skip = ValidateCmdDrawType(
414 commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV,
415 "vkCmdDrawMeshTasksIndirectCountNV()", VK_QUEUE_GRAPHICS_BIT,
416 "VUID-vkCmdDrawMeshTasksIndirectCountNV-commandBuffer-cmdpool", "VUID-vkCmdDrawMeshTasksIndirectCountNV-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600417 "VUID-vkCmdDrawMeshTasksIndirectCountNV-None-02700", "VUID-vkCmdDrawMeshTasksIndirectCountNV-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700418 BUFFER_STATE *buffer_state = GetBufferState(buffer);
419 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
420 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawMeshTasksIndirectCountNV()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600421 "VUID-vkCmdDrawMeshTasksIndirectCountNV-buffer-02708");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700422 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawMeshTasksIndirectCountNV()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600423 "VUID-vkCmdDrawMeshTasksIndirectCountNV-countBuffer-02714");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700424 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600425 "VUID-vkCmdDrawMeshTasksIndirectCountNV-buffer-02709", "vkCmdDrawIndexedIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700426 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
427 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600428 "VUID-vkCmdDrawMeshTasksIndirectCountNV-countBuffer-02715",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700429 "vkCmdDrawIndexedIndirectCountKHR()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600430 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawMeshTasksIndirectCountNV-stride-02182", stride,
431 "VkDrawMeshTasksIndirectCommandNV", sizeof(VkDrawMeshTasksIndirectCommandNV));
432 if (maxDrawCount > 1) {
433 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawMeshTasksIndirectCountNV-maxDrawCount-02183", stride,
434 "VkDrawMeshTasksIndirectCommandNV", sizeof(VkDrawMeshTasksIndirectCommandNV),
435 maxDrawCount, offset, buffer_state);
436 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700437 return skip;
438}
439
440void CoreChecks::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
441 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
442 uint32_t maxDrawCount, uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600443 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700444 BUFFER_STATE *buffer_state = GetBufferState(buffer);
445 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
446 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
447 if (buffer_state) {
448 AddCommandBufferBindingBuffer(cb_state, buffer_state);
449 }
450 if (count_buffer_state) {
451 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
452 }
453}