Change log for October 7, 2016 Vulkan 1.0.30 spec update:

* Bump API patch number and header version number to 30 for this update.

Github Issues:

  * Document missing pname:sType and pname:pNext parameters for
    slink:VkCommandBufferInheritanceInfo (public issue 224).
  * As promised, we are removing the example code, from the appendix, for
    the VK_KHR_surface and VK_KHR_swapchain extensions. The cube demo
    (shipped in the official Khronos SDK) has been updated, and is the
    example code that we want people to look at for how to use these two
    extensions (public issues 279, 308, and 311).
  * Clarify the formats for which the slink:VkClearColorValue pname:float32
    member is used. Also clean up related language for flink:vkCmdBlitImage
    (public issue 369).
  * Reword the <<invariance, Invariance>> appendix chapter to better match
    Vulkan terminology (public issue 372).

Internal Issues:

  * Update slink:VkMemoryRequirements to not require a host_visible memory
    type exists that can be bound to sparse buffers (internal issue 494).
  * Modify the <<features-supported-sample-counts,Supported Sample Counts>>
    language to allow multisampled depth-stencil images (internal issue
    521).
This commit is contained in:
Jon Leech 2016-10-07 02:40:18 -07:00
parent 42fcc80976
commit 49adf2575c
14 changed files with 86 additions and 859 deletions

View File

@ -1452,3 +1452,32 @@ Other Issues:
* Use the terms ``allocation scope'' and ``extension scope'' instead of * Use the terms ``allocation scope'' and ``extension scope'' instead of
just ``scope'', and add them to the glossary. just ``scope'', and add them to the glossary.
-----------------------------------------------------
Change log for October 7, 2016 Vulkan 1.0.30 spec update:
* Bump API patch number and header version number to 30 for this update.
Github Issues:
* Document missing pname:sType and pname:pNext parameters for
slink:VkCommandBufferInheritanceInfo (public issue 224).
* As promised, we are removing the example code, from the appendix, for
the VK_KHR_surface and VK_KHR_swapchain extensions. The cube demo
(shipped in the official Khronos SDK) has been updated, and is the
example code that we want people to look at for how to use these two
extensions (public issues 279, 308, and 311).
* Clarify the formats for which the slink:VkClearColorValue pname:float32
member is used. Also clean up related language for flink:vkCmdBlitImage
(public issue 369).
* Reword the <<invariance, Invariance>> appendix chapter to better match
Vulkan terminology (public issue 372).
Internal Issues:
* Update slink:VkMemoryRequirements to not require a host_visible memory
type exists that can be bound to sparse buffers (internal issue 494).
* Modify the <<features-supported-sample-counts,Supported Sample Counts>>
language to allow multisampled depth-stencil images (internal issue
521).

View File

@ -160,7 +160,7 @@ GENDEPENDS = api/timeMarker validity/timeMarker hostsynctable/timeMarker
COMMONDOCS = $(CHAPTERS) $(GENINCLUDE) $(GENDEPENDS) COMMONDOCS = $(CHAPTERS) $(GENINCLUDE) $(GENDEPENDS)
# A generated included file containing the spec version, date, and git commit # A generated included file containing the spec version, date, and git commit
SPECVERSION = specversion.txt SPECVERSION = specversion.txt
SPECREVISION = 1.0.29 SPECREVISION = 1.0.30
SPECREMARK = SPECREMARK =
# Spec targets # Spec targets

View File

