diff options
| author | Michael Lentine <mlentine@google.com> | 2016-02-02 22:24:26 -0600 |
|---|---|---|
| committer | Tobin Ehlis <tobine@google.com> | 2016-02-04 11:17:41 -0700 |
| commit | d2f061db888848768c827367cc02c5ddea7ce49c (patch) | |
| tree | b422dfb84403e9fe2b781cb174d2a3cd4218d1ab /layers | |
| parent | 4aab7a2c557dee3677a90734248a2f0267ad73b3 (diff) | |
| download | usermoji-d2f061db888848768c827367cc02c5ddea7ce49c.tar.xz | |
layers: Validate that fence is not in use when submitted.
Diffstat (limited to 'layers')
| -rw-r--r-- | layers/draw_state.cpp | 73 | ||||
| -rwxr-xr-x | layers/draw_state.h | 181 | ||||
| -rw-r--r-- | layers/vk_validation_layer_details.md | 3 |
3 files changed, 181 insertions, 76 deletions
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp index 06d76f1f..5952625d 100644 --- a/layers/draw_state.cpp +++ b/layers/draw_state.cpp @@ -3312,6 +3312,7 @@ void decrementResources(layer_data* my_data, uint32_t fenceCount, const VkFence* auto fence_data = my_data->fenceMap.find(pFences[i]); if (fence_data == my_data->fenceMap.end() || !fence_data->second.needsSignaled) return; fence_data->second.needsSignaled = false; + fence_data->second.in_use.fetch_sub(1); if (fence_data->second.priorFence != VK_NULL_HANDLE) { decrementResources(my_data, 1, &fence_data->second.priorFence); } @@ -3336,23 +3337,31 @@ void trackCommandBuffers(layer_data* my_data, VkQueue queue, uint32_t cmdBufferC auto queue_data = my_data->queueMap.find(queue); if (fence != VK_NULL_HANDLE) { VkFence priorFence = VK_NULL_HANDLE; + auto fence_data = my_data->fenceMap.find(fence); + if (fence_data == my_data->fenceMap.end()) { + return; + } if (queue_data != my_data->queueMap.end()) { priorFence = queue_data->second.priorFence; queue_data->second.priorFence = fence; for (auto cmdBuffer : queue_data->second.untrackedCmdBuffers) { - my_data->fenceMap[fence].cmdBuffers.push_back(cmdBuffer); + fence_data->second.cmdBuffers.push_back(cmdBuffer); } queue_data->second.untrackedCmdBuffers.clear(); } - my_data->fenceMap[fence].cmdBuffers.clear(); - my_data->fenceMap[fence].priorFence = priorFence; - my_data->fenceMap[fence].needsSignaled = true; - my_data->fenceMap[fence].queue = queue; + fence_data->second.cmdBuffers.clear(); + fence_data->second.priorFence = priorFence; + fence_data->second.needsSignaled = true; + fence_data->second.queue = queue; + fence_data->second.in_use.fetch_add(1); for (uint32_t i = 0; i < cmdBufferCount; ++i) { - for (auto secondaryCmdBuffer : my_data->commandBufferMap[pCmdBuffers[i]]->secondaryCommandBuffers) { - my_data->fenceMap[fence].cmdBuffers.push_back(secondaryCmdBuffer); + for (auto secondaryCmdBuffer : + my_data->commandBufferMap[pCmdBuffers[i]] + ->secondaryCommandBuffers) { + fence_data->second.cmdBuffers.push_back( + secondaryCmdBuffer); } - my_data->fenceMap[fence].cmdBuffers.push_back(pCmdBuffers[i]); + fence_data->second.cmdBuffers.push_back(pCmdBuffers[i]); } } else { if (queue_data != my_data->queueMap.end()) { @@ -3457,7 +3466,17 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint skipCall |= validateCommandBufferState(dev_data, pCB); loader_platform_thread_unlock_mutex(&globalLock); } - trackCommandBuffers(dev_data, queue, submit->commandBufferCount, submit->pCommandBuffers, fence); + if (dev_data->fenceMap[fence].in_use.load()) { + skipCall |= log_msg( + dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, + reinterpret_cast<uint64_t>(fence), __LINE__, + DRAWSTATE_INVALID_FENCE, "DS", + "Fence %#" PRIx64 " is already in use by another submission.", + reinterpret_cast<uint64_t>(fence)); + } + trackCommandBuffers(dev_data, queue, submit->commandBufferCount, + submit->pCommandBuffers, fence); } if (VK_FALSE == skipCall) return dev_data->device_dispatch_table->QueueSubmit(queue, submitCount, pSubmits, fence); @@ -3937,15 +3956,31 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(VkDevice device return result; } -//TODO handle pipeline caches -VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache( - VkDevice device, - const VkPipelineCacheCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkPipelineCache* pPipelineCache) -{ - layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); - VkResult result = dev_data->device_dispatch_table->CreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache); +VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL + vkCreateFence(VkDevice device, const VkFenceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, VkFence* pFence) { + layer_data *dev_data = + get_my_data_ptr(get_dispatch_key(device), layer_data_map); + VkResult result = dev_data->device_dispatch_table->CreateFence( + device, pCreateInfo, pAllocator, pFence); + if (VK_SUCCESS == result) { + loader_platform_thread_lock_mutex(&globalLock); + dev_data->fenceMap[*pFence].in_use.store(0); + loader_platform_thread_unlock_mutex(&globalLock); + } + return result; +} + +// TODO handle pipeline caches +VKAPI_ATTR VkResult VKAPI_CALL + vkCreatePipelineCache(VkDevice device, + const VkPipelineCacheCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkPipelineCache *pPipelineCache) { + layer_data *dev_data = + get_my_data_ptr(get_dispatch_key(device), layer_data_map); + VkResult result = dev_data->device_dispatch_table->CreatePipelineCache( + device, pCreateInfo, pAllocator, pPipelineCache); return result; } @@ -6743,6 +6778,8 @@ VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkD return (PFN_vkVoidFunction) vkCreateImage; if (!strcmp(funcName, "vkCreateImageView")) return (PFN_vkVoidFunction) vkCreateImageView; + if (!strcmp(funcName, "vkCreateFence")) + return (PFN_vkVoidFunction) vkCreateFence; if (!strcmp(funcName, "CreatePipelineCache")) return (PFN_vkVoidFunction) vkCreatePipelineCache; if (!strcmp(funcName, "DestroyPipelineCache")) diff --git a/layers/draw_state.h b/layers/draw_state.h index f8cf2f13..0726e0f6 100755 --- a/layers/draw_state.h +++ b/layers/draw_state.h @@ -41,63 +41,130 @@ using std::vector; // Draw State ERROR codes -typedef enum _DRAW_STATE_ERROR -{ - DRAWSTATE_NONE, // Used for INFO & other non-error messages - DRAWSTATE_INTERNAL_ERROR, // Error with DrawState internal data structures - DRAWSTATE_NO_PIPELINE_BOUND, // Unable to identify a bound pipeline - DRAWSTATE_INVALID_POOL, // Invalid DS pool - DRAWSTATE_INVALID_SET, // Invalid DS - DRAWSTATE_INVALID_LAYOUT, // Invalid DS layout - DRAWSTATE_INVALID_IMAGE_LAYOUT, // Invalid Image layout - DRAWSTATE_INVALID_PIPELINE, // Invalid Pipeline handle referenced - DRAWSTATE_INVALID_PIPELINE_LAYOUT, // Invalid PipelineLayout - DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, // Attempt to create a pipeline with invalid state - DRAWSTATE_INVALID_COMMAND_BUFFER, // Invalid CommandBuffer referenced - DRAWSTATE_INVALID_BARRIER, // Invalid Barrier - DRAWSTATE_INVALID_BUFFER, // Invalid Buffer - DRAWSTATE_INVALID_QUERY, // Invalid Query - DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, // binding in vkCmdBindVertexData() too large for PSO's pVertexBindingDescriptions array - DRAWSTATE_VTX_INDEX_ALIGNMENT_ERROR, // binding offset in vkCmdBindIndexBuffer() out of alignment based on indexType - //DRAWSTATE_MISSING_DOT_PROGRAM, // No "dot" program in order to generate png image - DRAWSTATE_OUT_OF_MEMORY, // malloc failed - DRAWSTATE_INVALID_DESCRIPTOR_SET, // Descriptor Set handle is unknown - DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, // Type in layout vs. update are not the same - DRAWSTATE_DESCRIPTOR_STAGEFLAGS_MISMATCH, // StageFlags in layout are not the same throughout a single VkWriteDescriptorSet update - DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, // Descriptors set for update out of bounds for corresponding layout section - DRAWSTATE_DESCRIPTOR_POOL_EMPTY, // Attempt to allocate descriptor from a pool with no more descriptors of that type available - DRAWSTATE_CANT_FREE_FROM_NON_FREE_POOL, // Invalid to call vkFreeDescriptorSets on Sets allocated from a NON_FREE Pool - DRAWSTATE_INVALID_UPDATE_INDEX, // Index of requested update is invalid for specified descriptors set - DRAWSTATE_INVALID_UPDATE_STRUCT, // Struct in DS Update tree is of invalid type - DRAWSTATE_NUM_SAMPLES_MISMATCH, // Number of samples in bound PSO does not match number in FB of current RenderPass - DRAWSTATE_NO_END_COMMAND_BUFFER, // Must call vkEndCommandBuffer() before QueueSubmit on that commandBuffer - DRAWSTATE_NO_BEGIN_COMMAND_BUFFER, // Binding cmds or calling End on CB that never had vkBeginCommandBuffer() called on it - DRAWSTATE_COMMAND_BUFFER_SINGLE_SUBMIT_VIOLATION, // Cmd Buffer created with VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT flag is submitted multiple times - DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, // vkCmdExecuteCommands() called with a primary commandBuffer in pCommandBuffers array - DRAWSTATE_VIEWPORT_NOT_BOUND, // Draw submitted with no viewport state bound - DRAWSTATE_SCISSOR_NOT_BOUND, // Draw submitted with no scissor state bound - DRAWSTATE_LINE_WIDTH_NOT_BOUND, // Draw submitted with no line width state bound - DRAWSTATE_DEPTH_BIAS_NOT_BOUND, // Draw submitted with no depth bias state bound - DRAWSTATE_BLEND_NOT_BOUND, // Draw submitted with no blend state bound when color write enabled - DRAWSTATE_DEPTH_BOUNDS_NOT_BOUND, // Draw submitted with no depth bounds state bound when depth enabled - DRAWSTATE_STENCIL_NOT_BOUND, // Draw submitted with no stencil state bound when stencil enabled - DRAWSTATE_INDEX_BUFFER_NOT_BOUND, // Draw submitted with no depth-stencil state bound when depth write enabled - DRAWSTATE_PIPELINE_LAYOUTS_INCOMPATIBLE, // Draw submitted PSO Pipeline layout that's not compatible with layout from BindDescriptorSets - DRAWSTATE_RENDERPASS_INCOMPATIBLE, // Incompatible renderpasses between secondary cmdBuffer and primary cmdBuffer or framebuffer - DRAWSTATE_FRAMEBUFFER_INCOMPATIBLE, // Incompatible framebuffer between secondary cmdBuffer and active renderPass - DRAWSTATE_INVALID_RENDERPASS, // Use of a NULL or otherwise invalid RenderPass object - DRAWSTATE_INVALID_RENDERPASS_CMD, // Invalid cmd submitted while a RenderPass is active - DRAWSTATE_NO_ACTIVE_RENDERPASS, // Rendering cmd submitted without an active RenderPass - DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, // DescriptorSet bound but it was never updated. This is a warning code. - DRAWSTATE_DESCRIPTOR_SET_NOT_BOUND, // DescriptorSet used by pipeline at draw time is not bound, or has been disturbed (which would have flagged previous warning) - DRAWSTATE_INVALID_DYNAMIC_OFFSET_COUNT, // DescriptorSets bound with different number of dynamic descriptors that were included in dynamicOffsetCount - DRAWSTATE_CLEAR_CMD_BEFORE_DRAW, // Clear cmd issued before any Draw in CommandBuffer, should use RenderPass Ops instead - DRAWSTATE_BEGIN_CB_INVALID_STATE, // CB state at Begin call is bad. Can be Primary/Secondary CB created with mismatched FB/RP information or CB in RECORDING state - DRAWSTATE_INVALID_CB_SIMULTANEOUS_USE, // CmdBuffer is being used in violation of VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT rules (i.e. simultaneous use w/o that bit set) - DRAWSTATE_INVALID_COMMAND_BUFFER_RESET, // Attempting to call Reset (or Begin on recorded cmdBuffer) that was allocated from Pool w/o VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit set. Can also happen when the command buffer is being reset (or freed) when in use. - DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, // Count for viewports and scissors mismatch and/or state doesn't match count - DRAWSTATE_INVALID_IMAGE_ASPECT, // Image aspect is invalid for the current operation - DRAWSTATE_MISSING_ATTACHMENT_REFERENCE, // Attachment reference must be present in active subpass +typedef enum _DRAW_STATE_ERROR { + DRAWSTATE_NONE, // Used for INFO & other non-error messages + DRAWSTATE_INTERNAL_ERROR, // Error with DrawState internal data structures + DRAWSTATE_NO_PIPELINE_BOUND, // Unable to identify a bound pipeline + DRAWSTATE_INVALID_POOL, // Invalid DS pool + DRAWSTATE_INVALID_SET, // Invalid DS + DRAWSTATE_INVALID_LAYOUT, // Invalid DS layout + DRAWSTATE_INVALID_IMAGE_LAYOUT, // Invalid Image layout + DRAWSTATE_INVALID_PIPELINE, // Invalid Pipeline handle referenced + DRAWSTATE_INVALID_PIPELINE_LAYOUT, // Invalid PipelineLayout + DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, // Attempt to create a pipeline + // with invalid state + DRAWSTATE_INVALID_COMMAND_BUFFER, // Invalid CommandBuffer referenced + DRAWSTATE_INVALID_BARRIER, // Invalid Barrier + DRAWSTATE_INVALID_BUFFER, // Invalid Buffer + DRAWSTATE_INVALID_QUERY, // Invalid Query + DRAWSTATE_INVALID_FENCE, // Invalid Fence + DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, // binding in vkCmdBindVertexData() too + // large for PSO's + // pVertexBindingDescriptions array + DRAWSTATE_VTX_INDEX_ALIGNMENT_ERROR, // binding offset in + // vkCmdBindIndexBuffer() out of + // alignment based on indexType + // DRAWSTATE_MISSING_DOT_PROGRAM, // No "dot" program in order + // to generate png image + DRAWSTATE_OUT_OF_MEMORY, // malloc failed + DRAWSTATE_INVALID_DESCRIPTOR_SET, // Descriptor Set handle is unknown + DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, // Type in layout vs. update are not the + // same + DRAWSTATE_DESCRIPTOR_STAGEFLAGS_MISMATCH, // StageFlags in layout are not + // the same throughout a single + // VkWriteDescriptorSet update + DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, // Descriptors set for update out + // of bounds for corresponding + // layout section + DRAWSTATE_DESCRIPTOR_POOL_EMPTY, // Attempt to allocate descriptor from a + // pool with no more descriptors of that + // type available + DRAWSTATE_CANT_FREE_FROM_NON_FREE_POOL, // Invalid to call + // vkFreeDescriptorSets on Sets + // allocated from a NON_FREE Pool + DRAWSTATE_INVALID_UPDATE_INDEX, // Index of requested update is invalid for + // specified descriptors set + DRAWSTATE_INVALID_UPDATE_STRUCT, // Struct in DS Update tree is of invalid + // type + DRAWSTATE_NUM_SAMPLES_MISMATCH, // Number of samples in bound PSO does not + // match number in FB of current RenderPass + DRAWSTATE_NO_END_COMMAND_BUFFER, // Must call vkEndCommandBuffer() before + // QueueSubmit on that commandBuffer + DRAWSTATE_NO_BEGIN_COMMAND_BUFFER, // Binding cmds or calling End on CB that + // never had vkBeginCommandBuffer() + // called on it + DRAWSTATE_COMMAND_BUFFER_SINGLE_SUBMIT_VIOLATION, // Cmd Buffer created with + // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT + // flag is submitted + // multiple times + DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, // vkCmdExecuteCommands() called + // with a primary commandBuffer + // in pCommandBuffers array + DRAWSTATE_VIEWPORT_NOT_BOUND, // Draw submitted with no viewport state bound + DRAWSTATE_SCISSOR_NOT_BOUND, // Draw submitted with no scissor state bound + DRAWSTATE_LINE_WIDTH_NOT_BOUND, // Draw submitted with no line width state + // bound + DRAWSTATE_DEPTH_BIAS_NOT_BOUND, // Draw submitted with no depth bias state + // bound + DRAWSTATE_BLEND_NOT_BOUND, // Draw submitted with no blend state bound when + // color write enabled + DRAWSTATE_DEPTH_BOUNDS_NOT_BOUND, // Draw submitted with no depth bounds + // state bound when depth enabled + DRAWSTATE_STENCIL_NOT_BOUND, // Draw submitted with no stencil state bound + // when stencil enabled + DRAWSTATE_INDEX_BUFFER_NOT_BOUND, // Draw submitted with no depth-stencil + // state bound when depth write enabled + DRAWSTATE_PIPELINE_LAYOUTS_INCOMPATIBLE, // Draw submitted PSO Pipeline + // layout that's not compatible + // with layout from + // BindDescriptorSets + DRAWSTATE_RENDERPASS_INCOMPATIBLE, // Incompatible renderpasses between + // secondary cmdBuffer and primary + // cmdBuffer or framebuffer + DRAWSTATE_FRAMEBUFFER_INCOMPATIBLE, // Incompatible framebuffer between + // secondary cmdBuffer and active + // renderPass + DRAWSTATE_INVALID_RENDERPASS, // Use of a NULL or otherwise invalid + // RenderPass object + DRAWSTATE_INVALID_RENDERPASS_CMD, // Invalid cmd submitted while a + // RenderPass is active + DRAWSTATE_NO_ACTIVE_RENDERPASS, // Rendering cmd submitted without an active + // RenderPass + DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, // DescriptorSet bound but it was + // never updated. This is a warning + // code. + DRAWSTATE_DESCRIPTOR_SET_NOT_BOUND, // DescriptorSet used by pipeline at + // draw time is not bound, or has been + // disturbed (which would have flagged + // previous warning) + DRAWSTATE_INVALID_DYNAMIC_OFFSET_COUNT, // DescriptorSets bound with + // different number of dynamic + // descriptors that were included in + // dynamicOffsetCount + DRAWSTATE_CLEAR_CMD_BEFORE_DRAW, // Clear cmd issued before any Draw in + // CommandBuffer, should use RenderPass Ops + // instead + DRAWSTATE_BEGIN_CB_INVALID_STATE, // CB state at Begin call is bad. Can be + // Primary/Secondary CB created with + // mismatched FB/RP information or CB in + // RECORDING state + DRAWSTATE_INVALID_CB_SIMULTANEOUS_USE, // CmdBuffer is being used in + // violation of + // VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT + // rules (i.e. simultaneous use w/o + // that bit set) + DRAWSTATE_INVALID_COMMAND_BUFFER_RESET, // Attempting to call Reset (or + // Begin on recorded cmdBuffer) that + // was allocated from Pool w/o + // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT + // bit set + DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, // Count for viewports and scissors + // mismatch and/or state doesn't match + // count + DRAWSTATE_INVALID_IMAGE_ASPECT, // Image aspect is invalid for the current + // operation + DRAWSTATE_MISSING_ATTACHMENT_REFERENCE, // Attachment reference must be + // present in active subpass DRAWSTATE_INVALID_EXTENSION, DRAWSTATE_SAMPLER_DESCRIPTOR_ERROR, // A Descriptor of *_SAMPLER type is being updated with an invalid or bad Sampler DRAWSTATE_INCONSISTENT_IMMUTABLE_SAMPLER_UPDATE, // Descriptors of *COMBINED_IMAGE_SAMPLER type are being updated where some, but not all, of the updates use immutable samplers diff --git a/layers/vk_validation_layer_details.md b/layers/vk_validation_layer_details.md index d4f1269d..cce7234b 100644 --- a/layers/vk_validation_layer_details.md +++ b/layers/vk_validation_layer_details.md @@ -71,7 +71,8 @@ The VK_LAYER_LUNARG_draw_state layer tracks state leading into Draw cmds. This i | Verify Memory Buffer Not Deleted | Validate Command Buffer not submitted with deleted memory buffer | INVALID_BUFFER | vkQueueSubmit | TBD | None | | Verify Memory Buffer Destroy | Validate memory buffers are not destroyed more than once | DOUBLE_DESTROY | vkDestroyBuffer | TBD | None | | Verify Object Not In Use | Validate that object being freed or modified is not in use | OBJECT_INUSE | vkDestroyBuffer vkFreeDescriptorSets vkUpdateDescriptorSets | TBD | None | -| Verify Get Queries| Validate that that queries are properly setup, initialized, synchronized | INVALID_QUERY | vkGetFenceStatus vkQueueWaitIdle vkWaitForFences vkDeviceWaitIdle vkCmdBeginQuery vkCmdEndQuery| TBD | None | +| Verify Get Queries| Validate that that queries are properly setup, initialized and synchronized | INVALID_QUERY | vkGetFenceStatus vkQueueWaitIdle vkWaitForFences vkDeviceWaitIdle vkCmdBeginQuery vkCmdEndQuery | TBD | None | +| Verify Fences Not In Use | Validate that that fences are not used in multiple submit calls at the same time | INVALID_FENCE | vkQueueSubmit | TBD | None | | Live Semaphore | When waiting on a semaphore, need to make sure that the semaphore is live and therefore can be signalled, otherwise queue is stalled and cannot make forward progress. | QUEUE_FORWARD_PROGRESS | vkQueueSubmit vkQueueBindSparse vkQueuePresentKHR vkAcquireNextImageKHR | TODO | Create test | | Storage Buffer Alignment | Storage Buffer offsets in BindDescriptorSets must agree with offset alignment device limit | INVALID_STORAGE_BUFFER_OFFSET | vkCmdBindDescriptorSets | TODO | Create test | | Uniform Buffer Alignment | Uniform Buffer offsets in BindDescriptorSets must agree with offset alignment device limit | INVALID_UNIFORM_BUFFER_OFFSET | vkCmdBindDescriptorSets | TODO | Create test | |
