[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

vulkan: Changes to 'upstream-unstable'



Rebased ref, commits from common ancestor:
commit 5b99166d38c86853cd5b744cdb13c08d7d9e0556
Author: Tony Barbour <tony@LunarG.com>
Date:   Thu Dec 15 14:52:44 2016 -0700

    tests: Remove test for nonCoherentAtomSize check
    
    Change-Id: I7ba25d6e0b8bf0623e386d04041070fbc505a129

diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index b194e98..81c8356 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -1484,6 +1484,7 @@ TEST_F(VkLayerTest, InvalidMemoryMapping) {
     vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
     m_errorMonitor->VerifyFound();
 
+#if 0 // Planning discussion with working group on this validation check.
     // Some platforms have an atomsize of 1 which makes the test meaningless
     if (atom_size > 3) {
         // Now with an offset NOT a multiple of the device limit
@@ -1506,7 +1507,7 @@ TEST_F(VkLayerTest, InvalidMemoryMapping) {
         vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
         m_errorMonitor->VerifyFound();
     }
-
+#endif
     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
                                            VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
     if (!pass) {

commit dd09f79361eeaeb05469a96b596c06a9ef980041
Author: Tony Barbour <tony@LunarG.com>
Date:   Thu Dec 15 12:12:29 2016 -0700

    layers: Remove check for nonCoherentAtomSize
    
    It's come to our attention that this check, while matching the spec,
    may be a little overzealous and could cause a lot of existing code
    to start failing validation.  We plan to address this with the spec
    working group, and we're removing the check for now.
    
    Change-Id: I7159b72fe0a2e81bf75bccddc9939da7086992b7

diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 43c767d..fa06308 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -11454,7 +11454,6 @@ static bool PreCallValidateFlushMappedMemoryRanges(layer_data *dev_data, uint32_
                                                    const VkMappedMemoryRange *mem_ranges) {
     bool skip = false;
     std::lock_guard<std::mutex> lock(global_lock);
-    skip |= ValidateMappedMemoryRangeDeviceLimits(dev_data, "vkFlushMappedMemoryRanges", mem_range_count, mem_ranges);
     skip |= ValidateAndCopyNoncoherentMemoryToDriver(dev_data, mem_range_count, mem_ranges);
     skip |= validateMemoryIsMapped(dev_data, "vkFlushMappedMemoryRanges", mem_range_count, mem_ranges);
     return skip;
@@ -11475,7 +11474,6 @@ static bool PreCallValidateInvalidateMappedMemoryRanges(layer_data *dev_data, ui
                                                         const VkMappedMemoryRange *mem_ranges) {
     bool skip = false;
     std::lock_guard<std::mutex> lock(global_lock);
-    skip |= ValidateMappedMemoryRangeDeviceLimits(dev_data, "vkInvalidateMappedMemoryRanges", mem_range_count, mem_ranges);
     skip |= validateMemoryIsMapped(dev_data, "vkInvalidateMappedMemoryRanges", mem_range_count, mem_ranges);
     return skip;
 }

commit 685755cf38a9fc175f5a423e2d81d975fa8972c1
Author: Mark Young <marky@lunarg.com>
Date:   Tue Dec 13 17:19:32 2016 -0700

    loader: Removed some unnecessary code.
    
    Now that all WSI paths need the ICD structs, I can get rid of
    a code path no longer used.
    
    Change-Id: Ib5073cd2074fcd66453dae5b6c89870c81f7f958

diff --git a/loader/wsi.c b/loader/wsi.c
index 9462b44..c577063 100644
--- a/loader/wsi.c
+++ b/loader/wsi.c
@@ -512,8 +512,7 @@ vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
 
 static VkIcdSurface *AllocateIcdSurfaceStruct(struct loader_instance *instance,
                                               size_t base_size,
-                                              size_t platform_size,
-                                              bool create_icd_surfs) {
+                                              size_t platform_size) {
     // Next, if so, proceed with the implementation of this function:
     VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(
         instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
@@ -526,19 +525,15 @@ static VkIcdSurface *AllocateIcdSurfaceStruct(struct loader_instance *instance,
             (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
         pIcdSurface->entire_size = sizeof(VkIcdSurface);
 
-        if (create_icd_surfs) {
-            pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(
-                instance, sizeof(VkSurfaceKHR) * instance->total_icd_count,
-                VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
-            if (pIcdSurface->real_icd_surfaces == NULL) {
-                loader_instance_heap_free(instance, pIcdSurface);
-                pIcdSurface = NULL;
-            } else {
-                memset(pIcdSurface->real_icd_surfaces, 0,
-                       sizeof(VkSurfaceKHR) * instance->total_icd_count);
-            }
+        pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(
+            instance, sizeof(VkSurfaceKHR) * instance->total_icd_count,
+            VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+        if (pIcdSurface->real_icd_surfaces == NULL) {
+            loader_instance_heap_free(instance, pIcdSurface);
+            pIcdSurface = NULL;
         } else {
-            pIcdSurface->real_icd_surfaces = NULL;
+            memset(pIcdSurface->real_icd_surfaces, 0,
+                   sizeof(VkSurfaceKHR) * instance->total_icd_count);
         }
     }
     return pIcdSurface;
@@ -584,7 +579,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(
     // Next, if so, proceed with the implementation of this function:
     pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance,
                                            sizeof(pIcdSurface->win_surf.base),
-                                           sizeof(pIcdSurface->win_surf), true);
+                                           sizeof(pIcdSurface->win_surf));
     if (pIcdSurface == NULL) {
         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;
@@ -716,7 +711,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMirSurfaceKHR(
     // Next, if so, proceed with the implementation of this function:
     pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance,
                                            sizeof(pIcdSurface->mir_surf.base),
-                                           sizeof(pIcdSurface->mir_surf), true);
+                                           sizeof(pIcdSurface->mir_surf));
     if (pIcdSurface == NULL) {
         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;
@@ -852,7 +847,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(
     // Next, if so, proceed with the implementation of this function:
     pIcdSurface = AllocateIcdSurfaceStruct(
         ptr_instance, sizeof(pIcdSurface->wayland_surf.base),
-        sizeof(pIcdSurface->wayland_surf), true);
+        sizeof(pIcdSurface->wayland_surf));
     if (pIcdSurface == NULL) {
         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;
@@ -987,7 +982,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(
     // Next, if so, proceed with the implementation of this function:
     pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance,
                                            sizeof(pIcdSurface->xcb_surf.base),
-                                           sizeof(pIcdSurface->xcb_surf), true);
+                                           sizeof(pIcdSurface->xcb_surf));
     if (pIcdSurface == NULL) {
         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;
@@ -1123,7 +1118,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(
     // Next, if so, proceed with the implementation of this function:
     pIcdSurface = AllocateIcdSurfaceStruct(
         ptr_instance, sizeof(pIcdSurface->xlib_surf.base),
-        sizeof(pIcdSurface->xlib_surf), true);
+        sizeof(pIcdSurface->xlib_surf));
     if (pIcdSurface == NULL) {
         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;
@@ -1531,7 +1526,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(
     // Next, if so, proceed with the implementation of this function:
     pIcdSurface =
         AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->display_surf.base),
-                                 sizeof(pIcdSurface->display_surf), true);
+                                 sizeof(pIcdSurface->display_surf));
     if (pIcdSurface == NULL) {
         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;

commit 013e39a0873b11a0690de3c3aeb9686128cef01b
Author: Piers Daniell <pdaniell@nvidia.com>
Date:   Tue Dec 13 16:51:49 2016 -0700

    Allocate for real ICD surfaces for the VK_KHR_display extension
    
    This was done for all the other WSI extensions, just not VK_KHR_display

diff --git a/loader/wsi.c b/loader/wsi.c
index c627026..9462b44 100644
--- a/loader/wsi.c
+++ b/loader/wsi.c
@@ -1528,11 +1528,10 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(
         goto out;
     }
 
-    // The VK_KHR_display path will continue to use the old path (hence the
-    // false as the last parameter).
+    // Next, if so, proceed with the implementation of this function:
     pIcdSurface =
         AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->display_surf.base),
-                                 sizeof(pIcdSurface->display_surf), false);
+                                 sizeof(pIcdSurface->display_surf), true);
     if (pIcdSurface == NULL) {
         vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
         goto out;

commit ccde29c12e76d93133ec01c8b297f83f99abb545
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Mon Dec 12 08:33:13 2016 -0700

    layers: Add some val/state-update todos
    
    Couple of routines combine state updates and validation, adding a
    note for future work.
    
    Change-Id: I417025bbcabfd3e80ccefe166bc6ea3497222753

diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 906a7b1..43c767d 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -3792,6 +3792,7 @@ static bool checkGraphicsOrComputeBit(const layer_data *my_data, VkQueueFlags fl
 
 // Add specified CMD to the CmdBuffer in given pCB, flagging errors if CB is not
 //  in the recording state or if there's an issue with the Cmd ordering
+// TODO: Tease apart validation and CB state updates
 static bool addCmd(layer_data *my_data, GLOBAL_CB_NODE *pCB, const CMD_TYPE cmd, const char *caller_name) {
     bool skip_call = false;
     auto pPool = getCommandPoolNode(my_data, pCB->createInfo.commandPool);
@@ -9022,6 +9023,7 @@ CmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags
         dev_data->dispatch_table.CmdResetEvent(commandBuffer, event, stageMask);
 }
 
+// TODO: Separate validation and layout state updates
 static bool TransitionImageLayouts(VkCommandBuffer cmdBuffer, uint32_t memBarrierCount,
                                    const VkImageMemoryBarrier *pImgMemBarriers) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);

commit 9f4d9dca546ec851f0d306e54dc0873411081098
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Tue Dec 13 08:47:35 2016 -0700

    layers: Update error database for new checks
    
    Added 2510 and 2518.
    
    Change-Id: I278bfe12d78c5239aa00f82ac4a1b35b5dcd58d0

diff --git a/layers/vk_validation_error_database.txt b/layers/vk_validation_error_database.txt
index 21764d3..efec68f 100644
--- a/layers/vk_validation_error_database.txt
+++ b/layers/vk_validation_error_database.txt
@@ -2439,10 +2439,10 @@ VALIDATION_ERROR_02506~^~U~^~Unknown~^~vkCreateXcbSurfaceKHR~^~For more informat
 VALIDATION_ERROR_02507~^~U~^~Unknown~^~vkCreateXlibSurfaceKHR~^~For more information refer to Vulkan Spec Section '30.2.6. Xlib Platform' which states 'window must be a valid Xlib Window.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXlibSurfaceCreateInfoKHR)~^~
 VALIDATION_ERROR_02508~^~U~^~Unknown~^~vkEnumerateDeviceExtensionProperties~^~For more information refer to Vulkan Spec Section '31.2. Extensions' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkExtensionProperties structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceExtensionProperties)~^~
 VALIDATION_ERROR_02509~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any stage flag included in any element of the pWaitDstStageMask member of any element of pSubmits must be a pipeline stage supported by one of the capabilities of queue, as specified in the table of supported pipeline stages.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueSubmit)~^~
-VALIDATION_ERROR_02510~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.4. Events' which states 'Any pipeline stage included in srcStageMask or dstStageMask must be supported by the capabilities of the queue family specified by the queueFamilyIndex member of the VkCommandPoolCreateInfo structure that was used to create the VkCommandPool that commandBuffer was allocated from, as specified in the table of supported pipeline stages.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_02510~^~Y~^~InvalidBarriers~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.4. Events' which states 'Any pipeline stage included in srcStageMask or dstStageMask must be supported by the capabilities of the queue family specified by the queueFamilyIndex member of the VkCommandPoolCreateInfo structure that was used to create the VkCommandPool that commandBuffer was allocated from, as specified in the table of supported pipeline stages.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
 VALIDATION_ERROR_02511~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.4. Events' which states 'Any given element of pMemoryBarriers, pBufferMemoryBarriers or pImageMemoryBarriers must not have any access flag included in its srcAccessMask member if that bit is not supported by any of the pipeline stages in srcStageMask, as specified in the table of supported access types.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
 VALIDATION_ERROR_02512~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.4. Events' which states 'Any given element of pMemoryBarriers, pBufferMemoryBarriers or pImageMemoryBarriers must not have any access flag included in its dstAccessMask member if that bit is not supported by any of the pipeline stages in dstStageMask, as specified in the table of supported access types.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
-VALIDATION_ERROR_02513~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'Any pipeline stage included in srcStageMask or dstStageMask must be supported by the capabilities of the queue family specified by the queueFamilyIndex member of the VkCommandPoolCreateInfo structure that was used to create the VkCommandPool that commandBuffer was allocated from, as specified in the table of supported pipeline stages.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_02513~^~Y~^~InvalidBarriers~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'Any pipeline stage included in srcStageMask or dstStageMask must be supported by the capabilities of the queue family specified by the queueFamilyIndex member of the VkCommandPoolCreateInfo structure that was used to create the VkCommandPool that commandBuffer was allocated from, as specified in the table of supported pipeline stages.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
 VALIDATION_ERROR_02514~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'Any given element of pMemoryBarriers, pBufferMemoryBarriers or pImageMemoryBarriers must not have any access flag included in its srcAccessMask member if that bit is not supported by any of the pipeline stages in srcStageMask, as specified in the table of supported access types.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
 VALIDATION_ERROR_02515~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'Any given element of pMemoryBarriers, pBufferMemoryBarriers or pImageMemoryBarriers must not have any access flag included in its dstAccessMask member if that bit is not supported by any of the pipeline stages in dstStageMask, as specified in the table of supported access types.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
 VALIDATION_ERROR_02516~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'For any element of pDependencies, if the srcSubpass is not VK_SUBPASS_EXTERNAL, all stage flags included in the srcStageMask member of that dependency must be a pipeline stage supported by the pipeline identified by the pipelineBindPoint member of the source subpass.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)~^~

commit e85b48ac674f16ae53d9db0dc360a4eeaab2065e
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Mon Dec 12 17:11:50 2016 -0700

    tests: Add barrier/event queue compatibility tests
    
    Change-Id: I2aa8635f50f2aecfa3e7c73be9be8b995a0420a1

diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index 05411f8..b194e98 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -8235,7 +8235,8 @@ TEST_F(VkLayerTest, InvalidBarriers) {
 
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Buffer Barriers cannot be used during a render pass");
     vk_testing::Buffer buffer;
-    buffer.init(*m_device, 256);
+    VkMemoryPropertyFlags mem_reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+    buffer.init_as_src_and_dst(*m_device, 256, mem_reqs);
     VkBufferMemoryBarrier buf_barrier = {};
     buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
     buf_barrier.pNext = NULL;
@@ -8339,6 +8340,66 @@ TEST_F(VkLayerTest, InvalidBarriers) {
     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
                          nullptr, 0, nullptr, 1, &img_barrier);
     m_errorMonitor->VerifyFound();
+
+    // Attempt to mismatch barriers/waitEvents calls with incompatible queues
+
+    // Create command pool with incompatible queueflags
+    const std::vector<VkQueueFamilyProperties> queue_props = m_device->queue_props;
+    uint32_t queue_family_index = UINT32_MAX;
+    for (uint32_t i = 0; i < queue_props.size(); i++) {
+        if ((queue_props[i].queueFlags & VK_QUEUE_COMPUTE_BIT) == 0) {
+            queue_family_index = i;
+            break;
+        }
+    }
+    if (queue_family_index == UINT32_MAX) {
+        printf("No non-compute queue found; skipped.\n");
+        return;
+    }
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_02513);
+
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = queue_family_index;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
+
+    // Allocate a command buffer
+    VkCommandBuffer bad_command_buffer;
+    VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    command_buffer_allocate_info.commandBufferCount = 1;
+    ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &bad_command_buffer));
+
+    VkCommandBufferBeginInfo cbbi = {};
+    cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    vkBeginCommandBuffer(bad_command_buffer, &cbbi);
+    buf_barrier.offset = 0;
+    buf_barrier.size = VK_WHOLE_SIZE;
+    vkCmdPipelineBarrier(bad_command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 1,
+                         &buf_barrier, 0, nullptr);
+    m_errorMonitor->VerifyFound();
+
+    if ((queue_props[queue_family_index].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0) {
+        vkEndCommandBuffer(bad_command_buffer);
+        vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+        printf("The non-compute queue does not support graphics; skipped.\n");
+        return;
+    }
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_02510);
+    VkEvent event;
+    VkEventCreateInfo event_create_info{};
+    event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
+    vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
+    vkCmdWaitEvents(bad_command_buffer, 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, nullptr, 0,
+                    nullptr, 0, nullptr);
+    m_errorMonitor->VerifyFound();
+
+    vkEndCommandBuffer(bad_command_buffer);
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
 }
 
 TEST_F(VkLayerTest, LayoutFromPresentWithoutAccessMemoryRead) {

commit d91b0b35cff4dc73d88fcf4ea567bd37997bbd98
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Mon Dec 12 08:27:42 2016 -0700

    layers: Update WaitEvents/PipelineBarrier for style
    
    Variable names, clang-format.
    
    Change-Id: I576bfd7944902bdf611b8a455eff83e43f56725b

diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index bb2b6f5..906a7b1 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -9465,70 +9465,68 @@ bool ValidateStageMasksAgainstQueueCapabilities(layer_data *dev_data, GLOBAL_CB_
     return skip;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents, VkPipelineStageFlags sourceStageMask,
-              VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
-              uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
-              uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
-    bool skip_call = false;
+VKAPI_ATTR void VKAPI_CALL CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
+                                         VkPipelineStageFlags sourceStageMask, VkPipelineStageFlags dstStageMask,
+                                         uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
+                                         uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
+                                         uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
+    bool skip = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
-    if (pCB) {
-        skip_call |= ValidateStageMasksAgainstQueueCapabilities(dev_data, pCB, sourceStageMask, dstStageMask, "vkCmdWaitEvents",
-                                                                VALIDATION_ERROR_02510);
-        auto firstEventIndex = pCB->events.size();
+    GLOBAL_CB_NODE *cb_state = getCBNode(dev_data, commandBuffer);
+    if (cb_state) {
+        skip |= ValidateStageMasksAgainstQueueCapabilities(dev_data, cb_state, sourceStageMask, dstStageMask, "vkCmdWaitEvents",
+                                                           VALIDATION_ERROR_02510);
+        auto first_event_index = cb_state->events.size();
         for (uint32_t i = 0; i < eventCount; ++i) {
             auto event_state = getEventNode(dev_data, pEvents[i]);
             if (event_state) {
                 addCommandBufferBinding(&event_state->cb_bindings,
                                         {reinterpret_cast<const uint64_t &>(pEvents[i]), VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT},
-                                        pCB);
-                event_state->cb_bindings.insert(pCB);
+                                        cb_state);
+                event_state->cb_bindings.insert(cb_state);
             }
-            pCB->waitedEvents.insert(pEvents[i]);
-            pCB->events.push_back(pEvents[i]);
+            cb_state->waitedEvents.insert(pEvents[i]);
+            cb_state->events.push_back(pEvents[i]);
         }
-        std::function<bool(VkQueue)> eventUpdate =
-            std::bind(validateEventStageMask, std::placeholders::_1, pCB, eventCount, firstEventIndex, sourceStageMask);
-        pCB->eventUpdates.push_back(eventUpdate);
-        if (pCB->state == CB_RECORDING) {
-            skip_call |= addCmd(dev_data, pCB, CMD_WAITEVENTS, "vkCmdWaitEvents()");
+        std::function<bool(VkQueue)> event_update =
+            std::bind(validateEventStageMask, std::placeholders::_1, cb_state, eventCount, first_event_index, sourceStageMask);
+        cb_state->eventUpdates.push_back(event_update);
+        if (cb_state->state == CB_RECORDING) {
+            skip |= addCmd(dev_data, cb_state, CMD_WAITEVENTS, "vkCmdWaitEvents()");
         } else {
-            skip_call |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdWaitEvents()");
+            skip |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdWaitEvents()");
         }
-        skip_call |= TransitionImageLayouts(commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers);
-        skip_call |=
-            ValidateBarriers("vkCmdWaitEvents", commandBuffer, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
-                             pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
+        skip |= TransitionImageLayouts(commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers);
+        skip |= ValidateBarriers("vkCmdWaitEvents", commandBuffer, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
+                                 pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
     }
     lock.unlock();
-    if (!skip_call)
+    if (!skip)
         dev_data->dispatch_table.CmdWaitEvents(commandBuffer, eventCount, pEvents, sourceStageMask, dstStageMask,
                                                memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
                                                imageMemoryBarrierCount, pImageMemoryBarriers);
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
-                   VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
-                   uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
-                   uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
-    bool skip_call = false;
+VKAPI_ATTR void VKAPI_CALL CmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
+                                              VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
+                                              uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
+                                              uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
+                                              uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
+    bool skip = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
-    if (pCB) {
-        skip_call |= ValidateStageMasksAgainstQueueCapabilities(dev_data, pCB, srcStageMask, dstStageMask, "vkCmdPipelineBarrier",
-                                                                VALIDATION_ERROR_02513);
-        skip_call |= addCmd(dev_data, pCB, CMD_PIPELINEBARRIER, "vkCmdPipelineBarrier()");
-        skip_call |= TransitionImageLayouts(commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers);
-        skip_call |=
-            ValidateBarriers("vkCmdPipelineBarrier", commandBuffer, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
-                             pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
+    GLOBAL_CB_NODE *cb_state = getCBNode(dev_data, commandBuffer);
+    if (cb_state) {
+        skip |= ValidateStageMasksAgainstQueueCapabilities(dev_data, cb_state, srcStageMask, dstStageMask, "vkCmdPipelineBarrier",
+                                                           VALIDATION_ERROR_02513);
+        skip |= addCmd(dev_data, cb_state, CMD_PIPELINEBARRIER, "vkCmdPipelineBarrier()");
+        skip |= TransitionImageLayouts(commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers);
+        skip |= ValidateBarriers("vkCmdPipelineBarrier", commandBuffer, memoryBarrierCount, pMemoryBarriers,
+                                 bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
     }
     lock.unlock();
-    if (!skip_call)
+    if (!skip)
         dev_data->dispatch_table.CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount,
                                                     pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
                                                     imageMemoryBarrierCount, pImageMemoryBarriers);

commit 07059341a6ab09b3bd64727d2689082828492191
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Sat Dec 10 10:53:34 2016 -0700

    layers: GH1233, Validate stagemask/queue compatibility
    
    Any pipeline stage included in srcStageMask or dstStageMask must be
    supported by the capabilities of the queue family specified by the
    queueFamilyIndex member of the VkCommandPoolCreateInfo structure
    that was used to create the VkCommandPool that commandBuffer was
    allocated from, as specified in the table of supported pipeline
    stages.
    
    Change-Id: I02117e7f60910f2154765b90340d8127d6bce0cd

diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 4ebdf12..bb2b6f5 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -152,6 +152,7 @@ struct layer_data {
     unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> imageLayoutMap;
     unordered_map<VkRenderPass, unique_ptr<RENDER_PASS_STATE>> renderPassMap;
     unordered_map<VkShaderModule, unique_ptr<shader_module>> shaderModuleMap;
+
     VkDevice device = VK_NULL_HANDLE;
     VkPhysicalDevice physical_device = VK_NULL_HANDLE;
 
@@ -9384,6 +9385,86 @@ bool validateEventStageMask(VkQueue queue, GLOBAL_CB_NODE *pCB, uint32_t eventCo
     return skip_call;
 }
 
+// Note that we only check bits that HAVE required queueflags -- don't care entries are skipped
+static std::unordered_map<VkPipelineStageFlags, VkQueueFlags> supported_pipeline_stages_table = {
+    {VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT},
+    {VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT},
+    {VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_QUEUE_GRAPHICS_BIT},
+    {VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT},
+    {VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT},
+    {VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT},
+    {VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT},
+    {VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT},
+    {VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_QUEUE_GRAPHICS_BIT},
+    {VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_QUEUE_GRAPHICS_BIT},
+    {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_QUEUE_GRAPHICS_BIT},
+    {VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_QUEUE_COMPUTE_BIT},
+    {VK_PIPELINE_STAGE_TRANSFER_BIT, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT},
+    {VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_QUEUE_GRAPHICS_BIT}};
+
+static const VkPipelineStageFlags stage_flag_bit_array[] = {VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX,
+                                                            VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
+                                                            VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
+                                                            VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
+                                                            VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT,
+                                                            VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT,
+                                                            VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT,
+                                                            VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
+                                                            VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
+                                                            VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
+                                                            VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                                                            VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
+                                                            VK_PIPELINE_STAGE_TRANSFER_BIT,
+                                                            VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT};
+
+bool CheckStageMaskQueueCompatibility(layer_data *dev_data, VkCommandBuffer command_buffer, VkPipelineStageFlags stage_mask,
+                                      VkQueueFlags queue_flags, const char *function, const char *src_or_dest,
+                                      UNIQUE_VALIDATION_ERROR_CODE error_code) {
+    bool skip = false;
+    // Lookup each bit in the stagemask and check for overlap between its table bits and queue_flags
+    for (const auto &item : stage_flag_bit_array) {
+        if (stage_mask & item) {
+            if ((supported_pipeline_stages_table[item] & queue_flags) == 0) {
+                skip |=
+                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                            reinterpret_cast<uint64_t &>(command_buffer), __LINE__, error_code, "DL",
+                            "%s(): %s flag %s is not compatible with the queue family properties of this "
+                            "command buffer. %s",
+                            function, src_or_dest, string_VkPipelineStageFlagBits(static_cast<VkPipelineStageFlagBits>(item)),
+                            validation_error_map[error_code]);
+            }
+        }
+    }
+    return skip;
+}
+
+bool ValidateStageMasksAgainstQueueCapabilities(layer_data *dev_data, GLOBAL_CB_NODE *cb_state,
+                                                VkPipelineStageFlags source_stage_mask, VkPipelineStageFlags dest_stage_mask,
+                                                const char *function, UNIQUE_VALIDATION_ERROR_CODE error_code) {
+    bool skip = false;
+    uint32_t queue_family_index = dev_data->commandPoolMap[cb_state->createInfo.commandPool].queueFamilyIndex;
+    instance_layer_data *instance_data = get_my_data_ptr(get_dispatch_key(dev_data->physical_device), instance_layer_data_map);
+    auto physical_device_state = getPhysicalDeviceState(instance_data, dev_data->physical_device);
+
+    // Any pipeline stage included in srcStageMask or dstStageMask must be supported by the capabilities of the queue family
+    // specified by the queueFamilyIndex member of the VkCommandPoolCreateInfo structure that was used to create the VkCommandPool
+    // that commandBuffer was allocated from, as specified in the table of supported pipeline stages.
+
+    if (queue_family_index < physical_device_state->queue_family_properties.size()) {
+        VkQueueFlags specified_queue_flags = physical_device_state->queue_family_properties[queue_family_index].queueFlags;
+
+        if ((source_stage_mask & VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) == 0) {
+            skip |= CheckStageMaskQueueCompatibility(dev_data, cb_state->commandBuffer, source_stage_mask, specified_queue_flags,
+                                                     function, "srcStageMask", error_code);
+        }
+        if ((dest_stage_mask & VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) == 0) {
+            skip |= CheckStageMaskQueueCompatibility(dev_data, cb_state->commandBuffer, dest_stage_mask, specified_queue_flags,
+                                                     function, "dstStageMask", error_code);
+        }
+    }
+    return skip;
+}
+
 VKAPI_ATTR void VKAPI_CALL
 CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents, VkPipelineStageFlags sourceStageMask,
               VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
@@ -9394,6 +9475,8 @@ CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
+        skip_call |= ValidateStageMasksAgainstQueueCapabilities(dev_data, pCB, sourceStageMask, dstStageMask, "vkCmdWaitEvents",
+                                                                VALIDATION_ERROR_02510);
         auto firstEventIndex = pCB->events.size();
         for (uint32_t i = 0; i < eventCount; ++i) {
             auto event_state = getEventNode(dev_data, pEvents[i]);
@@ -9436,6 +9519,8 @@ CmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageM
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
+        skip_call |= ValidateStageMasksAgainstQueueCapabilities(dev_data, pCB, srcStageMask, dstStageMask, "vkCmdPipelineBarrier",
+                                                                VALIDATION_ERROR_02513);
         skip_call |= addCmd(dev_data, pCB, CMD_PIPELINEBARRIER, "vkCmdPipelineBarrier()");
         skip_call |= TransitionImageLayouts(commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers);
         skip_call |=

commit 6f7c188624fc9df43a94329c7ce69f44152deab3
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Mon Dec 12 14:53:27 2016 -0700

    layers: Update err database w/new DisplayKHR checks
    
    Change-Id: I844e06439b295a36873ccb07819a38c414fd5098

diff --git a/layers/vk_validation_error_database.txt b/layers/vk_validation_error_database.txt
index 613d204..21764d3 100644
--- a/layers/vk_validation_error_database.txt
+++ b/layers/vk_validation_error_database.txt
@@ -1794,22 +1794,22 @@ VALIDATION_ERROR_01847~^~Y~^~None~^~vkDestroySurfaceKHR~^~For more information r
 VALIDATION_ERROR_01848~^~Y~^~None~^~vkDestroySurfaceKHR~^~For more information refer to Vulkan Spec Section '30.2.7. Platform-Independent Information' which states 'If surface is not VK_NULL_HANDLE, surface must be a valid VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)~^~
 VALIDATION_ERROR_01849~^~U~^~Unknown~^~vkDestroySurfaceKHR~^~For more information refer to Vulkan Spec Section '30.2.7. Platform-Independent Information' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)~^~
 VALIDATION_ERROR_01850~^~U~^~Unknown~^~vkDestroySurfaceKHR~^~For more information refer to Vulkan Spec Section '30.2.7. Platform-Independent Information' which states 'If surface is a valid handle, it must have been created, allocated, or retrieved from instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)~^~
-VALIDATION_ERROR_01851~^~U~^~Unknown~^~vkGetPhysicalDeviceDisplayPropertiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPropertiesKHR)~^~
+VALIDATION_ERROR_01851~^~Y~^~Unknown~^~vkGetPhysicalDeviceDisplayPropertiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPropertiesKHR)~^~
 VALIDATION_ERROR_01852~^~U~^~Unknown~^~vkGetPhysicalDeviceDisplayPropertiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPropertiesKHR)~^~
 VALIDATION_ERROR_01853~^~U~^~Unknown~^~vkGetPhysicalDeviceDisplayPropertiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkDisplayPropertiesKHR structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPropertiesKHR)~^~
-VALIDATION_ERROR_01854~^~U~^~Unknown~^~vkGetPhysicalDeviceDisplayPlanePropertiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPlanePropertiesKHR)~^~
+VALIDATION_ERROR_01854~^~Y~^~Unknown~^~vkGetPhysicalDeviceDisplayPlanePropertiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPlanePropertiesKHR)~^~
 VALIDATION_ERROR_01855~^~U~^~Unknown~^~vkGetPhysicalDeviceDisplayPlanePropertiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPlanePropertiesKHR)~^~
 VALIDATION_ERROR_01856~^~U~^~Unknown~^~vkGetPhysicalDeviceDisplayPlanePropertiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkDisplayPlanePropertiesKHR structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPlanePropertiesKHR)~^~
 VALIDATION_ERROR_01857~^~U~^~Unknown~^~vkGetDisplayPlaneSupportedDisplaysKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'planeIndex must be less than the number of display planes supported by the device as determined by calling vkGetPhysicalDeviceDisplayPlanePropertiesKHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneSupportedDisplaysKHR)~^~
-VALIDATION_ERROR_01858~^~U~^~Unknown~^~vkGetDisplayPlaneSupportedDisplaysKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneSupportedDisplaysKHR)~^~
+VALIDATION_ERROR_01858~^~Y~^~Unknown~^~vkGetDisplayPlaneSupportedDisplaysKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneSupportedDisplaysKHR)~^~
 VALIDATION_ERROR_01859~^~U~^~Unknown~^~vkGetDisplayPlaneSupportedDisplaysKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'pDisplayCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneSupportedDisplaysKHR)~^~
 VALIDATION_ERROR_01860~^~U~^~Unknown~^~vkGetDisplayPlaneSupportedDisplaysKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'If the value referenced by pDisplayCount is not 0, and pDisplays is not NULL, pDisplays must be a pointer to an array of pDisplayCount VkDisplayKHR handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneSupportedDisplaysKHR)~^~
-VALIDATION_ERROR_01861~^~U~^~Unknown~^~vkGetDisplayModePropertiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayModePropertiesKHR)~^~
-VALIDATION_ERROR_01862~^~U~^~Unknown~^~vkGetDisplayModePropertiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'display must be a valid VkDisplayKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayModePropertiesKHR)~^~
+VALIDATION_ERROR_01861~^~Y~^~Unknown~^~vkGetDisplayModePropertiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayModePropertiesKHR)~^~
+VALIDATION_ERROR_01862~^~Y~^~Unknown~^~vkGetDisplayModePropertiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'display must be a valid VkDisplayKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayModePropertiesKHR)~^~
 VALIDATION_ERROR_01863~^~U~^~Unknown~^~vkGetDisplayModePropertiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayModePropertiesKHR)~^~
 VALIDATION_ERROR_01864~^~U~^~Unknown~^~vkGetDisplayModePropertiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkDisplayModePropertiesKHR structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayModePropertiesKHR)~^~
