blob: efcd292c17ffd5109b075b98b1b0f1ecd553b327 [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 Lobodzinski89e997a2019-07-16 17:04:16 -060044static inline void UpdateResourceTrackingOnDraw(CMD_BUFFER_STATE *pCB) {
Mark Lobodzinski7f2abf02019-07-16 17:07:08 -060045 pCB->cb_vertex_buffer_binding_info.push_back(pCB->current_vertex_buffer_binding_info);
Mark Lobodzinski89e997a2019-07-16 17:04:16 -060046}
Jasper St. Pierre512613a2019-04-08 16:25:23 -070047
48// Generic function to handle validation for all CmdDraw* type functions
49bool CoreChecks::ValidateCmdDrawType(VkCommandBuffer cmd_buffer, bool indexed, VkPipelineBindPoint bind_point, CMD_TYPE cmd_type,
50 const char *caller, VkQueueFlags queue_flags, const char *queue_flag_code,
51 const char *renderpass_msg_code, const char *pipebound_msg_code,
52 const char *dynamic_state_msg_code) {
53 bool skip = false;
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -060054 CMD_BUFFER_STATE *cb_state = GetCBState(cmd_buffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -070055 if (cb_state) {
56 skip |= ValidateCmdQueueFlags(cb_state, caller, queue_flags, queue_flag_code);
57 skip |= ValidateCmd(cb_state, cmd_type, caller);
58 skip |=
59 ValidateCmdBufDrawState(cb_state, cmd_type, indexed, bind_point, caller, pipebound_msg_code, dynamic_state_msg_code);
60 skip |= (VK_PIPELINE_BIND_POINT_GRAPHICS == bind_point) ? OutsideRenderPass(cb_state, caller, renderpass_msg_code)
61 : InsideRenderPass(cb_state, caller, renderpass_msg_code);
62 }
63 return skip;
64}
65
66// Generic function to handle state update for all CmdDraw* and CmdDispatch* type functions
Mark Lobodzinski33a34b82019-04-25 11:38:36 -060067void CoreChecks::UpdateStateCmdDrawDispatchType(CMD_BUFFER_STATE *cb_state, VkPipelineBindPoint bind_point) {
Jasper St. Pierre512613a2019-04-08 16:25:23 -070068 UpdateDrawState(cb_state, bind_point);
69}
70
71// Generic function to handle state update for all CmdDraw* type functions
Mark Lobodzinski33a34b82019-04-25 11:38:36 -060072void CoreChecks::UpdateStateCmdDrawType(CMD_BUFFER_STATE *cb_state, VkPipelineBindPoint bind_point) {
Jasper St. Pierre512613a2019-04-08 16:25:23 -070073 UpdateStateCmdDrawDispatchType(cb_state, bind_point);
74 UpdateResourceTrackingOnDraw(cb_state);
75 cb_state->hasDrawCmd = true;
76}
77
78bool CoreChecks::PreCallValidateCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
79 uint32_t firstVertex, uint32_t firstInstance) {
80 return ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAW, "vkCmdDraw()",
81 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDraw-commandBuffer-cmdpool", "VUID-vkCmdDraw-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -060082 "VUID-vkCmdDraw-None-02700", "VUID-vkCmdDraw-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -070083}
84
85void CoreChecks::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
86 uint32_t firstVertex, uint32_t firstInstance) {
87 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
88}
89
90void CoreChecks::PostCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
91 uint32_t firstVertex, uint32_t firstInstance) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -060092 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -070093 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
94}
95
96bool CoreChecks::PreCallValidateCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
97 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
98 bool skip = ValidateCmdDrawType(commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXED, "vkCmdDrawIndexed()",
99 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDrawIndexed-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600100 "VUID-vkCmdDrawIndexed-renderpass", "VUID-vkCmdDrawIndexed-None-02700",
101 "VUID-vkCmdDrawIndexed-commandBuffer-02701");
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600102 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700103 if (!skip && (cb_state->status & CBSTATUS_INDEX_BUFFER_BOUND)) {
104 unsigned int index_size = 0;
105 const auto &index_buffer_binding = cb_state->index_buffer_binding;
106 if (index_buffer_binding.index_type == VK_INDEX_TYPE_UINT16) {
107 index_size = 2;
108 } else if (index_buffer_binding.index_type == VK_INDEX_TYPE_UINT32) {
109 index_size = 4;
110 }
111 VkDeviceSize end_offset = (index_size * ((VkDeviceSize)firstIndex + indexCount)) + index_buffer_binding.offset;
112 if (end_offset > index_buffer_binding.size) {
113 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
114 HandleToUint64(index_buffer_binding.buffer), "VUID-vkCmdDrawIndexed-indexSize-00463",
115 "vkCmdDrawIndexed() index size (%d) * (firstIndex (%d) + indexCount (%d)) "
116 "+ binding offset (%" PRIuLEAST64 ") = an ending offset of %" PRIuLEAST64
117 " bytes, "
118 "which is greater than the index buffer size (%" PRIuLEAST64 ").",
119 index_size, firstIndex, indexCount, index_buffer_binding.offset, end_offset, index_buffer_binding.size);
120 }
121 }
122 return skip;
123}
124
125void CoreChecks::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
126 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
127 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
128}
129
130void CoreChecks::PostCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
131 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600132 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700133 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
134}
135
136bool CoreChecks::PreCallValidateCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
137 uint32_t stride) {
138 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECT, "vkCmdDrawIndirect()",
139 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDrawIndirect-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600140 "VUID-vkCmdDrawIndirect-renderpass", "VUID-vkCmdDrawIndirect-None-02700",
141 "VUID-vkCmdDrawIndirect-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700142 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600143 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndirect()", "VUID-vkCmdDrawIndirect-buffer-02708");
144 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true, "VUID-vkCmdDrawIndirect-buffer-02709",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700145 "vkCmdDrawIndirect()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600146 if (count > 1) {
147 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndirect-drawCount-00476", stride,
148 "VkDrawIndirectCommand", sizeof(VkDrawIndirectCommand));
149 skip |=
150 ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndirect-drawCount-00488", stride,
151 "VkDrawIndirectCommand", sizeof(VkDrawIndirectCommand), count, offset, buffer_state);
152 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700153 // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the
154 // VkDrawIndirectCommand structures accessed by this command must be 0, which will require access to the contents of 'buffer'.
155 return skip;
156}
157
158void CoreChecks::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
159 uint32_t stride) {
160 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
161}
162
163void CoreChecks::PostCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
164 uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600165 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700166 BUFFER_STATE *buffer_state = GetBufferState(buffer);
167 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
168 AddCommandBufferBindingBuffer(cb_state, buffer_state);
169}
170
171bool CoreChecks::PreCallValidateCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
172 uint32_t count, uint32_t stride) {
173 bool skip = ValidateCmdDrawType(
174 commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECT, "vkCmdDrawIndexedIndirect()",
175 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDrawIndexedIndirect-commandBuffer-cmdpool", "VUID-vkCmdDrawIndexedIndirect-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600176 "VUID-vkCmdDrawIndexedIndirect-None-02700", "VUID-vkCmdDrawIndexedIndirect-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700177 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600178 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndexedIndirect()", "VUID-vkCmdDrawIndexedIndirect-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700179 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600180 "VUID-vkCmdDrawIndexedIndirect-buffer-02709", "vkCmdDrawIndexedIndirect()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700181 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600182 if (count > 1) {
183 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndexedIndirect-drawCount-00528", stride,
184 "VkDrawIndexedIndirectCommand", sizeof(VkDrawIndexedIndirectCommand));
185 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndexedIndirect-drawCount-00540", stride,
186 "VkDrawIndexedIndirectCommand", sizeof(VkDrawIndexedIndirectCommand), count, offset,
187 buffer_state);
188 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700189 // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the
190 // VkDrawIndexedIndirectCommand structures accessed by this command must be 0, which will require access to the contents of
191 // 'buffer'.
192 return skip;
193}
194
195void CoreChecks::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
196 uint32_t count, uint32_t stride) {
197 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
198}
199
200void CoreChecks::PostCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
201 uint32_t count, uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600202 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700203 BUFFER_STATE *buffer_state = GetBufferState(buffer);
204 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
205 AddCommandBufferBindingBuffer(cb_state, buffer_state);
206}
207
208bool CoreChecks::PreCallValidateCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Lockef39c0772019-04-03 14:40:02 -0600209 bool skip = false;
Lockef39c0772019-04-03 14:40:02 -0600210 skip |= ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH, "vkCmdDispatch()",
211 VK_QUEUE_COMPUTE_BIT, "VUID-vkCmdDispatch-commandBuffer-cmdpool", "VUID-vkCmdDispatch-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600212 "VUID-vkCmdDispatch-None-02700", kVUIDUndefined);
Lockef39c0772019-04-03 14:40:02 -0600213 return skip;
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700214}
215
216void CoreChecks::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
217 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
218}
219
220void CoreChecks::PostCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600221 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700222 UpdateStateCmdDrawDispatchType(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
223}
224
225bool CoreChecks::PreCallValidateCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
226 bool skip =
227 ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT, "vkCmdDispatchIndirect()",
228 VK_QUEUE_COMPUTE_BIT, "VUID-vkCmdDispatchIndirect-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600229 "VUID-vkCmdDispatchIndirect-renderpass", "VUID-vkCmdDispatchIndirect-None-02700", kVUIDUndefined);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700230 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600231 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDispatchIndirect()", "VUID-vkCmdDispatchIndirect-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700232 skip |=
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600233 ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true, "VUID-vkCmdDispatchIndirect-buffer-02709",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700234 "vkCmdDispatchIndirect()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700235 return skip;
236}
237
238void CoreChecks::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
239 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
240}
241
242void CoreChecks::PostCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600243 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700244 UpdateStateCmdDrawDispatchType(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
245 BUFFER_STATE *buffer_state = GetBufferState(buffer);
246 AddCommandBufferBindingBuffer(cb_state, buffer_state);
247}
248
249bool CoreChecks::PreCallValidateCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
250 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
251 uint32_t stride) {
252 bool skip = false;
253 if (offset & 3) {
254 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 -0600255 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndirectCountKHR-offset-02710",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700256 "vkCmdDrawIndirectCountKHR() parameter, VkDeviceSize offset (0x%" PRIxLEAST64 "), is not a multiple of 4.",
257 offset);
258 }
259
260 if (countBufferOffset & 3) {
261 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 -0600262 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndirectCountKHR-countBufferOffset-02716",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700263 "vkCmdDrawIndirectCountKHR() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64
264 "), is not a multiple of 4.",
265 countBufferOffset);
266 }
Lockee68ac652019-05-06 10:17:33 -0600267 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndirectCountKHR-stride-03110", stride,
268 "VkDrawIndirectCommand", sizeof(VkDrawIndirectCommand));
269 if (maxDrawCount > 1) {
270 BUFFER_STATE *buffer_state = GetBufferState(buffer);
271 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndirectCountKHR-maxDrawCount-03111", stride,
272 "VkDrawIndirectCommand", sizeof(VkDrawIndirectCommand), maxDrawCount, offset,
273 buffer_state);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700274 }
275
276 skip |= ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNTKHR,
277 "vkCmdDrawIndirectCountKHR()", VK_QUEUE_GRAPHICS_BIT,
278 "VUID-vkCmdDrawIndirectCountKHR-commandBuffer-cmdpool", "VUID-vkCmdDrawIndirectCountKHR-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600279 "VUID-vkCmdDrawIndirectCountKHR-None-02700", "VUID-vkCmdDrawIndirectCountKHR-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700280 BUFFER_STATE *buffer_state = GetBufferState(buffer);
281 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
282 skip |=
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600283 ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndirectCountKHR()", "VUID-vkCmdDrawIndirectCountKHR-buffer-02708");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700284 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawIndirectCountKHR()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600285 "VUID-vkCmdDrawIndirectCountKHR-countBuffer-02714");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700286 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600287 "VUID-vkCmdDrawIndirectCountKHR-buffer-02709", "vkCmdDrawIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700288 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
289 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600290 "VUID-vkCmdDrawIndirectCountKHR-countBuffer-02715", "vkCmdDrawIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700291 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700292 return skip;
293}
294
295void CoreChecks::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
296 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
297 uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600298 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700299 BUFFER_STATE *buffer_state = GetBufferState(buffer);
300 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
301 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
302 AddCommandBufferBindingBuffer(cb_state, buffer_state);
303 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
304}
305
306bool CoreChecks::PreCallValidateCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
307 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
308 uint32_t maxDrawCount, uint32_t stride) {
309 bool skip = false;
310 if (offset & 3) {
311 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 -0600312 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndexedIndirectCountKHR-offset-02710",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700313 "vkCmdDrawIndexedIndirectCountKHR() parameter, VkDeviceSize offset (0x%" PRIxLEAST64
314 "), is not a multiple of 4.",
315 offset);
316 }
317
318 if (countBufferOffset & 3) {
319 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 -0600320 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndexedIndirectCountKHR-countBufferOffset-02716",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700321 "vkCmdDrawIndexedIndirectCountKHR() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64
322 "), is not a multiple of 4.",
323 countBufferOffset);
324 }
325
Lockee68ac652019-05-06 10:17:33 -0600326 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndexedIndirectCountKHR-stride-03142", stride,
327 "VkDrawIndirectCommand", sizeof(VkDrawIndexedIndirectCommand));
328 if (maxDrawCount > 1) {
329 BUFFER_STATE *buffer_state = GetBufferState(buffer);
330 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndexedIndirectCountKHR-maxDrawCount-03143", stride,
331 "VkDrawIndirectCommand", sizeof(VkDrawIndexedIndirectCommand), maxDrawCount, offset,
332 buffer_state);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700333 }
334
335 skip |= ValidateCmdDrawType(
336 commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNTKHR, "vkCmdDrawIndexedIndirectCountKHR()",
337 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDrawIndexedIndirectCountKHR-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600338 "VUID-vkCmdDrawIndexedIndirectCountKHR-renderpass", "VUID-vkCmdDrawIndexedIndirectCountKHR-None-02700",
339 "VUID-vkCmdDrawIndexedIndirectCountKHR-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700340 BUFFER_STATE *buffer_state = GetBufferState(buffer);
341 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
342 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndexedIndirectCountKHR()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600343 "VUID-vkCmdDrawIndexedIndirectCountKHR-buffer-02708");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700344 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawIndexedIndirectCountKHR()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600345 "VUID-vkCmdDrawIndexedIndirectCountKHR-countBuffer-02714");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700346 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600347 "VUID-vkCmdDrawIndexedIndirectCountKHR-buffer-02709", "vkCmdDrawIndexedIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700348 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
349 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600350 "VUID-vkCmdDrawIndexedIndirectCountKHR-countBuffer-02715",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700351 "vkCmdDrawIndexedIndirectCountKHR()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700352 return skip;
353}
354
355void CoreChecks::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
356 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
357 uint32_t maxDrawCount, uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600358 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700359 BUFFER_STATE *buffer_state = GetBufferState(buffer);
360 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
361 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
362 AddCommandBufferBindingBuffer(cb_state, buffer_state);
363 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
364}
365
Jason Macnak67407e72019-07-11 11:05:09 -0700366void CoreChecks::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
367 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
368 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
369 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
370 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
371 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
372 uint32_t width, uint32_t height, uint32_t depth) {
373 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV);
374}
375
376void CoreChecks::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
377 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
378 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
379 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
380 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
381 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
382 uint32_t width, uint32_t height, uint32_t depth) {
383 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
384 UpdateStateCmdDrawDispatchType(cb_state, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV);
385 cb_state->hasTraceRaysCmd = true;
386}
387
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700388bool CoreChecks::PreCallValidateCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
389 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV,
390 "vkCmdDrawMeshTasksNV()", VK_QUEUE_GRAPHICS_BIT,
391 "VUID-vkCmdDrawMeshTasksNV-commandBuffer-cmdpool", "VUID-vkCmdDrawMeshTasksNV-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600392 "VUID-vkCmdDrawMeshTasksNV-None-02700", "VUID-vkCmdDrawMeshTasksNV-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700393 return skip;
394}
395
396void CoreChecks::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600397 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700398 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
399}
400
401bool CoreChecks::PreCallValidateCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
402 uint32_t drawCount, uint32_t stride) {
403 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV,
404 "vkCmdDrawMeshTasksIndirectNV()", VK_QUEUE_GRAPHICS_BIT,
405 "VUID-vkCmdDrawMeshTasksIndirectNV-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600406 "VUID-vkCmdDrawMeshTasksIndirectNV-renderpass", "VUID-vkCmdDrawMeshTasksIndirectNV-None-02700",
407 "VUID-vkCmdDrawMeshTasksIndirectNV-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700408 BUFFER_STATE *buffer_state = GetBufferState(buffer);
409 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawMeshTasksIndirectNV()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600410 "VUID-vkCmdDrawMeshTasksIndirectNV-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700411 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600412 "VUID-vkCmdDrawMeshTasksIndirectNV-buffer-02709", "vkCmdDrawMeshTasksIndirectNV()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700413 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600414 if (drawCount > 1) {
Lockee68ac652019-05-06 10:17:33 -0600415 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02157", stride,
416 "VkDrawMeshTasksIndirectCommandNV", sizeof(VkDrawMeshTasksIndirectCommandNV),
417 drawCount, offset, buffer_state);
418 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700419 return skip;
420}
421
422void CoreChecks::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
423 uint32_t drawCount, uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600424 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700425 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
426 BUFFER_STATE *buffer_state = GetBufferState(buffer);
427 if (buffer_state) {
428 AddCommandBufferBindingBuffer(cb_state, buffer_state);
429 }
430}
431
432bool CoreChecks::PreCallValidateCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
433 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
434 uint32_t maxDrawCount, uint32_t stride) {
435 bool skip = ValidateCmdDrawType(
436 commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV,
437 "vkCmdDrawMeshTasksIndirectCountNV()", VK_QUEUE_GRAPHICS_BIT,
438 "VUID-vkCmdDrawMeshTasksIndirectCountNV-commandBuffer-cmdpool", "VUID-vkCmdDrawMeshTasksIndirectCountNV-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600439 "VUID-vkCmdDrawMeshTasksIndirectCountNV-None-02700", "VUID-vkCmdDrawMeshTasksIndirectCountNV-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700440 BUFFER_STATE *buffer_state = GetBufferState(buffer);
441 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
442 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawMeshTasksIndirectCountNV()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600443 "VUID-vkCmdDrawMeshTasksIndirectCountNV-buffer-02708");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700444 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawMeshTasksIndirectCountNV()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600445 "VUID-vkCmdDrawMeshTasksIndirectCountNV-countBuffer-02714");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700446 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600447 "VUID-vkCmdDrawMeshTasksIndirectCountNV-buffer-02709", "vkCmdDrawIndexedIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700448 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
449 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600450 "VUID-vkCmdDrawMeshTasksIndirectCountNV-countBuffer-02715",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700451 "vkCmdDrawIndexedIndirectCountKHR()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600452 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawMeshTasksIndirectCountNV-stride-02182", stride,
453 "VkDrawMeshTasksIndirectCommandNV", sizeof(VkDrawMeshTasksIndirectCommandNV));
454 if (maxDrawCount > 1) {
455 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawMeshTasksIndirectCountNV-maxDrawCount-02183", stride,
456 "VkDrawMeshTasksIndirectCommandNV", sizeof(VkDrawMeshTasksIndirectCommandNV),
457 maxDrawCount, offset, buffer_state);
458 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700459 return skip;
460}
461
462void CoreChecks::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
463 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
464 uint32_t maxDrawCount, uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600465 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700466 BUFFER_STATE *buffer_state = GetBufferState(buffer);
467 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
468 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
469 if (buffer_state) {
470 AddCommandBufferBindingBuffer(cb_state, buffer_state);
471 }
472 if (count_buffer_state) {
473 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
474 }
475}