@ -82,165 +82,12 @@ this and other platform-independent extensions, in particular the
.Note .Note
==== ====
The example code for the +VK_KHR_surface+ and +VK_KHR_swapchain+ extensions The example code for the +VK_KHR_surface+ and +VK_KHR_swapchain+ extensions
will be removed from future versions of this appendix. was removed from the appendix after revision 1.0.29.
The WSI example code was ported to the cube demo, that is shipped with the This WSI example code was ported to the cube demo that is shipped with the
official Khronos SDK, and has been kept up-to-date in that location. official Khronos SDK, and is being kept up-to-date in that location (see:
There is little reason to maintain this example code in the appendix as https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/demos/cube.c).
well.
==== ====
**Example 1**
Show how to obtain function pointers for WSI commands.
Most applications should: not need to do this, because the functions for the
WSI extensions that are relevant for a given platform are exported by the
official loader for that platform (e.g. the official Khronos loader for
Microsoft Windows and Linux, and the Android loader).
Other examples, will directly call the relevant command, not through a
function pointer.
[source,{basebackend@docbook:c++:cpp}]
----------------------------------------
extern VkInstance instance;
...
// Obtain function pointers for the VK_KHR_surface commands:
PFN_vkGetPhysicalDeviceSurfaceSupportKHR pfnGetPhysicalDeviceSurfaceSupportKHR =
(PFN_vkGetPhysicalDeviceSurfaceSupportKHR)vkGetInstanceProcAddr(instance,
"vkGetPhysicalDeviceSurfaceSupportKHR");
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR pfnGetPhysicalDeviceSurfaceCapabilitiesKHR =
(PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)vkGetInstanceProcAddr(instance,
"vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR pfnGetPhysicalDeviceSurfaceFormatsKHR =
(PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)vkGetInstanceProcAddr(instance,
"vkGetPhysicalDeviceSurfaceFormatsKHR");
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR pfnGetPhysicalDeviceSurfacePresentModesKHR =
(PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)vkGetInstanceProcAddr(instance,
"vkGetPhysicalDeviceSurfacePresentModesKHR");
----------------------------------------
**Example 2**
Pick which queues on a physical device to use for graphics and present
operations for a given surface, and create a device with those queues.
[source,{basebackend@docbook:c++:cpp}]
----------------------------------------
extern VkInstance instance;
extern VkPhysicalDevice physicalDevice;
extern VkSurfaceKHR surface;
extern void Error(const char *);
uint32_t queueFamilyCount;
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice,
&queueFamilyCount, NULL);
VkQueueFamilyProperties* pMainQueueInfo =
(VkQueueFamilyProperties*)malloc(queueFamilyCount * sizeof(VkQueueFamilyProperties));
VkBool32* pSupportsPresent =
(VkBool32 *)malloc(queueFamilyCount * sizeof(VkBool32));
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount,
pMainQueueInfo);
for (uint32_t i = 0; i < queueFamilyCount; ++i)
vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, i, surface,
&pSupportsPresent[i]);
// Search for a graphics and a present queue in the array of queue
// families, try to find one that supports both
uint32_t graphicsQueueFamilyIndex = UINT32_MAX;
uint32_t presentQueueFamilyIndex = UINT32_MAX;
for (uint32_t i = 0; i < queueFamilyCount; ++i)
{
if ((pMainQueueInfo[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)
{
if (graphicsQueueFamilyIndex == UINT32_MAX)
graphicsQueueFamilyIndex = i;
if (pSupportsPresent[i] == VK_TRUE)
{
graphicsQueueFamilyIndex = i;
presentQueueFamilyIndex = i;
break;
}
}
}
if (presentQueueFamilyIndex == UINT32_MAX)
{
// If did not find a queue that supports both graphics and present, then
// find a separate present queue.
for (size_t i = 0; i < queueFamilyCount; ++i)
if (pSupportsPresent[i] == VK_TRUE)
{
presentQueueFamilyIndex = i;
break;
}
}
// Free the temporary queue info allocations
free(pMainQueueInfo);
free(pSupportsPresent);
// Generate error if could not find both a graphics and a present queue
if (graphicsQueueFamilyIndex == UINT32_MAX ||
presentQueueFamilyIndex == UINT32_MAX)
{
Error("Could not find a graphics and a present queue");
}
// Put together the list of requested queues
const float queuePriority = 1.0f;
const VkDeviceQueueCreateInfo requestedQueues[] =
{
{
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
NULL, // pNext
0, // flags
graphicsQueueFamilyIndex, // queueFamilyIndex
1, // queueCount
&queuePriority // pQueuePriorities
},
{
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
NULL, // pNext
0, // flags
presentQueueFamilyIndex, // queueFamilyIndex
1, // queueCount
&queuePriority // pQueuePriorities
}
};
uint32_t requestedQueueCount = 2;
if (graphicsQueueFamilyIndex == presentQueueFamilyIndex)
{
// We need only a single queue if the graphics queue is also the
// present queue
requestedQueueCount = 1;
}
// Create a device and request access to the specified queues
const VkDeviceCreateInfo deviceCreateInfo =
{
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
NULL, // pNext
0, // flags
requestedQueueCount, // queueCreateInfoCount
&requestedQueues, // pQueueCreateInfos
...
};
VkDevice device;
vkCreateDevice(physicalDevice, &deviceCreateInfo, &device);
// Acquire graphics and present queue handle from device
VkQueue graphicsQueue, presentQueue;
vkGetDeviceQueue(device, graphicsQueueFamilyIndex, 0, &graphicsQueue);
vkGetDeviceQueue(device, presentQueueFamilyIndex, 0, &presentQueue);
----------------------------------------
=== Issues === Issues
1) Should this extension include a method to query whether a physical device 1) Should this extension include a method to query whether a physical device

View File