-VALIDATION_ERROR_01865~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)~^~
-VALIDATION_ERROR_01866~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'display must be a valid VkDisplayKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)~^~
+VALIDATION_ERROR_01865~^~Y~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)~^~
+VALIDATION_ERROR_01866~^~Y~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'display must be a valid VkDisplayKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)~^~
 VALIDATION_ERROR_01867~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'pCreateInfo must be a pointer to a valid VkDisplayModeCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)~^~
 VALIDATION_ERROR_01868~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)~^~
 VALIDATION_ERROR_01869~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'pMode must be a pointer to a VkDisplayModeKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)~^~
@@ -1818,8 +1818,8 @@ VALIDATION_ERROR_01871~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more informa
 VALIDATION_ERROR_01872~^~N~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'sType must be VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayModeCreateInfoKHR)~^~TBD in parameter validation layer.
 VALIDATION_ERROR_01873~^~N~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayModeCreateInfoKHR)~^~TBD in parameter validation layer.
 VALIDATION_ERROR_01874~^~N~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayModeCreateInfoKHR)~^~TBD in parameter validation layer.
-VALIDATION_ERROR_01875~^~U~^~Unknown~^~vkGetDisplayPlaneCapabilitiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneCapabilitiesKHR)~^~
-VALIDATION_ERROR_01876~^~U~^~Unknown~^~vkGetDisplayPlaneCapabilitiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'mode must be a valid VkDisplayModeKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneCapabilitiesKHR)~^~
+VALIDATION_ERROR_01875~^~Y~^~Unknown~^~vkGetDisplayPlaneCapabilitiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneCapabilitiesKHR)~^~
+VALIDATION_ERROR_01876~^~Y~^~Unknown~^~vkGetDisplayPlaneCapabilitiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'mode must be a valid VkDisplayModeKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneCapabilitiesKHR)~^~
 VALIDATION_ERROR_01877~^~U~^~Unknown~^~vkGetDisplayPlaneCapabilitiesKHR~^~For more information refer to Vulkan Spec Section '30.3.1. Display Enumeration' which states 'pCapabilities must be a pointer to a VkDisplayPlaneCapabilitiesKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneCapabilitiesKHR)~^~
 VALIDATION_ERROR_01878~^~Y~^~None~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '30.3.2. Display Surfaces' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayPlaneSurfaceKHR)~^~
 VALIDATION_ERROR_01879~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '30.3.2. Display Surfaces' which states 'pCreateInfo must be a pointer to a valid VkDisplaySurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayPlaneSurfaceKHR)~^~

