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

vulkan: Changes to 'upstream-unstable'



Rebased ref, commits from common ancestor:
commit 97e3b677d9681aa8d420c314edae96c4bf72246d
Author: Mark Young <marky@lunarg.com>
Date:   Wed Jul 20 11:38:53 2016 -0600

    loader: Clean up some things in the MD file
    
    Clean up some documentation in the LoaderAndLayerInterface
    markdown.  Over the next few weeks, I'll be working on
    cleaning up the format and language of this doc.
    
    Change-Id: I7858981293de9befb34701c31542d88c664cd6d8

diff --git a/loader/LoaderAndLayerInterface.md b/loader/LoaderAndLayerInterface.md
index ca71fae..e5df181 100644
--- a/loader/LoaderAndLayerInterface.md
+++ b/loader/LoaderAndLayerInterface.md
@@ -1,23 +1,27 @@
 # Vulkan Loader Specification and Architecture Overview
 
+<br/>
 
-Goals of this document
+## Goals of this document ##
 ----------------------
 
 Specify necessary functions and expected behavior of interface between the
 loader library and ICDs and layers for Windows, Linux and Android based
 systems. Also describe the application visible behaviors of the loader.
 
-Audience
+<br/>
+
+## Audience ##
 --------
 
-Application, Vulkan driver and Vulkan layer developers.
+This document is primarily targeted at Vulkan application, driver and layer developers.
+However, it can also be used by any developer interested in understanding more about
+how the Vulkan loader and layers interact.
 
-Any developers interested in understanding more about loader and layer behavior
-and architecture.
+<br/>
 
 
-Loader goals
+## Loader goals ##
 ------------
 
 -   Support multiple ICDs (Installable Client Drivers) to co-exist on a system
@@ -29,39 +33,47 @@ developer or the system and have no impact when not enabled.
 -   Negligible performance cost for an application calling through the loader
 to an ICD entry point.
 
-Architectural overview of layers and loader
+<br/>
+
+## Architectural overview of layers and loader ##
 -------------------------------------------
 
-Vulkan is a layered architecture. Layers can hook (intercept) Vulkan commands to
-achieve various functionality that a Vulkan driver (aka ICD) or loader doesn't
-support. Functionality such as Vulkan API tracing and debugging, API usage
-validation, and other tools such as framebuffer overlays are all natural
-candidates for Vulkan layers. Layers are implemented as libraries that are
-inserted between the application and the driver.
-
-Not only is Vulkan a layered architecture but it also supports multiple GPUs
-and their drivers. Vulkan commands called by an application may wind up calling
-into a diverse set of modules: loader, layers, and ICDs. The loader is critical
-to managing the proper dispatching of Vulkan commands to the appropriate set of
-layers and ICDs. The Vulkan object model allows the loader to insert layers
-into a call chain so the layers can process Vulkan commands prior to the
-ICD being called.
+Vulkan is a layered architecture placing the Application on one end, the
+ICDs on the other, and the loader and some number of layers in between.
+
+Layers are implemented as libraries that can be enabled in different ways
+(including by application request) and loaded during CreateInstance.  Each
+layer can chooses to hook (intercept) any Vulkan commands which in turn
+can be ignored, augmented, or simply passed along.  A layer may also
+expose functionality not available in the loader or any ICD.  Some examples
+of this include: the ability to perform Vulkan API tracing and debugging,
+validate API usage, or overlay additional content on the applications surfaces.
+
+The loader is responsible for working with the various layers as well as
+supporting multiple GPUs and their drivers.  Any Vulkan command may
+wind up calling into a diverse set of modules: loader, layers, and ICDs.
+The loader is critical to managing the proper dispatching of Vulkan
+commands to the appropriate set of layers and ICDs. The Vulkan object
+model allows the loader to insert layers into a call chain so that the layers
+can process Vulkan commands prior to the ICD being called.
 
 Vulkan uses an object model to control the scope of a particular action /
 operation.  The object to be acted on is always the first parameter of a Vulkan
 call and is a dispatchable object (see Vulkan specification section 2.3 Object
 Model).  Under the covers, the dispatchable object handle is a pointer to a
-structure that contains a pointer to a dispatch table maintained by the loader.
-This dispatch table contains pointers to the Vulkan functions appropriate to
-that object. There are two types of dispatch tables the loader maintains,
-Instance and Device. I.e. a VkInstance object's dispatch table will point to Vulkan
-functions such as vkEnumeratePhysicalDevices, vkDestroyInstance,
-vkCreateInstance, etc. Instance functions take a VkInstance or VkPhysicalDevice as
-their first argument.
-
-Device objects have a separate dispatch table containing the appropriate
-function pointers. The device dispatch table is used for all functions that
-take a VkDevice, VkQueue or VkCommandBuffer as their first argument.
+structure, which in turn, contains a pointer to a dispatch table maintained by
+the loader.  This dispatch table contains pointers to the Vulkan functions appropriate to
+that object.
+
+There are two types of dispatch tables the loader maintains:
+-  **Instance Dispatch Table**
+  - Contains any function that takes a VkInstance or VkPhysicalDevice as their first parameter
+    - vkEnumeratePhysicalDevices
+    - vkDestroyInstance
+    - vkCreateInstance
+    - ...
+-  **Device Dispatch Table**
+  - Contains any function that takes a VkDevice, VkQueue or VkCommandBuffer as their first parameter
 
 These instance and device dispatch tables are constructed when the application
 calls vkCreateInstance and vkCreateDevice. At that time the application and/or