@ -457,665 +457,12 @@ None
.Note .Note
==== ====
The example code for the +VK_KHR_surface+ and +VK_KHR_swapchain+ extensions The example code for the +VK_KHR_surface+ and +VK_KHR_swapchain+ extensions
will be removed from future versions of this appendix. was removed from the appendix after revision 1.0.29.
The WSI example code was ported to the cube demo, that is shipped with the This WSI example code was ported to the cube demo that is shipped with the
official Khronos SDK, and has been kept up-to-date in that location. official Khronos SDK, and is being kept up-to-date in that location (see:
There is little reason to maintain this example code in the appendix as https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/demos/cube.c).
well.
==== ====
**Example 1**
Show how to obtain function pointers for WSI commands.
Most applications should: not need to do this, because the functions for the
WSI extensions that are relevant for a given platform are exported by the
official loader for that platform (e.g. the official Khronos loader for
Microsoft Windows and Linux, and the Android loader).
Other examples, will directly call the relevant command, not through a
function pointer.
[source,{basebackend@docbook:c++:cpp}]
----------------------------------------
extern VkDevice device;
...
// Obtain function pointers for the VK_KHR_swapchain commands:
PFN_vkCreateSwapchainKHR pfnCreateSwapchainKHR =
(PFN_vkCreateSwapchainKHR)vkGetDeviceProcAddr(device,
"vkCreateSwapchainKHR");
PFN_vkGetSwapchainImagesKHR pfnGetSwapchainImagesKHR =
(PFN_vkGetSwapchainImagesKHR)vkGetDeviceProcAddr(device,
"vkGetSwapchainImagesKHR");
PFN_vkAcquireNextImageKHR pfnAcquireNextImageKHR =
(PFN_vkAcquireNextImageKHR)vkGetDeviceProcAddr(device,
"vkAcquireNextImageKHR");
PFN_vkQueuePresentKHR pfnQueuePresentKHR =
(PFN_vkQueuePresentKHR)vkGetDeviceProcAddr(device,
"vkQueuePresentKHR");
PFN_vkDestroySwapchainKHR pfnDestroySwapchainKHR =
(PFN_vkDestroySwapchainKHR)vkGetDeviceProcAddr(device,
"vkDestroySwapchainKHR");
----------------------------------------
**Example 2**
Create a swapchain for a surface on a particular instance of a native
platform.
[source,{basebackend@docbook:c++:cpp}]
----------------------------------------
extern VkPhysicalDevice physicalDevice;
extern VkDevice device;
extern VkSurfaceKHR surface;
// Check the surface properties and formats
VkSurfaceCapabilitiesKHR surfCapabilities;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface,
&surfCapabilities);
uint32_t formatCount;
vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface,
&formatCount, NULL);
VkSurfaceFormatKHR* pSurfFormats =
(VkSurfaceFormatKHR*)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface,
&formatCount, pSurfFormats);
uint32_t presentModeCount;
vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface,
&presentModeCount, NULL);
VkPresentModeKHR* pPresentModes =
(VkPresentModeKHR*)malloc(presentModeCount * sizeof(VkPresentModeKHR));
vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface,
&presentModeCount, pPresentModes);
VkExtent2D swapchainExtent;
// width and height are either both 0xFFFFFFFF, or both not 0xFFFFFFFF.
if (surfCapabilities.currentExtent.width == 0xFFFFFFFF)
{
// If the surface size is undefined, the size is set to the size
// of the images requested, which must fit within the minimum and
// maximum values.
swapchainExtent.width = 320;
swapchainExtent.height = 320;
if (swapchainExtent.width < surfCapabilities.minImageExtent.width)
swapchainExtent.width = surfCapabilities.minImageExtent.width;
else if (swapchainExtent.width > surfCapabilities.maxImageExtent.width)
swapchainExtent.width = surfCapabilities.maxImageExtent.width;
if (swapchainExtent.height < surfCapabilities.minImageExtent.height)
swapchainExtent.height = surfCapabilities.minImageExtent.height;
else if (swapchainExtent.height > surfCapabilities.maxImageExtent.height)
swapchainExtent.height = surfCapabilities.maxImageExtent.height;
}
else
{
// If the surface size is defined, the swapchain size must match
swapchainExtent = surfCapabilities.currentExtent;
}
// Application desires to simultaneously acquire 2 images (which is one
// more than "surfCapabilities.minImageCount").
uint32_t desiredNumOfSwapchainImages = surfCapabilities.minImageCount + 1;
if ((surfCapabilities.maxImageCount > 0) &&
(desiredNumOfSwapchainImages > surfCapabilities.maxImageCount))
{
// Application must settle for fewer images than desired:
desiredNumOfSwapchainImages = surfCapabilities.maxImageCount;
}
VkFormat swapchainFormat;
// If the format list includes just one entry of VK_FORMAT_UNDEFINED,
// the surface has no preferred format. Otherwise, at least one
// supported format will be returned (assuming that the
// vkGetPhysicalDeviceSurfaceSupportKHR function, in the
// VK_KHR_surface extension returned support for the surface).
if ((formatCount == 1) && (pSurfFormats[0].format == VK_FORMAT_UNDEFINED))
swapchainFormat = VK_FORMAT_R8G8B8_UNORM;
else
{
assert(formatCount >= 1);
swapchainFormat = pSurfFormats[0].format;
}
VkColorSpaceKHR swapchainColorSpace = pSurfFormats[0].colorSpace;
// If mailbox mode is available, use it, as it is the lowest-latency non-
// tearing mode. If not, fall back to FIFO which is always available.
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
for (size_t i = 0; i < presentModeCount; ++i)
{
if (pPresentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR)
{
swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
break;
}
}
const VkSwapchainCreateInfoKHR createInfo =
{
VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, // sType
NULL, // pNext
0, // flags
surface, // surface
desiredNumOfSwapchainImages, // minImageCount
swapchainFormat, // imageFormat
swapchainColorSpace, // imageColorSpace
swapchainExtent, // imageExtent
1, // imageArrayLayers
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // imageUsage
VK_SHARING_MODE_EXCLUSIVE, // imageSharingMode
0, // queueFamilyIndexCount
NULL, // pQueueFamilyIndices
surfCapabilities.currentTransform, // preTransform
VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR, // compositeAlpha
swapchainPresentMode, // presentMode
VK_TRUE, // clipped
VK_NULL_HANDLE // oldSwapchain
};
VkSwapchainKHR swapchain;
vkCreateSwapchainKHR(device, &createInfo, NULL, &swapchain);
----------------------------------------
**Example 3**
Obtaining the persistent images of a swapchain
[source,{basebackend@docbook:c++:cpp}]
----------------------------------------
extern VkDevice device;
uint32_t swapchainImageCount;
vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, NULL);
VkImage* pSwapchainImages = (VkImage*)malloc(swapchainImageCount * sizeof(VkImage));
vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, pSwapchainImages);
----------------------------------------
**Example 4**
Simple rendering and presenting using separate graphics and present queues.
[source,{basebackend@docbook:c++:cpp}]
----------------------------------------
extern VkDevice device;
// Construct command buffers rendering to the presentable images
VkCmdBuffer cmdBuffers[swapchainImageCount];
VkImageView views[swapchainImageCount];
extern VkCmdBufferBeginInfo beginInfo;
extern uint32_t graphicsQueueFamilyIndex, presentQueueFamilyIndex;
for (size_t i = 0; i < swapchainImageCount; ++i)
{
const VkImageViewCreateInfo viewInfo =
{
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // sType
NULL, // pNext
0, // flags
pSwapchainImages[i], // image
VK_IMAGE_VIEW_TYPE_2D, // viewType
swapchainFormat, // format
...
};
vkCreateImageView(device, &viewInfo, &views[i]);
...
vkBeginCommandBuffer(cmdBuffers[i], &beginInfo);
// Need to transition image from presentable state before being able
// to render
const VkImageMemoryBarrier acquireImageBarrier =
{
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
NULL, // pNext
VK_ACCESS_MEMORY_READ_BIT, // srcAccessMask
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, // oldLayout
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
presentQueueFamilyIndex, // srcQueueFamilyIndex
graphicsQueueFamilyIndex, // dstQueueFamilyIndex
pSwapchainImages[i].image, // image
...
};
vkCmdPipelineBarrier(
cmdBuffers[i],
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_FALSE,
1,
&acquireImageBarrier)
// ... Render to views[i] ...
// Need to transition image into presentable state before being able
// to present
const VkImageMemoryBarrier presentImageBarrier =
{
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
NULL, // pNext
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
VK_ACCESS_MEMORY_READ_BIT, // dstAccessMask
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, // newLayout
graphicsQueueFamilyIndex, // srcQueueFamilyIndex
presentQueueFamilyIndex, // dstQueueFamilyIndex
pSwapchainImages[i].image, // image
...
};
vkCmdPipelineBarrier(
cmdBuffers[i],
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_FALSE,
1,
&presentImageBarrier);
...
vkEndCommandBuffer(cmdBuffers[i]);
}
const VkSemaphoreCreateInfo semaphoreCreateInfo =
{
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, // sType
NULL, // pNext
0 // flags
};
VkSemaphore imageAcquiredSemaphore;
vkCreateSemaphore(device,
&semaphoreCreateInfo,
&imageAcquiredSemaphore);
VkSemaphore renderingCompleteSemaphore;
vkCreateSemaphore(device,
&semaphoreCreateInfo,
&renderingCompleteSemaphore);
VkResult result;
do
{
uint32_t imageIndex = UINT32_MAX;
// Get the next available swapchain image
result = vkAcquireNextImageKHR(
device,
swapchain,
UINT64_MAX,
imageAcquiredSemaphore,
VK_NULL_HANDLE,
&imageIndex);
// Swapchain cannot be used for presentation if failed to acquired
// new image.
if (result < 0)
break;
// Submit rendering work to the graphics queue
const VkPipelineStageFlags waitDstStageMask =
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
const VkSubmitInfo submitInfo =
{
VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
NULL, // pNext
1, // waitSemaphoreCount
&imageAcquiredSemaphore, // pWaitSemaphores
&waitDstStageMask, // pWaitDstStageMasks
1, // commandBufferCount
&cmdBuffers[imageIndex], // pCommandBuffers
1, // signalSemaphoreCount
&renderingCompleteSemaphore // pSignalSemaphores
};
vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
// Submit present operation to present queue
const VkPresentInfoKHR presentInfo =
{
VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, // sType
NULL, // pNext
1, // waitSemaphoreCount
&renderingCompleteSemaphore, // pWaitSemaphores
1, // swapchainCount
&swapchain, // pSwapchains
&imageIndex, // pImageIndices
NULL // pResults
};
result = vkQueuePresentKHR(presentQueue, &presentInfo);
} while (result >= 0);
----------------------------------------
**Example 5**
Handle VK_ERROR_OUT_OF_DATE_KHR by recreating the swapchain and
VK_SUBOPTIMAL_KHR by checking whether recreation is needed.
[source,{basebackend@docbook:c++:cpp}]
----------------------------------------
extern VkInstance instance;
extern VkPhysicalDevice physicalDevice;
extern VkDevice device;
extern VkQueue presentQueue;
extern VkSurfaceKHR surface;
// Contains code to build the application's reusable command buffers.
extern void CreateCommandBuffers(VkDevice device,
const VkImage* swapchainImages);
// Returns non-zero if the application considers the swapchain out
// of date even though it is still compatible with the platform
// surface it is targeting.
extern int MustRecreateSwapchain(VkDevice device,
VkSwapchainKHR swapchain,
VkSurfaceKHR surface);
extern void CreateSwapchain(VkDevice device,
VkSurfaceKHR surface,
VkSwapchainKHR oldSwapchain,
VkSwapchainKHR* pSwapchain);
{
...
// Most of this function is identical to what is in Example 2.
// One differences is in the initialization of the following struct.
const VkSwapchainCreateInfoKHR createInfo =
{
VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, // sType
NULL, // pNext
0, // flags
surface, // surface
desiredNumOfSwapchainImages, // minImageCount
swapchainFormat, // imageFormat
swapchainColorSpace, // imageColorSpace
swapchainExtent, // imageExtent
1, // imageArrayLayers
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // imageUsage
VK_SHARING_MODE_EXCLUSIVE, // imageSharingMode
0, // queueFamilyIndexCount
NULL, // pQueueFamilyIndices
surfCapabilities.currentTransform, // preTransform
VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR, // compositeAlpha
swapchainPresentMode, // presentMode
VK_TRUE, // clipped
// If the caller specified an existing swapchain, replace it with
// the new swapchain being created here. This will allow a
// seamless transition between the old and new swapchains on
// platforms that support it.
oldSwapchain // oldSwapchain
};
...
// Another difference is in the need to destroy the old swapchain, if
// it exists.
//
// Note: destroying the swapchain also cleans up all its associated
// presentable images once the platform is done with them.
if (oldSwapchain != VK_NULL_HANDLE)
{
vkDestroySwapchainKHR(device, oldSwapchain, NULL);
}
}
void mainLoop(void)
{
VkSwapchainKHR swapchain = VK_NULL_HANDLE;
const VkSemaphoreCreateInfo semaphoreCreateInfo =
{
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, // sType
NULL, // pNext
0 // flags
};
VkSemaphore imageAcquiredSemaphore;
vkCreateSemaphore(device,
&semaphoreCreateInfo,
&imageAcquiredSemaphore);
VkSemaphore renderingCompleteSemaphore;
vkCreateSemaphore(device,
&semaphoreCreateInfo,
&renderingCompleteSemaphore);
while (1)
{
VkResult result;
CreateSwapchain(device, surface, swapchain, &swapchain);
uint32_t swapchainImageCount;
vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, NULL);
VkImage* pSwapchainImages =
(VkImage*)malloc(swapchainImageCount * sizeof(VkImage));
vkGetSwapchainImagesKHR(device, swapchain,
&swapchainImageCount, pSwapchainImages);
CreateCommandBuffers(device, pSwapchainImages);
free(pSwapchainImages);
while (1)
{
uint32_t imageIndex;
// Get the next available swapchain image
result = vkAcquireNextImageKHR(
device,
swapchain,
UINT64_MAX,
imageAcquiredSemaphore,
VK_NULL_HANDLE,
&imageIndex);
if (result == VK_ERROR_OUT_OF_DATE_KHR)
{
// swapchain is out of date. Needs to be recreated for
// defined results.
break;
}
else if (result == VK_SUBOPTIMAL_KHR)
{
// Ignore this result here. If any expensive
// preprocessing work has already been done for this
// frame, it is likely in the application's interest to
// continue processing this frame with the current
// swapchain rather than recreate it and waste the
// preprocessing work.
}
else if (result < 0)
{
// Unhandled error. Abort.
return;
}
// Submit rendering work to the graphics queue
const VkPipelineStageFlags waitDstStageMask =
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
const VkSubmitInfo submitInfo =
{
VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
NULL, // pNext
1, // waitSemaphoreCount
&imageAcquiredSemaphore, // pWaitSemaphores
&waitDstStageMask, // pWaitDstStageMasks
1, // commandBufferCount
&cmdBuffers[imageIndex], // pCommandBuffers
1, // signalSemaphoreCount
&renderingCompleteSemaphore // pSignalSemaphores
};
vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
// Submit present operation to present queue
const VkPresentInfoKHR presentInfo =
{
VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, // sType
NULL, // pNext
1, // waitSemaphoreCount
&renderingCompleteSemaphore, // pWaitSemaphores
1, // swapchainCount
&swapchain, // pSwapchains
&imageIndex, // pImageIndices
NULL // pResults
};
result = vkQueuePresentKHR(presentQueue, &presentInfo);
if (result == VK_ERROR_OUT_OF_DATE_KHR)
{
// The swapchain is out of date, and must be recreated for
// defined results.
break;
}
else if (result == VK_SUBOPTIMAL_KHR)
{
// Something has changed about the native surface since
// the swapchain was created, but it is still compatible
// with the swapchain. The app must choose whether it
// wants to create a more up to date swapchain before it
// begins processing the next frame.
if (MustRecreateSwapchain(device, swapchain, surface))
break;
}
else if (result < 0)
{
// Unhandled error. Abort.
return;
}
}
}
}
----------------------------------------
**Example 6**
Meter a CPU thread based on presentation rate.
Note this will only limit the thread to the actual presentation rate when
using VK_PRESENT_MODE_FIFO_KHR.
When using VK_PRESENT_MODE_IMMEDIATE_KHR, presentation rate will be limited
only by rendering rate, so this example will be equivalent to waiting on a
command buffer fence.
When using VK_PRESENT_MODE_MAILBOX_KHR, some presented images may be skipped
if a newer image is available by the time the presentation target is ready
to process a new frame, so this code would again be limited only by the
rendering rate.
Applications using mailbox mode should: use some other mechanism to meter
their rendering, and it is assumed applications using immediate mode have no
desire to limit the rate of their rendering based on presentation rate.
[source,{basebackend@docbook:c++:cpp}]
----------------------------------------
extern void CreateSemAndFences(VkDevice device, VkSemaphore sem,
VkFence *fences,
const int maxOutstandingPresents);
extern void GenFrameCmdBuffer(VkCmdbuffer cmdBuffer);
extern VkDevice device;
extern VkQueue queue;
extern VkCmdBuffer cmdBuffer;
extern VkSwapchain fifoModeSwapchain;
extern numSwapchainImages;
// Allow a maximum of two outstanding presentation operations.
static const int FRAME_LAG = 2
VkPresentInfoKHR presentInfo;
const VkSemaphoreCreateInfo semaphoreCreateInfo =
{
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, // sType
NULL, // pNext
0 // flags
};
VkSemaphore imageAcquiredSemaphore;
vkCreateSemaphore(device,
&semaphoreCreateInfo,
&imageAcquiredSemaphore);
VkSemaphore renderingCompleteSemaphore;
vkCreateSemaphore(device,
&semaphoreCreateInfo,
&renderingCompleteSemaphore);
VkFence fences[FRAME_LAG];
bool fencesInited[FRAME_LAG];
int frameIdx = 0;
int imageIdx = 0;
int waitFrame;
CreateFences(device, fences, FRAME_LAG);
for (int i = 0; i < FRAME_LAG; ++i)
fencesInited[i] = false;
while (1) {
if (fencesInited[frameIdx])
{
// Ensure no more than FRAME_LAG presentations are outstanding
vkWaitForFences(device, 1, &fences[frameIdx], VK_TRUE, UINT64_MAX);
vkResetFences(device, 1, &fences[frameIdx]);
}
vkAcquireNextImageKHR(
device,
fifoSwapchain,
UINT64_MAX,
imageAcquiredSemaphore,
fences[frameIdx],
&imageIdx);
fencesInited[frameIdx] = true;
// Generate a command buffer for the current frame.
GenFrameCmdBuffer(cmdBuffer);
// Submit rendering work to the graphics queue
const VkPipelineStageFlags waitDstStageMask =
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
const VkSubmitInfo submitInfo =
{
VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
NULL, // pNext
1, // waitSemaphoreCount
&imageAcquiredSemaphore, // pWaitSemaphores
&waitDstStageMask, // pWaitDstStageMasks
1, // commandBufferCount
&cmdBuffer, // pCommandBuffers
1, // signalSemaphoreCount
&renderingCompleteSemaphore // pSignalSemaphores
};
vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);
// Submit present operation to present queue
const VkPresentInfoKHR presentInfo =
{
VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, // sType
NULL, // pNext
1, // waitSemaphoreCount
&renderingCompleteSemaphore, // pWaitSemaphores
1, // swapchainCount
&fifoSwapchain, // pSwapchains
&imageIdx, // pImageIndices
NULL // pResults
};
result = vkQueuePresentKHR(queue, &presentInfo);
frameIdx += 1;
frameIdx %= FRAME_LAG;
}
----------------------------------------
=== Version History === Version History
* Revision 1, 2015-05-20 (James Jones) * Revision 1, 2015-05-20 (James Jones)