commit 85b6fea8638ed731a5a35ee2fbf5a293e7fc8084
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Mon Nov 14 10:32:41 2016 -0700

    layers: Fill out OT validation for vk_display_KHR
    
    Change-Id: I633fae1ba3bc076022eea6c4e599f617d0296534

diff --git a/layers/object_tracker.cpp b/layers/object_tracker.cpp
index 8ccaa27..0f2a2d6 100644
--- a/layers/object_tracker.cpp
+++ b/layers/object_tracker.cpp
@@ -2757,27 +2757,6 @@ VKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(VkQueue queue, const VkPresentInf
     return result;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL CreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
-                                                            const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
-    bool skip_call = false;
-    {
-        std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false, VALIDATION_ERROR_01878);
-    }
-    if (skip_call) {
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-    }
-    VkResult result = get_dispatch_table(ot_instance_table_map, instance)
-                          ->CreateDisplayPlaneSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
-    {
-        std::lock_guard<std::mutex> lock(global_lock);
-        if (result == VK_SUCCESS) {
-            CreateObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, pAllocator);
-        }
-    }
-    return result;
-}
-
 #ifdef VK_USE_PLATFORM_WIN32_KHR
 VKAPI_ATTR VkResult VKAPI_CALL CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
                                                      const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
@@ -3103,6 +3082,9 @@ static inline PFN_vkVoidFunction InterceptMsgCallbackGetProcAddrCommand(const ch
     return debug_report_get_instance_proc_addr(instance_data->report_data, name);
 }
 
