blob: e9510112cbe1db49792cb24196c748059f994e52 [file] [log] [blame]
Tony-LunarG73719992020-01-15 10:20:28 -07001/* Copyright (c) 2015-2020 The Khronos Group Inc.
2 * Copyright (c) 2015-2020 Valve Corporation
3 * Copyright (c) 2015-2020 LunarG, Inc.
4 * Copyright (C) 2015-2020 Google Inc.
Jasper St. Pierre512613a2019-04-08 16:25:23 -07005 *
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
Jasper St. Pierre512613a2019-04-08 16:25:23 -070038#include "chassis.h"
39#include "core_validation.h"
40
Spencer Fricke507600b2020-03-22 13:23:06 -070041// This LUT is created to allow a static listing of each VUID that is covered by drawdispatch commands
42// clang-format off
43static const std::map<CMD_TYPE, DrawDispatchVuid> drawdispatch_vuid = {
44 {CMD_DRAW, {
45 "VUID-vkCmdDraw-commandBuffer-cmdpool",
46 "VUID-vkCmdDraw-renderpass",
47 "VUID-vkCmdDraw-None-02700",
48 "VUID-vkCmdDraw-commandBuffer-02701",
49 "VUID-vkCmdDraw-None-02720",
50 "VUID-vkCmdDraw-None-02697",
51 "VUID-vkCmdDraw-renderPass-02684",
52 "VUID-vkCmdDraw-subpass-02685"
53 }},
54 {CMD_DRAWINDEXED, {
55 "VUID-vkCmdDrawIndexed-commandBuffer-cmdpool",
56 "VUID-vkCmdDrawIndexed-renderpass",
57 "VUID-vkCmdDrawIndexed-None-02700",
58 "VUID-vkCmdDrawIndexed-commandBuffer-02701",
59 "VUID-vkCmdDrawIndexed-None-02720",
60 "VUID-vkCmdDrawIndexed-None-02697",
61 "VUID-vkCmdDrawIndexed-renderPass-02684",
62 "VUID-vkCmdDrawIndexed-subpass-02685"
63 }},
64 {CMD_DRAWINDIRECT, {
65 "VUID-vkCmdDrawIndirect-commandBuffer-cmdpool",
66 "VUID-vkCmdDrawIndirect-renderpass",
67 "VUID-vkCmdDrawIndirect-None-02700",
68 "VUID-vkCmdDrawIndirect-commandBuffer-02701",
69 "VUID-vkCmdDrawIndirect-None-02720",
70 "VUID-vkCmdDrawIndirect-None-02697",
71 "VUID-vkCmdDrawIndirect-renderPass-02684",
72 "VUID-vkCmdDrawIndirect-subpass-02685"
73 }},
74 {CMD_DRAWINDEXEDINDIRECT, {
75 "VUID-vkCmdDrawIndexedIndirect-commandBuffer-cmdpool",
76 "VUID-vkCmdDrawIndexedIndirect-renderpass",
77 "VUID-vkCmdDrawIndexedIndirect-None-02700",
78 "VUID-vkCmdDrawIndexedIndirect-commandBuffer-02701",
79 "VUID-vkCmdDrawIndexedIndirect-None-02720",
80 "VUID-vkCmdDrawIndexedIndirect-None-02697",
81 "VUID-vkCmdDrawIndexedIndirect-renderPass-02684",
82 "VUID-vkCmdDrawIndexedIndirect-subpass-02685"
83 }},
84 {CMD_DISPATCH, {
85 "VUID-vkCmdDispatch-commandBuffer-cmdpool",
86 "VUID-vkCmdDispatch-renderpass",
87 "VUID-vkCmdDispatch-None-02700",
88 kVUIDUndefined, // dynamic_state
89 kVUIDUndefined, // vertex_binding
90 "VUID-vkCmdDispatch-None-02697",
91 kVUIDUndefined, // render_pass_compatible
92 kVUIDUndefined, // subpass_index
93 }},
94 {CMD_DISPATCHINDIRECT, {
95 "VUID-vkCmdDispatchIndirect-commandBuffer-cmdpool",
96 "VUID-vkCmdDispatchIndirect-renderpass",
97 "VUID-vkCmdDispatchIndirect-None-02700",
98 kVUIDUndefined, // dynamic_state
99 kVUIDUndefined, // vertex_binding
100 "VUID-vkCmdDispatchIndirect-None-02697",
101 kVUIDUndefined, // render_pass_compatible
102 kVUIDUndefined, // subpass_index
103 }},
104 {CMD_DRAWINDIRECTCOUNT, {
105 "VUID-vkCmdDrawIndirectCount-commandBuffer-cmdpool",
106 "VUID-vkCmdDrawIndirectCount-renderpass",
107 "VUID-vkCmdDrawIndirectCount-None-02700",
108 "VUID-vkCmdDrawIndirectCount-commandBuffer-02701",
109 "VUID-vkCmdDrawIndirectCount-None-02720",
110 "VUID-vkCmdDrawIndirectCount-None-02697",
111 "VUID-vkCmdDrawIndirectCount-renderPass-02684",
112 "VUID-vkCmdDrawIndirectCount-subpass-02685"
113 }},
114 {CMD_DRAWINDEXEDINDIRECTCOUNT,{
115 "VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-cmdpool",
116 "VUID-vkCmdDrawIndexedIndirectCount-renderpass",
117 "VUID-vkCmdDrawIndexedIndirectCount-None-02700",
118 "VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-02701",
119 "VUID-vkCmdDrawIndexedIndirectCount-None-02720",
120 "VUID-vkCmdDrawIndexedIndirectCount-None-02697",
121 "VUID-vkCmdDrawIndexedIndirectCount-renderPass-02684",
122 "VUID-vkCmdDrawIndexedIndirectCount-subpass-02685"
123 }},
124 {CMD_TRACERAYSNV, {
125 "VUID-vkCmdTraceRaysNV-commandBuffer-cmdpool",
126 "VUID-vkCmdTraceRaysNV-renderpass",
127 "VUID-vkCmdTraceRaysNV-None-02700",
128 "VUID-vkCmdTraceRaysNV-commandBuffer-02701",
129 kVUIDUndefined, // vertex_binding
130 "VUID-vkCmdTraceRaysNV-None-02697",
131 kVUIDUndefined, // render_pass_compatible
132 kVUIDUndefined, // subpass_index
133 }},
134 {CMD_DRAWMESHTASKSNV, {
135 "VUID-vkCmdDrawMeshTasksNV-commandBuffer-cmdpool",
136 "VUID-vkCmdDrawMeshTasksNV-renderpass",
137 "VUID-vkCmdDrawMeshTasksNV-None-02700",
138 "VUID-vkCmdDrawMeshTasksNV-commandBuffer-02701",
139 kVUIDUndefined, // vertex_binding
140 "VUID-vkCmdDrawMeshTasksNV-None-02697",
141 "VUID-vkCmdDrawMeshTasksNV-renderPass-02684",
142 "VUID-vkCmdDrawMeshTasksNV-subpass-02685"
143 }},
144 {CMD_DRAWMESHTASKSINDIRECTNV, {
145 "VUID-vkCmdDrawMeshTasksIndirectNV-commandBuffer-cmdpool",
146 "VUID-vkCmdDrawMeshTasksIndirectNV-renderpass",
147 "VUID-vkCmdDrawMeshTasksIndirectNV-None-02700",
148 "VUID-vkCmdDrawMeshTasksIndirectNV-commandBuffer-02701",
149 kVUIDUndefined, // vertex_binding
150 "VUID-vkCmdDrawMeshTasksIndirectNV-None-02697",
151 "VUID-vkCmdDrawMeshTasksIndirectNV-renderPass-02684",
152 "VUID-vkCmdDrawMeshTasksIndirectNV-subpass-02685"
153 }},
154 {CMD_DRAWMESHTASKSINDIRECTCOUNTNV, {
155 "VUID-vkCmdDrawMeshTasksIndirectCountNV-commandBuffer-cmdpool",
156 "VUID-vkCmdDrawMeshTasksIndirectCountNV-renderpass",
157 "VUID-vkCmdDrawMeshTasksIndirectCountNV-None-02700",
158 "VUID-vkCmdDrawMeshTasksIndirectCountNV-commandBuffer-02701",
159 kVUIDUndefined, // vertex_binding
160 "VUID-vkCmdDrawMeshTasksIndirectCountNV-None-02697",
161 "VUID-vkCmdDrawMeshTasksIndirectCountNV-renderPass-02684",
162 "VUID-vkCmdDrawMeshTasksIndirectCountNV-subpass-02685"
163 }},
164 // Used if invalid cmd_type is used
165 {CMD_NONE, {kVUIDUndefined, kVUIDUndefined, kVUIDUndefined, kVUIDUndefined, kVUIDUndefined, kVUIDUndefined, kVUIDUndefined, kVUIDUndefined}}
166};
167// clang-format on
168
169// Getter function to provide kVUIDUndefined in case an invalid cmd_type is passed in
170const DrawDispatchVuid &CoreChecks::GetDrawDispatchVuid(CMD_TYPE cmd_type) const {
171 if (drawdispatch_vuid.find(cmd_type) != drawdispatch_vuid.cend()) {
172 return drawdispatch_vuid.at(cmd_type);
173 } else {
174 return drawdispatch_vuid.at(CMD_NONE);
175 }
176}
177
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700178// Generic function to handle validation for all CmdDraw* type functions
179bool CoreChecks::ValidateCmdDrawType(VkCommandBuffer cmd_buffer, bool indexed, VkPipelineBindPoint bind_point, CMD_TYPE cmd_type,
Spencer Fricke507600b2020-03-22 13:23:06 -0700180 const char *caller, VkQueueFlags queue_flags) const {
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700181 bool skip = false;
Spencer Fricke507600b2020-03-22 13:23:06 -0700182 const DrawDispatchVuid vuid = GetDrawDispatchVuid(cmd_type);
John Zulauffbf3c202019-07-17 14:57:14 -0600183 const CMD_BUFFER_STATE *cb_state = GetCBState(cmd_buffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700184 if (cb_state) {
Spencer Fricke507600b2020-03-22 13:23:06 -0700185 skip |= ValidateCmdQueueFlags(cb_state, caller, queue_flags, vuid.queue_flag);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700186 skip |= ValidateCmd(cb_state, cmd_type, caller);
Spencer Fricke507600b2020-03-22 13:23:06 -0700187 skip |= ValidateCmdBufDrawState(cb_state, cmd_type, indexed, bind_point, caller);
188 skip |= (VK_PIPELINE_BIND_POINT_GRAPHICS == bind_point) ? OutsideRenderPass(cb_state, caller, vuid.inside_renderpass)
189 : InsideRenderPass(cb_state, caller, vuid.inside_renderpass);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700190 }
191 return skip;
192}
193
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700194bool CoreChecks::PreCallValidateCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500195 uint32_t firstVertex, uint32_t firstInstance) const {
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700196 return ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAW, "vkCmdDraw()",
Spencer Fricke507600b2020-03-22 13:23:06 -0700197 VK_QUEUE_GRAPHICS_BIT);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700198}
199
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700200bool CoreChecks::PreCallValidateCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500201 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) const {
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700202 bool skip = ValidateCmdDrawType(commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXED, "vkCmdDrawIndexed()",
Spencer Fricke507600b2020-03-22 13:23:06 -0700203 VK_QUEUE_GRAPHICS_BIT);
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500204 const CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700205 if (!skip && (cb_state->status & CBSTATUS_INDEX_BUFFER_BOUND)) {
206 unsigned int index_size = 0;
207 const auto &index_buffer_binding = cb_state->index_buffer_binding;
208 if (index_buffer_binding.index_type == VK_INDEX_TYPE_UINT16) {
209 index_size = 2;
210 } else if (index_buffer_binding.index_type == VK_INDEX_TYPE_UINT32) {
211 index_size = 4;
Piers Daniell5070e3e2019-08-20 13:39:35 -0600212 } else if (index_buffer_binding.index_type == VK_INDEX_TYPE_UINT8_EXT) {
213 index_size = 1;
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700214 }
215 VkDeviceSize end_offset = (index_size * ((VkDeviceSize)firstIndex + indexCount)) + index_buffer_binding.offset;
216 if (end_offset > index_buffer_binding.size) {
Mark Lobodzinskicf0e6d32020-01-30 12:12:58 -0700217 skip |=
218 LogError(index_buffer_binding.buffer, "VUID-vkCmdDrawIndexed-indexSize-00463",
219 "vkCmdDrawIndexed() index size (%d) * (firstIndex (%d) + indexCount (%d)) "
220 "+ binding offset (%" PRIuLEAST64 ") = an ending offset of %" PRIuLEAST64
221 " bytes, which is greater than the index buffer size (%" PRIuLEAST64 ").",
222 index_size, firstIndex, indexCount, index_buffer_binding.offset, end_offset, index_buffer_binding.size);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700223 }
224 }
225 return skip;
226}
227
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700228bool CoreChecks::PreCallValidateCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500229 uint32_t stride) const {
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700230 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECT, "vkCmdDrawIndirect()",
Spencer Fricke507600b2020-03-22 13:23:06 -0700231 VK_QUEUE_GRAPHICS_BIT);
John Zulauffbf3c202019-07-17 14:57:14 -0600232 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600233 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndirect()", "VUID-vkCmdDrawIndirect-buffer-02708");
234 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true, "VUID-vkCmdDrawIndirect-buffer-02709",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700235 "vkCmdDrawIndirect()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600236 if (count > 1) {
237 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndirect-drawCount-00476", stride,
238 "VkDrawIndirectCommand", sizeof(VkDrawIndirectCommand));
239 skip |=
240 ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndirect-drawCount-00488", stride,
241 "VkDrawIndirectCommand", sizeof(VkDrawIndirectCommand), count, offset, buffer_state);
242 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700243 // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the
244 // VkDrawIndirectCommand structures accessed by this command must be 0, which will require access to the contents of 'buffer'.
245 return skip;
246}
247
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700248bool CoreChecks::PreCallValidateCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500249 uint32_t count, uint32_t stride) const {
Spencer Fricke507600b2020-03-22 13:23:06 -0700250 bool skip = ValidateCmdDrawType(commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECT,
251 "vkCmdDrawIndexedIndirect()", VK_QUEUE_GRAPHICS_BIT);
John Zulauffbf3c202019-07-17 14:57:14 -0600252 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600253 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndexedIndirect()", "VUID-vkCmdDrawIndexedIndirect-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700254 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600255 "VUID-vkCmdDrawIndexedIndirect-buffer-02709", "vkCmdDrawIndexedIndirect()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700256 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600257 if (count > 1) {
258 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndexedIndirect-drawCount-00528", stride,
259 "VkDrawIndexedIndirectCommand", sizeof(VkDrawIndexedIndirectCommand));
260 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndexedIndirect-drawCount-00540", stride,
261 "VkDrawIndexedIndirectCommand", sizeof(VkDrawIndexedIndirectCommand), count, offset,
262 buffer_state);
263 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700264 // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the
265 // VkDrawIndexedIndirectCommand structures accessed by this command must be 0, which will require access to the contents of
266 // 'buffer'.
267 return skip;
268}
269
Jeff Bolz5c801d12019-10-09 10:38:45 -0500270bool CoreChecks::PreCallValidateCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) const {
Lockef39c0772019-04-03 14:40:02 -0600271 bool skip = false;
Lockef39c0772019-04-03 14:40:02 -0600272 skip |= ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH, "vkCmdDispatch()",
Spencer Fricke507600b2020-03-22 13:23:06 -0700273 VK_QUEUE_COMPUTE_BIT);
Lockef39c0772019-04-03 14:40:02 -0600274 return skip;
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700275}
276
Jeff Bolz5c801d12019-10-09 10:38:45 -0500277bool CoreChecks::PreCallValidateCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) const {
Mark Lobodzinski708aae72019-12-20 11:57:46 -0700278 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT,
Spencer Fricke507600b2020-03-22 13:23:06 -0700279 "vkCmdDispatchIndirect()", VK_QUEUE_COMPUTE_BIT);
John Zulauffbf3c202019-07-17 14:57:14 -0600280 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600281 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDispatchIndirect()", "VUID-vkCmdDispatchIndirect-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700282 skip |=
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600283 ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true, "VUID-vkCmdDispatchIndirect-buffer-02709",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700284 "vkCmdDispatchIndirect()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700285 return skip;
286}
Tony-LunarGa74d3fe2019-11-22 15:43:20 -0700287bool CoreChecks::ValidateCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
288 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Tony-LunarG83544c72020-01-17 12:30:19 -0700289 uint32_t stride, const char *apiName) const {
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700290 bool skip = false;
291 if (offset & 3) {
Mark Lobodzinskicf0e6d32020-01-30 12:12:58 -0700292 skip |= LogError(commandBuffer, "VUID-vkCmdDrawIndirectCount-offset-02710",
293 "%s() parameter, VkDeviceSize offset (0x%" PRIxLEAST64 "), is not a multiple of 4.", apiName, offset);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700294 }
295
296 if (countBufferOffset & 3) {
Mark Lobodzinskicf0e6d32020-01-30 12:12:58 -0700297 skip |= LogError(commandBuffer, "VUID-vkCmdDrawIndirectCount-countBufferOffset-02716",
298 "%s() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64 "), is not a multiple of 4.", apiName,
299 countBufferOffset);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700300 }
Tony-LunarG83544c72020-01-17 12:30:19 -0700301 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndirectCount-stride-03110", stride, apiName,
302 sizeof(VkDrawIndirectCommand));
Lockee68ac652019-05-06 10:17:33 -0600303 if (maxDrawCount > 1) {
John Zulauffbf3c202019-07-17 14:57:14 -0600304 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
Tony-LunarG83544c72020-01-17 12:30:19 -0700305 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndirectCount-maxDrawCount-03111", stride, apiName,
306 sizeof(VkDrawIndirectCommand), maxDrawCount, offset, buffer_state);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700307 }
308
Tony-LunarG83544c72020-01-17 12:30:19 -0700309 skip |= ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNT, apiName,
Spencer Fricke507600b2020-03-22 13:23:06 -0700310 VK_QUEUE_GRAPHICS_BIT);
John Zulauffbf3c202019-07-17 14:57:14 -0600311 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
312 const BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Tony-LunarG83544c72020-01-17 12:30:19 -0700313 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, apiName, "VUID-vkCmdDrawIndirectCount-buffer-02708");
314 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, apiName, "VUID-vkCmdDrawIndirectCount-countBuffer-02714");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700315 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Tony-LunarG83544c72020-01-17 12:30:19 -0700316 "VUID-vkCmdDrawIndirectCount-buffer-02709", apiName, "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
317 skip |=
318 ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
319 "VUID-vkCmdDrawIndirectCount-countBuffer-02715", apiName, "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700320 return skip;
321}
322
Tony-LunarGa74d3fe2019-11-22 15:43:20 -0700323bool CoreChecks::PreCallValidateCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
324 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
325 uint32_t stride) const {
Tony-LunarG83544c72020-01-17 12:30:19 -0700326 return ValidateCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
327 "VkCmdDrawIndirectCountKHR");
Tony-LunarGa74d3fe2019-11-22 15:43:20 -0700328}
329
330bool CoreChecks::PreCallValidateCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
331 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
332 uint32_t stride) const {
Tony-LunarG83544c72020-01-17 12:30:19 -0700333 return ValidateCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride,
334 "VkCmdDrawIndirectCount");
Tony-LunarGa74d3fe2019-11-22 15:43:20 -0700335}
336
337bool CoreChecks::ValidateCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
338 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
339 uint32_t stride) const {
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700340 bool skip = false;
341 if (offset & 3) {
Mark Lobodzinskicf0e6d32020-01-30 12:12:58 -0700342 skip |= LogError(
343 commandBuffer, "VUID-vkCmdDrawIndexedIndirectCount-offset-02710",
Tony-LunarGa74d3fe2019-11-22 15:43:20 -0700344 "vkCmdDrawIndexedIndirectCount() parameter, VkDeviceSize offset (0x%" PRIxLEAST64 "), is not a multiple of 4.", offset);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700345 }
346
347 if (countBufferOffset & 3) {
Mark Lobodzinskicf0e6d32020-01-30 12:12:58 -0700348 skip |= LogError(commandBuffer, "VUID-vkCmdDrawIndexedIndirectCount-countBufferOffset-02716",
349 "vkCmdDrawIndexedIndirectCount() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64
350 "), is not a multiple of 4.",
351 countBufferOffset);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700352 }
353
Mike Schuchardt65847d92019-12-20 13:50:47 -0800354 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndexedIndirectCount-stride-03142", stride,
Lockee68ac652019-05-06 10:17:33 -0600355 "VkDrawIndirectCommand", sizeof(VkDrawIndexedIndirectCommand));
356 if (maxDrawCount > 1) {
John Zulauffbf3c202019-07-17 14:57:14 -0600357 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
Mike Schuchardt65847d92019-12-20 13:50:47 -0800358 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndexedIndirectCount-maxDrawCount-03143", stride,
Lockee68ac652019-05-06 10:17:33 -0600359 "VkDrawIndirectCommand", sizeof(VkDrawIndexedIndirectCommand), maxDrawCount, offset,
360 buffer_state);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700361 }
362
Spencer Fricke507600b2020-03-22 13:23:06 -0700363 skip |= ValidateCmdDrawType(commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNT,
364 "vkCmdDrawIndexedIndirectCount()", VK_QUEUE_GRAPHICS_BIT);
John Zulauffbf3c202019-07-17 14:57:14 -0600365 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
366 const BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Tony-LunarGa74d3fe2019-11-22 15:43:20 -0700367 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndexedIndirectCount()",
Mike Schuchardt65847d92019-12-20 13:50:47 -0800368 "VUID-vkCmdDrawIndexedIndirectCount-buffer-02708");
Tony-LunarGa74d3fe2019-11-22 15:43:20 -0700369 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawIndexedIndirectCount()",
Mike Schuchardt65847d92019-12-20 13:50:47 -0800370 "VUID-vkCmdDrawIndexedIndirectCount-countBuffer-02714");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700371 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Tony-LunarGa74d3fe2019-11-22 15:43:20 -0700372 "VUID-vkCmdDrawIndexedIndirectCount-buffer-02709", "vkCmdDrawIndexedIndirectCount()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700373 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
374 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Tony-LunarGa74d3fe2019-11-22 15:43:20 -0700375 "VUID-vkCmdDrawIndexedIndirectCount-countBuffer-02715", "vkCmdDrawIndexedIndirectCount()",
Mike Schuchardt65847d92019-12-20 13:50:47 -0800376 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700377 return skip;
378}
379
Tony-LunarGa74d3fe2019-11-22 15:43:20 -0700380bool CoreChecks::PreCallValidateCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
381 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
382 uint32_t maxDrawCount, uint32_t stride) const {
383 return ValidateCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
384}
385
386bool CoreChecks::PreCallValidateCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
387 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
388 uint32_t maxDrawCount, uint32_t stride) const {
389 return ValidateCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
390}
391
Jeff Bolzf6e872c2019-10-22 12:17:28 -0500392bool CoreChecks::PreCallValidateCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
393 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
394 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
395 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
396 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
397 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
398 uint32_t width, uint32_t height, uint32_t depth) const {
Spencer Fricke507600b2020-03-22 13:23:06 -0700399 bool skip = ValidateCmdDrawType(commandBuffer, true, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, CMD_TRACERAYSNV,
400 "vkCmdTraceRaysNV()", VK_QUEUE_COMPUTE_BIT);
Jeff Bolzf6e872c2019-10-22 12:17:28 -0500401 return skip;
402}
403
Jason Macnak67407e72019-07-11 11:05:09 -0700404void CoreChecks::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
405 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
406 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
407 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
408 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
409 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
410 uint32_t width, uint32_t height, uint32_t depth) {
411 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
412 UpdateStateCmdDrawDispatchType(cb_state, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV);
413 cb_state->hasTraceRaysCmd = true;
414}
415
Jeff Bolz5c801d12019-10-09 10:38:45 -0500416bool CoreChecks::PreCallValidateCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) const {
Spencer Fricke507600b2020-03-22 13:23:06 -0700417 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV,
418 "vkCmdDrawMeshTasksNV()", VK_QUEUE_GRAPHICS_BIT);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700419 return skip;
420}
421
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700422bool CoreChecks::PreCallValidateCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500423 uint32_t drawCount, uint32_t stride) const {
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700424 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV,
Spencer Fricke507600b2020-03-22 13:23:06 -0700425 "vkCmdDrawMeshTasksIndirectNV()", VK_QUEUE_GRAPHICS_BIT);
John Zulauffbf3c202019-07-17 14:57:14 -0600426 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700427 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawMeshTasksIndirectNV()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600428 "VUID-vkCmdDrawMeshTasksIndirectNV-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700429 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600430 "VUID-vkCmdDrawMeshTasksIndirectNV-buffer-02709", "vkCmdDrawMeshTasksIndirectNV()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700431 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600432 if (drawCount > 1) {
Lockee68ac652019-05-06 10:17:33 -0600433 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02157", stride,
434 "VkDrawMeshTasksIndirectCommandNV", sizeof(VkDrawMeshTasksIndirectCommandNV),
435 drawCount, offset, buffer_state);
436 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700437 return skip;
438}
439
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700440bool CoreChecks::PreCallValidateCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
441 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500442 uint32_t maxDrawCount, uint32_t stride) const {
Mark Lobodzinski708aae72019-12-20 11:57:46 -0700443 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV,
Spencer Fricke507600b2020-03-22 13:23:06 -0700444 "vkCmdDrawMeshTasksIndirectCountNV()", VK_QUEUE_GRAPHICS_BIT);
John Zulauffbf3c202019-07-17 14:57:14 -0600445 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
446 const BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700447 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawMeshTasksIndirectCountNV()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600448 "VUID-vkCmdDrawMeshTasksIndirectCountNV-buffer-02708");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700449 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawMeshTasksIndirectCountNV()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600450 "VUID-vkCmdDrawMeshTasksIndirectCountNV-countBuffer-02714");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700451 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Tony-LunarGa74d3fe2019-11-22 15:43:20 -0700452 "VUID-vkCmdDrawMeshTasksIndirectCountNV-buffer-02709", "vkCmdDrawIndexedIndirectCount()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700453 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
454 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Tony-LunarGa74d3fe2019-11-22 15:43:20 -0700455 "VUID-vkCmdDrawMeshTasksIndirectCountNV-countBuffer-02715", "vkCmdDrawIndexedIndirectCount()",
456 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600457 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawMeshTasksIndirectCountNV-stride-02182", stride,
458 "VkDrawMeshTasksIndirectCommandNV", sizeof(VkDrawMeshTasksIndirectCommandNV));
459 if (maxDrawCount > 1) {
460 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawMeshTasksIndirectCountNV-maxDrawCount-02183", stride,
461 "VkDrawMeshTasksIndirectCommandNV", sizeof(VkDrawMeshTasksIndirectCommandNV),
462 maxDrawCount, offset, buffer_state);
463 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700464 return skip;
465}