blob: a4f702d1037e3918b4d3fe7751351c8c6e6e3195 [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,
John Zulauffbf3c202019-07-17 14:57:14 -060052 const char *dynamic_state_msg_code) const {
Jasper St. Pierre512613a2019-04-08 16:25:23 -070053 bool skip = false;
John Zulauffbf3c202019-07-17 14:57:14 -060054 const 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
John Zulauffbf3c202019-07-17 14:57:14 -060067void ValidationStateTracker::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
John Zulauffbf3c202019-07-17 14:57:14 -060072void ValidationStateTracker::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
John Zulauffbf3c202019-07-17 14:57:14 -060090void ValidationStateTracker::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
John Zulauffbf3c202019-07-17 14:57:14 -0600130void ValidationStateTracker::PostCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount,
131 uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
132 uint32_t firstInstance) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600133 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700134 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
135}
136
137bool CoreChecks::PreCallValidateCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
138 uint32_t stride) {
139 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECT, "vkCmdDrawIndirect()",
140 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDrawIndirect-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600141 "VUID-vkCmdDrawIndirect-renderpass", "VUID-vkCmdDrawIndirect-None-02700",
142 "VUID-vkCmdDrawIndirect-commandBuffer-02701");
John Zulauffbf3c202019-07-17 14:57:14 -0600143 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600144 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndirect()", "VUID-vkCmdDrawIndirect-buffer-02708");
145 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true, "VUID-vkCmdDrawIndirect-buffer-02709",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700146 "vkCmdDrawIndirect()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600147 if (count > 1) {
148 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndirect-drawCount-00476", stride,
149 "VkDrawIndirectCommand", sizeof(VkDrawIndirectCommand));
150 skip |=
151 ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndirect-drawCount-00488", stride,
152 "VkDrawIndirectCommand", sizeof(VkDrawIndirectCommand), count, offset, buffer_state);
153 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700154 // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the
155 // VkDrawIndirectCommand structures accessed by this command must be 0, which will require access to the contents of 'buffer'.
156 return skip;
157}
158
159void CoreChecks::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
160 uint32_t stride) {
161 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
162}
163
John Zulauffbf3c202019-07-17 14:57:14 -0600164void ValidationStateTracker::PostCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
165 uint32_t count, uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600166 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700167 BUFFER_STATE *buffer_state = GetBufferState(buffer);
168 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
169 AddCommandBufferBindingBuffer(cb_state, buffer_state);
170}
171
172bool CoreChecks::PreCallValidateCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
173 uint32_t count, uint32_t stride) {
174 bool skip = ValidateCmdDrawType(
175 commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECT, "vkCmdDrawIndexedIndirect()",
176 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDrawIndexedIndirect-commandBuffer-cmdpool", "VUID-vkCmdDrawIndexedIndirect-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600177 "VUID-vkCmdDrawIndexedIndirect-None-02700", "VUID-vkCmdDrawIndexedIndirect-commandBuffer-02701");
John Zulauffbf3c202019-07-17 14:57:14 -0600178 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600179 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndexedIndirect()", "VUID-vkCmdDrawIndexedIndirect-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700180 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600181 "VUID-vkCmdDrawIndexedIndirect-buffer-02709", "vkCmdDrawIndexedIndirect()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700182 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600183 if (count > 1) {
184 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndexedIndirect-drawCount-00528", stride,
185 "VkDrawIndexedIndirectCommand", sizeof(VkDrawIndexedIndirectCommand));
186 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndexedIndirect-drawCount-00540", stride,
187 "VkDrawIndexedIndirectCommand", sizeof(VkDrawIndexedIndirectCommand), count, offset,
188 buffer_state);
189 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700190 // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the
191 // VkDrawIndexedIndirectCommand structures accessed by this command must be 0, which will require access to the contents of
192 // 'buffer'.
193 return skip;
194}
195
196void CoreChecks::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
197 uint32_t count, uint32_t stride) {
198 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
199}
200
John Zulauffbf3c202019-07-17 14:57:14 -0600201void ValidationStateTracker::PostCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
202 VkDeviceSize offset, uint32_t count, uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600203 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700204 BUFFER_STATE *buffer_state = GetBufferState(buffer);
205 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
206 AddCommandBufferBindingBuffer(cb_state, buffer_state);
207}
208
209bool CoreChecks::PreCallValidateCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Lockef39c0772019-04-03 14:40:02 -0600210 bool skip = false;
Lockef39c0772019-04-03 14:40:02 -0600211 skip |= ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH, "vkCmdDispatch()",
212 VK_QUEUE_COMPUTE_BIT, "VUID-vkCmdDispatch-commandBuffer-cmdpool", "VUID-vkCmdDispatch-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600213 "VUID-vkCmdDispatch-None-02700", kVUIDUndefined);
Lockef39c0772019-04-03 14:40:02 -0600214 return skip;
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700215}
216
217void CoreChecks::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
218 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
219}
220
John Zulauffbf3c202019-07-17 14:57:14 -0600221void ValidationStateTracker::PostCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600222 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700223 UpdateStateCmdDrawDispatchType(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
224}
225
226bool CoreChecks::PreCallValidateCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
227 bool skip =
228 ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT, "vkCmdDispatchIndirect()",
229 VK_QUEUE_COMPUTE_BIT, "VUID-vkCmdDispatchIndirect-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600230 "VUID-vkCmdDispatchIndirect-renderpass", "VUID-vkCmdDispatchIndirect-None-02700", kVUIDUndefined);
John Zulauffbf3c202019-07-17 14:57:14 -0600231 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600232 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDispatchIndirect()", "VUID-vkCmdDispatchIndirect-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700233 skip |=
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600234 ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true, "VUID-vkCmdDispatchIndirect-buffer-02709",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700235 "vkCmdDispatchIndirect()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700236 return skip;
237}
238
239void CoreChecks::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
240 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
241}
242
John Zulauffbf3c202019-07-17 14:57:14 -0600243void ValidationStateTracker::PostCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
244 VkDeviceSize offset) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600245 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700246 UpdateStateCmdDrawDispatchType(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
247 BUFFER_STATE *buffer_state = GetBufferState(buffer);
248 AddCommandBufferBindingBuffer(cb_state, buffer_state);
249}
250
251bool CoreChecks::PreCallValidateCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
252 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
253 uint32_t stride) {
254 bool skip = false;
255 if (offset & 3) {
256 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 -0600257 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndirectCountKHR-offset-02710",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700258 "vkCmdDrawIndirectCountKHR() parameter, VkDeviceSize offset (0x%" PRIxLEAST64 "), is not a multiple of 4.",
259 offset);
260 }
261
262 if (countBufferOffset & 3) {
263 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 -0600264 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndirectCountKHR-countBufferOffset-02716",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700265 "vkCmdDrawIndirectCountKHR() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64
266 "), is not a multiple of 4.",
267 countBufferOffset);
268 }
Lockee68ac652019-05-06 10:17:33 -0600269 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndirectCountKHR-stride-03110", stride,
270 "VkDrawIndirectCommand", sizeof(VkDrawIndirectCommand));
271 if (maxDrawCount > 1) {
John Zulauffbf3c202019-07-17 14:57:14 -0600272 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
Lockee68ac652019-05-06 10:17:33 -0600273 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndirectCountKHR-maxDrawCount-03111", stride,
274 "VkDrawIndirectCommand", sizeof(VkDrawIndirectCommand), maxDrawCount, offset,
275 buffer_state);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700276 }
277
278 skip |= ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNTKHR,
279 "vkCmdDrawIndirectCountKHR()", VK_QUEUE_GRAPHICS_BIT,
280 "VUID-vkCmdDrawIndirectCountKHR-commandBuffer-cmdpool", "VUID-vkCmdDrawIndirectCountKHR-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600281 "VUID-vkCmdDrawIndirectCountKHR-None-02700", "VUID-vkCmdDrawIndirectCountKHR-commandBuffer-02701");
John Zulauffbf3c202019-07-17 14:57:14 -0600282 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
283 const BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700284 skip |=
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600285 ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndirectCountKHR()", "VUID-vkCmdDrawIndirectCountKHR-buffer-02708");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700286 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawIndirectCountKHR()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600287 "VUID-vkCmdDrawIndirectCountKHR-countBuffer-02714");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700288 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600289 "VUID-vkCmdDrawIndirectCountKHR-buffer-02709", "vkCmdDrawIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700290 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
291 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600292 "VUID-vkCmdDrawIndirectCountKHR-countBuffer-02715", "vkCmdDrawIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700293 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700294 return skip;
295}
296
John Zulauffbf3c202019-07-17 14:57:14 -0600297void ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer,
298 VkDeviceSize offset, VkBuffer countBuffer,
299 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
300 uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600301 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700302 BUFFER_STATE *buffer_state = GetBufferState(buffer);
303 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
304 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
305 AddCommandBufferBindingBuffer(cb_state, buffer_state);
306 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
307}
308
309bool CoreChecks::PreCallValidateCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
310 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
311 uint32_t maxDrawCount, uint32_t stride) {
312 bool skip = false;
313 if (offset & 3) {
314 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 -0600315 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndexedIndirectCountKHR-offset-02710",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700316 "vkCmdDrawIndexedIndirectCountKHR() parameter, VkDeviceSize offset (0x%" PRIxLEAST64
317 "), is not a multiple of 4.",
318 offset);
319 }
320
321 if (countBufferOffset & 3) {
322 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 -0600323 HandleToUint64(commandBuffer), "VUID-vkCmdDrawIndexedIndirectCountKHR-countBufferOffset-02716",
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700324 "vkCmdDrawIndexedIndirectCountKHR() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64
325 "), is not a multiple of 4.",
326 countBufferOffset);
327 }
328
Lockee68ac652019-05-06 10:17:33 -0600329 skip |= ValidateCmdDrawStrideWithStruct(commandBuffer, "VUID-vkCmdDrawIndexedIndirectCountKHR-stride-03142", stride,
330 "VkDrawIndirectCommand", sizeof(VkDrawIndexedIndirectCommand));
331 if (maxDrawCount > 1) {
John Zulauffbf3c202019-07-17 14:57:14 -0600332 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
Lockee68ac652019-05-06 10:17:33 -0600333 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawIndexedIndirectCountKHR-maxDrawCount-03143", stride,
334 "VkDrawIndirectCommand", sizeof(VkDrawIndexedIndirectCommand), maxDrawCount, offset,
335 buffer_state);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700336 }
337
338 skip |= ValidateCmdDrawType(
339 commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNTKHR, "vkCmdDrawIndexedIndirectCountKHR()",
340 VK_QUEUE_GRAPHICS_BIT, "VUID-vkCmdDrawIndexedIndirectCountKHR-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600341 "VUID-vkCmdDrawIndexedIndirectCountKHR-renderpass", "VUID-vkCmdDrawIndexedIndirectCountKHR-None-02700",
342 "VUID-vkCmdDrawIndexedIndirectCountKHR-commandBuffer-02701");
John Zulauffbf3c202019-07-17 14:57:14 -0600343 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
344 const BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700345 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawIndexedIndirectCountKHR()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600346 "VUID-vkCmdDrawIndexedIndirectCountKHR-buffer-02708");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700347 skip |= ValidateMemoryIsBoundToBuffer(count_buffer_state, "vkCmdDrawIndexedIndirectCountKHR()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600348 "VUID-vkCmdDrawIndexedIndirectCountKHR-countBuffer-02714");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700349 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600350 "VUID-vkCmdDrawIndexedIndirectCountKHR-buffer-02709", "vkCmdDrawIndexedIndirectCountKHR()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700351 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
352 skip |= ValidateBufferUsageFlags(count_buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600353 "VUID-vkCmdDrawIndexedIndirectCountKHR-countBuffer-02715",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700354 "vkCmdDrawIndexedIndirectCountKHR()", "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700355 return skip;
356}
357
John Zulauffbf3c202019-07-17 14:57:14 -0600358void ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer,
359 VkDeviceSize offset, VkBuffer countBuffer,
360 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
361 uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600362 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700363 BUFFER_STATE *buffer_state = GetBufferState(buffer);
364 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
365 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
366 AddCommandBufferBindingBuffer(cb_state, buffer_state);
367 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
368}
369
Jason Macnak67407e72019-07-11 11:05:09 -0700370void CoreChecks::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
371 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
372 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
373 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
374 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
375 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
376 uint32_t width, uint32_t height, uint32_t depth) {
377 GpuAllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV);
378}
379
380void CoreChecks::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
381 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
382 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
383 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
384 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
385 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
386 uint32_t width, uint32_t height, uint32_t depth) {
387 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
388 UpdateStateCmdDrawDispatchType(cb_state, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV);
389 cb_state->hasTraceRaysCmd = true;
390}
391
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700392bool CoreChecks::PreCallValidateCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
393 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV,
394 "vkCmdDrawMeshTasksNV()", VK_QUEUE_GRAPHICS_BIT,
395 "VUID-vkCmdDrawMeshTasksNV-commandBuffer-cmdpool", "VUID-vkCmdDrawMeshTasksNV-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600396 "VUID-vkCmdDrawMeshTasksNV-None-02700", "VUID-vkCmdDrawMeshTasksNV-commandBuffer-02701");
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700397 return skip;
398}
399
John Zulauffbf3c202019-07-17 14:57:14 -0600400void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount,
401 uint32_t firstTask) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600402 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700403 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
404}
405
406bool CoreChecks::PreCallValidateCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
407 uint32_t drawCount, uint32_t stride) {
408 bool skip = ValidateCmdDrawType(commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV,
409 "vkCmdDrawMeshTasksIndirectNV()", VK_QUEUE_GRAPHICS_BIT,
410 "VUID-vkCmdDrawMeshTasksIndirectNV-commandBuffer-cmdpool",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600411 "VUID-vkCmdDrawMeshTasksIndirectNV-renderpass", "VUID-vkCmdDrawMeshTasksIndirectNV-None-02700",
412 "VUID-vkCmdDrawMeshTasksIndirectNV-commandBuffer-02701");
John Zulauffbf3c202019-07-17 14:57:14 -0600413 const BUFFER_STATE *buffer_state = GetBufferState(buffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700414 skip |= ValidateMemoryIsBoundToBuffer(buffer_state, "vkCmdDrawMeshTasksIndirectNV()",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600415 "VUID-vkCmdDrawMeshTasksIndirectNV-buffer-02708");
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700416 skip |= ValidateBufferUsageFlags(buffer_state, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, true,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600417 "VUID-vkCmdDrawMeshTasksIndirectNV-buffer-02709", "vkCmdDrawMeshTasksIndirectNV()",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700418 "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT");
Lockee68ac652019-05-06 10:17:33 -0600419 if (drawCount > 1) {
Lockee68ac652019-05-06 10:17:33 -0600420 skip |= ValidateCmdDrawStrideWithBuffer(commandBuffer, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02157", stride,
421 "VkDrawMeshTasksIndirectCommandNV", sizeof(VkDrawMeshTasksIndirectCommandNV),
422 drawCount, offset, buffer_state);
423 }
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700424 return skip;
425}
426
John Zulauffbf3c202019-07-17 14:57:14 -0600427void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer,
428 VkDeviceSize offset, uint32_t drawCount, uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600429 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700430 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
431 BUFFER_STATE *buffer_state = GetBufferState(buffer);
432 if (buffer_state) {
433 AddCommandBufferBindingBuffer(cb_state, buffer_state);
434 }
435}
436
437bool CoreChecks::PreCallValidateCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
438 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
439 uint32_t maxDrawCount, uint32_t stride) {
440 bool skip = ValidateCmdDrawType(
441 commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV,
442 "vkCmdDrawMeshTasksIndirectCountNV()", VK_QUEUE_GRAPHICS_BIT,
443 "VUID-vkCmdDrawMeshTasksIndirectCountNV-commandBuffer-cmdpool", "VUID-vkCmdDrawMeshTasksIndirectCountNV-renderpass",
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600444 "VUID-vkCmdDrawMeshTasksIndirectCountNV-None-02700", "VUID-vkCmdDrawMeshTasksIndirectCountNV-commandBuffer-02701");
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,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600452 "VUID-vkCmdDrawMeshTasksIndirectCountNV-buffer-02709", "vkCmdDrawIndexedIndirectCountKHR()",
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,
Shannon McPhersonde3eeba2019-04-30 16:53:59 -0600455 "VUID-vkCmdDrawMeshTasksIndirectCountNV-countBuffer-02715",
Jasper St. Pierrebf080462019-04-11 12:54:38 -0700456 "vkCmdDrawIndexedIndirectCountKHR()", "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}
466
John Zulauffbf3c202019-07-17 14:57:14 -0600467void ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer,
468 VkDeviceSize offset, VkBuffer countBuffer,
469 VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
470 uint32_t stride) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -0600471 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
Jasper St. Pierre512613a2019-04-08 16:25:23 -0700472 BUFFER_STATE *buffer_state = GetBufferState(buffer);
473 BUFFER_STATE *count_buffer_state = GetBufferState(countBuffer);
474 UpdateStateCmdDrawType(cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS);
475 if (buffer_state) {
476 AddCommandBufferBindingBuffer(cb_state, buffer_state);
477 }
478 if (count_buffer_state) {
479 AddCommandBufferBindingBuffer(cb_state, count_buffer_state);
480 }
481}