+VKAPI_ATTR VkResult VKAPI_CALL CreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
+
 static inline PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, VkInstance instance) {
     VkLayerInstanceDispatchTable *pTable = get_dispatch_table(ot_instance_table_map, instance);
     if (instanceExtMap.size() == 0 || !instanceExtMap[pTable].wsi_enabled)
@@ -3820,12 +3802,15 @@ VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalD
                                                                      VkDisplayPropertiesKHR *pProperties) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip = false;
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
-    assert(my_data != NULL);
-
-    result = get_dispatch_table(ot_instance_table_map, physicalDevice)
-                 ->GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties);
-
+    {
+        std::unique_lock<std::mutex> lock(global_lock);
+        skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false,
+                               VALIDATION_ERROR_01851);
+    }
+    if (!skip) {
+        result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+            ->GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties);
+    }
     return result;
 }
 
@@ -3833,12 +3818,15 @@ VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhys
                                                                           VkDisplayPlanePropertiesKHR *pProperties) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip = false;
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
-    assert(my_data != NULL);
-
-    result = get_dispatch_table(ot_instance_table_map, physicalDevice)
-                 ->GetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties);
-
+    {
+        std::unique_lock<std::mutex> lock(global_lock);
+        skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false,
+                               VALIDATION_ERROR_01854);
+    }
+    if (!skip) {
+        result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+            ->GetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties);
+    }
     return result;
 }
 
