blob: 3668eaa2b2523f773ceb7c7c33ed52a47bc90a5d [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");
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) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600156 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700157 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",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600167 "VUID-vkCmdDrawIndexedIndirect-None-02700", "VUID-vkCmdDrawIndexedIndirect-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700168 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600169 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndexedIndirect()", "VUID-vkCmdDrawIndexedIndirect-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700170 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600171 "VUID-vkCmdDrawIndexedIndirect-buffer-02709", "vkCmdDrawIndexedIndirect()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700172 "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) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600186 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700187 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) {
Lockef39c0772019-04-03 14:40:02 -0600193 bool skip = false;
Lockef39c0772019-04-03 14:40:02 -0600194 skip |= ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH, "vkCmdDispatch()",
195 VK_QUEUE_COMPUTE_BIT, "VUID-vkCmdDispatch-commandBuffer-cmdpool", "VUID-vkCmdDispatch-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600196 "VUID-vkCmdDispatch-None-02700", kVUIDUndefined);
Lockef39c0772019-04-03 14:40:02 -0600197 return skip;
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700198}
199
200void CoreChecks::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
201 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
202}
203
204void CoreChecks::PostCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600205 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700206 UpdateStateCmdDrawDispatchType(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
207}
208
209bool CoreChecks::PreCallValidateCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
210 bool skip =
211 ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT, "vkCmdDispatchIndirect()",
212 VK_QUEUE_COMPUTE_BIT, "VUID-vkCmdDispatchIndirect-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600213 "VUID-vkCmdDispatchIndirect-renderpass", "VUID-vkCmdDispatchIndirect-None-02700", kVUIDUndefined);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700214 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600215 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDispatchIndirect()", "VUID-vkCmdDispatchIndirect-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700216 skip |=
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600217 ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true, "VUID-vkCmdDispatchIndirect-buffer-02709",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700218 "vkCmdDispatchIndirect()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700219 return skip;
220}
221
222void CoreChecks::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
223 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
224}
225
226void CoreChecks::PostCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600227 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700228 UpdateStateCmdDrawDispatchType(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
229 BUFFER_STATE *buffer_state = GetBufferState(buffer);
230 AddCommandBufferBindingBuffer(cb_state, buffer_state);
231}
232
233bool CoreChecks::PreCallValidateCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
234 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
235 uint32_t stride) {
236 bool skip = false;
237 if (offset & 3) {
238 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 -0600239 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndirectCountKHR-offset-02710",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700240 "vkCmdDrawIndirectCountKHR() parameter, VkDeviceSize offset (0x%" PRIxLEAST64 "), is not a multiple of 4.",
241 offset);
242 }
243
244 if (countBufferOffset & 3) {
245 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 -0600246 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndirectCountKHR-countBufferOffset-02716",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700247 "vkCmdDrawIndirectCountKHR() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64
248 "), is not a multiple of 4.",
249 countBufferOffset);
250 }
251
252 if ((stride & 3) || stride < sizeof(VkDrawIndirectCommand)) {
253 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
254 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndirectCountKHR-stride-03110",
255 "vkCmdDrawIndirectCountKHR() parameter, uint32_t stride (0x%" PRIxLEAST32
256 "), is not a multiple of 4 or smaller than sizeof (VkDrawIndirectCommand).",
257 stride);
258 }
259
260 skip |= ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNTKHR,
261 "vkCmdDrawIndirectCountKHR()", VK_QUEUE_GRAPHICS_BIT,
262 "VUID-vkCmdDrawIndirectCountKHR-commandBuffer-cmdpool", "VUID-vkCmdDrawIndirectCountKHR-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600263 "VUID-vkCmdDrawIndirectCountKHR-None-02700", "VUID-vkCmdDrawIndirectCountKHR-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700264 BUFFER_STATE *buffer_state = GetBufferState(buffer);
265 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
266 skip |=
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600267 ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndirectCountKHR()", "VUID-vkCmdDrawIndirectCountKHR-buffer-02708");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700268 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawIndirectCountKHR()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600269 "VUID-vkCmdDrawIndirectCountKHR-countBuffer-02714");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700270 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600271 "VUID-vkCmdDrawIndirectCountKHR-buffer-02709", "vkCmdDrawIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700272 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
273 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600274 "VUID-vkCmdDrawIndirectCountKHR-countBuffer-02715", "vkCmdDrawIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700275 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700276 return skip;
277}
278
279void CoreChecks::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
280 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
281 uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600282 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700283 BUFFER_STATE *buffer_state = GetBufferState(buffer);
284 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
285 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
286 AddCommandBufferBindingBuffer(cb_state, buffer_state);
287 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
288}
289
290bool CoreChecks::PreCallValidateCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
291 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
292 uint32_t maxDrawCount, uint32_t stride) {
293 bool skip = false;
294 if (offset & 3) {
295 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 -0600296 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndexedIndirectCountKHR-offset-02710",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700297 "vkCmdDrawIndexedIndirectCountKHR() parameter, VkDeviceSize offset (0x%" PRIxLEAST64
298 "), is not a multiple of 4.",
299 offset);
300 }
301
302 if (countBufferOffset & 3) {
303 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 -0600304 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndexedIndirectCountKHR-countBufferOffset-02716",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700305 "vkCmdDrawIndexedIndirectCountKHR() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64
306 "), is not a multiple of 4.",
307 countBufferOffset);
308 }
309
310 if ((stride & 3) || stride < sizeof(VkDrawIndexedIndirectCommand)) {
311 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
312 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndexedIndirectCountKHR-stride-03142",
313 "vkCmdDrawIndexedIndirectCountKHR() parameter, uint32_t stride (0x%" PRIxLEAST32
314 "), is not a multiple of 4 or smaller than sizeof (VkDrawIndexedIndirectCommand).",
315 stride);
316 }
317
318 skip |= ValidateCmdDrawType(
319 commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNTKHR, "vkCmdDrawIndexedIndirectCountKHR()",
320 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDrawIndexedIndirectCountKHR-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600321 "VUID-vkCmdDrawIndexedIndirectCountKHR-renderpass", "VUID-vkCmdDrawIndexedIndirectCountKHR-None-02700",
322 "VUID-vkCmdDrawIndexedIndirectCountKHR-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700323 BUFFER_STATE *buffer_state = GetBufferState(buffer);
324 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
325 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndexedIndirectCountKHR()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600326 "VUID-vkCmdDrawIndexedIndirectCountKHR-buffer-02708");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700327 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawIndexedIndirectCountKHR()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600328 "VUID-vkCmdDrawIndexedIndirectCountKHR-countBuffer-02714");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700329 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600330 "VUID-vkCmdDrawIndexedIndirectCountKHR-buffer-02709", "vkCmdDrawIndexedIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700331 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
332 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600333 "VUID-vkCmdDrawIndexedIndirectCountKHR-countBuffer-02715",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700334 "vkCmdDrawIndexedIndirectCountKHR()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700335 return skip;
336}
337
338void CoreChecks::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
339 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
340 uint32_t maxDrawCount, uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600341 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700342 BUFFER_STATE *buffer_state = GetBufferState(buffer);
343 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
344 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
345 AddCommandBufferBindingBuffer(cb_state, buffer_state);
346 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
347}
348
349bool CoreChecks::PreCallValidateCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
350 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV,
351 "vkCmdDrawMeshTasksNV()", VK_QUEUE_GRAPHICS_BIT,
352 "VUID-vkCmdDrawMeshTasksNV-commandBuffer-cmdpool", "VUID-vkCmdDrawMeshTasksNV-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600353 "VUID-vkCmdDrawMeshTasksNV-None-02700", "VUID-vkCmdDrawMeshTasksNV-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700354 return skip;
355}
356
357void CoreChecks::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600358 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700359 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
360}
361
362bool CoreChecks::PreCallValidateCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
363 uint32_t drawCount, uint32_t stride) {
364 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV,
365 "vkCmdDrawMeshTasksIndirectNV()", VK_QUEUE_GRAPHICS_BIT,
366 "VUID-vkCmdDrawMeshTasksIndirectNV-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600367 "VUID-vkCmdDrawMeshTasksIndirectNV-renderpass", "VUID-vkCmdDrawMeshTasksIndirectNV-None-02700",
368 "VUID-vkCmdDrawMeshTasksIndirectNV-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700369 BUFFER_STATE *buffer_state = GetBufferState(buffer);
370 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawMeshTasksIndirectNV()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600371 "VUID-vkCmdDrawMeshTasksIndirectNV-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700372 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600373 "VUID-vkCmdDrawMeshTasksIndirectNV-buffer-02709", "vkCmdDrawMeshTasksIndirectNV()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700374 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700375 return skip;
376}
377
378void CoreChecks::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
379 uint32_t drawCount, uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600380 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700381 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
382 BUFFER_STATE *buffer_state = GetBufferState(buffer);
383 if (buffer_state) {
384 AddCommandBufferBindingBuffer(cb_state, buffer_state);
385 }
386}
387
388bool CoreChecks::PreCallValidateCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
389 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
390 uint32_t maxDrawCount, uint32_t stride) {
391 bool skip = ValidateCmdDrawType(
392 commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV,
393 "vkCmdDrawMeshTasksIndirectCountNV()", VK_QUEUE_GRAPHICS_BIT,
394 "VUID-vkCmdDrawMeshTasksIndirectCountNV-commandBuffer-cmdpool", "VUID-vkCmdDrawMeshTasksIndirectCountNV-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600395 "VUID-vkCmdDrawMeshTasksIndirectCountNV-None-02700", "VUID-vkCmdDrawMeshTasksIndirectCountNV-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700396 BUFFER_STATE *buffer_state = GetBufferState(buffer);
397 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
398 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawMeshTasksIndirectCountNV()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600399 "VUID-vkCmdDrawMeshTasksIndirectCountNV-buffer-02708");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700400 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawMeshTasksIndirectCountNV()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600401 "VUID-vkCmdDrawMeshTasksIndirectCountNV-countBuffer-02714");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700402 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600403 "VUID-vkCmdDrawMeshTasksIndirectCountNV-buffer-02709", "vkCmdDrawIndexedIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700404 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
405 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600406 "VUID-vkCmdDrawMeshTasksIndirectCountNV-countBuffer-02715",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700407 "vkCmdDrawIndexedIndirectCountKHR()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700408 return skip;
409}
410
411void CoreChecks::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
412 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
413 uint32_t maxDrawCount, uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600414 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700415 BUFFER_STATE *buffer_state = GetBufferState(buffer);
416 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
417 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
418 if (buffer_state) {
419 AddCommandBufferBindingBuffer(cb_state, buffer_state);
420 }
421 if (count_buffer_state) {
422 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
423 }
424}