2015-05-08 22:32:37 -07:00
|
|
|
/*
|
|
|
|
|
* 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 <assert.h>
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
2015-07-17 15:04:27 -07:00
|
|
|
#include "anv_private.h"
|
2015-07-09 15:53:03 -07:00
|
|
|
#include "mesa/main/git_sha1.h"
|
2015-08-14 17:25:04 -07:00
|
|
|
#include "util/strtod.h"
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
static VkResult
|
2015-07-09 16:22:18 -07:00
|
|
|
anv_physical_device_init(struct anv_physical_device *device,
|
|
|
|
|
struct anv_instance *instance,
|
|
|
|
|
const char *path)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-07-21 13:09:25 -07:00
|
|
|
int fd;
|
|
|
|
|
|
|
|
|
|
fd = open(path, O_RDWR | O_CLOEXEC);
|
|
|
|
|
if (fd < 0)
|
2015-05-08 22:32:37 -07:00
|
|
|
return vk_error(VK_ERROR_UNAVAILABLE);
|
|
|
|
|
|
|
|
|
|
device->instance = instance;
|
|
|
|
|
device->path = path;
|
|
|
|
|
|
2015-08-14 09:39:01 -07:00
|
|
|
device->chipset_id = anv_gem_get_param(fd, I915_PARAM_CHIPSET_ID);
|
2015-05-08 22:32:37 -07:00
|
|
|
if (!device->chipset_id)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
device->name = brw_get_device_name(device->chipset_id);
|
|
|
|
|
device->info = brw_get_device_info(device->chipset_id, -1);
|
|
|
|
|
if (!device->info)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
2015-07-21 13:09:25 -07:00
|
|
|
if (anv_gem_get_aperture(fd, &device->aperture_size) == -1)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
if (!anv_gem_get_param(fd, I915_PARAM_HAS_WAIT_TIMEOUT))
|
2015-05-08 22:32:37 -07:00
|
|
|
goto fail;
|
|
|
|
|
|
2015-07-21 13:09:25 -07:00
|
|
|
if (!anv_gem_get_param(fd, I915_PARAM_HAS_EXECBUF2))
|
2015-05-08 22:32:37 -07:00
|
|
|
goto fail;
|
|
|
|
|
|
2015-07-21 13:09:25 -07:00
|
|
|
if (!anv_gem_get_param(fd, I915_PARAM_HAS_LLC))
|
2015-05-08 22:32:37 -07:00
|
|
|
goto fail;
|
|
|
|
|
|
2015-07-21 13:09:25 -07:00
|
|
|
if (!anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_CONSTANTS))
|
2015-05-08 22:32:37 -07:00
|
|
|
goto fail;
|
|
|
|
|
|
2015-07-21 13:09:25 -07:00
|
|
|
close(fd);
|
|
|
|
|
|
2015-05-08 22:32:37 -07:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
2015-07-09 16:31:39 -07:00
|
|
|
fail:
|
2015-07-21 13:09:25 -07:00
|
|
|
close(fd);
|
2015-05-08 22:32:37 -07:00
|
|
|
return vk_error(VK_ERROR_UNAVAILABLE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void *default_alloc(
|
|
|
|
|
void* pUserData,
|
|
|
|
|
size_t size,
|
|
|
|
|
size_t alignment,
|
|
|
|
|
VkSystemAllocType allocType)
|
|
|
|
|
{
|
|
|
|
|
return malloc(size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void default_free(
|
|
|
|
|
void* pUserData,
|
|
|
|
|
void* pMem)
|
|
|
|
|
{
|
|
|
|
|
free(pMem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const VkAllocCallbacks default_alloc_callbacks = {
|
|
|
|
|
.pUserData = NULL,
|
|
|
|
|
.pfnAlloc = default_alloc,
|
|
|
|
|
.pfnFree = default_free
|
|
|
|
|
};
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateInstance(
|
2015-05-08 22:32:37 -07:00
|
|
|
const VkInstanceCreateInfo* pCreateInfo,
|
|
|
|
|
VkInstance* pInstance)
|
|
|
|
|
{
|
|
|
|
|
struct anv_instance *instance;
|
|
|
|
|
const VkAllocCallbacks *alloc_callbacks = &default_alloc_callbacks;
|
|
|
|
|
void *user_data = NULL;
|
|
|
|
|
|
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
|
|
|
|
|
|
|
|
|
|
if (pCreateInfo->pAllocCb) {
|
|
|
|
|
alloc_callbacks = pCreateInfo->pAllocCb;
|
|
|
|
|
user_data = pCreateInfo->pAllocCb->pUserData;
|
|
|
|
|
}
|
|
|
|
|
instance = alloc_callbacks->pfnAlloc(user_data, sizeof(*instance), 8,
|
|
|
|
|
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (!instance)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
|
|
|
|
instance->pAllocUserData = alloc_callbacks->pUserData;
|
|
|
|
|
instance->pfnAlloc = alloc_callbacks->pfnAlloc;
|
|
|
|
|
instance->pfnFree = alloc_callbacks->pfnFree;
|
|
|
|
|
instance->apiVersion = pCreateInfo->pAppInfo->apiVersion;
|
|
|
|
|
instance->physicalDeviceCount = 0;
|
|
|
|
|
|
2015-08-14 17:25:04 -07:00
|
|
|
_mesa_locale_init();
|
|
|
|
|
|
2015-07-31 10:18:00 -07:00
|
|
|
VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pInstance = anv_instance_to_handle(instance);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_DestroyInstance(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkInstance _instance)
|
|
|
|
|
{
|
2015-07-09 18:41:27 -07:00
|
|
|
ANV_FROM_HANDLE(anv_instance, instance, _instance);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-31 10:18:00 -07:00
|
|
|
VG(VALGRIND_DESTROY_MEMPOOL(instance));
|
|
|
|
|
|
2015-08-14 17:25:04 -07:00
|
|
|
_mesa_locale_fini();
|
|
|
|
|
|
2015-05-08 22:32:37 -07:00
|
|
|
instance->pfnFree(instance->pAllocUserData, instance);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-31 10:13:24 -07:00
|
|
|
static void *
|
|
|
|
|
anv_instance_alloc(struct anv_instance *instance, size_t size,
|
|
|
|
|
size_t alignment, VkSystemAllocType allocType)
|
|
|
|
|
{
|
|
|
|
|
void *mem = instance->pfnAlloc(instance->pAllocUserData,
|
|
|
|
|
size, alignment, allocType);
|
2015-07-31 10:18:00 -07:00
|
|
|
if (mem) {
|
|
|
|
|
VALGRIND_MEMPOOL_ALLOC(instance, mem, size);
|
|
|
|
|
VALGRIND_MAKE_MEM_UNDEFINED(mem, size);
|
|
|
|
|
}
|
2015-07-31 10:13:24 -07:00
|
|
|
return mem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
anv_instance_free(struct anv_instance *instance, void *mem)
|
|
|
|
|
{
|
|
|
|
|
if (mem == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2015-07-31 10:18:00 -07:00
|
|
|
VALGRIND_MEMPOOL_FREE(instance, mem);
|
|
|
|
|
|
2015-07-31 10:13:24 -07:00
|
|
|
instance->pfnFree(instance->pAllocUserData, mem);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_EnumeratePhysicalDevices(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkInstance _instance,
|
|
|
|
|
uint32_t* pPhysicalDeviceCount,
|
|
|
|
|
VkPhysicalDevice* pPhysicalDevices)
|
|
|
|
|
{
|
2015-07-09 18:41:27 -07:00
|
|
|
ANV_FROM_HANDLE(anv_instance, instance, _instance);
|
2015-07-09 15:38:58 -07:00
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
if (instance->physicalDeviceCount == 0) {
|
2015-07-09 16:22:18 -07:00
|
|
|
result = anv_physical_device_init(&instance->physicalDevice,
|
|
|
|
|
instance, "/dev/dri/renderD128");
|
2015-07-09 15:38:58 -07:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
return result;
|
|
|
|
|
|
2015-07-09 15:51:06 -07:00
|
|
|
instance->physicalDeviceCount = 1;
|
2015-07-09 15:38:58 -07:00
|
|
|
}
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-09 15:51:06 -07:00
|
|
|
/* pPhysicalDeviceCount is an out parameter if pPhysicalDevices is NULL;
|
|
|
|
|
* otherwise it's an inout parameter.
|
|
|
|
|
*
|
|
|
|
|
* The Vulkan spec (git aaed022) says:
|
|
|
|
|
*
|
|
|
|
|
* pPhysicalDeviceCount is a pointer to an unsigned integer variable
|
|
|
|
|
* that is initialized with the number of devices the application is
|
|
|
|
|
* prepared to receive handles to. pname:pPhysicalDevices is pointer to
|
|
|
|
|
* an array of at least this many VkPhysicalDevice handles [...].
|
|
|
|
|
*
|
|
|
|
|
* Upon success, if pPhysicalDevices is NULL, vkEnumeratePhysicalDevices
|
|
|
|
|
* overwrites the contents of the variable pointed to by
|
|
|
|
|
* pPhysicalDeviceCount with the number of physical devices in in the
|
|
|
|
|
* instance; otherwise, vkEnumeratePhysicalDevices overwrites
|
|
|
|
|
* pPhysicalDeviceCount with the number of physical handles written to
|
|
|
|
|
* pPhysicalDevices.
|
|
|
|
|
*/
|
|
|
|
|
if (!pPhysicalDevices) {
|
|
|
|
|
*pPhysicalDeviceCount = instance->physicalDeviceCount;
|
|
|
|
|
} else if (*pPhysicalDeviceCount >= 1) {
|
2015-07-09 18:41:27 -07:00
|
|
|
pPhysicalDevices[0] = anv_physical_device_to_handle(&instance->physicalDevice);
|
2015-07-09 15:51:06 -07:00
|
|
|
*pPhysicalDeviceCount = 1;
|
|
|
|
|
} else {
|
|
|
|
|
*pPhysicalDeviceCount = 0;
|
|
|
|
|
}
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-09 13:54:08 -07:00
|
|
|
VkResult anv_GetPhysicalDeviceFeatures(
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
VkPhysicalDeviceFeatures* pFeatures)
|
|
|
|
|
{
|
|
|
|
|
anv_finishme("Get correct values for PhysicalDeviceFeatures");
|
|
|
|
|
|
|
|
|
|
*pFeatures = (VkPhysicalDeviceFeatures) {
|
|
|
|
|
.robustBufferAccess = false,
|
|
|
|
|
.fullDrawIndexUint32 = false,
|
|
|
|
|
.imageCubeArray = false,
|
|
|
|
|
.independentBlend = false,
|
|
|
|
|
.geometryShader = true,
|
|
|
|
|
.tessellationShader = false,
|
|
|
|
|
.sampleRateShading = false,
|
|
|
|
|
.dualSourceBlend = true,
|
|
|
|
|
.logicOp = true,
|
|
|
|
|
.instancedDrawIndirect = true,
|
|
|
|
|
.depthClip = false,
|
|
|
|
|
.depthBiasClamp = false,
|
|
|
|
|
.fillModeNonSolid = true,
|
|
|
|
|
.depthBounds = false,
|
|
|
|
|
.wideLines = true,
|
|
|
|
|
.largePoints = true,
|
|
|
|
|
.textureCompressionETC2 = true,
|
|
|
|
|
.textureCompressionASTC_LDR = true,
|
|
|
|
|
.textureCompressionBC = true,
|
|
|
|
|
.pipelineStatisticsQuery = true,
|
|
|
|
|
.vertexSideEffects = false,
|
|
|
|
|
.tessellationSideEffects = false,
|
|
|
|
|
.geometrySideEffects = false,
|
|
|
|
|
.fragmentSideEffects = false,
|
|
|
|
|
.shaderTessellationPointSize = false,
|
|
|
|
|
.shaderGeometryPointSize = true,
|
|
|
|
|
.shaderTextureGatherExtended = true,
|
|
|
|
|
.shaderStorageImageExtendedFormats = false,
|
|
|
|
|
.shaderStorageImageMultisample = false,
|
|
|
|
|
.shaderStorageBufferArrayConstantIndexing = false,
|
|
|
|
|
.shaderStorageImageArrayConstantIndexing = false,
|
|
|
|
|
.shaderUniformBufferArrayDynamicIndexing = true,
|
|
|
|
|
.shaderSampledImageArrayDynamicIndexing = false,
|
|
|
|
|
.shaderStorageBufferArrayDynamicIndexing = false,
|
|
|
|
|
.shaderStorageImageArrayDynamicIndexing = false,
|
|
|
|
|
.shaderClipDistance = false,
|
|
|
|
|
.shaderCullDistance = false,
|
|
|
|
|
.shaderFloat64 = false,
|
|
|
|
|
.shaderInt64 = false,
|
|
|
|
|
.shaderFloat16 = false,
|
|
|
|
|
.shaderInt16 = false,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-09 15:38:30 -07:00
|
|
|
VkResult anv_GetPhysicalDeviceLimits(
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
VkPhysicalDeviceLimits* pLimits)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
|
|
|
|
|
const struct brw_device_info *devinfo = physical_device->info;
|
|
|
|
|
|
|
|
|
|
anv_finishme("Get correct values for PhysicalDeviceLimits");
|
|
|
|
|
|
|
|
|
|
*pLimits = (VkPhysicalDeviceLimits) {
|
|
|
|
|
.maxImageDimension1D = (1 << 14),
|
|
|
|
|
.maxImageDimension2D = (1 << 14),
|
|
|
|
|
.maxImageDimension3D = (1 << 10),
|
|
|
|
|
.maxImageDimensionCube = (1 << 14),
|
|
|
|
|
.maxImageArrayLayers = (1 << 10),
|
|
|
|
|
.maxTexelBufferSize = (1 << 14),
|
|
|
|
|
.maxUniformBufferSize = UINT32_MAX,
|
|
|
|
|
.maxStorageBufferSize = UINT32_MAX,
|
|
|
|
|
.maxPushConstantsSize = 128,
|
|
|
|
|
.maxMemoryAllocationCount = UINT32_MAX,
|
2015-07-14 17:10:37 -07:00
|
|
|
.bufferImageGranularity = 64, /* A cache line */
|
2015-07-09 15:38:30 -07:00
|
|
|
.maxBoundDescriptorSets = MAX_SETS,
|
|
|
|
|
.maxDescriptorSets = UINT32_MAX,
|
|
|
|
|
.maxPerStageDescriptorSamplers = 64,
|
|
|
|
|
.maxPerStageDescriptorUniformBuffers = 64,
|
|
|
|
|
.maxPerStageDescriptorStorageBuffers = 64,
|
|
|
|
|
.maxPerStageDescriptorSampledImages = 64,
|
|
|
|
|
.maxPerStageDescriptorStorageImages = 64,
|
|
|
|
|
.maxDescriptorSetSamplers = 256,
|
|
|
|
|
.maxDescriptorSetUniformBuffers = 256,
|
|
|
|
|
.maxDescriptorSetStorageBuffers = 256,
|
|
|
|
|
.maxDescriptorSetSampledImages = 256,
|
|
|
|
|
.maxDescriptorSetStorageImages = 256,
|
|
|
|
|
.maxVertexInputAttributes = 32,
|
|
|
|
|
.maxVertexInputAttributeOffset = 256,
|
|
|
|
|
.maxVertexInputBindingStride = 256,
|
|
|
|
|
.maxVertexOutputComponents = 32,
|
|
|
|
|
.maxTessGenLevel = 0,
|
|
|
|
|
.maxTessPatchSize = 0,
|
|
|
|
|
.maxTessControlPerVertexInputComponents = 0,
|
|
|
|
|
.maxTessControlPerVertexOutputComponents = 0,
|
|
|
|
|
.maxTessControlPerPatchOutputComponents = 0,
|
|
|
|
|
.maxTessControlTotalOutputComponents = 0,
|
|
|
|
|
.maxTessEvaluationInputComponents = 0,
|
|
|
|
|
.maxTessEvaluationOutputComponents = 0,
|
|
|
|
|
.maxGeometryShaderInvocations = 6,
|
|
|
|
|
.maxGeometryInputComponents = 16,
|
|
|
|
|
.maxGeometryOutputComponents = 16,
|
|
|
|
|
.maxGeometryOutputVertices = 16,
|
|
|
|
|
.maxGeometryTotalOutputComponents = 16,
|
|
|
|
|
.maxFragmentInputComponents = 16,
|
|
|
|
|
.maxFragmentOutputBuffers = 8,
|
|
|
|
|
.maxFragmentDualSourceBuffers = 2,
|
|
|
|
|
.maxFragmentCombinedOutputResources = 8,
|
|
|
|
|
.maxComputeSharedMemorySize = 1024,
|
|
|
|
|
.maxComputeWorkGroupCount = {
|
|
|
|
|
16 * devinfo->max_cs_threads,
|
|
|
|
|
16 * devinfo->max_cs_threads,
|
|
|
|
|
16 * devinfo->max_cs_threads,
|
|
|
|
|
},
|
|
|
|
|
.maxComputeWorkGroupInvocations = 16 * devinfo->max_cs_threads,
|
|
|
|
|
.maxComputeWorkGroupSize = {
|
|
|
|
|
16 * devinfo->max_cs_threads,
|
|
|
|
|
16 * devinfo->max_cs_threads,
|
|
|
|
|
16 * devinfo->max_cs_threads,
|
|
|
|
|
},
|
|
|
|
|
.subPixelPrecisionBits = 4 /* FIXME */,
|
|
|
|
|
.subTexelPrecisionBits = 4 /* FIXME */,
|
|
|
|
|
.mipmapPrecisionBits = 4 /* FIXME */,
|
|
|
|
|
.maxDrawIndexedIndexValue = UINT32_MAX,
|
|
|
|
|
.maxDrawIndirectInstanceCount = UINT32_MAX,
|
|
|
|
|
.primitiveRestartForPatches = UINT32_MAX,
|
|
|
|
|
.maxSamplerLodBias = 16,
|
|
|
|
|
.maxSamplerAnisotropy = 16,
|
2015-07-09 15:53:03 -07:00
|
|
|
.maxViewports = 16,
|
2015-07-09 15:38:30 -07:00
|
|
|
.maxDynamicViewportStates = UINT32_MAX,
|
|
|
|
|
.maxViewportDimensions = { (1 << 14), (1 << 14) },
|
|
|
|
|
.viewportBoundsRange = { -1.0, 1.0 }, /* FIXME */
|
|
|
|
|
.viewportSubPixelBits = 13, /* We take a float? */
|
|
|
|
|
.minMemoryMapAlignment = 64, /* A cache line */
|
|
|
|
|
.minTexelBufferOffsetAlignment = 1,
|
|
|
|
|
.minUniformBufferOffsetAlignment = 1,
|
|
|
|
|
.minStorageBufferOffsetAlignment = 1,
|
|
|
|
|
.minTexelOffset = 0, /* FIXME */
|
|
|
|
|
.maxTexelOffset = 0, /* FIXME */
|
|
|
|
|
.minTexelGatherOffset = 0, /* FIXME */
|
|
|
|
|
.maxTexelGatherOffset = 0, /* FIXME */
|
|
|
|
|
.minInterpolationOffset = 0, /* FIXME */
|
|
|
|
|
.maxInterpolationOffset = 0, /* FIXME */
|
|
|
|
|
.subPixelInterpolationOffsetBits = 0, /* FIXME */
|
|
|
|
|
.maxFramebufferWidth = (1 << 14),
|
|
|
|
|
.maxFramebufferHeight = (1 << 14),
|
|
|
|
|
.maxFramebufferLayers = (1 << 10),
|
|
|
|
|
.maxFramebufferColorSamples = 8,
|
|
|
|
|
.maxFramebufferDepthSamples = 8,
|
|
|
|
|
.maxFramebufferStencilSamples = 8,
|
|
|
|
|
.maxColorAttachments = MAX_RTS,
|
|
|
|
|
.maxSampledImageColorSamples = 8,
|
|
|
|
|
.maxSampledImageDepthSamples = 8,
|
|
|
|
|
.maxSampledImageIntegerSamples = 1,
|
|
|
|
|
.maxStorageImageSamples = 1,
|
|
|
|
|
.maxSampleMaskWords = 1,
|
2015-07-09 15:53:03 -07:00
|
|
|
.timestampFrequency = 1000 * 1000 * 1000 / 80,
|
2015-07-09 15:38:30 -07:00
|
|
|
.maxClipDistances = 0 /* FIXME */,
|
|
|
|
|
.maxCullDistances = 0 /* FIXME */,
|
|
|
|
|
.maxCombinedClipAndCullDistances = 0 /* FIXME */,
|
|
|
|
|
.pointSizeRange = { 0.125, 255.875 },
|
|
|
|
|
.lineWidthRange = { 0.0, 7.9921875 },
|
|
|
|
|
.pointSizeGranularity = (1.0 / 8.0),
|
|
|
|
|
.lineWidthGranularity = (1.0 / 128.0),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-09 15:53:03 -07:00
|
|
|
VkResult anv_GetPhysicalDeviceProperties(
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
VkPhysicalDeviceProperties* pProperties)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
|
|
|
|
|
|
|
|
|
|
*pProperties = (VkPhysicalDeviceProperties) {
|
2015-07-23 10:44:27 -07:00
|
|
|
.apiVersion = VK_MAKE_VERSION(0, 138, 1),
|
2015-07-09 15:53:03 -07:00
|
|
|
.driverVersion = 1,
|
|
|
|
|
.vendorId = 0x8086,
|
|
|
|
|
.deviceId = pdevice->chipset_id,
|
|
|
|
|
.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
strcpy(pProperties->deviceName, pdevice->name);
|
|
|
|
|
snprintf((char *)pProperties->pipelineCacheUUID, VK_UUID_LENGTH,
|
|
|
|
|
"anv-%s", MESA_GIT_SHA1 + 4);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-09 16:11:24 -07:00
|
|
|
VkResult anv_GetPhysicalDeviceQueueCount(
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
uint32_t* pCount)
|
|
|
|
|
{
|
|
|
|
|
*pCount = 1;
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult anv_GetPhysicalDeviceQueueProperties(
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
uint32_t count,
|
|
|
|
|
VkPhysicalDeviceQueueProperties* pQueueProperties)
|
|
|
|
|
{
|
|
|
|
|
assert(count == 1);
|
|
|
|
|
|
|
|
|
|
*pQueueProperties = (VkPhysicalDeviceQueueProperties) {
|
|
|
|
|
.queueFlags = VK_QUEUE_GRAPHICS_BIT |
|
|
|
|
|
VK_QUEUE_COMPUTE_BIT |
|
|
|
|
|
VK_QUEUE_DMA_BIT,
|
|
|
|
|
.queueCount = 1,
|
|
|
|
|
.supportsTimestamps = true,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-09 19:49:19 -07:00
|
|
|
VkResult anv_GetPhysicalDeviceMemoryProperties(
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
VkPhysicalDeviceMemoryProperties* pMemoryProperties)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
|
2015-07-21 13:09:25 -07:00
|
|
|
VkDeviceSize heap_size;
|
2015-07-09 19:49:19 -07:00
|
|
|
|
|
|
|
|
/* Reserve some wiggle room for the driver by exposing only 75% of the
|
|
|
|
|
* aperture to the heap.
|
|
|
|
|
*/
|
2015-07-21 13:09:25 -07:00
|
|
|
heap_size = 3 * physical_device->aperture_size / 4;
|
2015-07-09 19:49:19 -07:00
|
|
|
|
|
|
|
|
/* The property flags below are valid only for llc platforms. */
|
|
|
|
|
pMemoryProperties->memoryTypeCount = 1;
|
|
|
|
|
pMemoryProperties->memoryTypes[0] = (VkMemoryType) {
|
|
|
|
|
.propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
|
|
|
|
.heapIndex = 1,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pMemoryProperties->memoryHeapCount = 1;
|
|
|
|
|
pMemoryProperties->memoryHeaps[0] = (VkMemoryHeap) {
|
|
|
|
|
.size = heap_size,
|
|
|
|
|
.flags = VK_MEMORY_HEAP_HOST_LOCAL,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-07 18:51:53 -07:00
|
|
|
PFN_vkVoidFunction anv_GetInstanceProcAddr(
|
|
|
|
|
VkInstance instance,
|
|
|
|
|
const char* pName)
|
|
|
|
|
{
|
|
|
|
|
return anv_lookup_entrypoint(pName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PFN_vkVoidFunction anv_GetDeviceProcAddr(
|
|
|
|
|
VkDevice device,
|
2015-05-08 22:32:37 -07:00
|
|
|
const char* pName)
|
|
|
|
|
{
|
2015-05-17 16:33:48 -07:00
|
|
|
return anv_lookup_entrypoint(pName);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-06-09 12:28:58 -07:00
|
|
|
static VkResult
|
|
|
|
|
anv_queue_init(struct anv_device *device, struct anv_queue *queue)
|
|
|
|
|
{
|
|
|
|
|
queue->device = device;
|
|
|
|
|
queue->pool = &device->surface_state_pool;
|
|
|
|
|
|
|
|
|
|
queue->completed_serial = anv_state_pool_alloc(queue->pool, 4, 4);
|
|
|
|
|
if (queue->completed_serial.map == NULL)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
|
|
|
|
|
|
|
|
|
*(uint32_t *)queue->completed_serial.map = 0;
|
|
|
|
|
queue->next_serial = 1;
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
anv_queue_finish(struct anv_queue *queue)
|
|
|
|
|
{
|
|
|
|
|
#ifdef HAVE_VALGRIND
|
|
|
|
|
/* This gets torn down with the device so we only need to do this if
|
|
|
|
|
* valgrind is present.
|
|
|
|
|
*/
|
|
|
|
|
anv_state_pool_free(queue->pool, queue->completed_serial);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-29 16:06:06 -07:00
|
|
|
static void
|
|
|
|
|
anv_device_init_border_colors(struct anv_device *device)
|
|
|
|
|
{
|
2015-07-08 11:44:52 -07:00
|
|
|
static const VkClearColorValue border_colors[] = {
|
|
|
|
|
[VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] = { .f32 = { 0.0, 0.0, 0.0, 0.0 } },
|
|
|
|
|
[VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] = { .f32 = { 0.0, 0.0, 0.0, 1.0 } },
|
|
|
|
|
[VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] = { .f32 = { 1.0, 1.0, 1.0, 1.0 } },
|
|
|
|
|
[VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] = { .u32 = { 0, 0, 0, 0 } },
|
|
|
|
|
[VK_BORDER_COLOR_INT_OPAQUE_BLACK] = { .u32 = { 0, 0, 0, 1 } },
|
|
|
|
|
[VK_BORDER_COLOR_INT_OPAQUE_WHITE] = { .u32 = { 1, 1, 1, 1 } },
|
2015-05-29 16:06:06 -07:00
|
|
|
};
|
|
|
|
|
|
2015-07-08 11:44:52 -07:00
|
|
|
device->border_colors =
|
2015-05-29 16:06:06 -07:00
|
|
|
anv_state_pool_alloc(&device->dynamic_state_pool,
|
2015-07-08 11:44:52 -07:00
|
|
|
sizeof(border_colors), 32);
|
|
|
|
|
memcpy(device->border_colors.map, border_colors, sizeof(border_colors));
|
2015-05-29 16:06:06 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateDevice(
|
2015-07-09 18:20:10 -07:00
|
|
|
VkPhysicalDevice physicalDevice,
|
2015-05-08 22:32:37 -07:00
|
|
|
const VkDeviceCreateInfo* pCreateInfo,
|
|
|
|
|
VkDevice* pDevice)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
|
|
|
|
|
struct anv_instance *instance = physical_device->instance;
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_device *device;
|
|
|
|
|
|
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
|
|
|
|
|
|
2015-07-31 10:13:24 -07:00
|
|
|
device = anv_instance_alloc(instance, sizeof(*device), 8,
|
2015-05-08 22:32:37 -07:00
|
|
|
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (!device)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
2015-07-09 18:20:10 -07:00
|
|
|
device->instance = physical_device->instance;
|
2015-07-09 16:31:39 -07:00
|
|
|
|
|
|
|
|
/* XXX(chadv): Can we dup() physicalDevice->fd here? */
|
2015-07-09 18:20:10 -07:00
|
|
|
device->fd = open(physical_device->path, O_RDWR | O_CLOEXEC);
|
2015-05-08 22:32:37 -07:00
|
|
|
if (device->fd == -1)
|
|
|
|
|
goto fail_device;
|
|
|
|
|
|
|
|
|
|
device->context_id = anv_gem_create_context(device);
|
|
|
|
|
if (device->context_id == -1)
|
|
|
|
|
goto fail_fd;
|
|
|
|
|
|
2015-07-30 11:34:09 -07:00
|
|
|
anv_bo_pool_init(&device->batch_bo_pool, device, ANV_CMD_BUFFER_BATCH_SIZE);
|
2015-05-25 15:46:48 -07:00
|
|
|
|
2015-05-13 15:34:34 -07:00
|
|
|
anv_block_pool_init(&device->dynamic_state_block_pool, device, 2048);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-05-13 15:34:34 -07:00
|
|
|
anv_state_pool_init(&device->dynamic_state_pool,
|
|
|
|
|
&device->dynamic_state_block_pool);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
anv_block_pool_init(&device->instruction_block_pool, device, 2048);
|
|
|
|
|
anv_block_pool_init(&device->surface_state_block_pool, device, 2048);
|
|
|
|
|
|
|
|
|
|
anv_state_pool_init(&device->surface_state_pool,
|
|
|
|
|
&device->surface_state_block_pool);
|
|
|
|
|
|
2015-06-19 15:41:30 -07:00
|
|
|
anv_block_pool_init(&device->scratch_block_pool, device, 0x10000);
|
|
|
|
|
|
2015-07-09 18:20:10 -07:00
|
|
|
device->info = *physical_device->info;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-06-03 23:03:29 -07:00
|
|
|
device->compiler = anv_compiler_create(device);
|
|
|
|
|
|
2015-05-08 22:32:37 -07:00
|
|
|
pthread_mutex_init(&device->mutex, NULL);
|
|
|
|
|
|
2015-06-09 12:28:58 -07:00
|
|
|
anv_queue_init(device, &device->queue);
|
|
|
|
|
|
2015-05-11 23:25:06 -07:00
|
|
|
anv_device_init_meta(device);
|
|
|
|
|
|
2015-05-29 16:06:06 -07:00
|
|
|
anv_device_init_border_colors(device);
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pDevice = anv_device_to_handle(device);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
|
|
|
fail_fd:
|
|
|
|
|
close(device->fd);
|
|
|
|
|
fail_device:
|
|
|
|
|
anv_device_free(device, device);
|
|
|
|
|
|
|
|
|
|
return vk_error(VK_ERROR_UNAVAILABLE);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_DestroyDevice(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
anv_compiler_destroy(device->compiler);
|
|
|
|
|
|
2015-06-09 12:28:58 -07:00
|
|
|
anv_queue_finish(&device->queue);
|
|
|
|
|
|
2015-06-09 11:08:51 -07:00
|
|
|
anv_device_finish_meta(device);
|
2015-05-25 15:46:48 -07:00
|
|
|
|
2015-06-09 11:41:31 -07:00
|
|
|
#ifdef HAVE_VALGRIND
|
|
|
|
|
/* We only need to free these to prevent valgrind errors. The backing
|
|
|
|
|
* BO will go away in a couple of lines so we don't actually leak.
|
|
|
|
|
*/
|
2015-07-08 11:44:52 -07:00
|
|
|
anv_state_pool_free(&device->dynamic_state_pool, device->border_colors);
|
2015-06-09 11:41:31 -07:00
|
|
|
#endif
|
|
|
|
|
|
2015-05-25 15:46:48 -07:00
|
|
|
anv_bo_pool_finish(&device->batch_bo_pool);
|
2015-07-31 10:30:57 -07:00
|
|
|
anv_state_pool_finish(&device->dynamic_state_pool);
|
2015-05-13 15:34:34 -07:00
|
|
|
anv_block_pool_finish(&device->dynamic_state_block_pool);
|
2015-05-08 22:32:37 -07:00
|
|
|
anv_block_pool_finish(&device->instruction_block_pool);
|
2015-07-31 10:30:57 -07:00
|
|
|
anv_state_pool_finish(&device->surface_state_pool);
|
2015-05-08 22:32:37 -07:00
|
|
|
anv_block_pool_finish(&device->surface_state_block_pool);
|
2015-07-22 17:51:14 -07:00
|
|
|
anv_block_pool_finish(&device->scratch_block_pool);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
close(device->fd);
|
|
|
|
|
|
2015-07-31 10:13:24 -07:00
|
|
|
anv_instance_free(device->instance, device);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-08 10:38:07 -07:00
|
|
|
static const VkExtensionProperties global_extensions[] = {
|
|
|
|
|
{
|
|
|
|
|
.extName = "VK_WSI_LunarG",
|
2015-07-14 16:11:21 -07:00
|
|
|
.specVersion = 3
|
2015-07-08 10:38:07 -07:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkResult anv_GetGlobalExtensionProperties(
|
2015-07-14 16:11:21 -07:00
|
|
|
const char* pLayerName,
|
|
|
|
|
uint32_t* pCount,
|
2015-07-08 10:38:07 -07:00
|
|
|
VkExtensionProperties* pProperties)
|
|
|
|
|
{
|
2015-07-14 16:11:21 -07:00
|
|
|
if (pProperties == NULL) {
|
|
|
|
|
*pCount = ARRAY_SIZE(global_extensions);
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
2015-05-15 22:04:52 -07:00
|
|
|
|
2015-07-14 16:11:21 -07:00
|
|
|
assert(*pCount < ARRAY_SIZE(global_extensions));
|
2015-07-08 10:38:07 -07:00
|
|
|
|
2015-07-14 16:11:21 -07:00
|
|
|
*pCount = ARRAY_SIZE(global_extensions);
|
|
|
|
|
memcpy(pProperties, global_extensions, sizeof(global_extensions));
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-08 10:38:07 -07:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
2015-05-17 19:22:52 -07:00
|
|
|
|
2015-07-08 10:38:07 -07:00
|
|
|
VkResult anv_GetPhysicalDeviceExtensionProperties(
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
2015-07-14 16:11:21 -07:00
|
|
|
const char* pLayerName,
|
|
|
|
|
uint32_t* pCount,
|
2015-07-08 10:38:07 -07:00
|
|
|
VkExtensionProperties* pProperties)
|
|
|
|
|
{
|
2015-07-14 16:11:21 -07:00
|
|
|
if (pProperties == NULL) {
|
|
|
|
|
*pCount = 0;
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-08 10:38:07 -07:00
|
|
|
/* None supported at this time */
|
|
|
|
|
return vk_error(VK_ERROR_INVALID_EXTENSION);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-14 16:11:21 -07:00
|
|
|
VkResult anv_GetGlobalLayerProperties(
|
|
|
|
|
uint32_t* pCount,
|
|
|
|
|
VkLayerProperties* pProperties)
|
|
|
|
|
{
|
|
|
|
|
if (pProperties == NULL) {
|
|
|
|
|
*pCount = 0;
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* None supported at this time */
|
|
|
|
|
return vk_error(VK_ERROR_INVALID_LAYER);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult anv_GetPhysicalDeviceLayerProperties(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkPhysicalDevice physicalDevice,
|
2015-07-14 16:11:21 -07:00
|
|
|
uint32_t* pCount,
|
|
|
|
|
VkLayerProperties* pProperties)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-07-14 16:11:21 -07:00
|
|
|
if (pProperties == NULL) {
|
|
|
|
|
*pCount = 0;
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-14 16:11:21 -07:00
|
|
|
/* None supported at this time */
|
|
|
|
|
return vk_error(VK_ERROR_INVALID_LAYER);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_GetDeviceQueue(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
|
|
|
|
uint32_t queueNodeIndex,
|
|
|
|
|
uint32_t queueIndex,
|
|
|
|
|
VkQueue* pQueue)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-06-09 12:28:58 -07:00
|
|
|
assert(queueIndex == 0);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pQueue = anv_queue_to_handle(&device->queue);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_QueueSubmit(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkQueue _queue,
|
|
|
|
|
uint32_t cmdBufferCount,
|
|
|
|
|
const VkCmdBuffer* pCmdBuffers,
|
2015-05-18 08:49:15 -07:00
|
|
|
VkFence _fence)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_queue, queue, _queue);
|
|
|
|
|
ANV_FROM_HANDLE(anv_fence, fence, _fence);
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_device *device = queue->device;
|
|
|
|
|
int ret;
|
|
|
|
|
|
2015-05-12 14:38:12 -07:00
|
|
|
for (uint32_t i = 0; i < cmdBufferCount; i++) {
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCmdBuffers[i]);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-30 11:36:48 -07:00
|
|
|
assert(cmd_buffer->level == VK_CMD_BUFFER_LEVEL_PRIMARY);
|
|
|
|
|
|
2015-08-14 09:39:01 -07:00
|
|
|
ret = anv_gem_execbuffer(device, &cmd_buffer->execbuf2.execbuf);
|
|
|
|
|
if (ret != 0)
|
|
|
|
|
return vk_error(VK_ERROR_UNKNOWN);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-08-14 09:39:01 -07:00
|
|
|
if (fence) {
|
|
|
|
|
ret = anv_gem_execbuffer(device, &fence->execbuf);
|
2015-05-12 14:38:12 -07:00
|
|
|
if (ret != 0)
|
2015-05-12 14:38:58 -07:00
|
|
|
return vk_error(VK_ERROR_UNKNOWN);
|
2015-05-12 14:38:12 -07:00
|
|
|
}
|
2015-08-14 09:39:01 -07:00
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < cmd_buffer->execbuf2.bo_count; i++)
|
|
|
|
|
cmd_buffer->execbuf2.bos[i]->offset = cmd_buffer->execbuf2.objects[i].offset;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_QueueWaitIdle(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkQueue _queue)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_queue, queue, _queue);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
return vkDeviceWaitIdle(anv_device_to_handle(queue->device));
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_DeviceWaitIdle(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_state state;
|
|
|
|
|
struct anv_batch batch;
|
|
|
|
|
struct drm_i915_gem_execbuffer2 execbuf;
|
|
|
|
|
struct drm_i915_gem_exec_object2 exec2_objects[1];
|
|
|
|
|
struct anv_bo *bo = NULL;
|
|
|
|
|
VkResult result;
|
|
|
|
|
int64_t timeout;
|
|
|
|
|
int ret;
|
|
|
|
|
|
2015-05-13 15:34:34 -07:00
|
|
|
state = anv_state_pool_alloc(&device->dynamic_state_pool, 32, 32);
|
|
|
|
|
bo = &device->dynamic_state_pool.block_pool->bo;
|
2015-05-27 11:42:55 -07:00
|
|
|
batch.start = batch.next = state.map;
|
|
|
|
|
batch.end = state.map + 32;
|
2015-05-08 22:32:37 -07:00
|
|
|
anv_batch_emit(&batch, GEN8_MI_BATCH_BUFFER_END);
|
|
|
|
|
anv_batch_emit(&batch, GEN8_MI_NOOP);
|
|
|
|
|
|
|
|
|
|
exec2_objects[0].handle = bo->gem_handle;
|
|
|
|
|
exec2_objects[0].relocation_count = 0;
|
|
|
|
|
exec2_objects[0].relocs_ptr = 0;
|
|
|
|
|
exec2_objects[0].alignment = 0;
|
|
|
|
|
exec2_objects[0].offset = bo->offset;
|
|
|
|
|
exec2_objects[0].flags = 0;
|
|
|
|
|
exec2_objects[0].rsvd1 = 0;
|
|
|
|
|
exec2_objects[0].rsvd2 = 0;
|
|
|
|
|
|
|
|
|
|
execbuf.buffers_ptr = (uintptr_t) exec2_objects;
|
|
|
|
|
execbuf.buffer_count = 1;
|
|
|
|
|
execbuf.batch_start_offset = state.offset;
|
|
|
|
|
execbuf.batch_len = batch.next - state.map;
|
|
|
|
|
execbuf.cliprects_ptr = 0;
|
|
|
|
|
execbuf.num_cliprects = 0;
|
|
|
|
|
execbuf.DR1 = 0;
|
|
|
|
|
execbuf.DR4 = 0;
|
|
|
|
|
|
|
|
|
|
execbuf.flags =
|
|
|
|
|
I915_EXEC_HANDLE_LUT | I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
|
|
|
|
|
execbuf.rsvd1 = device->context_id;
|
|
|
|
|
execbuf.rsvd2 = 0;
|
|
|
|
|
|
2015-08-14 09:39:01 -07:00
|
|
|
ret = anv_gem_execbuffer(device, &execbuf);
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
result = vk_error(VK_ERROR_UNKNOWN);
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-08-14 09:39:01 -07:00
|
|
|
timeout = INT64_MAX;
|
|
|
|
|
ret = anv_gem_wait(device, bo->gem_handle, &timeout);
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
result = vk_error(VK_ERROR_UNKNOWN);
|
|
|
|
|
goto fail;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-13 15:34:34 -07:00
|
|
|
anv_state_pool_free(&device->dynamic_state_pool, state);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
|
|
|
fail:
|
2015-05-13 15:34:34 -07:00
|
|
|
anv_state_pool_free(&device->dynamic_state_pool, state);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *
|
|
|
|
|
anv_device_alloc(struct anv_device * device,
|
|
|
|
|
size_t size,
|
|
|
|
|
size_t alignment,
|
|
|
|
|
VkSystemAllocType allocType)
|
|
|
|
|
{
|
2015-07-31 10:13:24 -07:00
|
|
|
return anv_instance_alloc(device->instance, size, alignment, allocType);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
anv_device_free(struct anv_device * device,
|
|
|
|
|
void * mem)
|
|
|
|
|
{
|
2015-07-31 10:13:24 -07:00
|
|
|
anv_instance_free(device->instance, mem);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult
|
|
|
|
|
anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size)
|
|
|
|
|
{
|
|
|
|
|
bo->gem_handle = anv_gem_create(device, size);
|
|
|
|
|
if (!bo->gem_handle)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
|
|
|
|
|
|
|
|
|
bo->map = NULL;
|
|
|
|
|
bo->index = 0;
|
|
|
|
|
bo->offset = 0;
|
|
|
|
|
bo->size = size;
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_AllocMemory(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
|
|
|
|
const VkMemoryAllocInfo* pAllocInfo,
|
|
|
|
|
VkDeviceMemory* pMem)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_device_memory *mem;
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
assert(pAllocInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO);
|
|
|
|
|
|
2015-07-09 19:59:44 -07:00
|
|
|
if (pAllocInfo->memoryTypeIndex != 0) {
|
|
|
|
|
/* We support exactly one memory heap. */
|
|
|
|
|
return vk_error(VK_ERROR_INVALID_VALUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* FINISHME: Fail if allocation request exceeds heap size. */
|
|
|
|
|
|
2015-05-08 22:32:37 -07:00
|
|
|
mem = anv_device_alloc(device, sizeof(*mem), 8,
|
|
|
|
|
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (mem == NULL)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
|
|
|
|
result = anv_bo_init_new(&mem->bo, device, pAllocInfo->allocationSize);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pMem = anv_device_memory_to_handle(mem);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-09 18:20:10 -07:00
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
anv_device_free(device, mem);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_FreeMemory(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
|
|
|
|
VkDeviceMemory _mem)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
if (mem->bo.map)
|
|
|
|
|
anv_gem_munmap(mem->bo.map, mem->bo.size);
|
|
|
|
|
|
|
|
|
|
if (mem->bo.gem_handle != 0)
|
|
|
|
|
anv_gem_close(device, mem->bo.gem_handle);
|
|
|
|
|
|
|
|
|
|
anv_device_free(device, mem);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_MapMemory(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
|
|
|
|
VkDeviceMemory _mem,
|
|
|
|
|
VkDeviceSize offset,
|
|
|
|
|
VkDeviceSize size,
|
|
|
|
|
VkMemoryMapFlags flags,
|
|
|
|
|
void** ppData)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
/* FIXME: Is this supposed to be thread safe? Since vkUnmapMemory() only
|
|
|
|
|
* takes a VkDeviceMemory pointer, it seems like only one map of the memory
|
|
|
|
|
* at a time is valid. We could just mmap up front and return an offset
|
|
|
|
|
* pointer here, but that may exhaust virtual memory on 32 bit
|
|
|
|
|
* userspace. */
|
|
|
|
|
|
|
|
|
|
mem->map = anv_gem_mmap(device, mem->bo.gem_handle, offset, size);
|
|
|
|
|
mem->map_size = size;
|
|
|
|
|
|
|
|
|
|
*ppData = mem->map;
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_UnmapMemory(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
|
|
|
|
VkDeviceMemory _mem)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
anv_gem_munmap(mem->map, mem->map_size);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-07 17:22:29 -07:00
|
|
|
VkResult anv_FlushMappedMemoryRanges(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice device,
|
2015-07-07 17:22:29 -07:00
|
|
|
uint32_t memRangeCount,
|
|
|
|
|
const VkMappedMemoryRange* pMemRanges)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
|
|
|
|
/* clflush here for !llc platforms */
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-07 17:22:29 -07:00
|
|
|
VkResult anv_InvalidateMappedMemoryRanges(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice device,
|
2015-07-07 17:22:29 -07:00
|
|
|
uint32_t memRangeCount,
|
|
|
|
|
const VkMappedMemoryRange* pMemRanges)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-07-07 17:22:29 -07:00
|
|
|
return anv_FlushMappedMemoryRanges(device, memRangeCount, pMemRanges);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-14 14:59:39 -07:00
|
|
|
VkResult anv_GetBufferMemoryRequirements(
|
2015-07-07 18:16:42 -07:00
|
|
|
VkDevice device,
|
2015-07-14 14:59:39 -07:00
|
|
|
VkBuffer _buffer,
|
2015-07-07 18:16:42 -07:00
|
|
|
VkMemoryRequirements* pMemoryRequirements)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-07-14 14:59:39 -07:00
|
|
|
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-09 19:59:44 -07:00
|
|
|
/* The Vulkan spec (git aaed022) says:
|
|
|
|
|
*
|
|
|
|
|
* memoryTypeBits is a bitfield and contains one bit set for every
|
|
|
|
|
* supported memory type for the resource. The bit `1<<i` is set if and
|
|
|
|
|
* only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
|
|
|
|
|
* structure for the physical device is supported.
|
|
|
|
|
*
|
|
|
|
|
* We support exactly one memory type.
|
|
|
|
|
*/
|
|
|
|
|
pMemoryRequirements->memoryTypeBits = 1;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-14 14:59:39 -07:00
|
|
|
pMemoryRequirements->size = buffer->size;
|
|
|
|
|
pMemoryRequirements->alignment = 16;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-07 18:16:42 -07:00
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-14 14:59:39 -07:00
|
|
|
VkResult anv_GetImageMemoryRequirements(
|
2015-07-08 09:04:16 -07:00
|
|
|
VkDevice device,
|
2015-07-14 14:59:39 -07:00
|
|
|
VkImage _image,
|
|
|
|
|
VkMemoryRequirements* pMemoryRequirements)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_image, image, _image);
|
|
|
|
|
|
|
|
|
|
/* The Vulkan spec (git aaed022) says:
|
|
|
|
|
*
|
|
|
|
|
* memoryTypeBits is a bitfield and contains one bit set for every
|
|
|
|
|
* supported memory type for the resource. The bit `1<<i` is set if and
|
|
|
|
|
* only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
|
|
|
|
|
* structure for the physical device is supported.
|
|
|
|
|
*
|
|
|
|
|
* We support exactly one memory type.
|
|
|
|
|
*/
|
|
|
|
|
pMemoryRequirements->memoryTypeBits = 1;
|
|
|
|
|
|
|
|
|
|
pMemoryRequirements->size = image->size;
|
|
|
|
|
pMemoryRequirements->alignment = image->alignment;
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 17:06:11 -07:00
|
|
|
VkResult anv_GetImageSparseMemoryRequirements(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
VkImage image,
|
|
|
|
|
uint32_t* pNumRequirements,
|
|
|
|
|
VkSparseImageMemoryRequirements* pSparseMemoryRequirements)
|
|
|
|
|
{
|
|
|
|
|
return vk_error(VK_UNSUPPORTED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult anv_GetDeviceMemoryCommitment(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
VkDeviceMemory memory,
|
|
|
|
|
VkDeviceSize* pCommittedMemoryInBytes)
|
|
|
|
|
{
|
|
|
|
|
*pCommittedMemoryInBytes = 0;
|
|
|
|
|
stub_return(VK_SUCCESS);
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 14:59:39 -07:00
|
|
|
VkResult anv_BindBufferMemory(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
VkBuffer _buffer,
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDeviceMemory _mem,
|
|
|
|
|
VkDeviceSize memOffset)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
|
2015-07-14 14:59:39 -07:00
|
|
|
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-14 14:59:39 -07:00
|
|
|
buffer->bo = &mem->bo;
|
|
|
|
|
buffer->offset = memOffset;
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult anv_BindImageMemory(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
VkImage _image,
|
|
|
|
|
VkDeviceMemory _mem,
|
|
|
|
|
VkDeviceSize memOffset)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
|
|
|
|
|
ANV_FROM_HANDLE(anv_image, image, _image);
|
|
|
|
|
|
|
|
|
|
image->bo = &mem->bo;
|
|
|
|
|
image->offset = memOffset;
|
2015-07-08 09:04:16 -07:00
|
|
|
|
2015-05-08 22:32:37 -07:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-08 09:16:48 -07:00
|
|
|
VkResult anv_QueueBindSparseBufferMemory(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkQueue queue,
|
2015-07-08 09:16:48 -07:00
|
|
|
VkBuffer buffer,
|
2015-07-14 17:06:11 -07:00
|
|
|
uint32_t numBindings,
|
|
|
|
|
const VkSparseMemoryBindInfo* pBindInfo)
|
|
|
|
|
{
|
|
|
|
|
stub_return(VK_UNSUPPORTED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult anv_QueueBindSparseImageOpaqueMemory(
|
|
|
|
|
VkQueue queue,
|
|
|
|
|
VkImage image,
|
|
|
|
|
uint32_t numBindings,
|
|
|
|
|
const VkSparseMemoryBindInfo* pBindInfo)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-05-12 13:44:43 -07:00
|
|
|
stub_return(VK_UNSUPPORTED);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-08 09:16:48 -07:00
|
|
|
VkResult anv_QueueBindSparseImageMemory(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkQueue queue,
|
|
|
|
|
VkImage image,
|
2015-07-14 17:06:11 -07:00
|
|
|
uint32_t numBindings,
|
|
|
|
|
const VkSparseImageMemoryBindInfo* pBindInfo)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-05-12 13:44:43 -07:00
|
|
|
stub_return(VK_UNSUPPORTED);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateFence(
|
2015-05-18 08:49:15 -07:00
|
|
|
VkDevice _device,
|
2015-05-08 22:32:37 -07:00
|
|
|
const VkFenceCreateInfo* pCreateInfo,
|
|
|
|
|
VkFence* pFence)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-18 08:49:15 -07:00
|
|
|
struct anv_fence *fence;
|
|
|
|
|
struct anv_batch batch;
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
const uint32_t fence_size = 128;
|
|
|
|
|
|
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO);
|
|
|
|
|
|
|
|
|
|
fence = anv_device_alloc(device, sizeof(*fence), 8,
|
|
|
|
|
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (fence == NULL)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
|
|
|
|
result = anv_bo_init_new(&fence->bo, device, fence_size);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
fence->bo.map =
|
|
|
|
|
anv_gem_mmap(device, fence->bo.gem_handle, 0, fence->bo.size);
|
2015-05-27 11:42:55 -07:00
|
|
|
batch.next = batch.start = fence->bo.map;
|
|
|
|
|
batch.end = fence->bo.map + fence->bo.size;
|
2015-05-18 08:49:15 -07:00
|
|
|
anv_batch_emit(&batch, GEN8_MI_BATCH_BUFFER_END);
|
|
|
|
|
anv_batch_emit(&batch, GEN8_MI_NOOP);
|
|
|
|
|
|
|
|
|
|
fence->exec2_objects[0].handle = fence->bo.gem_handle;
|
|
|
|
|
fence->exec2_objects[0].relocation_count = 0;
|
|
|
|
|
fence->exec2_objects[0].relocs_ptr = 0;
|
|
|
|
|
fence->exec2_objects[0].alignment = 0;
|
|
|
|
|
fence->exec2_objects[0].offset = fence->bo.offset;
|
|
|
|
|
fence->exec2_objects[0].flags = 0;
|
|
|
|
|
fence->exec2_objects[0].rsvd1 = 0;
|
|
|
|
|
fence->exec2_objects[0].rsvd2 = 0;
|
|
|
|
|
|
|
|
|
|
fence->execbuf.buffers_ptr = (uintptr_t) fence->exec2_objects;
|
|
|
|
|
fence->execbuf.buffer_count = 1;
|
|
|
|
|
fence->execbuf.batch_start_offset = 0;
|
|
|
|
|
fence->execbuf.batch_len = batch.next - fence->bo.map;
|
|
|
|
|
fence->execbuf.cliprects_ptr = 0;
|
|
|
|
|
fence->execbuf.num_cliprects = 0;
|
|
|
|
|
fence->execbuf.DR1 = 0;
|
|
|
|
|
fence->execbuf.DR4 = 0;
|
|
|
|
|
|
|
|
|
|
fence->execbuf.flags =
|
|
|
|
|
I915_EXEC_HANDLE_LUT | I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
|
|
|
|
|
fence->execbuf.rsvd1 = device->context_id;
|
|
|
|
|
fence->execbuf.rsvd2 = 0;
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pFence = anv_fence_to_handle(fence);
|
2015-05-18 08:49:15 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
anv_device_free(device, fence);
|
|
|
|
|
|
|
|
|
|
return result;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-14 09:29:35 -07:00
|
|
|
VkResult anv_DestroyFence(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
VkFence _fence)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_fence, fence, _fence);
|
|
|
|
|
|
|
|
|
|
anv_gem_munmap(fence->bo.map, fence->bo.size);
|
|
|
|
|
anv_gem_close(device, fence->bo.gem_handle);
|
|
|
|
|
anv_device_free(device, fence);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_ResetFences(
|
2015-05-18 08:49:15 -07:00
|
|
|
VkDevice _device,
|
2015-05-08 22:32:37 -07:00
|
|
|
uint32_t fenceCount,
|
2015-07-07 17:18:00 -07:00
|
|
|
const VkFence* pFences)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-07-17 13:59:48 -07:00
|
|
|
for (uint32_t i = 0; i < fenceCount; i++) {
|
|
|
|
|
ANV_FROM_HANDLE(anv_fence, fence, pFences[i]);
|
|
|
|
|
fence->ready = false;
|
|
|
|
|
}
|
2015-05-18 08:49:15 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_GetFenceStatus(
|
2015-05-18 08:49:15 -07:00
|
|
|
VkDevice _device,
|
|
|
|
|
VkFence _fence)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_fence, fence, _fence);
|
2015-05-18 08:49:15 -07:00
|
|
|
int64_t t = 0;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if (fence->ready)
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
|
|
|
ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
|
|
|
|
|
if (ret == 0) {
|
|
|
|
|
fence->ready = true;
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
2015-07-09 18:20:28 -07:00
|
|
|
|
2015-05-18 08:49:15 -07:00
|
|
|
return VK_NOT_READY;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_WaitForFences(
|
2015-05-18 08:49:15 -07:00
|
|
|
VkDevice _device,
|
2015-05-08 22:32:37 -07:00
|
|
|
uint32_t fenceCount,
|
|
|
|
|
const VkFence* pFences,
|
2015-07-13 12:59:42 -07:00
|
|
|
VkBool32 waitAll,
|
2015-05-08 22:32:37 -07:00
|
|
|
uint64_t timeout)
|
|
|
|
|
{
|
2015-07-08 14:24:12 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-18 08:49:15 -07:00
|
|
|
int64_t t = timeout;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
/* FIXME: handle !waitAll */
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < fenceCount; i++) {
|
2015-07-08 14:24:12 -07:00
|
|
|
ANV_FROM_HANDLE(anv_fence, fence, pFences[i]);
|
|
|
|
|
ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
|
2015-05-18 08:49:15 -07:00
|
|
|
if (ret == -1 && errno == ETIME)
|
|
|
|
|
return VK_TIMEOUT;
|
|
|
|
|
else if (ret == -1)
|
|
|
|
|
return vk_error(VK_ERROR_UNKNOWN);
|
2015-07-09 18:20:28 -07:00
|
|
|
}
|
2015-05-18 08:49:15 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Queue semaphore functions
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateSemaphore(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice device,
|
|
|
|
|
const VkSemaphoreCreateInfo* pCreateInfo,
|
|
|
|
|
VkSemaphore* pSemaphore)
|
|
|
|
|
{
|
2015-05-12 13:44:43 -07:00
|
|
|
stub_return(VK_UNSUPPORTED);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-14 09:31:34 -07:00
|
|
|
VkResult anv_DestroySemaphore(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
VkSemaphore semaphore)
|
|
|
|
|
{
|
|
|
|
|
stub_return(VK_UNSUPPORTED);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_QueueSignalSemaphore(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkQueue queue,
|
|
|
|
|
VkSemaphore semaphore)
|
|
|
|
|
{
|
2015-05-12 13:44:43 -07:00
|
|
|
stub_return(VK_UNSUPPORTED);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_QueueWaitSemaphore(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkQueue queue,
|
|
|
|
|
VkSemaphore semaphore)
|
|
|
|
|
{
|
2015-05-12 13:44:43 -07:00
|
|
|
stub_return(VK_UNSUPPORTED);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Event functions
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateEvent(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice device,
|
|
|
|
|
const VkEventCreateInfo* pCreateInfo,
|
|
|
|
|
VkEvent* pEvent)
|
|
|
|
|
{
|
2015-05-12 13:44:43 -07:00
|
|
|
stub_return(VK_UNSUPPORTED);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-14 09:33:47 -07:00
|
|
|
VkResult anv_DestroyEvent(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
VkEvent event)
|
|
|
|
|
{
|
|
|
|
|
stub_return(VK_UNSUPPORTED);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_GetEventStatus(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice device,
|
|
|
|
|
VkEvent event)
|
|
|
|
|
{
|
2015-05-12 13:44:43 -07:00
|
|
|
stub_return(VK_UNSUPPORTED);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_SetEvent(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice device,
|
|
|
|
|
VkEvent event)
|
|
|
|
|
{
|
2015-05-12 13:44:43 -07:00
|
|
|
stub_return(VK_UNSUPPORTED);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_ResetEvent(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice device,
|
|
|
|
|
VkEvent event)
|
|
|
|
|
{
|
2015-05-12 13:44:43 -07:00
|
|
|
stub_return(VK_UNSUPPORTED);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Buffer functions
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateBuffer(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
|
|
|
|
const VkBufferCreateInfo* pCreateInfo,
|
|
|
|
|
VkBuffer* pBuffer)
|
|
|
|
|
{
|
2015-07-08 14:24:12 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_buffer *buffer;
|
|
|
|
|
|
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
|
|
|
|
|
|
|
|
|
|
buffer = anv_device_alloc(device, sizeof(*buffer), 8,
|
|
|
|
|
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (buffer == NULL)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
|
|
|
|
buffer->size = pCreateInfo->size;
|
2015-05-11 22:19:58 -07:00
|
|
|
buffer->bo = NULL;
|
2015-05-08 22:32:37 -07:00
|
|
|
buffer->offset = 0;
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pBuffer = anv_buffer_to_handle(buffer);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 09:47:45 -07:00
|
|
|
VkResult anv_DestroyBuffer(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
VkBuffer _buffer)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
|
|
|
|
|
|
|
|
|
|
anv_device_free(device, buffer);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-08 22:32:37 -07:00
|
|
|
// Buffer view functions
|
|
|
|
|
|
2015-07-15 15:34:41 -07:00
|
|
|
void
|
2015-08-17 13:20:33 -07:00
|
|
|
anv_fill_buffer_surface_state(void *state, const struct anv_format *format,
|
2015-07-15 15:34:41 -07:00
|
|
|
uint32_t offset, uint32_t range)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
|
|
|
|
/* This assumes RGBA float format. */
|
|
|
|
|
uint32_t stride = 4;
|
2015-05-27 14:05:50 -07:00
|
|
|
uint32_t num_elements = range / stride;
|
|
|
|
|
|
2015-05-08 22:32:37 -07:00
|
|
|
struct GEN8_RENDER_SURFACE_STATE surface_state = {
|
|
|
|
|
.SurfaceType = SURFTYPE_BUFFER,
|
|
|
|
|
.SurfaceArray = false,
|
2015-08-17 13:20:33 -07:00
|
|
|
.SurfaceFormat = format->surface_format,
|
2015-05-08 22:32:37 -07:00
|
|
|
.SurfaceVerticalAlignment = VALIGN4,
|
|
|
|
|
.SurfaceHorizontalAlignment = HALIGN4,
|
|
|
|
|
.TileMode = LINEAR,
|
|
|
|
|
.VerticalLineStride = 0,
|
|
|
|
|
.VerticalLineStrideOffset = 0,
|
|
|
|
|
.SamplerL2BypassModeDisable = true,
|
|
|
|
|
.RenderCacheReadWriteMode = WriteOnlyCache,
|
2015-05-21 14:35:34 -07:00
|
|
|
.MemoryObjectControlState = GEN8_MOCS,
|
2015-06-10 23:11:37 -07:00
|
|
|
.BaseMipLevel = 0.0,
|
2015-05-08 22:32:37 -07:00
|
|
|
.SurfaceQPitch = 0,
|
|
|
|
|
.Height = (num_elements >> 7) & 0x3fff,
|
|
|
|
|
.Width = num_elements & 0x7f,
|
|
|
|
|
.Depth = (num_elements >> 21) & 0x3f,
|
|
|
|
|
.SurfacePitch = stride - 1,
|
|
|
|
|
.MinimumArrayElement = 0,
|
|
|
|
|
.NumberofMultisamples = MULTISAMPLECOUNT_1,
|
|
|
|
|
.XOffset = 0,
|
|
|
|
|
.YOffset = 0,
|
|
|
|
|
.SurfaceMinLOD = 0,
|
|
|
|
|
.MIPCountLOD = 0,
|
|
|
|
|
.AuxiliarySurfaceMode = AUX_NONE,
|
|
|
|
|
.RedClearColor = 0,
|
|
|
|
|
.GreenClearColor = 0,
|
|
|
|
|
.BlueClearColor = 0,
|
|
|
|
|
.AlphaClearColor = 0,
|
|
|
|
|
.ShaderChannelSelectRed = SCS_RED,
|
|
|
|
|
.ShaderChannelSelectGreen = SCS_GREEN,
|
|
|
|
|
.ShaderChannelSelectBlue = SCS_BLUE,
|
|
|
|
|
.ShaderChannelSelectAlpha = SCS_ALPHA,
|
2015-06-10 23:11:37 -07:00
|
|
|
.ResourceMinLOD = 0.0,
|
2015-05-08 22:32:37 -07:00
|
|
|
/* FIXME: We assume that the image must be bound at this time. */
|
2015-05-27 14:05:50 -07:00
|
|
|
.SurfaceBaseAddress = { NULL, offset },
|
2015-05-08 22:32:37 -07:00
|
|
|
};
|
|
|
|
|
|
2015-05-27 14:05:50 -07:00
|
|
|
GEN8_RENDER_SURFACE_STATE_pack(NULL, state, &surface_state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult anv_CreateBufferView(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
const VkBufferViewCreateInfo* pCreateInfo,
|
|
|
|
|
VkBufferView* pView)
|
|
|
|
|
{
|
2015-07-08 14:24:12 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer);
|
2015-07-15 12:00:27 -07:00
|
|
|
struct anv_buffer_view *bview;
|
2015-05-27 14:05:50 -07:00
|
|
|
struct anv_surface_view *view;
|
|
|
|
|
|
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO);
|
|
|
|
|
|
2015-07-15 12:00:27 -07:00
|
|
|
bview = anv_device_alloc(device, sizeof(*view), 8,
|
|
|
|
|
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (bview == NULL)
|
2015-05-27 14:05:50 -07:00
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
2015-07-15 12:00:27 -07:00
|
|
|
view = &bview->view;
|
2015-05-27 14:05:50 -07:00
|
|
|
view->bo = buffer->bo;
|
|
|
|
|
view->offset = buffer->offset + pCreateInfo->offset;
|
|
|
|
|
view->surface_state =
|
|
|
|
|
anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
|
2015-08-17 13:26:28 -07:00
|
|
|
view->format = anv_format_for_vk_format(pCreateInfo->format);
|
2015-05-27 14:05:50 -07:00
|
|
|
view->range = pCreateInfo->range;
|
|
|
|
|
|
2015-08-17 13:26:28 -07:00
|
|
|
anv_fill_buffer_surface_state(view->surface_state.map, view->format,
|
2015-07-15 15:34:41 -07:00
|
|
|
view->offset, pCreateInfo->range);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-15 12:00:27 -07:00
|
|
|
*pView = anv_buffer_view_to_handle(bview);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-10 12:25:30 -07:00
|
|
|
VkResult anv_DestroyBufferView(
|
|
|
|
|
VkDevice _device,
|
2015-07-15 12:00:27 -07:00
|
|
|
VkBufferView _bview)
|
2015-07-10 12:25:30 -07:00
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-07-15 12:00:27 -07:00
|
|
|
ANV_FROM_HANDLE(anv_buffer_view, bview, _bview);
|
2015-07-10 12:25:30 -07:00
|
|
|
|
2015-07-15 12:00:27 -07:00
|
|
|
anv_surface_view_fini(device, &bview->view);
|
|
|
|
|
anv_device_free(device, bview);
|
2015-07-10 12:25:30 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-08 22:32:37 -07:00
|
|
|
// Sampler functions
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateSampler(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
|
|
|
|
const VkSamplerCreateInfo* pCreateInfo,
|
|
|
|
|
VkSampler* pSampler)
|
|
|
|
|
{
|
2015-07-08 14:24:12 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_sampler *sampler;
|
2015-05-31 22:15:34 -07:00
|
|
|
uint32_t mag_filter, min_filter, max_anisotropy;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-05-13 13:53:01 -07:00
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
sampler = anv_device_alloc(device, sizeof(*sampler), 8,
|
|
|
|
|
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (!sampler)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
2015-05-12 21:44:59 -07:00
|
|
|
static const uint32_t vk_to_gen_tex_filter[] = {
|
2015-05-31 22:35:11 -07:00
|
|
|
[VK_TEX_FILTER_NEAREST] = MAPFILTER_NEAREST,
|
|
|
|
|
[VK_TEX_FILTER_LINEAR] = MAPFILTER_LINEAR
|
2015-05-12 21:44:59 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const uint32_t vk_to_gen_mipmap_mode[] = {
|
2015-05-31 22:35:11 -07:00
|
|
|
[VK_TEX_MIPMAP_MODE_BASE] = MIPFILTER_NONE,
|
|
|
|
|
[VK_TEX_MIPMAP_MODE_NEAREST] = MIPFILTER_NEAREST,
|
|
|
|
|
[VK_TEX_MIPMAP_MODE_LINEAR] = MIPFILTER_LINEAR
|
2015-05-12 21:44:59 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const uint32_t vk_to_gen_tex_address[] = {
|
2015-05-31 22:35:11 -07:00
|
|
|
[VK_TEX_ADDRESS_WRAP] = TCM_WRAP,
|
|
|
|
|
[VK_TEX_ADDRESS_MIRROR] = TCM_MIRROR,
|
|
|
|
|
[VK_TEX_ADDRESS_CLAMP] = TCM_CLAMP,
|
|
|
|
|
[VK_TEX_ADDRESS_MIRROR_ONCE] = TCM_MIRROR_ONCE,
|
|
|
|
|
[VK_TEX_ADDRESS_CLAMP_BORDER] = TCM_CLAMP_BORDER,
|
2015-05-12 21:44:59 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const uint32_t vk_to_gen_compare_op[] = {
|
2015-05-31 22:35:11 -07:00
|
|
|
[VK_COMPARE_OP_NEVER] = PREFILTEROPNEVER,
|
|
|
|
|
[VK_COMPARE_OP_LESS] = PREFILTEROPLESS,
|
|
|
|
|
[VK_COMPARE_OP_EQUAL] = PREFILTEROPEQUAL,
|
|
|
|
|
[VK_COMPARE_OP_LESS_EQUAL] = PREFILTEROPLEQUAL,
|
|
|
|
|
[VK_COMPARE_OP_GREATER] = PREFILTEROPGREATER,
|
|
|
|
|
[VK_COMPARE_OP_NOT_EQUAL] = PREFILTEROPNOTEQUAL,
|
|
|
|
|
[VK_COMPARE_OP_GREATER_EQUAL] = PREFILTEROPGEQUAL,
|
|
|
|
|
[VK_COMPARE_OP_ALWAYS] = PREFILTEROPALWAYS,
|
2015-05-12 21:44:59 -07:00
|
|
|
};
|
|
|
|
|
|
2015-05-31 22:15:34 -07:00
|
|
|
if (pCreateInfo->maxAnisotropy > 1) {
|
|
|
|
|
mag_filter = MAPFILTER_ANISOTROPIC;
|
|
|
|
|
min_filter = MAPFILTER_ANISOTROPIC;
|
|
|
|
|
max_anisotropy = (pCreateInfo->maxAnisotropy - 2) / 2;
|
|
|
|
|
} else {
|
|
|
|
|
mag_filter = vk_to_gen_tex_filter[pCreateInfo->magFilter];
|
|
|
|
|
min_filter = vk_to_gen_tex_filter[pCreateInfo->minFilter];
|
|
|
|
|
max_anisotropy = RATIO21;
|
|
|
|
|
}
|
2015-07-09 18:20:28 -07:00
|
|
|
|
2015-05-08 22:32:37 -07:00
|
|
|
struct GEN8_SAMPLER_STATE sampler_state = {
|
2015-05-12 21:44:59 -07:00
|
|
|
.SamplerDisable = false,
|
|
|
|
|
.TextureBorderColorMode = DX10OGL,
|
2015-05-08 22:32:37 -07:00
|
|
|
.LODPreClampMode = 0,
|
2015-06-10 23:11:37 -07:00
|
|
|
.BaseMipLevel = 0.0,
|
2015-05-12 21:44:59 -07:00
|
|
|
.MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipMode],
|
2015-05-31 22:15:34 -07:00
|
|
|
.MagModeFilter = mag_filter,
|
|
|
|
|
.MinModeFilter = min_filter,
|
2015-05-12 21:44:59 -07:00
|
|
|
.TextureLODBias = pCreateInfo->mipLodBias * 256,
|
|
|
|
|
.AnisotropicAlgorithm = EWAApproximation,
|
2015-06-10 23:11:37 -07:00
|
|
|
.MinLOD = pCreateInfo->minLod,
|
|
|
|
|
.MaxLOD = pCreateInfo->maxLod,
|
2015-05-08 22:32:37 -07:00
|
|
|
.ChromaKeyEnable = 0,
|
|
|
|
|
.ChromaKeyIndex = 0,
|
|
|
|
|
.ChromaKeyMode = 0,
|
2015-05-12 21:44:59 -07:00
|
|
|
.ShadowFunction = vk_to_gen_compare_op[pCreateInfo->compareOp],
|
2015-05-08 22:32:37 -07:00
|
|
|
.CubeSurfaceControlMode = 0,
|
2015-05-29 16:06:06 -07:00
|
|
|
|
|
|
|
|
.IndirectStatePointer =
|
2015-07-08 11:44:52 -07:00
|
|
|
device->border_colors.offset +
|
2015-05-31 22:15:34 -07:00
|
|
|
pCreateInfo->borderColor * sizeof(float) * 4,
|
2015-05-29 16:06:06 -07:00
|
|
|
|
2015-05-12 21:44:59 -07:00
|
|
|
.LODClampMagnificationMode = MIPNONE,
|
2015-05-31 22:15:34 -07:00
|
|
|
.MaximumAnisotropy = max_anisotropy,
|
2015-05-08 22:32:37 -07:00
|
|
|
.RAddressMinFilterRoundingEnable = 0,
|
|
|
|
|
.RAddressMagFilterRoundingEnable = 0,
|
|
|
|
|
.VAddressMinFilterRoundingEnable = 0,
|
|
|
|
|
.VAddressMagFilterRoundingEnable = 0,
|
|
|
|
|
.UAddressMinFilterRoundingEnable = 0,
|
|
|
|
|
.UAddressMagFilterRoundingEnable = 0,
|
|
|
|
|
.TrilinearFilterQuality = 0,
|
|
|
|
|
.NonnormalizedCoordinateEnable = 0,
|
2015-05-12 21:44:59 -07:00
|
|
|
.TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressU],
|
|
|
|
|
.TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressV],
|
|
|
|
|
.TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressW],
|
2015-05-08 22:32:37 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
GEN8_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pSampler = anv_sampler_to_handle(sampler);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 10:34:00 -07:00
|
|
|
VkResult anv_DestroySampler(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
VkSampler _sampler)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_sampler, sampler, _sampler);
|
|
|
|
|
|
|
|
|
|
anv_device_free(device, sampler);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-08 22:32:37 -07:00
|
|
|
// Descriptor set functions
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateDescriptorSetLayout(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
|
|
|
|
const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
|
|
|
|
|
VkDescriptorSetLayout* pSetLayout)
|
|
|
|
|
{
|
2015-07-08 14:24:12 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_descriptor_set_layout *set_layout;
|
|
|
|
|
|
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
|
|
|
|
|
|
2015-07-06 16:43:28 -07:00
|
|
|
uint32_t sampler_count[VK_SHADER_STAGE_NUM] = { 0, };
|
|
|
|
|
uint32_t surface_count[VK_SHADER_STAGE_NUM] = { 0, };
|
2015-05-15 15:03:21 -07:00
|
|
|
uint32_t num_dynamic_buffers = 0;
|
|
|
|
|
uint32_t count = 0;
|
2015-05-30 10:07:29 -07:00
|
|
|
uint32_t stages = 0;
|
2015-05-15 15:03:21 -07:00
|
|
|
uint32_t s;
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < pCreateInfo->count; i++) {
|
|
|
|
|
switch (pCreateInfo->pBinding[i].descriptorType) {
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
2015-05-27 14:05:50 -07:00
|
|
|
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
2015-05-15 15:03:21 -07:00
|
|
|
for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
|
2015-07-06 17:43:58 -07:00
|
|
|
sampler_count[s] += pCreateInfo->pBinding[i].arraySize;
|
2015-05-15 15:03:21 -07:00
|
|
|
break;
|
2015-05-27 14:05:50 -07:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-05-15 15:03:21 -07:00
|
|
|
|
2015-05-27 14:05:50 -07:00
|
|
|
switch (pCreateInfo->pBinding[i].descriptorType) {
|
2015-05-15 15:03:21 -07:00
|
|
|
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
2015-07-10 20:18:52 -07:00
|
|
|
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
2015-05-15 15:03:21 -07:00
|
|
|
for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
|
2015-07-06 17:43:58 -07:00
|
|
|
surface_count[s] += pCreateInfo->pBinding[i].arraySize;
|
2015-05-15 15:03:21 -07:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (pCreateInfo->pBinding[i].descriptorType) {
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
2015-07-06 17:43:58 -07:00
|
|
|
num_dynamic_buffers += pCreateInfo->pBinding[i].arraySize;
|
2015-05-15 15:03:21 -07:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-05-27 14:05:50 -07:00
|
|
|
|
2015-05-30 10:07:29 -07:00
|
|
|
stages |= pCreateInfo->pBinding[i].stageFlags;
|
2015-07-06 17:43:58 -07:00
|
|
|
count += pCreateInfo->pBinding[i].arraySize;
|
2015-05-15 15:03:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t sampler_total = 0;
|
|
|
|
|
uint32_t surface_total = 0;
|
2015-07-06 16:43:28 -07:00
|
|
|
for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
|
2015-05-15 15:03:21 -07:00
|
|
|
sampler_total += sampler_count[s];
|
|
|
|
|
surface_total += surface_count[s];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t size = sizeof(*set_layout) +
|
2015-05-27 14:05:50 -07:00
|
|
|
(sampler_total + surface_total) * sizeof(set_layout->entries[0]);
|
2015-05-08 22:32:37 -07:00
|
|
|
set_layout = anv_device_alloc(device, size, 8,
|
|
|
|
|
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (!set_layout)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
2015-05-15 15:03:21 -07:00
|
|
|
set_layout->num_dynamic_buffers = num_dynamic_buffers;
|
|
|
|
|
set_layout->count = count;
|
2015-05-30 10:07:29 -07:00
|
|
|
set_layout->shader_stages = stages;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-05-27 14:05:50 -07:00
|
|
|
struct anv_descriptor_slot *p = set_layout->entries;
|
2015-07-06 16:43:28 -07:00
|
|
|
struct anv_descriptor_slot *sampler[VK_SHADER_STAGE_NUM];
|
|
|
|
|
struct anv_descriptor_slot *surface[VK_SHADER_STAGE_NUM];
|
|
|
|
|
for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
|
2015-05-15 15:03:21 -07:00
|
|
|
set_layout->stage[s].surface_count = surface_count[s];
|
|
|
|
|
set_layout->stage[s].surface_start = surface[s] = p;
|
|
|
|
|
p += surface_count[s];
|
|
|
|
|
set_layout->stage[s].sampler_count = sampler_count[s];
|
|
|
|
|
set_layout->stage[s].sampler_start = sampler[s] = p;
|
|
|
|
|
p += sampler_count[s];
|
|
|
|
|
}
|
2015-05-13 14:43:08 -07:00
|
|
|
|
2015-05-15 15:03:21 -07:00
|
|
|
uint32_t descriptor = 0;
|
2015-05-29 11:32:53 -07:00
|
|
|
int8_t dynamic_slot = 0;
|
|
|
|
|
bool is_dynamic;
|
2015-05-15 15:03:21 -07:00
|
|
|
for (uint32_t i = 0; i < pCreateInfo->count; i++) {
|
2015-05-13 14:43:08 -07:00
|
|
|
switch (pCreateInfo->pBinding[i].descriptorType) {
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
2015-05-15 15:03:21 -07:00
|
|
|
for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
|
2015-07-06 17:43:58 -07:00
|
|
|
for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
|
2015-05-27 14:05:50 -07:00
|
|
|
sampler[s]->index = descriptor + j;
|
2015-05-29 11:32:53 -07:00
|
|
|
sampler[s]->dynamic_slot = -1;
|
2015-05-27 14:05:50 -07:00
|
|
|
sampler[s]++;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-05-15 15:03:21 -07:00
|
|
|
|
2015-05-27 14:05:50 -07:00
|
|
|
switch (pCreateInfo->pBinding[i].descriptorType) {
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
2015-05-29 11:32:53 -07:00
|
|
|
is_dynamic = true;
|
2015-05-27 14:05:50 -07:00
|
|
|
break;
|
|
|
|
|
default:
|
2015-05-29 11:32:53 -07:00
|
|
|
is_dynamic = false;
|
2015-05-27 14:05:50 -07:00
|
|
|
break;
|
|
|
|
|
}
|
2015-05-13 14:43:08 -07:00
|
|
|
|
2015-05-27 14:05:50 -07:00
|
|
|
switch (pCreateInfo->pBinding[i].descriptorType) {
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
2015-05-13 14:43:08 -07:00
|
|
|
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
2015-07-10 20:18:52 -07:00
|
|
|
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
2015-05-15 15:03:21 -07:00
|
|
|
for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
|
2015-07-06 17:43:58 -07:00
|
|
|
for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
|
2015-05-27 14:05:50 -07:00
|
|
|
surface[s]->index = descriptor + j;
|
2015-05-29 11:32:53 -07:00
|
|
|
if (is_dynamic)
|
|
|
|
|
surface[s]->dynamic_slot = dynamic_slot + j;
|
|
|
|
|
else
|
|
|
|
|
surface[s]->dynamic_slot = -1;
|
2015-05-27 14:05:50 -07:00
|
|
|
surface[s]++;
|
2015-05-15 15:03:21 -07:00
|
|
|
}
|
2015-05-13 14:43:08 -07:00
|
|
|
break;
|
|
|
|
|
default:
|
2015-05-27 14:05:50 -07:00
|
|
|
break;
|
2015-05-13 14:43:08 -07:00
|
|
|
}
|
2015-05-29 11:32:53 -07:00
|
|
|
|
|
|
|
|
if (is_dynamic)
|
2015-07-06 17:43:58 -07:00
|
|
|
dynamic_slot += pCreateInfo->pBinding[i].arraySize;
|
2015-05-29 11:32:53 -07:00
|
|
|
|
2015-07-06 17:43:58 -07:00
|
|
|
descriptor += pCreateInfo->pBinding[i].arraySize;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pSetLayout = anv_descriptor_set_layout_to_handle(set_layout);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 10:36:49 -07:00
|
|
|
VkResult anv_DestroyDescriptorSetLayout(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
VkDescriptorSetLayout _set_layout)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout, _set_layout);
|
|
|
|
|
|
|
|
|
|
anv_device_free(device, set_layout);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateDescriptorPool(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice device,
|
|
|
|
|
VkDescriptorPoolUsage poolUsage,
|
|
|
|
|
uint32_t maxSets,
|
|
|
|
|
const VkDescriptorPoolCreateInfo* pCreateInfo,
|
|
|
|
|
VkDescriptorPool* pDescriptorPool)
|
|
|
|
|
{
|
2015-07-14 16:01:42 -07:00
|
|
|
anv_finishme("VkDescriptorPool is a stub");
|
2015-07-15 15:48:41 -07:00
|
|
|
pDescriptorPool->handle = 1;
|
2015-05-17 18:38:34 -07:00
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-14 10:38:22 -07:00
|
|
|
VkResult anv_DestroyDescriptorPool(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
VkDescriptorPool _pool)
|
|
|
|
|
{
|
2015-07-14 16:01:42 -07:00
|
|
|
anv_finishme("VkDescriptorPool is a stub: free the pool's descriptor sets");
|
2015-07-14 10:38:22 -07:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_ResetDescriptorPool(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice device,
|
|
|
|
|
VkDescriptorPool descriptorPool)
|
|
|
|
|
{
|
2015-07-14 16:01:42 -07:00
|
|
|
anv_finishme("VkDescriptorPool is a stub: free the pool's descriptor sets");
|
2015-05-17 18:38:34 -07:00
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-15 14:14:04 -07:00
|
|
|
VkResult
|
|
|
|
|
anv_descriptor_set_create(struct anv_device *device,
|
|
|
|
|
const struct anv_descriptor_set_layout *layout,
|
|
|
|
|
struct anv_descriptor_set **out_set)
|
|
|
|
|
{
|
|
|
|
|
struct anv_descriptor_set *set;
|
|
|
|
|
size_t size = sizeof(*set) + layout->count * sizeof(set->descriptors[0]);
|
|
|
|
|
|
|
|
|
|
set = anv_device_alloc(device, size, 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (!set)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
|
|
|
|
/* A descriptor set may not be 100% filled. Clear the set so we can can
|
|
|
|
|
* later detect holes in it.
|
|
|
|
|
*/
|
|
|
|
|
memset(set, 0, size);
|
|
|
|
|
|
|
|
|
|
*out_set = set;
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
anv_descriptor_set_destroy(struct anv_device *device,
|
|
|
|
|
struct anv_descriptor_set *set)
|
|
|
|
|
{
|
|
|
|
|
anv_device_free(device, set);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_AllocDescriptorSets(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
|
|
|
|
VkDescriptorPool descriptorPool,
|
|
|
|
|
VkDescriptorSetUsage setUsage,
|
|
|
|
|
uint32_t count,
|
|
|
|
|
const VkDescriptorSetLayout* pSetLayouts,
|
|
|
|
|
VkDescriptorSet* pDescriptorSets,
|
|
|
|
|
uint32_t* pCount)
|
|
|
|
|
{
|
2015-07-08 14:24:12 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-07-15 14:14:04 -07:00
|
|
|
|
|
|
|
|
VkResult result;
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_descriptor_set *set;
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < count; i++) {
|
2015-07-08 14:24:12 -07:00
|
|
|
ANV_FROM_HANDLE(anv_descriptor_set_layout, layout, pSetLayouts[i]);
|
2015-07-15 14:14:04 -07:00
|
|
|
|
|
|
|
|
result = anv_descriptor_set_create(device, layout, &set);
|
|
|
|
|
if (result != VK_SUCCESS) {
|
2015-05-08 22:32:37 -07:00
|
|
|
*pCount = i;
|
2015-07-15 14:14:04 -07:00
|
|
|
return result;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
pDescriptorSets[i] = anv_descriptor_set_to_handle(set);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*pCount = count;
|
|
|
|
|
|
2015-05-17 18:39:12 -07:00
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-22 17:33:09 -07:00
|
|
|
VkResult anv_FreeDescriptorSets(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
VkDescriptorPool descriptorPool,
|
|
|
|
|
uint32_t count,
|
|
|
|
|
const VkDescriptorSet* pDescriptorSets)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < count; i++) {
|
|
|
|
|
ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
|
|
|
|
|
|
|
|
|
|
anv_descriptor_set_destroy(device, set);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-08 14:24:56 -07:00
|
|
|
VkResult anv_UpdateDescriptorSets(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
uint32_t writeCount,
|
|
|
|
|
const VkWriteDescriptorSet* pDescriptorWrites,
|
|
|
|
|
uint32_t copyCount,
|
|
|
|
|
const VkCopyDescriptorSet* pDescriptorCopies)
|
|
|
|
|
{
|
|
|
|
|
for (uint32_t i = 0; i < writeCount; i++) {
|
|
|
|
|
const VkWriteDescriptorSet *write = &pDescriptorWrites[i];
|
|
|
|
|
ANV_FROM_HANDLE(anv_descriptor_set, set, write->destSet);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-08 14:24:56 -07:00
|
|
|
switch (write->descriptorType) {
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
|
|
|
|
for (uint32_t j = 0; j < write->count; j++) {
|
|
|
|
|
set->descriptors[write->destBinding + j].sampler =
|
2015-07-09 18:41:27 -07:00
|
|
|
anv_sampler_from_handle(write->pDescriptors[j].sampler);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-08 14:24:56 -07:00
|
|
|
if (write->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
|
|
|
|
|
break;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-08 14:24:56 -07:00
|
|
|
/* fallthrough */
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-08 14:24:56 -07:00
|
|
|
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
|
|
|
|
for (uint32_t j = 0; j < write->count; j++) {
|
2015-07-15 12:00:27 -07:00
|
|
|
ANV_FROM_HANDLE(anv_image_view, iview,
|
|
|
|
|
write->pDescriptors[j].imageView);
|
|
|
|
|
set->descriptors[write->destBinding + j].view = &iview->view;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2015-07-08 14:24:56 -07:00
|
|
|
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
|
|
|
|
anv_finishme("texel buffers not implemented");
|
2015-05-08 22:32:37 -07:00
|
|
|
break;
|
|
|
|
|
|
2015-07-10 20:18:52 -07:00
|
|
|
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
|
|
|
|
anv_finishme("input attachments not implemented");
|
|
|
|
|
break;
|
|
|
|
|
|
2015-07-08 14:24:56 -07:00
|
|
|
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
|
|
|
|
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
|
|
|
|
for (uint32_t j = 0; j < write->count; j++) {
|
2015-07-15 12:00:27 -07:00
|
|
|
ANV_FROM_HANDLE(anv_buffer_view, bview,
|
|
|
|
|
write->pDescriptors[j].bufferView);
|
|
|
|
|
set->descriptors[write->destBinding + j].view = &bview->view;
|
2015-07-08 14:24:56 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-08 22:32:37 -07:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-08 14:24:56 -07:00
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < copyCount; i++) {
|
|
|
|
|
const VkCopyDescriptorSet *copy = &pDescriptorCopies[i];
|
|
|
|
|
ANV_FROM_HANDLE(anv_descriptor_set, src, copy->destSet);
|
|
|
|
|
ANV_FROM_HANDLE(anv_descriptor_set, dest, copy->destSet);
|
|
|
|
|
for (uint32_t j = 0; j < copy->count; j++) {
|
|
|
|
|
dest->descriptors[copy->destBinding + j] =
|
|
|
|
|
src->descriptors[copy->srcBinding + j];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// State object functions
|
|
|
|
|
|
|
|
|
|
static inline int64_t
|
|
|
|
|
clamp_int64(int64_t x, int64_t min, int64_t max)
|
|
|
|
|
{
|
|
|
|
|
if (x < min)
|
|
|
|
|
return min;
|
|
|
|
|
else if (x < max)
|
|
|
|
|
return x;
|
|
|
|
|
else
|
|
|
|
|
return max;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateDynamicViewportState(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
2015-07-13 13:19:33 -07:00
|
|
|
const VkDynamicViewportStateCreateInfo* pCreateInfo,
|
|
|
|
|
VkDynamicViewportState* pState)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_dynamic_vp_state *state;
|
|
|
|
|
|
2015-07-14 16:34:31 -07:00
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_VIEWPORT_STATE_CREATE_INFO);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
state = anv_device_alloc(device, sizeof(*state), 8,
|
|
|
|
|
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (state == NULL)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
|
|
|
|
unsigned count = pCreateInfo->viewportAndScissorCount;
|
2015-05-13 15:34:34 -07:00
|
|
|
state->sf_clip_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
|
2015-05-08 22:32:37 -07:00
|
|
|
count * 64, 64);
|
2015-05-13 15:34:34 -07:00
|
|
|
state->cc_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
|
2015-05-08 22:32:37 -07:00
|
|
|
count * 8, 32);
|
2015-05-13 15:34:34 -07:00
|
|
|
state->scissor = anv_state_pool_alloc(&device->dynamic_state_pool,
|
2015-05-08 22:32:37 -07:00
|
|
|
count * 32, 32);
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < pCreateInfo->viewportAndScissorCount; i++) {
|
|
|
|
|
const VkViewport *vp = &pCreateInfo->pViewports[i];
|
2015-07-06 17:47:18 -07:00
|
|
|
const VkRect2D *s = &pCreateInfo->pScissors[i];
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
struct GEN8_SF_CLIP_VIEWPORT sf_clip_viewport = {
|
|
|
|
|
.ViewportMatrixElementm00 = vp->width / 2,
|
|
|
|
|
.ViewportMatrixElementm11 = vp->height / 2,
|
|
|
|
|
.ViewportMatrixElementm22 = (vp->maxDepth - vp->minDepth) / 2,
|
|
|
|
|
.ViewportMatrixElementm30 = vp->originX + vp->width / 2,
|
|
|
|
|
.ViewportMatrixElementm31 = vp->originY + vp->height / 2,
|
|
|
|
|
.ViewportMatrixElementm32 = (vp->maxDepth + vp->minDepth) / 2,
|
|
|
|
|
.XMinClipGuardband = -1.0f,
|
|
|
|
|
.XMaxClipGuardband = 1.0f,
|
|
|
|
|
.YMinClipGuardband = -1.0f,
|
|
|
|
|
.YMaxClipGuardband = 1.0f,
|
|
|
|
|
.XMinViewPort = vp->originX,
|
|
|
|
|
.XMaxViewPort = vp->originX + vp->width - 1,
|
|
|
|
|
.YMinViewPort = vp->originY,
|
|
|
|
|
.YMaxViewPort = vp->originY + vp->height - 1,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct GEN8_CC_VIEWPORT cc_viewport = {
|
|
|
|
|
.MinimumDepth = vp->minDepth,
|
|
|
|
|
.MaximumDepth = vp->maxDepth
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Since xmax and ymax are inclusive, we have to have xmax < xmin or
|
|
|
|
|
* ymax < ymin for empty clips. In case clip x, y, width height are all
|
|
|
|
|
* 0, the clamps below produce 0 for xmin, ymin, xmax, ymax, which isn't
|
|
|
|
|
* what we want. Just special case empty clips and produce a canonical
|
|
|
|
|
* empty clip. */
|
|
|
|
|
static const struct GEN8_SCISSOR_RECT empty_scissor = {
|
|
|
|
|
.ScissorRectangleYMin = 1,
|
|
|
|
|
.ScissorRectangleXMin = 1,
|
|
|
|
|
.ScissorRectangleYMax = 0,
|
|
|
|
|
.ScissorRectangleXMax = 0
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const int max = 0xffff;
|
|
|
|
|
struct GEN8_SCISSOR_RECT scissor = {
|
|
|
|
|
/* Do this math using int64_t so overflow gets clamped correctly. */
|
|
|
|
|
.ScissorRectangleYMin = clamp_int64(s->offset.y, 0, max),
|
|
|
|
|
.ScissorRectangleXMin = clamp_int64(s->offset.x, 0, max),
|
|
|
|
|
.ScissorRectangleYMax = clamp_int64((uint64_t) s->offset.y + s->extent.height - 1, 0, max),
|
|
|
|
|
.ScissorRectangleXMax = clamp_int64((uint64_t) s->offset.x + s->extent.width - 1, 0, max)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
GEN8_SF_CLIP_VIEWPORT_pack(NULL, state->sf_clip_vp.map + i * 64, &sf_clip_viewport);
|
|
|
|
|
GEN8_CC_VIEWPORT_pack(NULL, state->cc_vp.map + i * 32, &cc_viewport);
|
|
|
|
|
|
|
|
|
|
if (s->extent.width <= 0 || s->extent.height <= 0) {
|
|
|
|
|
GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &empty_scissor);
|
|
|
|
|
} else {
|
|
|
|
|
GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &scissor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-09 18:59:05 -07:00
|
|
|
*pState = anv_dynamic_vp_state_to_handle(state);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 10:42:45 -07:00
|
|
|
VkResult anv_DestroyDynamicViewportState(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
VkDynamicViewportState _vp_state)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_dynamic_vp_state, vp_state, _vp_state);
|
|
|
|
|
|
|
|
|
|
anv_state_pool_free(&device->dynamic_state_pool, vp_state->sf_clip_vp);
|
|
|
|
|
anv_state_pool_free(&device->dynamic_state_pool, vp_state->cc_vp);
|
|
|
|
|
anv_state_pool_free(&device->dynamic_state_pool, vp_state->scissor);
|
|
|
|
|
|
|
|
|
|
anv_device_free(device, vp_state);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateDynamicRasterState(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
2015-07-13 13:19:33 -07:00
|
|
|
const VkDynamicRasterStateCreateInfo* pCreateInfo,
|
|
|
|
|
VkDynamicRasterState* pState)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_dynamic_rs_state *state;
|
|
|
|
|
|
2015-07-14 16:34:31 -07:00
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
state = anv_device_alloc(device, sizeof(*state), 8,
|
|
|
|
|
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (state == NULL)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
|
|
|
|
struct GEN8_3DSTATE_SF sf = {
|
|
|
|
|
GEN8_3DSTATE_SF_header,
|
|
|
|
|
.LineWidth = pCreateInfo->lineWidth,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
GEN8_3DSTATE_SF_pack(NULL, state->state_sf, &sf);
|
|
|
|
|
|
2015-05-26 09:40:10 -07:00
|
|
|
bool enable_bias = pCreateInfo->depthBias != 0.0f ||
|
|
|
|
|
pCreateInfo->slopeScaledDepthBias != 0.0f;
|
|
|
|
|
struct GEN8_3DSTATE_RASTER raster = {
|
|
|
|
|
.GlobalDepthOffsetEnableSolid = enable_bias,
|
|
|
|
|
.GlobalDepthOffsetEnableWireframe = enable_bias,
|
|
|
|
|
.GlobalDepthOffsetEnablePoint = enable_bias,
|
|
|
|
|
.GlobalDepthOffsetConstant = pCreateInfo->depthBias,
|
|
|
|
|
.GlobalDepthOffsetScale = pCreateInfo->slopeScaledDepthBias,
|
|
|
|
|
.GlobalDepthOffsetClamp = pCreateInfo->depthBiasClamp
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
GEN8_3DSTATE_RASTER_pack(NULL, state->state_raster, &raster);
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pState = anv_dynamic_rs_state_to_handle(state);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 10:51:08 -07:00
|
|
|
VkResult anv_DestroyDynamicRasterState(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
VkDynamicRasterState _rs_state)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_dynamic_rs_state, rs_state, _rs_state);
|
|
|
|
|
|
|
|
|
|
anv_device_free(device, rs_state);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateDynamicColorBlendState(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
2015-07-13 13:19:33 -07:00
|
|
|
const VkDynamicColorBlendStateCreateInfo* pCreateInfo,
|
|
|
|
|
VkDynamicColorBlendState* pState)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_dynamic_cb_state *state;
|
|
|
|
|
|
2015-07-14 16:34:31 -07:00
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_COLOR_BLEND_STATE_CREATE_INFO);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
state = anv_device_alloc(device, sizeof(*state), 8,
|
|
|
|
|
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (state == NULL)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
2015-05-26 11:22:12 -07:00
|
|
|
struct GEN8_COLOR_CALC_STATE color_calc_state = {
|
|
|
|
|
.BlendConstantColorRed = pCreateInfo->blendConst[0],
|
|
|
|
|
.BlendConstantColorGreen = pCreateInfo->blendConst[1],
|
|
|
|
|
.BlendConstantColorBlue = pCreateInfo->blendConst[2],
|
|
|
|
|
.BlendConstantColorAlpha = pCreateInfo->blendConst[3]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pState = anv_dynamic_cb_state_to_handle(state);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 10:52:45 -07:00
|
|
|
VkResult anv_DestroyDynamicColorBlendState(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
VkDynamicColorBlendState _cb_state)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_dynamic_cb_state, cb_state, _cb_state);
|
|
|
|
|
|
|
|
|
|
anv_device_free(device, cb_state);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateDynamicDepthStencilState(
|
2015-05-24 21:19:26 -07:00
|
|
|
VkDevice _device,
|
2015-07-13 13:19:33 -07:00
|
|
|
const VkDynamicDepthStencilStateCreateInfo* pCreateInfo,
|
|
|
|
|
VkDynamicDepthStencilState* pState)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-24 21:19:26 -07:00
|
|
|
struct anv_dynamic_ds_state *state;
|
|
|
|
|
|
2015-07-14 16:34:31 -07:00
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO);
|
2015-05-24 21:19:26 -07:00
|
|
|
|
|
|
|
|
state = anv_device_alloc(device, sizeof(*state), 8,
|
|
|
|
|
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (state == NULL)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
|
|
|
|
struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
|
|
|
|
|
GEN8_3DSTATE_WM_DEPTH_STENCIL_header,
|
|
|
|
|
|
|
|
|
|
/* Is this what we need to do? */
|
|
|
|
|
.StencilBufferWriteEnable = pCreateInfo->stencilWriteMask != 0,
|
|
|
|
|
|
2015-06-03 16:59:13 -07:00
|
|
|
.StencilTestMask = pCreateInfo->stencilReadMask & 0xff,
|
|
|
|
|
.StencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
|
2015-05-24 21:19:26 -07:00
|
|
|
|
2015-06-03 16:59:13 -07:00
|
|
|
.BackfaceStencilTestMask = pCreateInfo->stencilReadMask & 0xff,
|
|
|
|
|
.BackfaceStencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
|
2015-05-24 21:19:26 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, state->state_wm_depth_stencil,
|
|
|
|
|
&wm_depth_stencil);
|
|
|
|
|
|
2015-05-26 11:22:12 -07:00
|
|
|
struct GEN8_COLOR_CALC_STATE color_calc_state = {
|
|
|
|
|
.StencilReferenceValue = pCreateInfo->stencilFrontRef,
|
|
|
|
|
.BackFaceStencilReferenceValue = pCreateInfo->stencilBackRef
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pState = anv_dynamic_ds_state_to_handle(state);
|
2015-05-24 21:19:26 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-14 10:54:16 -07:00
|
|
|
VkResult anv_DestroyDynamicDepthStencilState(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
VkDynamicDepthStencilState _ds_state)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_dynamic_ds_state, ds_state, _ds_state);
|
|
|
|
|
|
|
|
|
|
anv_device_free(device, ds_state);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateFramebuffer(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
|
|
|
|
const VkFramebufferCreateInfo* pCreateInfo,
|
|
|
|
|
VkFramebuffer* pFramebuffer)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_framebuffer *framebuffer;
|
|
|
|
|
|
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
|
|
|
|
|
|
2015-07-10 20:18:52 -07:00
|
|
|
size_t size = sizeof(*framebuffer) +
|
|
|
|
|
sizeof(struct anv_attachment_view *) * pCreateInfo->attachmentCount;
|
|
|
|
|
framebuffer = anv_device_alloc(device, size, 8,
|
2015-05-08 22:32:37 -07:00
|
|
|
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (framebuffer == NULL)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
2015-07-10 20:18:52 -07:00
|
|
|
framebuffer->attachment_count = pCreateInfo->attachmentCount;
|
|
|
|
|
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
|
|
|
|
|
ANV_FROM_HANDLE(anv_attachment_view, view,
|
|
|
|
|
pCreateInfo->pAttachments[i].view);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-10 20:18:52 -07:00
|
|
|
framebuffer->attachments[i] = view;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
framebuffer->width = pCreateInfo->width;
|
|
|
|
|
framebuffer->height = pCreateInfo->height;
|
|
|
|
|
framebuffer->layers = pCreateInfo->layers;
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
anv_CreateDynamicViewportState(anv_device_to_handle(device),
|
2015-07-13 13:19:33 -07:00
|
|
|
&(VkDynamicViewportStateCreateInfo) {
|
2015-07-14 16:34:31 -07:00
|
|
|
.sType = VK_STRUCTURE_TYPE_DYNAMIC_VIEWPORT_STATE_CREATE_INFO,
|
2015-06-09 15:53:10 -07:00
|
|
|
.viewportAndScissorCount = 1,
|
|
|
|
|
.pViewports = (VkViewport[]) {
|
|
|
|
|
{
|
|
|
|
|
.originX = 0,
|
|
|
|
|
.originY = 0,
|
|
|
|
|
.width = pCreateInfo->width,
|
|
|
|
|
.height = pCreateInfo->height,
|
|
|
|
|
.minDepth = 0,
|
|
|
|
|
.maxDepth = 1
|
|
|
|
|
},
|
|
|
|
|
},
|
2015-07-06 17:47:18 -07:00
|
|
|
.pScissors = (VkRect2D[]) {
|
2015-06-09 15:53:10 -07:00
|
|
|
{ { 0, 0 },
|
|
|
|
|
{ pCreateInfo->width, pCreateInfo->height } },
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
&framebuffer->vp_state);
|
2015-05-11 23:25:06 -07:00
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pFramebuffer = anv_framebuffer_to_handle(framebuffer);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 10:59:30 -07:00
|
|
|
VkResult anv_DestroyFramebuffer(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
VkFramebuffer _fb)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_framebuffer, fb, _fb);
|
|
|
|
|
|
|
|
|
|
anv_DestroyDynamicViewportState(anv_device_to_handle(device),
|
|
|
|
|
fb->vp_state);
|
|
|
|
|
anv_device_free(device, fb);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateRenderPass(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
|
|
|
|
const VkRenderPassCreateInfo* pCreateInfo,
|
|
|
|
|
VkRenderPass* pRenderPass)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_render_pass *pass;
|
2015-05-11 23:25:06 -07:00
|
|
|
size_t size;
|
2015-08-19 15:10:14 -07:00
|
|
|
size_t attachments_offset;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
|
|
|
|
|
|
2015-08-19 15:10:14 -07:00
|
|
|
size = sizeof(*pass);
|
|
|
|
|
size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
|
|
|
|
|
attachments_offset = size;
|
|
|
|
|
size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
|
|
|
|
|
|
2015-05-11 23:25:06 -07:00
|
|
|
pass = anv_device_alloc(device, size, 8,
|
2015-05-08 22:32:37 -07:00
|
|
|
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
if (pass == NULL)
|
|
|
|
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
2015-07-15 15:02:47 -07:00
|
|
|
/* Clear the subpasses along with the parent pass. This required because
|
|
|
|
|
* each array member of anv_subpass must be a valid pointer if not NULL.
|
|
|
|
|
*/
|
|
|
|
|
memset(pass, 0, size);
|
2015-07-10 20:18:52 -07:00
|
|
|
pass->attachment_count = pCreateInfo->attachmentCount;
|
2015-07-15 15:02:47 -07:00
|
|
|
pass->subpass_count = pCreateInfo->subpassCount;
|
2015-08-19 15:10:14 -07:00
|
|
|
pass->attachments = (void *) pass + attachments_offset;
|
2015-07-15 15:02:47 -07:00
|
|
|
|
2015-07-10 20:18:52 -07:00
|
|
|
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
|
2015-08-20 09:54:32 -07:00
|
|
|
struct anv_render_pass_attachment *att = &pass->attachments[i];
|
|
|
|
|
|
|
|
|
|
att->format = anv_format_for_vk_format(pCreateInfo->pAttachments[i].format);
|
|
|
|
|
att->samples = pCreateInfo->pAttachments[i].samples;
|
|
|
|
|
att->load_op = pCreateInfo->pAttachments[i].loadOp;
|
|
|
|
|
att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
|
|
|
|
|
// att->store_op = pCreateInfo->pAttachments[i].storeOp;
|
|
|
|
|
// att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
|
2015-08-20 10:03:58 -07:00
|
|
|
|
|
|
|
|
if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
|
|
|
|
|
if (anv_format_is_color(att->format)) {
|
|
|
|
|
++pass->num_color_clear_attachments;
|
|
|
|
|
} else if (att->format->depth_format) {
|
|
|
|
|
pass->has_depth_clear_attachment = true;
|
|
|
|
|
}
|
|
|
|
|
} else if (att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
|
|
|
|
|
assert(att->format->has_stencil);
|
|
|
|
|
pass->has_stencil_clear_attachment = true;
|
|
|
|
|
}
|
2015-07-10 20:18:52 -07:00
|
|
|
}
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-10 20:18:52 -07:00
|
|
|
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
|
|
|
|
|
const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
|
|
|
|
|
struct anv_subpass *subpass = &pass->subpasses[i];
|
|
|
|
|
|
|
|
|
|
subpass->input_count = desc->inputCount;
|
|
|
|
|
subpass->color_count = desc->colorCount;
|
2015-07-15 15:02:47 -07:00
|
|
|
|
|
|
|
|
if (desc->inputCount > 0) {
|
|
|
|
|
subpass->input_attachments =
|
|
|
|
|
anv_device_alloc(device, desc->inputCount * sizeof(uint32_t),
|
|
|
|
|
8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j < desc->inputCount; j++) {
|
|
|
|
|
subpass->input_attachments[j]
|
|
|
|
|
= desc->inputAttachments[j].attachment;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (desc->colorCount > 0) {
|
|
|
|
|
subpass->color_attachments =
|
|
|
|
|
anv_device_alloc(device, desc->colorCount * sizeof(uint32_t),
|
|
|
|
|
8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
|
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j < desc->colorCount; j++) {
|
|
|
|
|
subpass->color_attachments[j]
|
|
|
|
|
= desc->colorAttachments[j].attachment;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-10 20:18:52 -07:00
|
|
|
|
|
|
|
|
if (desc->resolveAttachments) {
|
|
|
|
|
subpass->resolve_attachments =
|
|
|
|
|
anv_device_alloc(device, desc->colorCount * sizeof(uint32_t),
|
|
|
|
|
8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
|
2015-07-15 15:02:47 -07:00
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j < desc->colorCount; j++) {
|
|
|
|
|
subpass->resolve_attachments[j]
|
|
|
|
|
= desc->resolveAttachments[j].attachment;
|
|
|
|
|
}
|
2015-07-10 20:18:52 -07:00
|
|
|
}
|
2015-05-11 23:25:06 -07:00
|
|
|
|
2015-07-10 20:18:52 -07:00
|
|
|
subpass->depth_stencil_attachment = desc->depthStencilAttachment.attachment;
|
2015-05-11 23:25:06 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pRenderPass = anv_render_pass_to_handle(pass);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-10 12:33:04 -07:00
|
|
|
VkResult anv_DestroyRenderPass(
|
|
|
|
|
VkDevice _device,
|
2015-07-14 11:21:01 -07:00
|
|
|
VkRenderPass _pass)
|
2015-07-10 12:33:04 -07:00
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-07-14 11:21:01 -07:00
|
|
|
ANV_FROM_HANDLE(anv_render_pass, pass, _pass);
|
2015-07-10 12:33:04 -07:00
|
|
|
|
2015-07-15 15:02:47 -07:00
|
|
|
for (uint32_t i = 0; i < pass->subpass_count; i++) {
|
|
|
|
|
/* In VkSubpassCreateInfo, each of the attachment arrays may be null.
|
|
|
|
|
* Don't free the null arrays.
|
|
|
|
|
*/
|
|
|
|
|
struct anv_subpass *subpass = &pass->subpasses[i];
|
|
|
|
|
|
2015-07-15 15:19:59 -07:00
|
|
|
anv_device_free(device, subpass->input_attachments);
|
|
|
|
|
anv_device_free(device, subpass->color_attachments);
|
|
|
|
|
anv_device_free(device, subpass->resolve_attachments);
|
2015-07-10 20:18:52 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-14 11:21:01 -07:00
|
|
|
anv_device_free(device, pass);
|
2015-07-10 12:33:04 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-07 17:11:35 -07:00
|
|
|
VkResult anv_GetRenderAreaGranularity(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
VkRenderPass renderPass,
|
|
|
|
|
VkExtent2D* pGranularity)
|
|
|
|
|
{
|
|
|
|
|
*pGranularity = (VkExtent2D) { 1, 1 };
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-15 22:04:15 -07:00
|
|
|
void vkCmdDbgMarkerBegin(
|
|
|
|
|
VkCmdBuffer cmdBuffer,
|
|
|
|
|
const char* pMarker)
|
|
|
|
|
__attribute__ ((visibility ("default")));
|
|
|
|
|
|
|
|
|
|
void vkCmdDbgMarkerEnd(
|
|
|
|
|
VkCmdBuffer cmdBuffer)
|
|
|
|
|
__attribute__ ((visibility ("default")));
|
|
|
|
|
|
|
|
|
|
void vkCmdDbgMarkerBegin(
|
|
|
|
|
VkCmdBuffer cmdBuffer,
|
|
|
|
|
const char* pMarker)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void vkCmdDbgMarkerEnd(
|
|
|
|
|
VkCmdBuffer cmdBuffer)
|
|
|
|
|
{
|
|
|
|
|
}
|