@@ -3846,12 +3834,19 @@ VKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDev
                                                                    uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip = false;
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
-    assert(my_data != NULL);
-
+    {
+        std::unique_lock<std::mutex> lock(global_lock);
+        skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false,
+                               VALIDATION_ERROR_01858);
+    }
     result = get_dispatch_table(ot_instance_table_map, physicalDevice)
                  ->GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays);
-
+    if (((result == VK_SUCCESS) || (result == VK_INCOMPLETE)) && (pDisplays != NULL)) {
+        std::lock_guard<std::mutex> lock(global_lock);
+        for (uint32_t displays = 0; displays < *pDisplayCount; displays++) {
+            CreateObject(physicalDevice, pDisplays[displays], VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT, nullptr);
+        }
+    }
     return result;
 }
 
@@ -3859,9 +3854,13 @@ VKAPI_ATTR VkResult VKAPI_CALL GetDisplayModePropertiesKHR(VkPhysicalDevice phys
                                                            uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip = false;
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
-    assert(my_data != NULL);
-
+    {
+        std::unique_lock<std::mutex> lock(global_lock);
+        skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false,
+                               VALIDATION_ERROR_01861);
+        skip |= ValidateObject(physicalDevice, display, VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT, false,
+                               VALIDATION_ERROR_01862);
+    }
     result = get_dispatch_table(ot_instance_table_map, physicalDevice)
                  ->GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties);
 