@@ -90,7 +102,9 @@ the chain. The below diagram also illustrates how layers (either device or
 instance) can skip intercepting any given Vulkan entry point.
 ![Chain skipping layers](chain_skipping_layers.png)
 
-Application interface to loader
+<br/>
+
+## Application interface to loader ##
 -------------------------------
 
 In this section we'll discuss how an application interacts with the loader.
@@ -308,8 +322,10 @@ No!  Most extension functionality only affects a device and not an instance or a
 device.  Thus, the overwhelming majority of extensions will be device extensions rather than
 instance extensions.
 
+<br/>
+
 
-Vulkan Installable Client Driver interface with the loader
+## Vulkan Installable Client Driver interface with the loader ##
 ----------------------------------------------------------
 
 ### ICD discovery
@@ -544,8 +560,9 @@ changed. The loader will load the driver/ICD via hw_get_module with the ID
 of "vulkan". Due to security policies in Android none of this can be modified
 under normal use.
 
+<br/>
 
-ICD interface requirements
+## ICD interface requirements ##
 ----------------------------------------
 
 Generally, for all Vulkan commands issued by an application, the loader can be
@@ -752,7 +769,9 @@ loader queries layer and extension information directly from the
 respective libraries and does not use the json manifest files used
 by the Windows and Linux loaders.
 
-Vulkan layer interface with the loader
+<br/>
+
+## Vulkan layer interface with the loader ##
 --------------------------------------
 
 ### Layer discovery
@@ -1022,7 +1041,9 @@ application would.
 An application enabled for debug has more options. It can enumerate and enable
 layers located in /data/local/vulkan/debug.
 
-Layer interface requirements
+<br/>
+
+## Layer interface requirements ##
 ------------------------------------------------------
 
 #### Architectural interface overview

commit 0e6c3149ca9fb53b00b89bc32c16a0d3c7a2b191
Author: Mark Young <marky@lunarg.com>
Date:   Tue Jul 19 11:49:45 2016 -0600

    loader: Clarify in docs about WSI and inst ext.
    
    Clarify in the LoaderAndLayerInterface markdown file what WSI
    extensions are available by default in the desktop loader.
    Additionally, clarify that instance extensions are not supported
    by the Loader unless they have been specifically added to the
    Loader.
    
    Change-Id: I21bd2a63ed1e4a7e50d27e7a6b136eeeaea4d68c

diff --git a/loader/LoaderAndLayerInterface.md b/loader/LoaderAndLayerInterface.md
index 3f0fef8..ca71fae 100644
--- a/loader/LoaderAndLayerInterface.md
+++ b/loader/LoaderAndLayerInterface.md
@@ -248,6 +248,66 @@ Get\*ProcAddr will often be the only way to access extension API features.
 
 ![Get*ProcAddr efficiency](get_proc_addr.png)
 
+##### WSI Extensions
+
+Khronos approved WSI extensions are available and provide Windows System Integration
+support for various execution environments. It is important to understand that some WSI
+extensions are valid for all targets, but others are particular to a given execution
+environment (and loader). This desktop loader (currently targeting Windows and Linux)
+only enables those WSI extensions that are appropriate to the current environment.
+For the most part, the selection is done in the loader using  compile-time preprocessor
+flags. All versions of the desktop loader currently expose at least the following WSI
+extension support:
+- VK_KHR_surface
+- VK_KHR_swapchain
+- VK_KHR_display
+
+In addition, each of the following OS targets for the loader support target-specific extensions:
+- **Windows** : VK_KHR_win32_surface
+- **Linux (default)** : VK_KHR_xcb_surface and VK_KHR_xlib_surface
+- **Linux (Wayland build)** : VK_KHR_wayland_surface
+- **Linux (Mir build)** : VK_KHR_mir_surface
+
+**NOTE:** Wayland and Mir targets are not fully supported at this time and should be considered
+alpha quality.
+
+It is important to understand that while the loader may support the various entry-points
+for these extensions, there is a hand-shake required to actually use them:
+* At least one physical device must support the extension(s)
+* The application must select such a physical device
+* The application must request the extension(s) be enabled while creating the instance or logical device (This depends on whether or not the given extension works with an instance or a device).
+* The instance and/or logical device creation must succeed.
+
+Only then can you expect to properly use a WSI extension in your Vulkan program.
+
+##### New Extensions
+
+With the ability to expand Vulkan so easily, extensions will be created that the loader knows
+nothing about.  If the extension is a device extension, the loader will pass the unknown
+entry-point down the device call chain ending with the appropriate ICD entry-points.
+However, if the extension is an instance extension, the loader will fail to load it.
+
+*But why doesn't the loader support unknown instance extensions?*
+<br/>
+Let's look again at the Instance call chain:
+![Instance call chain](instance_call_chain.png)
+
+Notice that for a normal instance function call, the loader has to handle passing along the
+function call to the available ICDs.  If the loader has no idea of the parameters or return
+value of the instance call, it can't properly pass information along to the ICDs.
+There may be ways to do this, which will be explored in the future.  However, for now, this
+loader does not support any unknown instance extensions.
+
+Because the device call-chain does not pass through the loader terminator, this is not
+a problem for device extensions.  Instead, device extensions terminate directly in the
+ICD they are associated with.
+
+*Is this a big problem?*
+<br/>
+No!  Most extension functionality only affects a device and not an instance or a physical
+device.  Thus, the overwhelming majority of extensions will be device extensions rather than
+instance extensions.
+
 
 Vulkan Installable Client Driver interface with the loader
 ----------------------------------------------------------

