vk: Add WSI implementation
This commit is contained in:
197
include/vulkan/vk_wsi_lunarg.h
Normal file
197
include/vulkan/vk_wsi_lunarg.h
Normal file
@@ -0,0 +1,197 @@
|
||||
//
|
||||
// File: vk_wsi_display.h
|
||||
//
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
#ifndef __VK_WSI_LUNARG_H__
|
||||
#define __VK_WSI_LUNARG_H__
|
||||
|
||||
#include "vulkan.h"
|
||||
|
||||
#define VK_WSI_LUNARG_REVISION 3
|
||||
#define VK_WSI_LUNARG_EXTENSION_NUMBER 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Objects
|
||||
|
||||
VK_DEFINE_DISP_SUBCLASS_HANDLE(VkDisplayWSI, VkObject)
|
||||
VK_DEFINE_DISP_SUBCLASS_HANDLE(VkSwapChainWSI, VkObject)
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Enumeration constants
|
||||
|
||||
#define VK_WSI_LUNARG_ENUM(type,id) ((type)(VK_WSI_LUNARG_EXTENSION_NUMBER * -1000 + (id)))
|
||||
|
||||
// Extend VkPhysicalDeviceInfoType enum with extension specific constants
|
||||
#define VK_PHYSICAL_DEVICE_INFO_TYPE_DISPLAY_PROPERTIES_WSI VK_WSI_LUNARG_ENUM(VkPhysicalDeviceInfoType, 0)
|
||||
#define VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PRESENT_PROPERTIES_WSI VK_WSI_LUNARG_ENUM(VkPhysicalDeviceInfoType, 1)
|
||||
|
||||
// Extend VkStructureType enum with extension specific constants
|
||||
#define VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_WSI VK_WSI_LUNARG_ENUM(VkStructureType, 0)
|
||||
#define VK_STRUCTURE_TYPE_PRESENT_INFO_WSI VK_WSI_LUNARG_ENUM(VkStructureType, 1)
|
||||
|
||||
// Extend VkImageLayout enum with extension specific constants
|
||||
#define VK_IMAGE_LAYOUT_PRESENT_SOURCE_WSI VK_WSI_LUNARG_ENUM(VkImageLayout, 0)
|
||||
|
||||
// Extend VkObjectType enum for new objects
|
||||
#define VK_OBJECT_TYPE_DISPLAY_WSI VK_WSI_LUNARG_ENUM(VkObjectType, 0)
|
||||
#define VK_OBJECT_TYPE_SWAP_CHAIN_WSI VK_WSI_LUNARG_ENUM(VkObjectType, 1)
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Enumerations
|
||||
|
||||
typedef enum VkDisplayInfoTypeWSI_
|
||||
{
|
||||
// Info type for vkGetDisplayInfo()
|
||||
VK_DISPLAY_INFO_TYPE_FORMAT_PROPERTIES_WSI = 0x00000003, // Return the VkFormat(s) supported for swap chains with the display
|
||||
|
||||
VK_ENUM_RANGE(DISPLAY_INFO_TYPE, FORMAT_PROPERTIES_WSI, FORMAT_PROPERTIES_WSI)
|
||||
} VkDisplayInfoTypeWSI;
|
||||
|
||||
typedef enum VkSwapChainInfoTypeWSI_
|
||||
{
|
||||
// Info type for vkGetSwapChainInfo()
|
||||
VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI = 0x00000000, // Return information about the persistent images of the swapchain
|
||||
|
||||
VK_ENUM_RANGE(SWAP_CHAIN_INFO_TYPE, PERSISTENT_IMAGES_WSI, PERSISTENT_IMAGES_WSI)
|
||||
} VkSwapChainInfoTypeWSI;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Flags
|
||||
|
||||
typedef VkFlags VkSwapModeFlagsWSI;
|
||||
typedef enum VkSwapModeFlagBitsWSI_
|
||||
{
|
||||
VK_SWAP_MODE_FLIP_BIT_WSI = VK_BIT(0),
|
||||
VK_SWAP_MODE_BLIT_BIT_WSI = VK_BIT(1),
|
||||
} VkSwapModeFlagBitsWSI;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Structures
|
||||
|
||||
typedef struct VkDisplayPropertiesWSI_
|
||||
{
|
||||
VkDisplayWSI display; // Handle of the display object
|
||||
VkExtent2D physicalResolution; // Max resolution for CRT?
|
||||
} VkDisplayPropertiesWSI;
|
||||
|
||||
typedef struct VkDisplayFormatPropertiesWSI_
|
||||
{
|
||||
VkFormat swapChainFormat; // Format of the images of the swap chain
|
||||
} VkDisplayFormatPropertiesWSI;
|
||||
|
||||
typedef struct VkSwapChainCreateInfoWSI_
|
||||
{
|
||||
VkStructureType sType; // Must be VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_WSI
|
||||
const void* pNext; // Pointer to next structure
|
||||
|
||||
// TBD: It is not yet clear what the use will be for the following two
|
||||
// values. It seems to be needed for more-global window-system handles
|
||||
// (e.g. X11 display). If not needed for the SDK, we will drop it from
|
||||
// this extension, and from a future version of this header.
|
||||
const void* pNativeWindowSystemHandle; // Pointer to native window system handle
|
||||
const void* pNativeWindowHandle; // Pointer to native window handle
|
||||
|
||||
uint32_t displayCount; // Number of displays the swap chain is created for
|
||||
const VkDisplayWSI* pDisplays; // displayCount number of display objects the swap chain is created for
|
||||
|
||||
uint32_t imageCount; // Number of images in the swap chain
|
||||
|
||||
VkFormat imageFormat; // Format of the images of the swap chain
|
||||
VkExtent2D imageExtent; // Width and height of the images of the swap chain
|
||||
uint32_t imageArraySize; // Number of layers of the images of the swap chain (needed for multi-view rendering)
|
||||
VkFlags imageUsageFlags; // Usage flags for the images of the swap chain (see VkImageUsageFlags)
|
||||
|
||||
VkFlags swapModeFlags; // Allowed swap modes (see VkSwapModeFlagsWSI)
|
||||
} VkSwapChainCreateInfoWSI;
|
||||
|
||||
typedef struct VkSwapChainImageInfoWSI_
|
||||
{
|
||||
VkImage image; // Persistent swap chain image handle
|
||||
VkDeviceMemory memory; // Persistent swap chain image's memory handle
|
||||
} VkSwapChainImageInfoWSI;
|
||||
|
||||
typedef struct VkPhysicalDeviceQueuePresentPropertiesWSI_
|
||||
{
|
||||
bool32_t supportsPresent; // Tells whether the queue supports presenting
|
||||
} VkPhysicalDeviceQueuePresentPropertiesWSI;
|
||||
|
||||
typedef struct VkPresentInfoWSI_
|
||||
{
|
||||
VkStructureType sType; // Must be VK_STRUCTURE_TYPE_PRESENT_INFO_WSI
|
||||
const void* pNext; // Pointer to next structure
|
||||
VkImage image; // Image to present
|
||||
uint32_t flipInterval; // Flip interval
|
||||
} VkPresentInfoWSI;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Function types
|
||||
|
||||
typedef VkResult (VKAPI *PFN_vkGetDisplayInfoWSI)(VkDisplayWSI display, VkDisplayInfoTypeWSI infoType, size_t* pDataSize, void* pData);
|
||||
typedef VkResult (VKAPI *PFN_vkCreateSwapChainWSI)(VkDevice device, const VkSwapChainCreateInfoWSI* pCreateInfo, VkSwapChainWSI* pSwapChain);
|
||||
typedef VkResult (VKAPI *PFN_vkDestroySwapChainWSI)(VkSwapChainWSI swapChain);
|
||||
typedef VkResult (VKAPI *PFN_vkGetSwapChainInfoWSI)(VkSwapChainWSI swapChain, VkSwapChainInfoTypeWSI infoType, size_t* pDataSize, void* pData);
|
||||
typedef VkResult (VKAPI *PFN_vkQueuePresentWSI)(VkQueue queue, const VkPresentInfoWSI* pPresentInfo);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Function prototypes
|
||||
|
||||
#ifdef VK_PROTOTYPES
|
||||
|
||||
VkResult VKAPI vkGetDisplayInfoWSI(
|
||||
VkDisplayWSI display,
|
||||
VkDisplayInfoTypeWSI infoType,
|
||||
size_t* pDataSize,
|
||||
void* pData);
|
||||
|
||||
VkResult VKAPI vkCreateSwapChainWSI(
|
||||
VkDevice device,
|
||||
const VkSwapChainCreateInfoWSI* pCreateInfo,
|
||||
VkSwapChainWSI* pSwapChain);
|
||||
|
||||
VkResult VKAPI vkDestroySwapChainWSI(
|
||||
VkSwapChainWSI swapChain);
|
||||
|
||||
VkResult VKAPI vkGetSwapChainInfoWSI(
|
||||
VkSwapChainWSI swapChain,
|
||||
VkSwapChainInfoTypeWSI infoType,
|
||||
size_t* pDataSize,
|
||||
void* pData);
|
||||
|
||||
VkResult VKAPI vkQueuePresentWSI(
|
||||
VkQueue queue,
|
||||
const VkPresentInfoWSI* pPresentInfo);
|
||||
|
||||
#endif // VK_PROTOTYPES
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __VK_WSI_LUNARG_H__
|
@@ -22,10 +22,11 @@
|
||||
|
||||
vulkan_includedir = $(includedir)/vulkan
|
||||
|
||||
vulkan_include_HEADERS = \
|
||||
$(top_srcdir)/include/vulkan/vk_platform.h \
|
||||
$(top_srcdir)/include/vulkan/vulkan.h \
|
||||
$(top_srcdir)/include/vulkan/vulkan_intel.h
|
||||
vulkan_include_HEADERS = \
|
||||
$(top_srcdir)/include/vulkan/vk_platform.h \
|
||||
$(top_srcdir)/include/vulkan/vulkan.h \
|
||||
$(top_srcdir)/include/vulkan/vulkan_intel.h \
|
||||
$(top_srcdir)/include/vulkan/vk_wsi_lunarg.h
|
||||
|
||||
lib_LTLIBRARIES = libvulkan.la
|
||||
|
||||
@@ -64,6 +65,7 @@ libvulkan_la_SOURCES = \
|
||||
intel.c \
|
||||
entrypoints.c \
|
||||
entrypoints.h \
|
||||
x11.c \
|
||||
formats.c \
|
||||
compiler.cpp
|
||||
|
||||
|
@@ -187,9 +187,10 @@ VkResult anv_GetPhysicalDeviceInfo(
|
||||
VkPhysicalDevicePerformance *performance;
|
||||
VkPhysicalDeviceQueueProperties *queue_properties;
|
||||
VkPhysicalDeviceMemoryProperties *memory_properties;
|
||||
VkDisplayPropertiesWSI *display_properties;
|
||||
uint64_t ns_per_tick = 80;
|
||||
|
||||
switch (infoType) {
|
||||
switch ((uint32_t) infoType) {
|
||||
case VK_PHYSICAL_DEVICE_INFO_TYPE_PROPERTIES:
|
||||
properties = pData;
|
||||
|
||||
@@ -252,6 +253,23 @@ VkResult anv_GetPhysicalDeviceInfo(
|
||||
memory_properties->supportsPinning = false;
|
||||
return VK_SUCCESS;
|
||||
|
||||
case VK_PHYSICAL_DEVICE_INFO_TYPE_DISPLAY_PROPERTIES_WSI:
|
||||
anv_finishme("VK_PHYSICAL_DEVICE_INFO_TYPE_DISPLAY_PROPERTIES_WSI");
|
||||
|
||||
*pDataSize = sizeof(*display_properties);
|
||||
if (pData == NULL)
|
||||
return VK_SUCCESS;
|
||||
|
||||
display_properties = pData;
|
||||
display_properties->display = 0;
|
||||
display_properties->physicalResolution = (VkExtent2D) { 0, 0 };
|
||||
return VK_SUCCESS;
|
||||
|
||||
case VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PRESENT_PROPERTIES_WSI:
|
||||
anv_finishme("VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PRESENT_PROPERTIES_WSI");
|
||||
return VK_SUCCESS;
|
||||
|
||||
|
||||
default:
|
||||
return VK_UNSUPPORTED;
|
||||
}
|
||||
@@ -383,18 +401,28 @@ VkResult anv_GetGlobalExtensionInfo(
|
||||
size_t* pDataSize,
|
||||
void* pData)
|
||||
{
|
||||
uint32_t *count;
|
||||
static const VkExtensionProperties extensions[] = {
|
||||
{
|
||||
.extName = "VK_WSI_LunarG",
|
||||
.version = 3
|
||||
}
|
||||
};
|
||||
uint32_t count = ARRAY_SIZE(extensions);
|
||||
|
||||
switch (infoType) {
|
||||
case VK_EXTENSION_INFO_TYPE_COUNT:
|
||||
count = pData;
|
||||
assert(*pDataSize == 4);
|
||||
*count = 0;
|
||||
memcpy(pData, &count, sizeof(count));
|
||||
*pDataSize = sizeof(count);
|
||||
return VK_SUCCESS;
|
||||
|
||||
|
||||
case VK_EXTENSION_INFO_TYPE_PROPERTIES:
|
||||
return vk_error(VK_ERROR_INVALID_EXTENSION);
|
||||
|
||||
if (extensionIndex >= count)
|
||||
return vk_error(VK_ERROR_INVALID_EXTENSION);
|
||||
|
||||
memcpy(pData, &extensions[extensionIndex], sizeof(extensions[0]));
|
||||
*pDataSize = sizeof(extensions[0]);
|
||||
return VK_SUCCESS;
|
||||
|
||||
default:
|
||||
return VK_UNSUPPORTED;
|
||||
}
|
||||
|
@@ -41,9 +41,10 @@ static const struct anv_tile_mode_info {
|
||||
[WMAJOR] = { 128, 32 }
|
||||
};
|
||||
|
||||
VkResult anv_CreateImage(
|
||||
VkResult anv_image_create(
|
||||
VkDevice _device,
|
||||
const VkImageCreateInfo* pCreateInfo,
|
||||
const struct anv_image_create_info * extra,
|
||||
VkImage* pImage)
|
||||
{
|
||||
struct anv_device *device = (struct anv_device *) _device;
|
||||
@@ -63,6 +64,7 @@ VkResult anv_CreateImage(
|
||||
image->type = pCreateInfo->imageType;
|
||||
image->format = pCreateInfo->format;
|
||||
image->extent = pCreateInfo->extent;
|
||||
image->swap_chain = NULL;
|
||||
|
||||
assert(image->extent.width > 0);
|
||||
assert(image->extent.height > 0);
|
||||
@@ -71,20 +73,28 @@ VkResult anv_CreateImage(
|
||||
switch (pCreateInfo->tiling) {
|
||||
case VK_IMAGE_TILING_LINEAR:
|
||||
image->tile_mode = LINEAR;
|
||||
/* Linear depth buffers must be 64 byte aligned, which is the strictest
|
||||
* requirement for all kinds of linear surfaces.
|
||||
*/
|
||||
image->alignment = 64;
|
||||
break;
|
||||
case VK_IMAGE_TILING_OPTIMAL:
|
||||
image->tile_mode = YMAJOR;
|
||||
image->alignment = 4096;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (extra)
|
||||
image->tile_mode = extra->tile_mode;
|
||||
|
||||
if (image->tile_mode == LINEAR) {
|
||||
/* Linear depth buffers must be 64 byte aligned, which is the strictest
|
||||
* requirement for all kinds of linear surfaces.
|
||||
*/
|
||||
image->alignment = 64;
|
||||
} else {
|
||||
image->alignment = 4096;
|
||||
}
|
||||
|
||||
format = anv_format_for_vk_format(pCreateInfo->format);
|
||||
assert(format->cpp > 0);
|
||||
image->stride = ALIGN_I32(image->extent.width * format->cpp,
|
||||
tile_mode_info[image->tile_mode].tile_width);
|
||||
aligned_height = ALIGN_I32(image->extent.height,
|
||||
@@ -96,6 +106,14 @@ VkResult anv_CreateImage(
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult anv_CreateImage(
|
||||
VkDevice device,
|
||||
const VkImageCreateInfo* pCreateInfo,
|
||||
VkImage* pImage)
|
||||
{
|
||||
return anv_image_create(device, pCreateInfo, NULL, pImage);
|
||||
}
|
||||
|
||||
VkResult anv_GetImageSubresourceInfo(
|
||||
VkDevice device,
|
||||
VkImage image,
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#define VK_PROTOTYPES
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <vulkan/vulkan_intel.h>
|
||||
#include <vulkan/vk_wsi_lunarg.h>
|
||||
|
||||
#include "entrypoints.h"
|
||||
|
||||
@@ -661,6 +662,8 @@ struct anv_image {
|
||||
/* Set when bound */
|
||||
struct anv_bo * bo;
|
||||
VkDeviceSize offset;
|
||||
|
||||
struct anv_swap_chain * swap_chain;
|
||||
};
|
||||
|
||||
struct anv_surface_view {
|
||||
@@ -671,6 +674,15 @@ struct anv_surface_view {
|
||||
VkFormat format;
|
||||
};
|
||||
|
||||
struct anv_image_create_info {
|
||||
uint32_t tile_mode;
|
||||
};
|
||||
|
||||
VkResult anv_image_create(VkDevice _device,
|
||||
const VkImageCreateInfo *pCreateInfo,
|
||||
const struct anv_image_create_info *extra,
|
||||
VkImage *pImage);
|
||||
|
||||
void anv_image_view_init(struct anv_surface_view *view,
|
||||
struct anv_device *device,
|
||||
const VkImageViewCreateInfo* pCreateInfo,
|
||||
|
282
src/vulkan/x11.c
Normal file
282
src/vulkan/x11.c
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Copyright © 2015 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/dri3.h>
|
||||
#include <xcb/present.h>
|
||||
|
||||
static const VkFormat formats[] = {
|
||||
VK_FORMAT_B5G6R5_UNORM,
|
||||
VK_FORMAT_B8G8R8A8_UNORM,
|
||||
VK_FORMAT_B8G8R8A8_SRGB,
|
||||
};
|
||||
|
||||
VkResult anv_GetDisplayInfoWSI(
|
||||
VkDisplayWSI display,
|
||||
VkDisplayInfoTypeWSI infoType,
|
||||
size_t* pDataSize,
|
||||
void* pData)
|
||||
{
|
||||
VkDisplayFormatPropertiesWSI *properties = pData;
|
||||
size_t size;
|
||||
|
||||
if (pDataSize == NULL)
|
||||
return VK_ERROR_INVALID_POINTER;
|
||||
|
||||
switch (infoType) {
|
||||
case VK_DISPLAY_INFO_TYPE_FORMAT_PROPERTIES_WSI:
|
||||
size = sizeof(properties[0]) * ARRAY_SIZE(formats);
|
||||
if (pData && *pDataSize < size)
|
||||
return vk_error(VK_ERROR_INVALID_VALUE);
|
||||
|
||||
*pDataSize = size;
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(formats); i++)
|
||||
properties[i].swapChainFormat = formats[i];
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
default:
|
||||
return VK_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
struct anv_swap_chain {
|
||||
struct anv_device * device;
|
||||
xcb_connection_t * conn;
|
||||
xcb_window_t window;
|
||||
xcb_gc_t gc;
|
||||
VkExtent2D extent;
|
||||
uint32_t count;
|
||||
struct {
|
||||
struct anv_image * image;
|
||||
struct anv_device_memory * memory;
|
||||
xcb_pixmap_t pixmap;
|
||||
} images[0];
|
||||
};
|
||||
|
||||
VkResult anv_CreateSwapChainWSI(
|
||||
VkDevice _device,
|
||||
const VkSwapChainCreateInfoWSI* pCreateInfo,
|
||||
VkSwapChainWSI* pSwapChain)
|
||||
{
|
||||
struct anv_device *device = (struct anv_device *) _device;
|
||||
struct anv_swap_chain *chain;
|
||||
xcb_void_cookie_t cookie;
|
||||
VkResult result;
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_WSI);
|
||||
|
||||
size = sizeof(*chain) + pCreateInfo->imageCount * sizeof(chain->images[0]);
|
||||
chain = anv_device_alloc(device, size, 8,
|
||||
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
||||
if (chain == NULL)
|
||||
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
chain->device = device;
|
||||
chain->conn = (xcb_connection_t *) pCreateInfo->pNativeWindowSystemHandle;
|
||||
chain->window = (xcb_window_t) (uintptr_t) pCreateInfo->pNativeWindowHandle;
|
||||
chain->count = pCreateInfo->imageCount;
|
||||
chain->extent = pCreateInfo->imageExtent;
|
||||
|
||||
for (uint32_t i = 0; i < chain->count; i++) {
|
||||
struct anv_image *image;
|
||||
struct anv_device_memory *memory;
|
||||
|
||||
anv_image_create((VkDevice) device,
|
||||
&(VkImageCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
.imageType = VK_IMAGE_TYPE_2D,
|
||||
.format = pCreateInfo->imageFormat,
|
||||
.extent = {
|
||||
.width = pCreateInfo->imageExtent.width,
|
||||
.height = pCreateInfo->imageExtent.height,
|
||||
.depth = 1
|
||||
},
|
||||
.mipLevels = 1,
|
||||
.arraySize = 1,
|
||||
.samples = 1,
|
||||
/* FIXME: Need a way to use X tiling to allow scanout */
|
||||
.tiling = VK_IMAGE_TILING_OPTIMAL,
|
||||
.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
.flags = 0,
|
||||
},
|
||||
&(struct anv_image_create_info) {
|
||||
.tile_mode = XMAJOR
|
||||
},
|
||||
(VkImage *) &image);
|
||||
|
||||
anv_AllocMemory((VkDevice) device,
|
||||
&(VkMemoryAllocInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
|
||||
.allocationSize = image->size,
|
||||
},
|
||||
(VkDeviceMemory *) &memory);
|
||||
|
||||
anv_QueueBindObjectMemory(VK_NULL_HANDLE,
|
||||
VK_OBJECT_TYPE_IMAGE,
|
||||
(VkImage) image, 0,
|
||||
(VkDeviceMemory) memory, 0);
|
||||
|
||||
ret = anv_gem_set_tiling(device, memory->bo.gem_handle,
|
||||
image->stride, I915_TILING_X);
|
||||
if (ret) {
|
||||
result = vk_error(VK_ERROR_UNKNOWN);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
int fd = anv_gem_handle_to_fd(device, memory->bo.gem_handle);
|
||||
if (fd == -1) {
|
||||
result = vk_error(VK_ERROR_UNKNOWN);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
uint32_t bpp = 32;
|
||||
uint32_t depth = 24;
|
||||
xcb_pixmap_t pixmap = xcb_generate_id(chain->conn);
|
||||
|
||||
cookie =
|
||||
xcb_dri3_pixmap_from_buffer_checked(chain->conn,
|
||||
pixmap,
|
||||
chain->window,
|
||||
image->size,
|
||||
pCreateInfo->imageExtent.width,
|
||||
pCreateInfo->imageExtent.height,
|
||||
image->stride,
|
||||
depth, bpp, fd);
|
||||
|
||||
chain->images[i].image = image;
|
||||
chain->images[i].memory = memory;
|
||||
chain->images[i].pixmap = pixmap;
|
||||
image->swap_chain = chain;
|
||||
|
||||
xcb_discard_reply(chain->conn, cookie.sequence);
|
||||
}
|
||||
|
||||
chain->gc = xcb_generate_id(chain->conn);
|
||||
if (!chain->gc) {
|
||||
result = vk_error(VK_ERROR_UNKNOWN);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
cookie = xcb_create_gc(chain->conn,
|
||||
chain->gc,
|
||||
chain->window,
|
||||
XCB_GC_GRAPHICS_EXPOSURES,
|
||||
(uint32_t []) { 0 });
|
||||
xcb_discard_reply(chain->conn, cookie.sequence);
|
||||
|
||||
*pSwapChain = (VkSwapChainWSI) chain;
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
fail:
|
||||
return result;
|
||||
}
|
||||
|
||||
VkResult anv_DestroySwapChainWSI(
|
||||
VkSwapChainWSI swapChain)
|
||||
{
|
||||
struct anv_swap_chain *chain = (struct anv_swap_chain *) swapChain;
|
||||
struct anv_device *device = chain->device;
|
||||
|
||||
anv_device_free(device, chain);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult anv_GetSwapChainInfoWSI(
|
||||
VkSwapChainWSI swapChain,
|
||||
VkSwapChainInfoTypeWSI infoType,
|
||||
size_t* pDataSize,
|
||||
void* pData)
|
||||
{
|
||||
struct anv_swap_chain *chain = (struct anv_swap_chain *) swapChain;
|
||||
VkSwapChainImageInfoWSI *images;
|
||||
size_t size;
|
||||
|
||||
switch (infoType) {
|
||||
case VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI:
|
||||
size = sizeof(*images) * chain->count;
|
||||
if (pData && *pDataSize < size)
|
||||
return VK_ERROR_INVALID_VALUE;
|
||||
|
||||
*pDataSize = size;
|
||||
if (!pData)
|
||||
return VK_SUCCESS;
|
||||
|
||||
images = pData;
|
||||
for (uint32_t i = 0; i < chain->count; i++) {
|
||||
images[i].image = (VkImage) chain->images[i].image;
|
||||
images[i].memory = (VkDeviceMemory) chain->images[i].memory;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
default:
|
||||
return VK_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
VkResult anv_QueuePresentWSI(
|
||||
VkQueue queue_,
|
||||
const VkPresentInfoWSI* pPresentInfo)
|
||||
{
|
||||
struct anv_image *image = (struct anv_image *) pPresentInfo->image;
|
||||
struct anv_swap_chain *chain = image->swap_chain;
|
||||
xcb_void_cookie_t cookie;
|
||||
xcb_pixmap_t pixmap;
|
||||
|
||||
assert(pPresentInfo->sType == VK_STRUCTURE_TYPE_PRESENT_INFO_WSI);
|
||||
|
||||
if (chain == NULL)
|
||||
return vk_error(VK_ERROR_INVALID_VALUE);
|
||||
|
||||
pixmap = XCB_NONE;
|
||||
for (uint32_t i = 0; i < chain->count; i++) {
|
||||
if ((VkImage) chain->images[i].image == pPresentInfo->image) {
|
||||
pixmap = chain->images[i].pixmap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pixmap == XCB_NONE)
|
||||
return vk_error(VK_ERROR_INVALID_VALUE);
|
||||
|
||||
cookie = xcb_copy_area(chain->conn,
|
||||
pixmap,
|
||||
chain->window,
|
||||
chain->gc,
|
||||
0, 0,
|
||||
0, 0,
|
||||
chain->extent.width,
|
||||
chain->extent.height);
|
||||
xcb_discard_reply(chain->conn, cookie.sequence);
|
||||
|
||||
xcb_flush(chain->conn);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
Reference in New Issue
Block a user