@@ -3873,12 +3872,21 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDisplayModeKHR(VkPhysicalDevice physicalDev
                                                     const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip = false;
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
-    assert(my_data != NULL);
-
+    {
+        std::unique_lock<std::mutex> lock(global_lock);
+        skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false,
+                               VALIDATION_ERROR_01865);
+        skip |= ValidateObject(physicalDevice, display, VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT, false,
+                               VALIDATION_ERROR_01866);
+    }
     result = get_dispatch_table(ot_instance_table_map, physicalDevice)
                  ->CreateDisplayModeKHR(physicalDevice, display, pCreateInfo, pAllocator, pMode);
-
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateObject(physicalDevice, *pMode, VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT, pAllocator);
+        }
+    }
     return result;
 }
 
@@ -3886,15 +3894,40 @@ VKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice p
                                                               uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip = false;
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
-    assert(my_data != NULL);
-
+    {
+        std::unique_lock<std::mutex> lock(global_lock);
+        skip |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false,
+                               VALIDATION_ERROR_01875);
+        skip |= ValidateObject(physicalDevice, mode, VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT, false,
+                               VALIDATION_ERROR_01876);
+    }
     result = get_dispatch_table(ot_instance_table_map, physicalDevice)
                  ->GetDisplayPlaneCapabilitiesKHR(physicalDevice, mode, planeIndex, pCapabilities);
 
     return result;
 }
 
