From 8bdf16246fd714be2cf1dc311e2df3e6ae936c8d Mon Sep 17 00:00:00 2001 From: Unknown <0.tamas.marton@gmail.com> Date: Wed, 26 Sep 2018 21:59:00 +0100 Subject: [PATCH] added more of the draw call functionality --- driver/ControlListUtil.c | 5 +- driver/common.c | 117 +++++++++++++++++++++++++++++++------ driver/common.h | 54 ++++++++--------- driver/vkCaps.h | 8 +-- test/triangle/triangle.cpp | 12 ++-- 5 files changed, 139 insertions(+), 57 deletions(-) diff --git a/driver/ControlListUtil.c b/driver/ControlListUtil.c index 0439d1c..704b5e0 100644 --- a/driver/ControlListUtil.c +++ b/driver/ControlListUtil.c @@ -452,6 +452,7 @@ void clInsertClipWindow(ControlList* cl, *(uint32_t*)cl->nextFreeByte = moveBits(width, 16, 0) | moveBits(height, 16, 16); cl->nextFreeByte += 4; } +//viewport centre x/y coordinate void clInsertViewPortOffset(ControlList* cl, uint32_t x, //sint16 uint32_t y //sint16 @@ -477,8 +478,8 @@ void clInsertZMinMaxClippingPlanes(ControlList* cl, } void clInsertClipperXYScaling(ControlList* cl, - float width, //half height in 1/16 of pixel - float height //half width in 1/16 of pixel + float width, //half width in 1/16 of pixel + float height //half height in 1/16 of pixel ) { assert(cl); diff --git a/driver/common.c b/driver/common.c index c22412b..5d1f2e4 100644 --- a/driver/common.c +++ b/driver/common.c @@ -367,7 +367,7 @@ void vkCmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBegin if(cb->renderpass->attachments[c].loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { cb->fbo->attachmentViews[c].image->needToClear = 1; - cb->fbo->attachmentViews[c].image->clearColor = packVec4IntoABGR8(pRenderPassBegin->pClearValues->color.float32); + cb->fbo->attachmentViews[c].image->clearColor[0] = cb->fbo->attachmentViews[c].image->clearColor[1] = packVec4IntoABGR8(pRenderPassBegin->pClearValues->color.float32); } else if(isDepthStencilFormat(cb->renderpass->attachments[c].format) && cb->renderpass->attachments[c].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { @@ -414,6 +414,70 @@ void vkCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint3 //TODO } +uint32_t getDepthCompareOp(VkCompareOp op) +{ + switch(op) + { + case VK_COMPARE_OP_NEVER: + return V3D_COMPARE_FUNC_NEVER; + case VK_COMPARE_OP_LESS: + return V3D_COMPARE_FUNC_LESS; + case VK_COMPARE_OP_EQUAL: + return V3D_COMPARE_FUNC_EQUAL; + case VK_COMPARE_OP_LESS_OR_EQUAL: + return V3D_COMPARE_FUNC_LEQUAL; + case VK_COMPARE_OP_GREATER: + return V3D_COMPARE_FUNC_GREATER; + case VK_COMPARE_OP_NOT_EQUAL: + return V3D_COMPARE_FUNC_NOTEQUAL; + case VK_COMPARE_OP_GREATER_OR_EQUAL: + return V3D_COMPARE_FUNC_GEQUAL; + case VK_COMPARE_OP_ALWAYS: + return V3D_COMPARE_FUNC_ALWAYS; + default: + return -1; + } +} + +uint32_t getTopology(VkPrimitiveTopology topology) +{ + switch(topology) + { + case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: + return 0; + case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: + case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: + return 1; + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: + return 2; + default: + return -1; + } +} + +uint32_t getPrimitiveMode(VkPrimitiveTopology topology) +{ + switch(topology) + { + case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: + return V3D_PRIM_POINTS; + case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: + return V3D_PRIM_LINES; + case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: + return V3D_PRIM_LINE_STRIP; + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: + return V3D_PRIM_TRIANGLES; + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: + return V3D_PRIM_TRIANGLE_STRIP; + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: + return V3D_PRIM_TRIANGLE_FAN; + default: + return -1; + } +} + /* * https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkCmdDraw */ @@ -421,6 +485,14 @@ void vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t ins { assert(commandBuffer); + _commandBuffer* cb = commandBuffer; + _renderpass* rp = cb->renderpass; + _framebuffer* fb = cb->fbo; + + //TODO handle multiple attachments etc. + _image* i = fb->attachmentViews[rp->subpasses[cb->currentSubpass].pColorAttachments[0].attachment].image; + + //stuff needed to submit a draw call: //Tile Binning Mode Configuration clFit(commandBuffer, &commandBuffer->binCl, V3D21_TILE_BINNING_MODE_CONFIGURATION_length); @@ -438,32 +510,32 @@ void vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t ins clFit(commandBuffer, &commandBuffer->binCl, V3D21_PRIMITIVE_LIST_FORMAT_length); clInsertPrimitiveListFormat(&commandBuffer->binCl, 1, //16 bit - 2); //tris + getTopology(cb->graphicsPipeline->topology)); //tris //Clip Window clFit(commandBuffer, &commandBuffer->binCl, V3D21_CLIP_WINDOW_length); - clInsertClipWindow(&commandBuffer->binCl, width, height, 0, 0); + clInsertClipWindow(&commandBuffer->binCl, i->width, i->height, 0, 0); //Configuration Bits clFit(commandBuffer, &commandBuffer->binCl, V3D21_CONFIGURATION_BITS_length); clInsertConfigurationBits(&commandBuffer->binCl, - 1, //earlyz updates - 1, //earlyz enable - 1, //z updates - V3D_COMPARE_FUNC_ALWAYS, //depth compare func + 1, //TODO earlyz updates + 0, //TODO earlyz enable + 0, //TODO z updates + getDepthCompareOp(cb->graphicsPipeline->depthCompareOp), //depth compare func 0, 0, 0, 0, 0, - 0, //depth offset enable - 1, //clockwise - 1, //enable back facing primitives - 1); //enable front facing primitives + cb->graphicsPipeline->depthBiasEnable, //depth offset enable + cb->graphicsPipeline->frontFace == VK_FRONT_FACE_CLOCKWISE, //clockwise + cb->graphicsPipeline->cullMode & VK_CULL_MODE_BACK_BIT, //enable back facing primitives + cb->graphicsPipeline->cullMode & VK_CULL_MODE_FRONT_BIT); //enable front facing primitives - //Depth Offset + //TODO Depth Offset clFit(commandBuffer, &commandBuffer->binCl, V3D21_DEPTH_OFFSET_length); - clInsertDepthOffset(&commandBuffer->binCl, 0, 0); + clInsertDepthOffset(&commandBuffer->binCl, cb->graphicsPipeline->depthBiasConstantFactor, cb->graphicsPipeline->depthBiasSlopeFactor); //Point size clFit(commandBuffer, &commandBuffer->binCl, V3D21_POINT_SIZE_length); @@ -471,31 +543,38 @@ void vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t ins //Line width clFit(commandBuffer, &commandBuffer->binCl, V3D21_LINE_WIDTH_length); - clInsertLineWidth(&commandBuffer->binCl, 1.0f); + clInsertLineWidth(&commandBuffer->binCl, cb->graphicsPipeline->lineWidth); + //TODO why flipped??? //Clipper XY Scaling clFit(commandBuffer, &commandBuffer->binCl, V3D21_CLIPPER_XY_SCALING_length); - clInsertClipperXYScaling(&commandBuffer->binCl, 1.0f, 1.0f); + clInsertClipperXYScaling(&commandBuffer->binCl, (float)(i->width) * 0.5f * 16.0f, -1.0f * (float)(i->height) * 0.5f * 16.0f); + //TODO how is this calculated? + //seems to go from -1.0 .. 1.0 to 0.0 .. 1.0 + //eg. x * 0.5 + 0.5 + //cb->graphicsPipeline->minDepthBounds; //Clipper Z Scale and Offset clFit(commandBuffer, &commandBuffer->binCl, V3D21_CLIPPER_Z_SCALE_AND_OFFSET_length); - clInsertClipperZScaleOffset(&commandBuffer->binCl, 1.0f, 1.0f); + clInsertClipperZScaleOffset(&commandBuffer->binCl, 0.5f, 0.5f); //Viewport Offset clFit(commandBuffer, &commandBuffer->binCl, V3D21_VIEWPORT_OFFSET_length); - clInsertViewPortOffset(&commandBuffer->binCl, 0, 0); + clInsertViewPortOffset(&commandBuffer->binCl, i->width >> 1, i->height >> 1); + //TODO? //Flat Shade Flags clFit(commandBuffer, &commandBuffer->binCl, V3D21_FLAT_SHADE_FLAGS_length); clInsertFlatShadeFlags(&commandBuffer->binCl, 0); + //TODO how to get address? //GL Shader State clFit(commandBuffer, &commandBuffer->binCl, V3D21_GL_SHADER_STATE_length); - clInsertShaderState(&commandBuffer->binCl, 0, 0, 0); + clInsertShaderState(&commandBuffer->binCl, 0, 0, cb->graphicsPipeline->vertexAttributeDescriptionCount); //Vertex Array Primitives (draw call) clFit(commandBuffer, &commandBuffer->binCl, V3D21_VERTEX_ARRAY_PRIMITIVES_length); - clInsertVertexArrayPrimitives(&commandBuffer->binCl, 0, 0, V3D_PRIM_TRIANGLES); + clInsertVertexArrayPrimitives(&commandBuffer->binCl, firstVertex, vertexCount, getPrimitiveMode(cb->graphicsPipeline->topology)); //Insert image handle index clFit(commandBuffer, &commandBuffer->handlesCl, 4); diff --git a/driver/common.h b/driver/common.h index aa11630..572700b 100644 --- a/driver/common.h +++ b/driver/common.h @@ -62,33 +62,6 @@ typedef enum commandBufferState CMDBUF_STATE_LAST } commandBufferState; -typedef struct VkCommandBuffer_T -{ - //Recorded commands include commands to bind pipelines and descriptor sets to the command buffer, commands to modify dynamic state, commands to draw (for graphics rendering), - //commands to dispatch (for compute), commands to execute secondary command buffers (for primary command buffers only), commands to copy buffers and images, and other commands - - struct drm_vc4_submit_cl submitCl; - - ControlList binCl; - ControlList shaderRecCl; - uint32_t shaderRecCount; - ControlList uniformsCl; - ControlList handlesCl; - commandBufferState state; - VkCommandBufferUsageFlags usageFlags; - _commandPool* cp; - - VkRect2D renderArea; - _renderpass* renderpass; - _framebuffer* fbo; - uint32_t currentSubpass; - _pipeline* graphicsPipeline; - _pipeline* computePipeline; - - uint32_t vertexBufferOffsets[VkPhysicalDeviceLimits::maxVertexInputBindings]; - _buffer* vertexBuffers[VkPhysicalDeviceLimits::maxVertexInputBindings]; -} _commandBuffer; - typedef struct VkInstance_T { //supposedly this should contain all the enabled layers? @@ -264,6 +237,33 @@ typedef struct VkPipeline_T uint32_t subpass; } _pipeline; +typedef struct VkCommandBuffer_T +{ + //Recorded commands include commands to bind pipelines and descriptor sets to the command buffer, commands to modify dynamic state, commands to draw (for graphics rendering), + //commands to dispatch (for compute), commands to execute secondary command buffers (for primary command buffers only), commands to copy buffers and images, and other commands + + struct drm_vc4_submit_cl submitCl; + + ControlList binCl; + ControlList shaderRecCl; + uint32_t shaderRecCount; + ControlList uniformsCl; + ControlList handlesCl; + commandBufferState state; + VkCommandBufferUsageFlags usageFlags; + _commandPool* cp; + + VkRect2D renderArea; + _renderpass* renderpass; + _framebuffer* fbo; + uint32_t currentSubpass; + _pipeline* graphicsPipeline; + _pipeline* computePipeline; + + uint32_t vertexBufferOffsets[8]; + _buffer* vertexBuffers[8]; +} _commandBuffer; + 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/vkCaps.h b/driver/vkCaps.h index f3058c3..a8434d2 100644 --- a/driver/vkCaps.h +++ b/driver/vkCaps.h @@ -35,8 +35,8 @@ static VkPhysicalDeviceLimits _limits = .maxDescriptorSetSampledImages = 98304, .maxDescriptorSetStorageImages = 98304, .maxDescriptorSetInputAttachments = 8, //TODO - .maxVertexInputAttributes = 32, - .maxVertexInputBindings = 32, + .maxVertexInputAttributes = 8, + .maxVertexInputBindings = 8, .maxVertexInputAttributeOffset = 2047, .maxVertexInputBindingStride = 2048, .maxVertexOutputComponents = 128, @@ -103,9 +103,9 @@ static VkPhysicalDeviceLimits _limits = .maxCullDistances = 8, .maxCombinedClipAndCullDistances = 8, .discreteQueuePriorities = 1, - .pointSizeRange = {1, 189.875}, + .pointSizeRange = {1, 1}, .lineWidthRange = {0.5, 10}, - .pointSizeGranularity = 0.125, + .pointSizeGranularity = 0.0, .lineWidthGranularity = 0.125, .strictLines = 0, //TODO .standardSampleLocations = 1, diff --git a/test/triangle/triangle.cpp b/test/triangle/triangle.cpp index 367d11f..a0a8501 100644 --- a/test/triangle/triangle.cpp +++ b/test/triangle/triangle.cpp @@ -109,6 +109,7 @@ VkBuffer vertexBuffer; VkDeviceMemory vertexBufferMemory; VkPhysicalDeviceMemoryProperties pdmp; std::vector views; //? +VkSurfaceFormatKHR swapchainFormat; uint32_t graphicsQueueFamily; uint32_t presentQueueFamily; @@ -473,7 +474,7 @@ void createSwapChain() { std::cout << "using " << imageCount << " images for swap chain" << std::endl; // Select a surface format - VkSurfaceFormatKHR surfaceFormat = chooseSurfaceFormat(surfaceFormats); + swapchainFormat = chooseSurfaceFormat(surfaceFormats); // Select swap chain size VkExtent2D swapChainExtent = chooseSwapExtent(surfaceCapabilities); @@ -502,8 +503,8 @@ void createSwapChain() { createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; createInfo.surface = windowSurface; createInfo.minImageCount = imageCount; - createInfo.imageFormat = surfaceFormat.format; - createInfo.imageColorSpace = surfaceFormat.colorSpace; + createInfo.imageFormat = swapchainFormat.format; + createInfo.imageColorSpace = swapchainFormat.colorSpace; createInfo.imageExtent = swapChainExtent; createInfo.imageArrayLayers = 1; createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; @@ -763,13 +764,14 @@ void CreateRenderPass() subpassDesc.pColorAttachments = &attachRef; VkAttachmentDescription attachDesc = {}; - attachDesc.format = VkFormat::VK_FORMAT_R8G8B8A8_UNORM; //Todo + attachDesc.format = swapchainFormat.format; //Todo attachDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachDesc.initialLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; attachDesc.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + attachDesc.samples = VK_SAMPLE_COUNT_1_BIT; VkRenderPassCreateInfo renderPassCreateInfo = {}; renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; @@ -794,7 +796,7 @@ void CreateFramebuffer() VkImageViewCreateInfo ViewCreateInfo = {}; ViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; ViewCreateInfo.image = swapChainImages[i]; - ViewCreateInfo.format = VkFormat::VK_FORMAT_R8G8B8A8_UNORM; //Todo + ViewCreateInfo.format = swapchainFormat.format; //Todo ViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; ViewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; ViewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;