commit f5aa7ebbe3b3916d891eaf041c5bf7d72df81c84
Author: Karl Schultz <karl@lunarg.com>
Date:   Mon Jul 18 16:40:49 2016 -0600

    misc: update spirv tools revision
    
    Change-Id: I8abb31de604ae4a50bb4900e9498de9953c5646b

diff --git a/spirv-tools_revision b/spirv-tools_revision
index d019f66..2df4b89 100644
--- a/spirv-tools_revision
+++ b/spirv-tools_revision
@@ -1 +1 @@
-37e4600c3efad7b1cfdc1df70a977be82eb3c811
+1a9385bbd0e6eae188c14302cf37c415ecc8b698

commit f93e39d823e1edf17d58ce476a8aab0efe1a2e5a
Author: Dustin Graves <dustin@lunarg.com>
Date:   Fri Jul 15 11:40:20 2016 -0600

    tests: Add NV_dedicated_allocation support test
    
    Add a positive test for NV_dedicated_allocation extension structure
    support in the parameter_validation and unique_objects layers.
    
    Change-Id: I332c2383aa663d0368db2dc477160bd0fa4aa012

diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index edff0cf..717ed6d 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -1114,6 +1114,87 @@ TEST_F(VkLayerTest, InvalidStructPNext) {
     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
 
+    // Positive test to check parameter_validation and unique_objects support
+    // for NV_dedicated_allocation
+    uint32_t extension_count = 0;
+    bool supports_nv_dedicated_allocation = false;
+    err = vkEnumerateDeviceExtensionProperties(gpu(), nullptr, &extension_count,
+                                               nullptr);
+    ASSERT_VK_SUCCESS(err);
+
+    if (extension_count > 0) {
+        std::vector<VkExtensionProperties> available_extensions(
+            extension_count);
+
+        err = vkEnumerateDeviceExtensionProperties(
+            gpu(), nullptr, &extension_count, &available_extensions[0]);
+        ASSERT_VK_SUCCESS(err);
+
+        for (const auto &extension_props : available_extensions) {
+            if (strcmp(extension_props.extensionName,
+                       VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME) == 0) {
+                supports_nv_dedicated_allocation = true;
+            }
+        }
+    }
+
+    if (supports_nv_dedicated_allocation) {
+        m_errorMonitor->ExpectSuccess();
+
+        VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info =
+            {};
+        dedicated_buffer_create_info.sType =
+            VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV;
+        dedicated_buffer_create_info.pNext = nullptr;
+        dedicated_buffer_create_info.dedicatedAllocation = VK_TRUE;
+
+        uint32_t queue_family_index = 0;
+        VkBufferCreateInfo buffer_create_info = {};
+        buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+        buffer_create_info.pNext = &dedicated_buffer_create_info;
+        buffer_create_info.size = 1024;
+        buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+        buffer_create_info.queueFamilyIndexCount = 1;
+        buffer_create_info.pQueueFamilyIndices = &queue_family_index;
+
+        VkBuffer buffer;
+        VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info,
+                                      NULL, &buffer);
+        ASSERT_VK_SUCCESS(err);
+
+        VkMemoryRequirements memory_reqs;
+        vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
+
+        VkDedicatedAllocationMemoryAllocateInfoNV dedicated_memory_info = {};
+        dedicated_memory_info.sType =
+            VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV;
+        dedicated_memory_info.pNext = nullptr;
+        dedicated_memory_info.buffer = buffer;
+        dedicated_memory_info.image = VK_NULL_HANDLE;
+
+        VkMemoryAllocateInfo memory_info = {};
+        memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+        memory_info.pNext = &dedicated_memory_info;
+        memory_info.allocationSize = memory_reqs.size;
+
+        bool pass;
+        pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits,
+                                               &memory_info, 0);
+        ASSERT_TRUE(pass);
+
+        VkDeviceMemory buffer_memory;
+        err = vkAllocateMemory(m_device->device(), &memory_info, NULL,
+                               &buffer_memory);
+        ASSERT_VK_SUCCESS(err);
+
+        err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
+        ASSERT_VK_SUCCESS(err);
+
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        vkFreeMemory(m_device->device(), buffer_memory, NULL);
+
+        m_errorMonitor->VerifyNotFound();
+    }
 }
 
 TEST_F(VkLayerTest, UnrecognizedValue) {

commit 15b4845aaf667fa51be8fa910970901da84cc5a9
Author: Dustin Graves <dustin@lunarg.com>
Date:   Thu Jul 14 17:28:11 2016 -0600

    layers: NV_dedicated_allocation support for unique_objects
    
    Add ID substitution support for the
    VkDedicatedAllocationMemoryAllocateInfoNV extension structure to the
    unique_objects layer.  The current implementation is specific to the
    case where the vkAllocateMemory pAllocateInfo parameter references
    a single VkDedicatedAllocationMemoryAllocateInfoNV struct.
    
    Issues-Addressed: GitHub #755
    Change-Id: I33c3f00d32149044694ecafe808673e5d90107b4

diff --git a/layers/unique_objects.h b/layers/unique_objects.h
index 18a07ac..962985e 100644
--- a/layers/unique_objects.h
+++ b/layers/unique_objects.h
@@ -21,10 +21,11 @@
 #include "vk_loader_platform.h"
 #include "vulkan/vulkan.h"
 
+#include <cinttypes>
+#include <memory>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <cinttypes>
 
 #include <unordered_map>
 #include <vector>
@@ -71,6 +72,27 @@ static device_table_map unique_objects_device_table_map;
 static instance_table_map unique_objects_instance_table_map;
 static std::mutex global_lock; // Protect map accesses and unique_id increments
 
+struct GenericHeader {
+    VkStructureType sType;
+    void *pNext;
+};
+
+template <typename T> bool ContainsExtStruct(const T *target, VkStructureType ext_type) {
+    assert(target != nullptr);
+
+    const GenericHeader *ext_struct = reinterpret_cast<const GenericHeader *>(target->pNext);
+
+    while (ext_struct != nullptr) {
+        if (ext_struct->sType == ext_type) {
+            return true;
+        }
+
+        ext_struct = reinterpret_cast<const GenericHeader *>(ext_struct->pNext);
+    }
+
+    return false;
+}
+
 // Handle CreateInstance
 static void createInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
     uint32_t i;
@@ -253,6 +275,68 @@ void explicit_DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAlloc
     layer_data_map.erase(key);
 }
 