+VKAPI_ATTR VkResult VKAPI_CALL CreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false, VALIDATION_ERROR_01878);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_instance_table_map, instance)
+        ->CreateDisplayPlaneSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, pAllocator);
+        }
+    }
+    return result;
+}
+
 #ifdef VK_USE_PLATFORM_WIN32_KHR
 // VK_NV_external_memory_win32 Extension
 VKAPI_ATTR VkResult VKAPI_CALL GetMemoryWin32HandleNV(VkDevice device, VkDeviceMemory memory,

commit dfb417d980dc0341eb6b8e50c6095d7fcffff1ac
Author: Mark Lobodzinski <mark@lunarg.com>
Date:   Mon Nov 14 10:00:41 2016 -0700

    layers: GH897, Add VK_KHR_display stubs to OT
    
    Added extension enable and function stubs for VK_KHR_display
    extension functions to object_tracker.
    
    Change-Id: Iaee862efaadf4657271b74d75a289dbaf13af26c

diff --git a/layers/object_tracker.cpp b/layers/object_tracker.cpp
index e4b8694..8ccaa27 100644
--- a/layers/object_tracker.cpp
+++ b/layers/object_tracker.cpp
@@ -3163,6 +3163,7 @@ static void CheckDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo,
     layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     device_data->wsi_enabled = false;
     device_data->wsi_display_swapchain_enabled = false;
+    device_data->wsi_display_extension_enabled = false;
     device_data->objtrack_extensions_enabled = false;
 
     for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
@@ -3172,6 +3173,9 @@ static void CheckDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo,
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME) == 0) {
             device_data->wsi_display_swapchain_enabled = true;
         }
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) {
+            device_data->wsi_display_extension_enabled = true;
+        }
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], "OBJTRACK_EXTENSIONS") == 0) {
             device_data->objtrack_extensions_enabled = true;
         }