View File

@ -2,6 +2,7 @@
// Copyright notice at https://www.khronos.org/registry/speccopyright.html // Copyright notice at https://www.khronos.org/registry/speccopyright.html
[appendix] [appendix]
[[invariance]]
= Invariance = Invariance
The Vulkan specification is not pixel exact. The Vulkan specification is not pixel exact.
@ -59,7 +60,7 @@ Examples of these algorithms include:
== Invariance Rules == Invariance Rules
For a given instantiation of an Vulkan rendering context: For a given Vulkan device:
*Rule 1* _For any given Vulkan and framebuffer state vector, and for any *Rule 1* _For any given Vulkan and framebuffer state vector, and for any
given Vulkan command, the resulting Vulkan and framebuffer state must: be given Vulkan command, the resulting Vulkan and framebuffer state must: be
@ -71,19 +72,17 @@ use of any other state value is not affected by the change):_
*Required:* *Required:*
* _Framebuffer contents (all bit planes)_ * _Color and depth/stencil attachment contents_
* _The color buffers enabled for writing_
* _Scissor parameters (other than enable)_ * _Scissor parameters (other than enable)_
* _Writemasks (color, depth, stencil)_ * _Write masks (color, depth, stencil)_
* _Clear values (color, depth, stencil)_ * _Clear values (color, depth, stencil)_
*Strongly suggested:* *Strongly suggested:*
* _Stencil Parameters (other than enable)_ * _Stencil parameters (other than enable)_
* _Depth test parameters (other than enable)_ * _Depth test parameters (other than enable)_
* _Blend parameters (other than enable)_ * _Blend parameters (other than enable)_
* _Logical operation parameters (other than enable)_ * _Logical operation parameters (other than enable)_
* _Pixel storage state_
*Corollary 1* _Fragment generation is invariant with respect to the state *Corollary 1* _Fragment generation is invariant with respect to the state
values listed in Rule 2._ values listed in Rule 2._
@ -91,16 +90,15 @@ values listed in Rule 2._
*Rule 3* _The arithmetic of each per-fragment operation is invariant except *Rule 3* _The arithmetic of each per-fragment operation is invariant except
with respect to parameters that directly control it._ with respect to parameters that directly control it._
*Corollary 2* _Images rendered into different color buffers sharing the same *Corollary 2* _Images rendered into different color attachments of the same
framebuffer, either simultaneously or separately using the same command framebuffer, either simultaneously or separately using the same command
sequence, are pixel identical._ sequence, are pixel identical._
*Rule 4* _The same vertex or fragment shader will produce the same result *Rule 4* _Identical pipelines will produce the same result when run multiple
when run multiple times with the same input. times with the same input.
The wording ``the same shader'' means a program object that is populated The wording ``Identical pipelines'' means sname:VkPipeline objects that have
with the same SPIR-V binary, which is used to create pipelines, possibly been created with identical SPIR-V binaries and identical state, which are
multiple times, and which program object is then executed using the same then used by commands executed using the same Vulkan state vector.
Vulkan state vector.
Invariance is relaxed for shaders with side effects, such as performing Invariance is relaxed for shaders with side effects, such as performing
stores or atomics._ stores or atomics._
@ -124,8 +122,8 @@ indirectly affected by results of shader image or buffer variable stores or
atomic operations must: be identical each time the command is executed on atomic operations must: be identical each time the command is executed on
that initial Vulkan and framebuffer state._ that initial Vulkan and framebuffer state._
*Rule 7* _The same vertex or fragment shader will produce the same result *Rule 7* _Identical pipelines will produce the same result when run multiple
when run multiple times with the same input as long as:_ times with the same input as long as:_
* _shader invocations do not use image atomic operations;_ * _shader invocations do not use image atomic operations;_
* _no framebuffer memory is written to more than once by image stores, * _no framebuffer memory is written to more than once by image stores,
@ -141,7 +139,7 @@ be explicitly synchronized.
== Tessellation Invariance == Tessellation Invariance
When using a program containing tessellation evaluation shaders, the When using a pipeline containing tessellation evaluation shaders, the
fixed-function tessellation primitive generator consumes the input patch fixed-function tessellation primitive generator consumes the input patch
specified by an application and emits a new set of primitives. specified by an application and emits a new set of primitives.
The following invariance rules are intended to provide repeatability The following invariance rules are intended to provide repeatability
@ -154,10 +152,10 @@ positions of vertices along shared edges.
*Rule 1* _When processing two patches with identical outer and inner *Rule 1* _When processing two patches with identical outer and inner
tessellation levels, the tessellation primitive generator will emit an tessellation levels, the tessellation primitive generator will emit an
identical set of point, line, or triangle primitives as long as the active identical set of point, line, or triangle primitives as long as the pipeline
program used to process the patch primitives has tessellation evaluation used to process the patch primitives has tessellation evaluation shaders
shaders specifying the same tessellation mode, spacing, vertex order, and specifying the same tessellation mode, spacing, vertex order, and point mode
point mode decorations. decorations.
Two sets of primitives are considered identical if and only if they contain Two sets of primitives are considered identical if and only if they contain
the same number and type of primitives and the generated tessellation the same number and type of primitives and the generated tessellation
coordinates for the vertex numbered m of the primitive numbered n are coordinates for the vertex numbered m of the primitive numbered n are