+VkResult explicit_AllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
+                                 const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) {
+    const VkMemoryAllocateInfo *input_allocate_info = pAllocateInfo;
+    std::unique_ptr<safe_VkMemoryAllocateInfo> safe_allocate_info;
+    std::unique_ptr<safe_VkDedicatedAllocationMemoryAllocateInfoNV> safe_dedicated_allocate_info;
+    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+
+    if ((pAllocateInfo != nullptr) &&
+        ContainsExtStruct(pAllocateInfo, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV)) {
+        // Assuming there is only one extension struct of this type in the list for now
+        safe_dedicated_allocate_info =
+            std::unique_ptr<safe_VkDedicatedAllocationMemoryAllocateInfoNV>(new safe_VkDedicatedAllocationMemoryAllocateInfoNV);
+        safe_allocate_info = std::unique_ptr<safe_VkMemoryAllocateInfo>(new safe_VkMemoryAllocateInfo);
+
+        safe_allocate_info->initialize(pAllocateInfo);
+        input_allocate_info = reinterpret_cast<const VkMemoryAllocateInfo *>(safe_allocate_info.get());
+
+        const GenericHeader *orig_pnext = reinterpret_cast<const GenericHeader *>(pAllocateInfo->pNext);
+        GenericHeader *input_pnext = reinterpret_cast<GenericHeader *>(safe_allocate_info.get());
+        while (orig_pnext != nullptr) {
+            if (orig_pnext->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV) {
+                safe_dedicated_allocate_info->initialize(
+                    reinterpret_cast<const VkDedicatedAllocationMemoryAllocateInfoNV *>(orig_pnext));
+
+                std::unique_lock<std::mutex> lock(global_lock);
+
+                if (safe_dedicated_allocate_info->buffer != VK_NULL_HANDLE) {
+                    uint64_t local_buffer = reinterpret_cast<uint64_t &>(safe_dedicated_allocate_info->buffer);
+                    safe_dedicated_allocate_info->buffer =
+                        reinterpret_cast<VkBuffer &>(my_map_data->unique_id_mapping[local_buffer]);
+                }
+
+                if (safe_dedicated_allocate_info->image != VK_NULL_HANDLE) {
+                    uint64_t local_image = reinterpret_cast<uint64_t &>(safe_dedicated_allocate_info->image);
+                    safe_dedicated_allocate_info->image = reinterpret_cast<VkImage &>(my_map_data->unique_id_mapping[local_image]);
+                }
+
+                lock.unlock();
+
+                input_pnext->pNext = reinterpret_cast<GenericHeader *>(safe_dedicated_allocate_info.get());
+                input_pnext = reinterpret_cast<GenericHeader *>(input_pnext->pNext);
+            } else {
+                // TODO: generic handling of pNext copies
+            }
+
+            orig_pnext = reinterpret_cast<const GenericHeader *>(orig_pnext->pNext);
+        }
+    }
+
+    VkResult result = get_dispatch_table(unique_objects_device_table_map, device)
+                          ->AllocateMemory(device, input_allocate_info, pAllocator, pMemory);
+
+    if (VK_SUCCESS == result) {
+        std::lock_guard<std::mutex> lock(global_lock);
+        uint64_t unique_id = global_unique_id++;
+        my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*pMemory);
+        *pMemory = reinterpret_cast<VkDeviceMemory &>(unique_id);
+    }
+
+    return result;
+}
+
 VkResult explicit_CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
                                          const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
                                          VkPipeline *pPipelines) {
diff --git a/vk-layer-generate.py b/vk-layer-generate.py
index 29b3281..bde7e34 100755
--- a/vk-layer-generate.py
+++ b/vk-layer-generate.py
@@ -1557,6 +1557,7 @@ class UniqueObjectsSubcommand(Subcommand):
                                              'DestroyInstance',
                                              'CreateDevice',
                                              'DestroyDevice',
+                                             'AllocateMemory',
                                              'CreateComputePipelines',
                                              'CreateGraphicsPipelines',
                                              'GetPhysicalDeviceDisplayPropertiesKHR',

commit 433d502aac873f69f6a48e222ff45283ed0fb7eb
Author: Karl Schultz <karl@lunarg.com>
Date:   Mon Jul 18 12:04:39 2016 -0600

    misc: Update to Vulkan header version 21
    
    Change-Id: I112bb3d53daf067b231532620f45cd8891537cbb

diff --git a/include/vulkan/vulkan.h b/include/vulkan/vulkan.h
index 38affba..34de809 100644
--- a/include/vulkan/vulkan.h
+++ b/include/vulkan/vulkan.h
@@ -43,7 +43,7 @@ extern "C" {
 #define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
 #define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
 // Version of this file
-#define VK_HEADER_VERSION 20
+#define VK_HEADER_VERSION 21
 
 
 #define VK_NULL_HANDLE 0
diff --git a/layers/linux/VkLayer_core_validation.json b/layers/linux/VkLayer_core_validation.json
index 3d0a159..3f2162d 100644
--- a/layers/linux/VkLayer_core_validation.json
+++ b/layers/linux/VkLayer_core_validation.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_core_validation",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_core_validation.so",
-        "api_version": "1.0.20",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/linux/VkLayer_image.json b/layers/linux/VkLayer_image.json
index aaa923a..97a250e 100644
--- a/layers/linux/VkLayer_image.json
+++ b/layers/linux/VkLayer_image.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_image",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_image.so",
-        "api_version": "1.0.20",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/linux/VkLayer_object_tracker.json b/layers/linux/VkLayer_object_tracker.json
index fa6a9da..1c5d79b 100644
--- a/layers/linux/VkLayer_object_tracker.json
+++ b/layers/linux/VkLayer_object_tracker.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_object_tracker",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_object_tracker.so",
-        "api_version": "1.0.20",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/linux/VkLayer_parameter_validation.json b/layers/linux/VkLayer_parameter_validation.json
index e9ec19f..899ea88 100644
--- a/layers/linux/VkLayer_parameter_validation.json
+++ b/layers/linux/VkLayer_parameter_validation.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_parameter_validation",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_parameter_validation.so",
-        "api_version": "1.0.20",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/linux/VkLayer_swapchain.json b/layers/linux/VkLayer_swapchain.json
index 88492f4..5fe0ef8 100644
--- a/layers/linux/VkLayer_swapchain.json
+++ b/layers/linux/VkLayer_swapchain.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_swapchain",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_swapchain.so",
-        "api_version": "1.0.20",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/linux/VkLayer_threading.json b/layers/linux/VkLayer_threading.json
index bfc08ef..59feb59 100644
--- a/layers/linux/VkLayer_threading.json
+++ b/layers/linux/VkLayer_threading.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_GOOGLE_threading",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_threading.so",
-        "api_version": "1.0.20",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "Google Validation Layer",
         "instance_extensions": [
diff --git a/layers/linux/VkLayer_unique_objects.json b/layers/linux/VkLayer_unique_objects.json
index 7439037..59e1f89 100644
--- a/layers/linux/VkLayer_unique_objects.json
+++ b/layers/linux/VkLayer_unique_objects.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_GOOGLE_unique_objects",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_unique_objects.so",
-        "api_version": "1.0.20",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "Google Validation Layer"
     }
diff --git a/layers/windows/VkLayer_core_validation.json b/layers/windows/VkLayer_core_validation.json
index df02686..a8d8cef 100644
--- a/layers/windows/VkLayer_core_validation.json
+++ b/layers/windows/VkLayer_core_validation.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_core_validation",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_core_validation.dll",
-        "api_version": "1.0.20",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/windows/VkLayer_image.json b/layers/windows/VkLayer_image.json
index a9511e7..a27dd5c 100644
--- a/layers/windows/VkLayer_image.json
+++ b/layers/windows/VkLayer_image.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_image",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_image.dll",
-        "api_version": "1.0.20",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/windows/VkLayer_object_tracker.json b/layers/windows/VkLayer_object_tracker.json
index c5ed8b3..1b97c67 100644
--- a/layers/windows/VkLayer_object_tracker.json
+++ b/layers/windows/VkLayer_object_tracker.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_object_tracker",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_object_tracker.dll",
-        "api_version": "1.0.20",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/windows/VkLayer_parameter_validation.json b/layers/windows/VkLayer_parameter_validation.json
index 0955064..efe91db 100644
--- a/layers/windows/VkLayer_parameter_validation.json
+++ b/layers/windows/VkLayer_parameter_validation.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_parameter_validation",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_parameter_validation.dll",
-        "api_version": "1.0.20",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/windows/VkLayer_swapchain.json b/layers/windows/VkLayer_swapchain.json
index 5f66220..b06c95c 100644
--- a/layers/windows/VkLayer_swapchain.json
+++ b/layers/windows/VkLayer_swapchain.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_swapchain",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_swapchain.dll",
-        "api_version": "1.0.20",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/windows/VkLayer_threading.json b/layers/windows/VkLayer_threading.json
index c65d250..dabee1f 100644
--- a/layers/windows/VkLayer_threading.json
+++ b/layers/windows/VkLayer_threading.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_GOOGLE_threading",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_threading.dll",
-        "api_version": "1.0.20",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "Google Validation Layer",
         "instance_extensions": [
diff --git a/layers/windows/VkLayer_unique_objects.json b/layers/windows/VkLayer_unique_objects.json
index ae07542..40a7c63 100644
--- a/layers/windows/VkLayer_unique_objects.json
+++ b/layers/windows/VkLayer_unique_objects.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_GOOGLE_unique_objects",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_unique_objects.dll",
-        "api_version": "1.0.20",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "Google Validation Layer"
     }
diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt
index f24beb1..a4d2b21 100644
--- a/loader/CMakeLists.txt
+++ b/loader/CMakeLists.txt
@@ -82,6 +82,6 @@ else()
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith")
 
     add_library(vulkan SHARED ${LOADER_SRCS})
-    set_target_properties(vulkan PROPERTIES SOVERSION "1" VERSION "1.0.20")
+    set_target_properties(vulkan PROPERTIES SOVERSION "1" VERSION "1.0.21")
     target_link_libraries(vulkan -ldl -lpthread -lm)
 endif()

commit 104c762bc9ade56a60c6294406df1fd2b843e182
Author: Karl Schultz <karl@lunarg.com>
Date:   Mon Jul 18 09:40:37 2016 -0600

    build: Update glslang to e4821e
    
    This includes applying a patch to glslang to revert glslang
    commit a5c33d, which fixes a texel fetch problem that many IHV
    drivers are not ready to cope with yet.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e5f3238..263002e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -217,15 +217,15 @@ if (WIN32)
     add_library(Loader      STATIC IMPORTED)
     add_library(SPIRV-Tools STATIC IMPORTED)
 
-    find_library(GLSLANG_DLIB NAMES glslang
+    find_library(GLSLANG_DLIB NAMES glslangd
                  HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
-    find_library(OGLCompiler_DLIB NAMES OGLCompiler
+    find_library(OGLCompiler_DLIB NAMES OGLCompilerd
                  HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
-    find_library(OSDependent_DLIB NAMES OSDependent
+    find_library(OSDependent_DLIB NAMES OSDependentd
                  HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
-    find_library(HLSL_DLIB NAMES HLSL
+    find_library(HLSL_DLIB NAMES HLSLd
                  HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
-    find_library(SPIRV_DLIB NAMES SPIRV
+    find_library(SPIRV_DLIB NAMES SPIRVd
                  HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
     find_library(SPIRV_TOOLS_DLIB NAMES SPIRV-Tools
                  HINTS ${SPIRV_TOOLS_DEBUG_SEARCH_PATH} )
diff --git a/glslang_revert_a5c33d.patch.txt b/glslang_revert_a5c33d.patch.txt
new file mode 100644
index 0000000..0d7075c
--- /dev/null
+++ b/glslang_revert_a5c33d.patch.txt
@@ -0,0 +1,18 @@
+diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
+index dd11304..aebc986 100755
+--- a/SPIRV/GlslangToSpv.cpp
++++ b/SPIRV/GlslangToSpv.cpp
+@@ -2630,13 +2630,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
+             bias = true;
+     }
+ 
+-    // See if the sampler param should really be just the SPV image part
+-    if (cracked.fetch) {
+-        // a fetch needs to have the image extracted first
+-        if (builder.isSampledImage(params.sampler))
+-            params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler);
+-    }
+-
+     // set the rest of the arguments
+ 
+     params.coords = arguments[1];
diff --git a/glslang_revision b/glslang_revision
index ac7412c..9a03f5a 100644
--- a/glslang_revision
+++ b/glslang_revision
@@ -1 +1 @@
-4678ca9dacfec7a084dbc69bbe568bdad6889f1b
+e4821e43c86d97bcf65fb07c1f70471b7102978d
diff --git a/update_external_sources.bat b/update_external_sources.bat
index b72d7bc..d027313 100644
--- a/update_external_sources.bat
+++ b/update_external_sources.bat
@@ -215,13 +215,9 @@ goto:eof
    cd %GLSLANG_DIR%
    git fetch --all
    git checkout %GLSLANG_REVISION%
-   REM Special case for this particular revision:
-   REM Pull in a patch that fixes a compilation issue with g++ 5.3
+   REM Revert glslang a5c33d6ffb34ccede5b233bc724c907166b6e479
    REM See https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/issues/681
-   if "%GLSLANG_REVISION%" == "4678ca9dacfec7a084dbc69bbe568bdad6889f1b" (
-      git checkout %GLSLANG_REVISION% -B temp1610
-      git cherry-pick 880bf36cacee1cfce7d5d94991eb18c9e2d59d39
-   )
+   git apply --whitespace=fix %BUILD_DIR%\glslang_revert_a5c33d.patch.txt
 goto:eof
 
 :create_spirv-tools
@@ -289,7 +285,7 @@ goto:eof
    msbuild INSTALL.vcxproj /p:Platform=x86 /p:Configuration=Debug /verbosity:quiet
    
    REM Check for existence of one lib, even though we should check for all results
-   if not exist %GLSLANG_BUILD_DIR%\glslang\Debug\glslang.lib (
+   if not exist %GLSLANG_BUILD_DIR%\glslang\Debug\glslangd.lib (
       echo.
       echo glslang 32-bit Debug build failed!
       set errorCode=1
@@ -319,7 +315,7 @@ goto:eof
    msbuild INSTALL.vcxproj /p:Platform=x64 /p:Configuration=Debug /verbosity:quiet
    
    REM Check for existence of one lib, even though we should check for all results
-   if not exist %GLSLANG_BUILD_DIR%\glslang\Debug\glslang.lib (
+   if not exist %GLSLANG_BUILD_DIR%\glslang\Debug\glslangd.lib (
       echo.
       echo glslang 64-bit Debug build failed!
       set errorCode=1
diff --git a/update_external_sources.sh b/update_external_sources.sh
index 43992e2..f9f94ec 100755
--- a/update_external_sources.sh
+++ b/update_external_sources.sh
@@ -25,13 +25,14 @@ function update_glslang () {
    cd $BASEDIR/glslang
    git fetch --all
    git checkout $GLSLANG_REVISION
-   # Special case for this particular revision:
-   # Pull in a patch that fixes a compilation issue with g++ 5.3
+   # Revert glslang a5c33d6ffb34ccede5b233bc724c907166b6e479
    # See https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/issues/681
-   if [ $GLSLANG_REVISION == "4678ca9dacfec7a084dbc69bbe568bdad6889f1b" ] ;
+   git diff-index --quiet HEAD | true
+   rc=${PIPESTATUS[0]}
+   if (( $rc == 0 ))
    then
-      git checkout $GLSLANG_REVISION -B temp1610
-      git cherry-pick 880bf36cacee1cfce7d5d94991eb18c9e2d59d39
+      echo "applying patch to revert glslang a5c33d"
+      git apply $BUILDDIR/glslang_revert_a5c33d.patch.txt
    fi
 }
 

commit 06811df0256552cd7da9d7297672af377463fc4a
Author: Mark Mueller <markm@lunarg.com>
Date:   Wed Jul 13 14:49:35 2016 -0600

    layers: Fix minor completeness/performance issue
    
    The first time the condition is discovered it will
    be the same as every subsequent time, so there is
    no need to continue. Also, the whole structure must
    be compared, so memcmp assures that will happen
    with good efficiency
    
    Change-Id: I71f608c71f83ebcd02212bb391a30bdf15279ff6

diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 9211503..4ca938f 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -3093,18 +3093,16 @@ static bool verifyPipelineCreateState(layer_data *my_data, const VkDevice device
             if (pPipeline->attachments.size() > 1) {
                 VkPipelineColorBlendAttachmentState *pAttachments = &pPipeline->attachments[0];
                 for (size_t i = 1; i < pPipeline->attachments.size(); i++) {
-                    if ((pAttachments[0].blendEnable != pAttachments[i].blendEnable) ||
-                        (pAttachments[0].srcColorBlendFactor != pAttachments[i].srcColorBlendFactor) ||
-                        (pAttachments[0].dstColorBlendFactor != pAttachments[i].dstColorBlendFactor) ||
-                        (pAttachments[0].colorBlendOp != pAttachments[i].colorBlendOp) ||
-                        (pAttachments[0].srcAlphaBlendFactor != pAttachments[i].srcAlphaBlendFactor) ||
-                        (pAttachments[0].dstAlphaBlendFactor != pAttachments[i].dstAlphaBlendFactor) ||
-                        (pAttachments[0].alphaBlendOp != pAttachments[i].alphaBlendOp) ||
-                        (pAttachments[0].colorWriteMask != pAttachments[i].colorWriteMask)) {
+                    // Quoting the spec: "If [the independent blend] feature is not enabled, the VkPipelineColorBlendAttachmentState
+                    // settings for all color attachments must be identical." VkPipelineColorBlendAttachmentState contains
+                    // only attachment state, so memcmp is best suited for the comparison
+                    if (memcmp(static_cast<const void *>(pAttachments), static_cast<const void *>(&pAttachments[i]),
+                               sizeof(pAttachments[0]))) {
                         skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
                                              __LINE__, DRAWSTATE_INDEPENDENT_BLEND, "DS",
                                              "Invalid Pipeline CreateInfo: If independent blend feature not "
                                              "enabled, all elements of pAttachments must be identical");
+                        break;
                     }
                 }
             }

commit 7e9ec4c5da3c1f7bf99353ea547e5fe4d283b110
Author: Cody Northrop <cnorthrop@google.com>
Date:   Wed Jul 13 15:59:22 2016 -0600

    windows: Return exit code from build script if any step fails

diff --git a/build_windows_targets.bat b/build_windows_targets.bat
index 3844742..eb13209 100644
--- a/build_windows_targets.bat
+++ b/build_windows_targets.bat
@@ -34,7 +34,7 @@ if %do_cmake%==0 (
     if %do_32%==0 (
         if %do_64%==0 (
             echo No valid parameters specified.
-            exit /B 1
+            exit 1
         )
     )
 )
@@ -76,7 +76,7 @@ if %do_64%==1 (
        echo.
        echo 64-bit Debug build failed!
        popd
-       exit /B 1
+       exit 1
     )   
    
     echo Building 64-bit Release 
@@ -85,7 +85,7 @@ if %do_64%==1 (
        echo.
        echo 64-bit Release build failed!
        popd
-       exit /B 1
+       exit 1
     )   
     popd
 )
@@ -106,7 +106,7 @@ if %do_32%==1 (
        echo.
        echo 32-bit Debug build failed!
        popd
-       exit /B 1
+       exit 1
     )   
        
     echo Building 32-bit Release 
@@ -115,8 +115,8 @@ if %do_32%==1 (
        echo.
        echo 32-bit Release build failed!
        popd
-       exit /B 1
+       exit 1
     )   
     popd
 )
-exit /B 0
+exit 0

commit 6de3c6ffa0819ee37cd5cecee918b062145e2ff1
Author: Tobin Ehlis <tobine@google.com>
Date:   Fri Jul 15 16:01:13 2016 -0600

    layers: Update clearValueCount check
    
    The pClearValues array is indexed by the attachment index which
    means that it must be at least as large as the last LOAD_OP_CLEAR
    attachment in the renderpass. Updating this check to reflect this
    requirement.

diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 1414bd5..9211503 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -9489,7 +9489,7 @@ CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *p
     auto framebuffer = pRenderPassBegin ? getFramebuffer(dev_data, pRenderPassBegin->framebuffer) : nullptr;
     if (pCB) {
         if (renderPass) {
-            uint32_t clear_op_count = 0;
+            uint32_t clear_op_size = 0; // Make sure pClearValues is at least as large as last LOAD_OP_CLEAR
             pCB->activeFramebuffer = pRenderPassBegin->framebuffer;
             for (size_t i = 0; i < renderPass->attachments.size(); ++i) {


Reply to: