1
0
mirror of https://github.com/Yours3lf/rpi-vk-driver.git synced 2024-12-13 01:08:53 +01:00
rpi-vk-driver/driver/resource.c

506 lines
13 KiB
C
Raw Normal View History

#include "common.h"
2018-10-15 23:37:09 +02:00
#include "kernel/vc4_packet.h"
/*
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkCreateImageView
*/
2019-09-30 00:52:21 +02:00
VkResult rpi_vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView)
2018-10-15 23:37:09 +02:00
{
assert(device);
assert(pCreateInfo);
assert(pView);
_imageView* view = ALLOCATE(sizeof(_imageView), 1, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2018-10-15 23:37:09 +02:00
if(!view)
{
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
view->image = pCreateInfo->image;
view->viewType = pCreateInfo->viewType;
view->interpretedFormat = pCreateInfo->format;
view->swizzle = pCreateInfo->components;
view->subresourceRange = pCreateInfo->subresourceRange;
*pView = view;
return VK_SUCCESS;
}
/*
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkCreateBuffer
*/
2019-09-30 00:52:21 +02:00
VkResult rpi_vkCreateBuffer(VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer)
2018-10-15 23:37:09 +02:00
{
assert(device);
assert(pCreateInfo);
assert(pBuffer);
_buffer* buf = ALLOCATE(sizeof(_buffer), 1, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2018-10-15 23:37:09 +02:00
if(!buf)
{
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
buf->size = pCreateInfo->size;
buf->usage = pCreateInfo->usage;
buf->boundMem = 0;
2020-04-26 21:21:18 +02:00
buf->alignment = ARM_PAGE_SIZE;
2019-09-08 00:30:52 +02:00
buf->alignedSize = getBOAlignedSize(buf->size, ARM_PAGE_SIZE);
2018-10-15 23:37:09 +02:00
*pBuffer = buf;
return VK_SUCCESS;
}
/*
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkGetBufferMemoryRequirements
*/
2019-09-30 00:52:21 +02:00
void rpi_vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements)
2018-10-15 23:37:09 +02:00
{
assert(device);
assert(buffer);
assert(pMemoryRequirements);
pMemoryRequirements->alignment = ((_buffer*)buffer)->alignment;
2019-09-08 00:30:52 +02:00
pMemoryRequirements->size = getBOAlignedSize(((_buffer*)buffer)->size, ARM_PAGE_SIZE);
//there's only one memory type so that's gonna be it...
pMemoryRequirements->memoryTypeBits = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
2018-10-15 23:37:09 +02:00
}
2019-09-30 00:52:21 +02:00
VKAPI_ATTR void VKAPI_CALL rpi_vkGetBufferMemoryRequirements2(
2019-04-22 15:58:27 +02:00
VkDevice device,
const VkBufferMemoryRequirementsInfo2* pInfo,
VkMemoryRequirements2* pMemoryRequirements)
{
assert(device);
assert(pInfo);
assert(pMemoryRequirements);
2019-09-30 02:13:55 +02:00
rpi_vkGetBufferMemoryRequirements(device, pInfo->buffer, &pMemoryRequirements->memoryRequirements);
2019-04-22 15:58:27 +02:00
}
2018-10-15 23:37:09 +02:00
/*
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkBindBufferMemory
*/
2019-09-30 00:52:21 +02:00
VkResult rpi_vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset)
2018-10-15 23:37:09 +02:00
{
assert(device);
assert(buffer);
assert(memory);
_buffer* buf = buffer;
_deviceMemory* mem = memory;
assert(!buf->boundMem);
assert(memoryOffset < mem->size);
assert(memoryOffset % buf->alignment == 0);
assert(buf->alignedSize <= mem->size - memoryOffset);
buf->boundMem = mem;
buf->boundOffset = memoryOffset;
return VK_SUCCESS;
}
2019-09-30 00:52:21 +02:00
void rpi_vkDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks* pAllocator)
2018-10-15 23:37:09 +02:00
{
assert(device);
_buffer* buf = buffer;
2019-02-10 00:53:32 +01:00
if(buf)
{
FREE(buf);
}
2018-10-15 23:37:09 +02:00
}
2019-09-30 00:52:21 +02:00
void rpi_vkDestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks* pAllocator)
2018-10-15 23:37:09 +02:00
{
assert(device);
_imageView* view = imageView;
2019-02-10 00:53:32 +01:00
if(view)
{
FREE(view);
}
2018-10-15 23:37:09 +02:00
}
2018-10-18 22:17:02 +02:00
/*
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkCreateBufferView
*/
2019-09-30 00:52:21 +02:00
VKAPI_ATTR VkResult VKAPI_CALL rpi_vkCreateBufferView(
2018-10-18 22:17:02 +02:00
VkDevice device,
const VkBufferViewCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkBufferView* pView)
{
assert(device);
assert(pCreateInfo);
assert(pView);
_bufferView* bv = ALLOCATE(sizeof(_bufferView), 1, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2018-10-18 22:17:02 +02:00
2019-02-08 01:33:51 +01:00
if(!bv)
{
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
2018-10-18 22:17:02 +02:00
bv->buffer = pCreateInfo->buffer;
bv->format = pCreateInfo->format;
bv->offset = pCreateInfo->offset;
bv->range = pCreateInfo->range;
*pView = bv;
2019-02-08 01:33:51 +01:00
return VK_SUCCESS;
2018-10-18 22:17:02 +02:00
}
/*
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkDestroyBufferView
*/
2019-09-30 00:52:21 +02:00
VKAPI_ATTR void VKAPI_CALL rpi_vkDestroyBufferView(
2018-10-18 22:17:02 +02:00
VkDevice device,
VkBufferView bufferView,
const VkAllocationCallbacks* pAllocator)
{
assert(device);
_bufferView* bv = bufferView;
2019-02-10 00:53:32 +01:00
if(bv)
{
FREE(bv);
}
2018-10-18 22:17:02 +02:00
}
/*
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkCreateImage
*/
2019-09-30 00:52:21 +02:00
VKAPI_ATTR VkResult VKAPI_CALL rpi_vkCreateImage(
2018-10-18 22:17:02 +02:00
VkDevice device,
const VkImageCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkImage* pImage)
{
assert(device);
assert(pCreateInfo);
assert(pImage);
_image* i = ALLOCATE(sizeof(_image), 1, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2018-10-18 22:17:02 +02:00
if(!i)
{
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
i->flags = pCreateInfo->flags;
i->type = pCreateInfo->imageType;
i->fb = 0; //needed for modeset
2018-10-18 22:17:02 +02:00
i->width = pCreateInfo->extent.width;
i->height = pCreateInfo->extent.height;
i->depth = pCreateInfo->extent.depth;
i->miplevels = pCreateInfo->mipLevels;
2020-03-01 20:11:31 +01:00
memset(i->levelOffsets, 0, sizeof(uint32_t) * 11);
i->samples = pCreateInfo->samples;
2018-10-18 22:17:02 +02:00
i->layers = pCreateInfo->arrayLayers;
i->size = 0;
i->stride = 0;
2018-10-18 22:17:02 +02:00
i->usageBits = pCreateInfo->usage;
i->format = pCreateInfo->format;
i->imageSpace = 0;
i->tiling = 0;
if(pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR)
{
i->tiling = VC4_TILING_FORMAT_LINEAR;
}
else
{
2020-05-15 19:58:21 +02:00
uint32_t isLT = isLTformat(getFormatBpp(i->format), i->width, i->height);
if(!isLT)
{
i->tiling = VC4_TILING_FORMAT_T;
}
else
{
i->tiling = VC4_TILING_FORMAT_LT;
}
}
i->layout = pCreateInfo->initialLayout;
i->boundMem = 0;
i->boundOffset = 0;
2020-04-26 21:21:18 +02:00
i->alignment = ARM_PAGE_SIZE;
2018-10-18 22:17:02 +02:00
i->concurrentAccess = pCreateInfo->sharingMode; //TODO?
i->numQueueFamiliesWithAccess = pCreateInfo->queueFamilyIndexCount;
if(i->numQueueFamiliesWithAccess > 0)
{
i->queueFamiliesWithAccess = ALLOCATE(sizeof(uint32_t) * i->numQueueFamiliesWithAccess, 1, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2018-10-18 22:17:02 +02:00
if(!i->queueFamiliesWithAccess)
2019-02-08 01:33:51 +01:00
{
2018-10-18 22:17:02 +02:00
return VK_ERROR_OUT_OF_HOST_MEMORY;
2019-02-08 01:33:51 +01:00
}
2018-10-18 22:17:02 +02:00
memcpy(i->queueFamiliesWithAccess, pCreateInfo->pQueueFamilyIndices, sizeof(uint32_t) * i->numQueueFamiliesWithAccess);
}
i->preTransformMode = 0;
i->compositeAlpha = 0;
i->presentMode = 0;
i->clipped = 0;
2018-10-18 22:17:02 +02:00
*pImage = i;
return VK_SUCCESS;
}
/*
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkDestroyImage
*/
2019-09-30 00:52:21 +02:00
VKAPI_ATTR void VKAPI_CALL rpi_vkDestroyImage(
2018-10-18 22:17:02 +02:00
VkDevice device,
VkImage image,
const VkAllocationCallbacks* pAllocator)
{
assert(device);
_image* i = image;
2019-02-09 17:18:15 +01:00
if(i)
{
if(i->numQueueFamiliesWithAccess > 0)
{
FREE(i->queueFamiliesWithAccess);
}
2019-02-10 00:53:32 +01:00
FREE(i);
2019-02-09 17:18:15 +01:00
}
2018-10-18 22:17:02 +02:00
}
/*
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkGetImageMemoryRequirements
*/
2019-09-30 00:52:21 +02:00
VKAPI_ATTR void VKAPI_CALL rpi_vkGetImageMemoryRequirements(
2018-10-18 22:17:02 +02:00
VkDevice device,
VkImage image,
VkMemoryRequirements* pMemoryRequirements)
{
assert(device);
assert(image);
assert(pMemoryRequirements);
_image* i = image;
uint32_t bpp = getFormatBpp(i->format);
uint32_t utileW, utileH;
getUTileDimensions(bpp, &utileW, &utileH);
2020-05-15 20:55:27 +02:00
uint32_t w = i->width;
uint32_t h = i->height;
if(i->format == VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK)
{
w = (w + 3) >> 2;
h = (h + 3) >> 2;
}
uint32_t potW = getPow2Pad(w);
uint32_t potH = getPow2Pad(h);
uint32_t offset = 0;
uint32_t sizes[11];
uint32_t strides[11];
for(int c = i->miplevels - 1; c >= 0; c--)
{
2020-05-15 20:55:27 +02:00
uint32_t mipW, mipH;
if(!c)
{
2020-05-15 20:55:27 +02:00
mipW = w;
mipH = h;
}
2020-05-15 20:55:27 +02:00
else
{
2020-05-15 20:55:27 +02:00
mipW = max(potW >> c, 1);
mipH = max(potH >> c, 1);
}
2020-05-15 20:55:27 +02:00
if(i->tiling == VC4_TILING_FORMAT_LINEAR)
{
2020-05-15 20:55:27 +02:00
if(i->samples > 1)
{
mipW = roundUp(mipW, 32);
mipH = roundUp(mipH, 32);
}
else
{
mipW = roundUp(mipW, utileW);
}
}
else
{
uint32_t isMipLT = isLTformat(bpp, mipW, mipH);
if(isMipLT)
{
mipW = roundUp(mipW, utileW);
mipH = roundUp(mipH, utileH);
}
else
{
mipW = roundUp(mipW, utileW * 8);
mipH = roundUp(mipH, utileH * 8);
}
}
2020-03-01 20:11:31 +01:00
2020-05-15 20:55:27 +02:00
i->levelOffsets[c] = offset;
2020-05-15 20:55:27 +02:00
strides[c] = (mipW * bpp * max(i->samples, 1)) >> 3;
sizes[c] = mipH * strides[c];
2020-05-15 20:55:27 +02:00
offset += sizes[c];
2020-03-01 20:11:31 +01:00
}
2020-05-15 20:55:27 +02:00
uint32_t levelZeroOffset = roundUp(i->levelOffsets[0], ARM_PAGE_SIZE) - i->levelOffsets[0];
2020-05-15 20:55:27 +02:00
if(levelZeroOffset)
{
2020-05-15 20:55:27 +02:00
for(uint32_t c = 0; c < i->miplevels; ++c)
{
i->levelOffsets[c] += levelZeroOffset;
}
}
2020-05-15 20:55:27 +02:00
i->size = getBOAlignedSize(sizes[0] + i->levelOffsets[0], ARM_PAGE_SIZE) * i->layers;
i->stride = strides[0];
2020-03-01 20:11:31 +01:00
pMemoryRequirements->alignment = ARM_PAGE_SIZE;
2020-03-01 20:11:31 +01:00
pMemoryRequirements->memoryTypeBits = memoryTypes[0].propertyFlags; //TODO
pMemoryRequirements->size = i->size;
2018-10-18 22:17:02 +02:00
}
/*
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkBindImageMemory
*/
2019-09-30 00:52:21 +02:00
VKAPI_ATTR VkResult VKAPI_CALL rpi_vkBindImageMemory(
2018-10-18 22:17:02 +02:00
VkDevice device,
VkImage image,
VkDeviceMemory memory,
VkDeviceSize memoryOffset)
{
assert(device);
assert(image);
assert(memory);
_image* i = image;
_deviceMemory* m = memory;
assert(!i->boundMem);
assert(memoryOffset < m->size);
assert(memoryOffset % i->alignment == 0);
assert(i->size <= m->size - memoryOffset);
i->boundMem = m;
i->boundOffset = memoryOffset;
2018-10-18 22:17:02 +02:00
2020-04-26 21:21:18 +02:00
//TODO this is necessary, but maybe don't do it here?
if(i->tiling == VC4_TILING_FORMAT_LINEAR)
{
int ret = vc4_bo_set_tiling(controlFd, i->boundMem->bo, DRM_FORMAT_MOD_LINEAR); assert(ret);
}
else if(i->tiling == VC4_TILING_FORMAT_T || i->tiling == VC4_TILING_FORMAT_LT)
{
int ret = vc4_bo_set_tiling(controlFd, i->boundMem->bo, DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED); assert(ret);
}
2018-10-18 22:17:02 +02:00
return VK_SUCCESS;
}
2019-04-22 15:58:27 +02:00
2019-09-30 00:52:21 +02:00
VKAPI_ATTR VkResult VKAPI_CALL rpi_vkBindBufferMemory2(
2019-04-22 15:58:27 +02:00
VkDevice device,
uint32_t bindInfoCount,
const VkBindBufferMemoryInfo* pBindInfos)
{
2019-09-08 00:30:52 +02:00
assert(device);
assert(pBindInfos);
VkResult ret = VK_SUCCESS;
for(uint32_t c = 0; c < bindInfoCount; ++c)
{
2019-09-30 02:13:55 +02:00
VkResult res = rpi_vkBindBufferMemory(device, pBindInfos[c].buffer, pBindInfos[c].memory, pBindInfos[c].memoryOffset);
2019-09-08 00:30:52 +02:00
if(res != VK_SUCCESS)
{
ret = res;
}
}
return ret;
2019-04-22 15:58:27 +02:00
}
2019-09-30 00:52:21 +02:00
VKAPI_ATTR void VKAPI_CALL rpi_vkGetImageMemoryRequirements2(
2019-04-22 15:58:27 +02:00
VkDevice device,
const VkImageMemoryRequirementsInfo2* pInfo,
VkMemoryRequirements2* pMemoryRequirements)
{
2019-09-08 00:30:52 +02:00
assert(device);
assert(pInfo);
assert(pMemoryRequirements);
2019-09-30 02:13:55 +02:00
rpi_vkGetImageMemoryRequirements(device, pInfo->image, pMemoryRequirements);
2019-04-22 15:58:27 +02:00
}
2019-09-30 00:52:21 +02:00
VKAPI_ATTR VkResult VKAPI_CALL rpi_vkBindImageMemory2(
2019-04-22 15:58:27 +02:00
VkDevice device,
uint32_t bindInfoCount,
const VkBindImageMemoryInfo* pBindInfos)
{
2019-09-08 00:30:52 +02:00
assert(device);
assert(pBindInfos);
VkResult ret = VK_SUCCESS;
for(uint32_t c = 0; c < bindInfoCount; ++c)
{
2019-09-30 02:13:55 +02:00
VkResult res = rpi_vkBindImageMemory(device, pBindInfos[c].image, pBindInfos[c].memory, pBindInfos[c].memoryOffset);
2019-09-08 00:30:52 +02:00
if(res != VK_SUCCESS)
{
ret = res;
}
}
return ret;
2019-04-22 15:58:27 +02:00
}
2019-09-30 00:52:21 +02:00
VKAPI_ATTR void VKAPI_CALL rpi_vkCmdPushConstants(
2019-04-22 15:58:27 +02:00
VkCommandBuffer commandBuffer,
VkPipelineLayout layout,
VkShaderStageFlags stageFlags,
uint32_t offset,
uint32_t size,
const void* pValues)
{
assert(commandBuffer);
assert(layout);
2019-04-22 15:58:27 +02:00
_pipelineLayout* pl = layout;
_commandBuffer* cb = commandBuffer;
if(stageFlags & VK_SHADER_STAGE_VERTEX_BIT)
{
memcpy(cb->pushConstantBufferVertex + offset, pValues, size);
}
if(stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT)
{
memcpy(cb->pushConstantBufferPixel + offset, pValues, size);
}
cb->pushConstantDirty = 1;
2019-04-22 15:58:27 +02:00
}
2019-09-30 00:52:21 +02:00
VKAPI_ATTR void VKAPI_CALL rpi_vkGetImageSubresourceLayout(
2019-04-22 15:58:27 +02:00
VkDevice device,
VkImage image,
const VkImageSubresource* pSubresource,
VkSubresourceLayout* pLayout)
{
2019-09-08 00:30:52 +02:00
//TODO
2019-04-22 15:58:27 +02:00
}