From cd40b75c8099e874087ea21cd919bb5f434e3e6e Mon Sep 17 00:00:00 2001 From: John Zulauf Date: Fri, 26 Jan 2018 11:23:10 -0700 Subject: layers: Add CmdPushDescriptorSet parameter checks Added the stateful parameter checks for push descriptor. VALIDATION_ERROR_1be02415 VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations VALIDATION_ERROR_1be002d6 VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363 pipelineBindPoint must be supported by the commandBuffer's parent VkCommandPool's queue family VALIDATION_ERROR_1be002da VUID-vkCmdPushDescriptorSetKHR-set-00365 set must be the unique set number in the pipeline layout that uses a descriptor set layout that was created with VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR VALIDATION_ERROR_1be002d8 VUID-vkCmdPushDescriptorSetKHR-set-00364 set must be less than VkPipelineLayoutCreateInfo::setLayoutCount provided when layout was created // Not implemented using VUID as ValidateCmd currently doesn't support (TODO) VUID-vkCmdPushDescriptorSetKHR-commandBuffer-recording commandBuffer must be in the recording state Change-Id: I52f39780003e23953dd2dc46ec007e884c04fa5b --- layers/core_validation.cpp | 86 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 9 deletions(-) (limited to 'layers/core_validation.cpp') diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index c36d6477..2257178d 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -37,6 +37,7 @@ #define NOMINMAX #include +#include #include #include #include @@ -5624,7 +5625,7 @@ VKAPI_ATTR void VKAPI_CALL CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipe skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdBindPipeline()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_18002415); skip |= ValidateCmd(dev_data, cb_state, CMD_BINDPIPELINE, "vkCmdBindPipeline()"); - // TODO: VALIDATION_ERROR_18000612 VALIDATION_ERROR_18000616 + // TODO: VALIDATION_ERROR_18000612 VALIDATION_ERROR_18000616 -- using ValidatePipelineBindPoint auto pipe_state = getPipelineState(dev_data, pipeline); if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) { @@ -6045,11 +6046,73 @@ VKAPI_ATTR void VKAPI_CALL CmdBindDescriptorSets(VkCommandBuffer commandBuffer, } } -static void PreCallRecordCmdPushDescriptorSetKHR(layer_data *device_data, VkCommandBuffer commandBuffer, +// Validates that the supplied bind point is supported for the command buffer (vis. the command pool) +// Takes array of error codes as some of the VUID's (e.g. vkCmdBindPipeline) are written per bindpoint +// TODO add vkCmdBindPipeline bind_point validation using this call. +bool ValidatePipelineBindPoint(layer_data *device_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point, + const char *func_name, + const std::array &bind_errors) { + bool skip = false; + auto pool = GetCommandPoolNode(device_data, cb_state->createInfo.commandPool); + if (pool) { // The loss of a pool in a recording cmd is reported in DestroyCommandPool + static const VkQueueFlags flag_mask[VK_PIPELINE_BIND_POINT_RANGE_SIZE] = {VK_QUEUE_GRAPHICS_BIT, VK_QUEUE_COMPUTE_BIT}; + const auto bind_point_index = bind_point - VK_PIPELINE_BIND_POINT_BEGIN_RANGE; // typeof enum is not defined, use auto + const auto &qfp = GetPhysDevProperties(device_data)->queue_family_properties[pool->queueFamilyIndex]; + if (0 == (qfp.queueFlags & flag_mask[bind_point_index])) { + const UNIQUE_VALIDATION_ERROR_CODE error = bind_errors[bind_point_index]; + auto cb_u64 = HandleToUint64(cb_state->commandBuffer); + auto cp_u64 = HandleToUint64(cb_state->createInfo.commandPool); + skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, + cb_u64, __LINE__, error, "DS", + "%s: CommandBuffer 0x%" PRIxLEAST64 " was allocated from VkCommandPool 0x%" PRIxLEAST64 + " that does not support bindpoint %s. %s", + func_name, cb_u64, cp_u64, string_VkPipelineBindPoint(bind_point), validation_error_map[error]); + } + } + return skip; +} + +static bool PreCallValidateCmdPushDescriptorSetKHR(layer_data *device_data, GLOBAL_CB_NODE *cb_state, + const VkPipelineBindPoint bind_point, const VkPipelineLayout layout, + const uint32_t set, const uint32_t descriptor_write_count, + const VkWriteDescriptorSet *descriptor_writes, const char *func_name) { + bool skip = false; + skip |= ValidateCmd(device_data, cb_state, CMD_PUSHDESCRIPTORSET, func_name); + skip |= ValidateCmdQueueFlags(device_data, cb_state, func_name, (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT), + VALIDATION_ERROR_1be02415); + skip |= ValidatePipelineBindPoint(device_data, cb_state, bind_point, func_name, + {{VALIDATION_ERROR_1be002d6, VALIDATION_ERROR_1be002d6}}); + auto layout_data = getPipelineLayout(device_data, layout); + + // Validate the set index points to a push descriptor set and is in range + if (layout_data) { + const auto &set_layouts = layout_data->set_layouts; + const auto layout_u64 = HandleToUint64(layout); + if (set < set_layouts.size()) { + const auto *dsl = set_layouts[set].get(); + if (dsl && (0 == (dsl->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR))) { + skip = + log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, layout_u64, __LINE__, VALIDATION_ERROR_1be002da, "DS", + "%s: Set index %" PRIu32 + " does not match push descriptor set layout index for VkPipelineLayout 0x%" PRIxLEAST64 ". %s", + func_name, set, layout_u64, validation_error_map[VALIDATION_ERROR_1be002da]); + } + } else { + skip = log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, + layout_u64, __LINE__, VALIDATION_ERROR_1be002d8, "DS", + "%s: Set index %" PRIu32 " is outside of range for VkPipelineLayout 0x%" PRIxLEAST64 " (set < %" PRIu32 + "). %s", + func_name, set, layout_u64, static_cast(set_layouts.size()), + validation_error_map[VALIDATION_ERROR_1be002d8]); + } + } + + return skip; +} +static void PreCallRecordCmdPushDescriptorSetKHR(layer_data *device_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites) { - auto cb_state = GetCBNode(device_data, commandBuffer); - if (set >= cb_state->lastBound[pipelineBindPoint].boundDescriptorSets.size()) { cb_state->lastBound[pipelineBindPoint].boundDescriptorSets.resize(set + 1); cb_state->lastBound[pipelineBindPoint].dynamicOffsets.resize(set + 1); @@ -6066,11 +6129,16 @@ VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer const VkWriteDescriptorSet *pDescriptorWrites) { layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); unique_lock_t lock(global_lock); - PreCallRecordCmdPushDescriptorSetKHR(device_data, commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount, - pDescriptorWrites); - lock.unlock(); - device_data->dispatch_table.CmdPushDescriptorSetKHR(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount, - pDescriptorWrites); + auto cb_state = GetCBNode(device_data, commandBuffer); + bool skip = PreCallValidateCmdPushDescriptorSetKHR(device_data, cb_state, pipelineBindPoint, layout, set, descriptorWriteCount, + pDescriptorWrites, "vkCmdPushDescriptorSetKHR()"); + if (!skip) { + PreCallRecordCmdPushDescriptorSetKHR(device_data, cb_state, pipelineBindPoint, layout, set, descriptorWriteCount, + pDescriptorWrites); + lock.unlock(); + device_data->dispatch_table.CmdPushDescriptorSetKHR(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount, + pDescriptorWrites); + } } static VkDeviceSize GetIndexAlignment(VkIndexType indexType) { -- cgit v1.2.3