View File

@ -223,13 +223,15 @@ The sname:VkClearColorValue structure is defined as:
include::../api/structs/VkClearColorValue.txt[] include::../api/structs/VkClearColorValue.txt[]
* pname:float32 are the color clear values when the format of the image or * pname:float32 are the color clear values when the format of the image or
attachment is floating point, unorm, snorm, uscaled, packed float, or attachment is one of the formats in the
sRGB. <<features-formats-numericformat, Interpretation of Numeric Format>>
table other than signed integer (etext:SINT) or unsigned integer
(etext:UINT).
Floating point values are automatically converted to the format of the Floating point values are automatically converted to the format of the
image, with the clear value being treated as linear if the image is image, with the clear value being treated as linear if the image is
sRGB. sRGB.
* pname:int32 are the color clear values when the format of the image or * pname:int32 are the color clear values when the format of the image or
attachment is signed integer. attachment is signed integer (etext:SINT).
Signed integer values are converted to the format of the image by Signed integer values are converted to the format of the image by
casting to the smaller type (with negative 32-bit values mapping to casting to the smaller type (with negative 32-bit values mapping to
negative values in the smaller type). negative values in the smaller type).
@ -237,7 +239,7 @@ include::../api/structs/VkClearColorValue.txt[]
would overflow in conversion to that type), the clear value is would overflow in conversion to that type), the clear value is
undefined. undefined.
* pname:uint32 are the color clear values when the format of the image or * pname:uint32 are the color clear values when the format of the image or
attachment is unsigned integer. attachment is unsigned integer (etext:UINT).
Unsigned integer values are converted to the format of the image by Unsigned integer values are converted to the format of the image by
casting to the integer type with fewer bits. casting to the integer type with fewer bits.