@@ -3811,6 +3815,86 @@ VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceExternalImageFormatPropertiesNV(
     return result;
 }
 
+// VK_KHR_display Extension
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
+                                                                     VkDisplayPropertiesKHR *pProperties) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                 ->GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties);
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
+                                                                          VkDisplayPlanePropertiesKHR *pProperties) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                 ->GetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties);
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex,
+                                                                   uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                 ->GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays);
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+                                                           uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                 ->GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties);
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+                                                    const VkDisplayModeCreateInfoKHR *pCreateInfo,
+                                                    const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                 ->CreateDisplayModeKHR(physicalDevice, display, pCreateInfo, pAllocator, pMode);
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode,
+                                                              uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                 ->GetDisplayPlaneCapabilitiesKHR(physicalDevice, mode, planeIndex, pCapabilities);
+
+    return result;
+}
+
 #ifdef VK_USE_PLATFORM_WIN32_KHR
 // VK_NV_external_memory_win32 Extension
 VKAPI_ATTR VkResult VKAPI_CALL GetMemoryWin32HandleNV(VkDevice device, VkDeviceMemory memory,
@@ -4191,6 +4275,23 @@ static inline PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, Vk
                 return reinterpret_cast<PFN_vkVoidFunction>(CreateSharedSwapchainsKHR);
             }
         }
+
+        if (device_data->wsi_display_extension_enabled) {
+            if (!strcmp("vkGetPhysicalDeviceDisplayPropertiesKHR", name))
+                return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceDisplayPropertiesKHR);
+            if (!strcmp("vkGetPhysicalDeviceDisplayPlanePropertiesKHR", name))
+                return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceDisplayPlanePropertiesKHR);
+            if (!strcmp("vkGetDisplayPlaneSupportedDisplaysKHR", name))


Reply to: