From 68a41c6a40cd7c14f5307d44ea50a9455c073f12 Mon Sep 17 00:00:00 2001 From: Unknown <0.tamas.marton@gmail.com> Date: Tue, 18 Sep 2018 21:22:43 +0100 Subject: [PATCH] implemented more of the vk driver for the triangle example --- driver/common.c | 157 +++++++++++++++++++++++++++++++++++++ driver/common.h | 85 +++++++++++++++++--- driver/modeset.h | 26 +----- driver/vkExt.h | 10 +++ driver/wsi.c | 1 + test/triangle/triangle.cpp | 16 ++-- 6 files changed, 253 insertions(+), 42 deletions(-) diff --git a/driver/common.c b/driver/common.c index 22f9ad2..865cdb9 100644 --- a/driver/common.c +++ b/driver/common.c @@ -386,12 +386,88 @@ VkResult vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCrea assert(pAllocator == 0); //TODO allocators not supported yet + //just copy all data from create info + //we'll later need to bake the control list based on this + _renderpass* rp = malloc(sizeof(_renderpass)); if(!rp) { return VK_ERROR_OUT_OF_HOST_MEMORY; } + rp->numAttachments = pCreateInfo->attachmentCount; + rp->attachments = malloc(sizeof(VkAttachmentDescription)*rp->numAttachments); + if(!rp->attachments) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + memcpy(rp->attachments, pCreateInfo->pAttachments, sizeof(VkAttachmentDescription)*rp->numAttachments); + + rp->numSubpasses = pCreateInfo->subpassCount; + rp->subpasses = malloc(sizeof(VkSubpassDescription)*rp->numSubpasses); + if(!rp->subpasses) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + for(int c = 0; c < rp->numSubpasses; ++c) + { + rp->subpasses[c].flags = pCreateInfo->pSubpasses[c].flags; + rp->subpasses[c].pipelineBindPoint = pCreateInfo->pSubpasses[c].pipelineBindPoint; + rp->subpasses[c].inputAttachmentCount = pCreateInfo->pSubpasses[c].inputAttachmentCount; + rp->subpasses[c].colorAttachmentCount = pCreateInfo->pSubpasses[c].colorAttachmentCount; + rp->subpasses[c].preserveAttachmentCount = pCreateInfo->pSubpasses[c].preserveAttachmentCount; + + rp->subpasses[c].pInputAttachments = malloc(sizeof(VkAttachmentReference)*rp->subpasses[c].inputAttachmentCount); + if(!rp->subpasses[c].pInputAttachments) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + memcpy(rp->subpasses[c].pInputAttachments, pCreateInfo->pSubpasses[c].pInputAttachments, sizeof(VkAttachmentReference)*rp->subpasses[c].inputAttachmentCount); + + rp->subpasses[c].pColorAttachments = malloc(sizeof(VkAttachmentReference)*rp->subpasses[c].colorAttachmentCount); + if(!rp->subpasses[c].pColorAttachments) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + rp->subpasses[c].pResolveAttachments = malloc(sizeof(VkAttachmentReference)*rp->subpasses[c].colorAttachmentCount); + if(!rp->subpasses[c].pResolveAttachments) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + memcpy(rp->subpasses[c].pColorAttachments, pCreateInfo->pSubpasses[c].pColorAttachments, sizeof(VkAttachmentReference)*rp->subpasses[c].colorAttachmentCount); + memcpy(rp->subpasses[c].pResolveAttachments, pCreateInfo->pSubpasses[c].pResolveAttachments, sizeof(VkAttachmentReference)*rp->subpasses[c].colorAttachmentCount); + + rp->subpasses[c].pDepthStencilAttachment = malloc(sizeof(VkAttachmentReference)); + if(!rp->subpasses[c].pDepthStencilAttachment) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + memcpy(rp->subpasses[c].pDepthStencilAttachment, pCreateInfo->pSubpasses[c].pDepthStencilAttachment, sizeof(VkAttachmentReference)); + + rp->subpasses[c].pPreserveAttachments = malloc(sizeof(uint32_t)*rp->subpasses[c].preserveAttachmentCount); + if(!rp->subpasses[c].pPreserveAttachments) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + memcpy(rp->subpasses[c].pPreserveAttachments, pCreateInfo->pSubpasses[c].pPreserveAttachments, sizeof(uint32_t)*rp->subpasses[c].preserveAttachmentCount); + } + + rp->numSubpassDependencies = pCreateInfo->dependencyCount; + rp->subpassDependencies = malloc(sizeof(VkSubpassDependency)*rp->numSubpassDependencies); + if(!rp->subpassDependencies) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + memcpy(rp->subpassDependencies, pCreateInfo->pDependencies, sizeof(VkSubpassDependency)*rp->numSubpassDependencies); + *pRenderPass = rp; return VK_SUCCESS; @@ -402,6 +478,29 @@ VkResult vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCrea */ VkResult vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView) { + assert(device); + assert(pCreateInfo); + assert(pView); + + assert(pAllocator == 0); //TODO + + _imageView* view = malloc(sizeof(_imageView)); + + 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; + + //TODO errors/validation + + *pView = view; + return VK_SUCCESS; } @@ -410,6 +509,64 @@ VkResult vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreate */ VkResult vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer) { + assert(device); + assert(pCreateInfo); + assert(pFramebuffer); + + assert(pAllocator == 0); //TODO + + _framebuffer* fb = malloc(sizeof(_framebuffer)); + + if(!fb) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + fb->renderpass = pCreateInfo->renderPass; + + fb->numAttachmentViews = pCreateInfo->attachmentCount; + fb->attachmentViews = malloc(sizeof(_imageView) * fb->numAttachmentViews); + + if(!fb->attachmentViews) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + memcpy(fb->attachmentViews, pCreateInfo->pAttachments, sizeof(_imageView) * fb->numAttachmentViews); + + fb->width = pCreateInfo->width; + fb->height = pCreateInfo->height; + fb->layers = pCreateInfo->layers; + + //TODO errors/validation + + *pFramebuffer = fb; + + return VK_SUCCESS; +} + + +VkResult vkCreateShaderModuleFromRpiAssemblyKHR(VkDevice device, uint32_t numBytes, char* byteStream, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule) +{ + assert(device); + assert(numBytes > 0); + assert(byteStream); + assert(pShaderModule); + + assert(pAllocator == 0); //TODO + + _shaderModule* shader = malloc(sizeof(_shaderModule)); + + if(!shader) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + uint32_t size = numBytes; + shader->bo = vc4_bo_alloc_shader(controlFd, byteStream, &size); + + *pShaderModule = shader; + return VK_SUCCESS; } diff --git a/driver/common.h b/driver/common.h index b81810f..bcf465a 100644 --- a/driver/common.h +++ b/driver/common.h @@ -21,7 +21,6 @@ #include #include -#include "modeset.h" #include "kernelInterface.h" #include "ControlListUtil.h" @@ -104,17 +103,27 @@ typedef struct VkDevice_T int numQueues[numQueueFamilies]; } _device; -typedef struct VkSwapchain_T -{ - _image* images; - uint32_t numImages; - uint32_t backbufferIdx; - VkSurfaceKHR surface; -} _swapchain; - typedef struct VkRenderPass_T { - //TODO + //collection of: + //attachments, subpasses, dependencies between subpasses + //describes how attachments are used in subpasses + + //attachment describes: + //format, sample count, how contents are treated at start/end of a renderpass + + //subpasses render to same dimensions and fragments + + //framebuffer objects specify views for attachements + + VkAttachmentDescription* attachments; + uint32_t numAttachments; + + VkSubpassDescription* subpasses; + uint32_t numSubpasses; + + VkSubpassDependency* subpassDependencies; + uint32_t numSubpassDependencies; } _renderpass; typedef struct VkDeviceMemory_T @@ -136,6 +145,62 @@ typedef struct VkBuffer_T uint32_t alignedSize; } _buffer; +typedef struct VkImage_T +{ + uint32_t handle; + uint32_t fb; //needed for swapchain + uint32_t width, height, depth; + uint32_t paddedWidth, paddedHeight; + uint32_t miplevels, samples; + uint32_t layers; //number of views for multiview/stereo + uint32_t size; //overall size including padding + uint32_t stride; //the number of bytes from one row of pixels in memory to the next row of pixels in memory (aka pitch) + uint32_t usageBits; + uint32_t format; + uint32_t imageSpace; + uint32_t tiling; + uint32_t needToClear; + uint32_t clearColor[2]; + uint32_t layout; + uint32_t concurrentAccess; //TODO + uint32_t numQueueFamiliesWithAccess; + uint32_t* queueFamiliesWithAccess; + uint32_t preTransformMode; + uint32_t compositeAlpha; + uint32_t presentMode; + uint32_t clipped; +} _image; + +typedef struct VkImageView_T +{ + _image* image; + VkImageViewType viewType; + VkFormat interpretedFormat; + VkComponentMapping swizzle; + VkImageSubresourceRange subresourceRange; +} _imageView; + +typedef struct VkSwapchain_T +{ + _image* images; + uint32_t numImages; + uint32_t backbufferIdx; + VkSurfaceKHR surface; +} _swapchain; + +typedef struct VkFramebuffer_T +{ + _renderpass* renderpass; + _imageView* attachmentViews; + uint32_t numAttachmentViews; + uint32_t width, height, layers; +} _framebuffer; + +typedef struct VkShaderModule_T +{ + uint32_t bo; +} _shaderModule; + void getPaddedTextureDimensionsT(uint32_t width, uint32_t height, uint32_t bpp, uint32_t* paddedWidth, uint32_t* paddedHeight); uint32_t getFormatBpp(VkFormat f); uint32_t packVec4IntoABGR8(const float rgba[4]); diff --git a/driver/modeset.h b/driver/modeset.h index 0eef9c5..553d4f7 100644 --- a/driver/modeset.h +++ b/driver/modeset.h @@ -18,31 +18,7 @@ extern "C" { #include #include "CustomAssert.h" -typedef struct VkImage_T -{ - uint32_t handle; - uint32_t fb; //needed for swapchain - uint32_t width, height, depth; - uint32_t paddedWidth, paddedHeight; - uint32_t miplevels, samples; - uint32_t layers; //number of views for multiview/stereo - uint32_t size; //overall size including padding - uint32_t stride; //the number of bytes from one row of pixels in memory to the next row of pixels in memory (aka pitch) - uint32_t usageBits; - uint32_t format; - uint32_t imageSpace; - uint32_t tiling; - uint32_t needToClear; - uint32_t clearColor[2]; - uint32_t layout; - uint32_t concurrentAccess; //TODO - uint32_t numQueueFamiliesWithAccess; - uint32_t* queueFamiliesWithAccess; - uint32_t preTransformMode; - uint32_t compositeAlpha; - uint32_t presentMode; - uint32_t clipped; -} _image; +#include "common.h" typedef struct modeset_dev { struct modeset_dev *next; diff --git a/driver/vkExt.h b/driver/vkExt.h index 28921c4..d5aa736 100644 --- a/driver/vkExt.h +++ b/driver/vkExt.h @@ -21,12 +21,22 @@ typedef struct VkRpiSurfaceCreateInfoKHR { } VkRpiSurfaceCreateInfoKHR; //extension name something like: VK_KHR_rpi_surface +//extension that allows developers to create a surface to render to on Raspbian Stretch Lite VkResult vkCreateRpiSurfaceKHR( VkInstance instance, const VkRpiSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +//extension that allows developers to submit QPU assembly directly and thus hand optimise code +VkResult vkCreateShaderModuleFromRpiAssemblyKHR( + VkDevice device, + uint32_t numBytes, + char* byteStream, + const VkAllocationCallbacks* pAllocator, + VkShaderModule* pShaderModule + ); + #ifdef __cplusplus } diff --git a/driver/wsi.c b/driver/wsi.c index 3aa8d69..b9a12e2 100644 --- a/driver/wsi.c +++ b/driver/wsi.c @@ -1,4 +1,5 @@ #include "common.h" +#include "modeset.h" /* * Implementation of our RPI specific "extension" diff --git a/test/triangle/triangle.cpp b/test/triangle/triangle.cpp index 33858d4..d6cd3db 100644 --- a/test/triangle/triangle.cpp +++ b/test/triangle/triangle.cpp @@ -792,17 +792,19 @@ void CreateFramebuffer() printf("Frame buffers created\n"); } -VkShaderModule VulkanCreateShaderModule(VkDevice& device, char* code) +VkShaderModule VulkanCreateShaderModule(VkDevice& device, char* byteStream, uint32_t byteStreamSize) { - int codeSize = strlen(code); + VkShaderModule shaderModule; - VkShaderModuleCreateInfo shaderCreateInfo = {}; + /*VkShaderModuleCreateInfo shaderCreateInfo = {}; shaderCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; shaderCreateInfo.codeSize = codeSize; shaderCreateInfo.pCode = (const uint32_t*)code; - VkShaderModule shaderModule; - VkResult res = vkCreateShaderModule(device, &shaderCreateInfo, NULL, &shaderModule); + VkResult res = vkCreateShaderModule(device, &shaderCreateInfo, NULL, &shaderModule);*/ + + VkResult res = vkCreateShaderModuleFromRpiAssemblyKHR(device, byteStreamSize, byteStream, NULL, &shaderModule); + printf("Created shader\n"); return shaderModule; @@ -816,10 +818,10 @@ void CreateShaders() char* fptr = (char*)malloc(strlen(fragShader) + 1); memcpy(fptr, fragShader, strlen(fragShader) + 1); - vsModule = VulkanCreateShaderModule(device, vptr); + vsModule = VulkanCreateShaderModule(device, vptr, strlen(vptr)); assert(vsModule); - fsModule = VulkanCreateShaderModule(device, fptr); + fsModule = VulkanCreateShaderModule(device, fptr, strlen(fptr)); assert(fsModule); free(vptr);