View File

@ -418,6 +418,8 @@ be inherited from the primary command buffer:
include::../api/structs/VkCommandBufferInheritanceInfo.txt[] include::../api/structs/VkCommandBufferInheritanceInfo.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:renderPass is a sname:VkRenderPass object defining which render * pname:renderPass is a sname:VkRenderPass object defining which render
passes the sname:VkCommandBuffer will be <<renderpass-compatibility, passes the sname:VkCommandBuffer will be <<renderpass-compatibility,
compatible>> with and can: be executed within. compatible>> with and can: be executed within.

View File

@ -759,13 +759,13 @@ The following filtering and conversion rules apply:
* Integer formats can: only be converted to other integer formats with the * Integer formats can: only be converted to other integer formats with the
same signedness. same signedness.
* No format conversion is supported between depth/stencil images - the * No format conversion is supported between depth/stencil images.
formats must: match. The formats must: match.
* Format conversions on unorm, snorm, unscaled and packed float formats of * Format conversions on unorm, snorm, unscaled and packed float formats of
the copied aspect of the image are performed by first converting the the copied aspect of the image are performed by first converting the
pixels to float values. pixels to float values.
* In case of sRGB source format, nonlinear RGB values are converted to * For sRGB source formats, nonlinear RGB values are converted to linear
linear representation prior to filtering. representation prior to filtering.
* After filtering, the float values are first clamped and then cast to the * After filtering, the float values are first clamped and then cast to the
destination image format. destination image format.
In case of sRGB destination format, linear RGB values are converted to In case of sRGB destination format, linear RGB values are converted to

View File

@ -3828,9 +3828,10 @@ one of the following conditions is true:
* pname:tiling is ename:VK_IMAGE_TILING_LINEAR * pname:tiling is ename:VK_IMAGE_TILING_LINEAR
* pname:type is not ename:VK_IMAGE_TYPE_2D * pname:type is not ename:VK_IMAGE_TYPE_2D
* pname:flags contains ename:VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT * pname:flags contains ename:VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT
* The ename:VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in * Neither the ename:VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag nor the
ename:VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT flag in
sname:VkFormatProperties::pname:optimalTilingFeatures returned by sname:VkFormatProperties::pname:optimalTilingFeatures returned by
flink:vkGetPhysicalDeviceFormatProperties is not set flink:vkGetPhysicalDeviceFormatProperties is set
Otherwise, the bits set in pname:sampleCounts will be the sample counts Otherwise, the bits set in pname:sampleCounts will be the sample counts
supported for the specified values of pname:usage and pname:format. supported for the specified values of pname:usage and pname:format.

View File

@ -196,7 +196,7 @@ sname:VkPipelineShaderStageCreateInfo.
chapter chapter
* pname:layout must: be * pname:layout must: be
<<descriptorsets-pipelinelayout-consistency,consistent>> with the layout <<descriptorsets-pipelinelayout-consistency,consistent>> with the layout
of the compute shader specified in pname:stage</usage> of the compute shader specified in pname:stage
**** ****
include::../validity/structs/VkComputePipelineCreateInfo.txt[] include::../validity/structs/VkComputePipelineCreateInfo.txt[]

View File

@ -1736,11 +1736,12 @@ requirements returned by flink:vkGetBufferMemoryRequirements and
flink:vkGetImageMemoryRequirements: flink:vkGetImageMemoryRequirements:
* The pname:memoryTypeBits member always contains at least one bit set. * The pname:memoryTypeBits member always contains at least one bit set.
* If pname:buffer is a sname:VkBuffer, or if pname:image is a * If pname:buffer is a sname:VkBuffer not created with the
sname:VkImage that was created with a ename:VK_IMAGE_TILING_LINEAR value ename:VK_BUFFER_CREATE_SPARSE_BINDING_BIT bit set, or if pname:image is
in the pname:tiling member of the sname:VkImageCreateInfo structure a sname:VkImage that was created with a ename:VK_IMAGE_TILING_LINEAR
passed to fname:vkCreateImage, then the pname:memoryTypeBits member value in the pname:tiling member of the sname:VkImageCreateInfo
always contains at least one bit set corresponding to a structure passed to fname:vkCreateImage, then the pname:memoryTypeBits
member always contains at least one bit set corresponding to a
sname:VkMemoryType with a pname:propertyFlags that has both the sname:VkMemoryType with a pname:propertyFlags that has both the
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT bit and the ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT bit and the
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT bit set. ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT bit set.

View File

@ -19,17 +19,17 @@ from genspec import *
print('echo Building in Vulkan-Docs for public release') print('echo Building in Vulkan-Docs for public release')
print('') print('')
buildBranch('1.0-wsi_extensions', buildBranch('1.0-extensions',
extensions = KHRextensions, extensions = allExtensions,
apititle = '(with KHR extensions)', apititle = '(with all registered Vulkan extensions)',
xmlTargets = 'clobber install', xmlTargets = 'clobber install',
specTargets = 'xhtml pdf', specTargets = 'xhtml pdf',
repoDir = '/home/tree/git/Vulkan-Docs', repoDir = '/home/tree/git/Vulkan-Docs',
outDir = '/home/tree/git/Vulkan-Web-Registry/specs') outDir = '/home/tree/git/Vulkan-Web-Registry/specs')
buildBranch('1.0-extensions', buildBranch('1.0-wsi_extensions',
extensions = allExtensions, extensions = KHRextensions,
apititle = '(with all registered Vulkan extensions)', apititle = '(with KHR extensions)',
xmlTargets = 'clobber install', xmlTargets = 'clobber install',
specTargets = 'xhtml pdf', specTargets = 'xhtml pdf',
repoDir = '/home/tree/git/Vulkan-Docs', repoDir = '/home/tree/git/Vulkan-Docs',

View File

@ -104,7 +104,7 @@ maintained in the master branch of the Khronos Vulkan GitHub project.
<type category="define">// Vulkan 1.0 version number <type category="define">// Vulkan 1.0 version number
#define <name>VK_API_VERSION_1_0</name> <type>VK_MAKE_VERSION</type>(1, 0, 0)</type> <!-- The patch version here should never be set to anything other than 0 --> #define <name>VK_API_VERSION_1_0</name> <type>VK_MAKE_VERSION</type>(1, 0, 0)</type> <!-- The patch version here should never be set to anything other than 0 -->
<type category="define">// Version of this file <type category="define">// Version of this file
#define <name>VK_HEADER_VERSION</name> 29</type> #define <name>VK_HEADER_VERSION</name> 30</type>
<type category="define"> <type category="define">
#define <name>VK_DEFINE_HANDLE</name>(object) typedef struct object##_T* object;</type> #define <name>VK_DEFINE_HANDLE</name>(object) typedef struct object##_T* object;</type>

View File

@ -43,7 +43,7 @@ extern "C" {
#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff) #define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff) #define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
// Version of this file // Version of this file
#define VK_HEADER_VERSION 29 #define VK_HEADER_VERSION 30
#define VK_NULL_HANDLE 0 #define VK_NULL_HANDLE 0