From 6bd2351a56ddf2d70f08aee86f73ee27b3d06ec3 Mon Sep 17 00:00:00 2001 From: turanszkij Date: Wed, 11 Apr 2018 17:09:43 +0100 Subject: [PATCH] vulkan updates --- WickedEngine/wiGraphicsDevice.cpp | 30 ++ WickedEngine/wiGraphicsDevice.h | 3 +- WickedEngine/wiGraphicsDevice_Vulkan.cpp | 641 +++++++++++++---------- 3 files changed, 388 insertions(+), 286 deletions(-) diff --git a/WickedEngine/wiGraphicsDevice.cpp b/WickedEngine/wiGraphicsDevice.cpp index bc99c635b..26c84ba83 100644 --- a/WickedEngine/wiGraphicsDevice.cpp +++ b/WickedEngine/wiGraphicsDevice.cpp @@ -34,3 +34,33 @@ bool GraphicsDevice::CheckCapability(GRAPHICSDEVICE_CAPABILITY capability) } return false; } + +uint32_t GraphicsDevice::GetFormatStride(FORMAT value) +{ + switch (value) + { + case FORMAT_R32G32B32A32_FLOAT: + return 16; + break; + case FORMAT_R32G32_FLOAT: + return 8; + break; + case FORMAT_R16G16_FLOAT: + case FORMAT_R32_FLOAT: + case FORMAT_R32_UINT: + case FORMAT_R8G8B8A8_UINT: + case FORMAT_R8G8B8A8_SINT: + case FORMAT_R8G8B8A8_UNORM: + case FORMAT_R8G8B8A8_SNORM: + return 4; + break; + case FORMAT_R16_FLOAT: + return 2; + break; + } + + // TODO more formats + + return 16; +} + diff --git a/WickedEngine/wiGraphicsDevice.h b/WickedEngine/wiGraphicsDevice.h index 892ed6a59..24ab4e7ee 100644 --- a/WickedEngine/wiGraphicsDevice.h +++ b/WickedEngine/wiGraphicsDevice.h @@ -63,7 +63,6 @@ namespace wiGraphicsTypes virtual void SetResolution(int width, int height) = 0; - virtual Texture2D GetBackBuffer() = 0; @@ -78,6 +77,8 @@ namespace wiGraphicsTypes }; bool CheckCapability(GRAPHICSDEVICE_CAPABILITY capability); + uint32_t GetFormatStride(FORMAT value); + XMMATRIX GetScreenProjection() { return XMMatrixOrthographicOffCenterLH(0, (float)GetScreenWidth(), (float)GetScreenHeight(), 0, -1, 1); diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.cpp b/WickedEngine/wiGraphicsDevice_Vulkan.cpp index a1db36e85..c42c75729 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.cpp +++ b/WickedEngine/wiGraphicsDevice_Vulkan.cpp @@ -1952,7 +1952,13 @@ namespace wiGraphicsTypes HRESULT GraphicsDevice_Vulkan::CreateInputLayout(const VertexLayoutDesc *pInputElementDescs, UINT NumElements, const void *pShaderBytecodeWithInputSignature, SIZE_T BytecodeLength, VertexLayout *pInputLayout) { - return E_FAIL; + pInputLayout->desc.reserve((size_t)NumElements); + for (UINT i = 0; i < NumElements; ++i) + { + pInputLayout->desc.push_back(pInputElementDescs[i]); + } + + return S_OK; } HRESULT GraphicsDevice_Vulkan::CreateVertexShader(const void *pShaderBytecode, SIZE_T BytecodeLength, VertexShader *pVertexShader) { @@ -2037,359 +2043,424 @@ namespace wiGraphicsTypes } HRESULT GraphicsDevice_Vulkan::CreateGraphicsPSO(const GraphicsPSODesc* pDesc, GraphicsPSO* pso) { - //pso->desc = *pDesc; - - //pso->renderPass_Vulkan = new VkRenderPass; - //pso->pipeline_Vulkan = new VkPipeline; + pso->desc = *pDesc; - //std::vector attachments; - //std::vector colorAttachmentRefs; + std::vector attachments; + std::vector colorAttachmentRefs; - //attachments.reserve(pDesc->numRTs); - //colorAttachmentRefs.reserve(pDesc->numRTs); + attachments.reserve(pDesc->numRTs); + colorAttachmentRefs.reserve(pDesc->numRTs); - //for (UINT i = 0; i < pDesc->numRTs; ++i) - //{ - // VkAttachmentDescription attachment = {}; - // attachment.format = _ConvertFormat(pDesc->RTFormats[i]); - // attachment.samples = VK_SAMPLE_COUNT_1_BIT; - // attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - // attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - // attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - // attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - // attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - // attachment.finalLayout = VK_IMAGE_LAYOUT_GENERAL; - // attachments.push_back(attachment); + for (UINT i = 0; i < pDesc->numRTs; ++i) + { + VkAttachmentDescription attachment = {}; + attachment.format = _ConvertFormat(pDesc->RTFormats[i]); + attachment.samples = VK_SAMPLE_COUNT_1_BIT; + attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attachment.finalLayout = VK_IMAGE_LAYOUT_GENERAL; + attachments.push_back(attachment); - // VkAttachmentReference ref = {}; - // ref.attachment = i; - // ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - // colorAttachmentRefs.push_back(ref); - //} + VkAttachmentReference ref = {}; + ref.attachment = i; + ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + colorAttachmentRefs.push_back(ref); + } - //VkSubpassDescription subpass = {}; - //subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - //subpass.colorAttachmentCount = pDesc->numRTs; - //subpass.pColorAttachments = colorAttachmentRefs.data(); + VkSubpassDescription subpass = {}; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.colorAttachmentCount = pDesc->numRTs; + subpass.pColorAttachments = colorAttachmentRefs.data(); - //if (pDesc->DSFormat != FORMAT_UNKNOWN) - //{ - // VkAttachmentDescription attachment = {}; - // attachment.format = _ConvertFormat(pDesc->DSFormat); - // attachment.samples = VK_SAMPLE_COUNT_1_BIT; - // attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // hmmm... - // attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - // attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // hmmm... - // attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - // attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - // attachment.finalLayout = VK_IMAGE_LAYOUT_GENERAL; - // attachments.push_back(attachment); + VkAttachmentDescription attachment = {}; + VkAttachmentReference depthAttachmentRef = {}; + if (pDesc->DSFormat != FORMAT_UNKNOWN) + { + attachment.format = _ConvertFormat(pDesc->DSFormat); + attachment.samples = VK_SAMPLE_COUNT_1_BIT; + attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // hmmm... + attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // hmmm... + attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; + attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attachment.finalLayout = VK_IMAGE_LAYOUT_GENERAL; + attachments.push_back(attachment); - // VkAttachmentReference depthAttachmentRef = {}; - // depthAttachmentRef.attachment = static_cast(attachments.size() - 1); - // depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + depthAttachmentRef.attachment = static_cast(attachments.size() - 1); + depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - // subpass.pDepthStencilAttachment = &depthAttachmentRef; - //} + subpass.pDepthStencilAttachment = &depthAttachmentRef; + } - //VkRenderPassCreateInfo renderPassInfo = {}; - //renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - //renderPassInfo.attachmentCount = static_cast(attachments.size()); - //renderPassInfo.pAttachments = attachments.data(); - //renderPassInfo.subpassCount = 1; - //renderPassInfo.pSubpasses = &subpass; + VkRenderPassCreateInfo renderPassInfo = {}; + renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + renderPassInfo.attachmentCount = static_cast(attachments.size()); + renderPassInfo.pAttachments = attachments.data(); + renderPassInfo.subpassCount = 1; + renderPassInfo.pSubpasses = &subpass; - //if (vkCreateRenderPass(device, &renderPassInfo, nullptr, static_cast(pso->renderPass_Vulkan)) != VK_SUCCESS) { - // throw std::runtime_error("failed to create render pass!"); - //} + if (vkCreateRenderPass(device, &renderPassInfo, nullptr, reinterpret_cast(&pso->renderPass_Vulkan)) != VK_SUCCESS) { + throw std::runtime_error("failed to create render pass!"); + } - //VkGraphicsPipelineCreateInfo pipelineInfo = {}; - //pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - //pipelineInfo.layout = defaultPipelineLayout_Graphics; - //pipelineInfo.renderPass = *static_cast(pso->renderPass_Vulkan); - //pipelineInfo.subpass = 0; - //pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; + VkGraphicsPipelineCreateInfo pipelineInfo = {}; + pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipelineInfo.layout = defaultPipelineLayout_Graphics; + pipelineInfo.renderPass = static_cast(pso->renderPass_Vulkan); + pipelineInfo.subpass = 0; + pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; - //// Shaders: + // Shaders: - //std::vector shaderStages; + std::vector shaderStages; - //if (pDesc->vs != nullptr) - //{ - // VkShaderModuleCreateInfo moduleInfo = {}; - // moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - // moduleInfo.codeSize = pDesc->vs->code.size; - // moduleInfo.pCode = reinterpret_cast(pDesc->vs->code.data); - // VkShaderModule shaderModule; - // if (vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule) != VK_SUCCESS) { - // throw std::runtime_error("failed to create shader module!"); - // } + if (pDesc->vs != nullptr) + { + VkShaderModuleCreateInfo moduleInfo = {}; + moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleInfo.codeSize = pDesc->vs->code.size; + moduleInfo.pCode = reinterpret_cast(pDesc->vs->code.data); + VkShaderModule shaderModule; + if (vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule) != VK_SUCCESS) { + throw std::runtime_error("failed to create shader module!"); + } - // VkPipelineShaderStageCreateInfo stageInfo = {}; - // stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - // stageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; - // stageInfo.module = shaderModule; - // stageInfo.pName = "main"; + VkPipelineShaderStageCreateInfo stageInfo = {}; + stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; + stageInfo.module = shaderModule; + stageInfo.pName = "main"; - // shaderStages.push_back(stageInfo); - //} + shaderStages.push_back(stageInfo); + } - //if (pDesc->hs != nullptr) - //{ - // VkShaderModuleCreateInfo moduleInfo = {}; - // moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - // moduleInfo.codeSize = pDesc->hs->code.size; - // moduleInfo.pCode = reinterpret_cast(pDesc->hs->code.data); - // VkShaderModule shaderModule; - // if (vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule) != VK_SUCCESS) { - // throw std::runtime_error("failed to create shader module!"); - // } + if (pDesc->hs != nullptr) + { + VkShaderModuleCreateInfo moduleInfo = {}; + moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleInfo.codeSize = pDesc->hs->code.size; + moduleInfo.pCode = reinterpret_cast(pDesc->hs->code.data); + VkShaderModule shaderModule; + if (vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule) != VK_SUCCESS) { + throw std::runtime_error("failed to create shader module!"); + } - // VkPipelineShaderStageCreateInfo stageInfo = {}; - // stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - // stageInfo.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; - // stageInfo.module = shaderModule; - // stageInfo.pName = "main"; + VkPipelineShaderStageCreateInfo stageInfo = {}; + stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stageInfo.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; + stageInfo.module = shaderModule; + stageInfo.pName = "main"; - // shaderStages.push_back(stageInfo); - //} + shaderStages.push_back(stageInfo); + } - //if (pDesc->ds != nullptr) - //{ - // VkShaderModuleCreateInfo moduleInfo = {}; - // moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - // moduleInfo.codeSize = pDesc->ds->code.size; - // moduleInfo.pCode = reinterpret_cast(pDesc->ds->code.data); - // VkShaderModule shaderModule; - // if (vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule) != VK_SUCCESS) { - // throw std::runtime_error("failed to create shader module!"); - // } + if (pDesc->ds != nullptr) + { + VkShaderModuleCreateInfo moduleInfo = {}; + moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleInfo.codeSize = pDesc->ds->code.size; + moduleInfo.pCode = reinterpret_cast(pDesc->ds->code.data); + VkShaderModule shaderModule; + if (vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule) != VK_SUCCESS) { + throw std::runtime_error("failed to create shader module!"); + } - // VkPipelineShaderStageCreateInfo stageInfo = {}; - // stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - // stageInfo.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; - // stageInfo.module = shaderModule; - // stageInfo.pName = "main"; + VkPipelineShaderStageCreateInfo stageInfo = {}; + stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stageInfo.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; + stageInfo.module = shaderModule; + stageInfo.pName = "main"; - // shaderStages.push_back(stageInfo); - //} + shaderStages.push_back(stageInfo); + } - //if (pDesc->gs != nullptr) - //{ - // VkShaderModuleCreateInfo moduleInfo = {}; - // moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - // moduleInfo.codeSize = pDesc->gs->code.size; - // moduleInfo.pCode = reinterpret_cast(pDesc->gs->code.data); - // VkShaderModule shaderModule; - // if (vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule) != VK_SUCCESS) { - // throw std::runtime_error("failed to create shader module!"); - // } + if (pDesc->gs != nullptr) + { + VkShaderModuleCreateInfo moduleInfo = {}; + moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleInfo.codeSize = pDesc->gs->code.size; + moduleInfo.pCode = reinterpret_cast(pDesc->gs->code.data); + VkShaderModule shaderModule; + if (vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule) != VK_SUCCESS) { + throw std::runtime_error("failed to create shader module!"); + } - // VkPipelineShaderStageCreateInfo stageInfo = {}; - // stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - // stageInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT; - // stageInfo.module = shaderModule; - // stageInfo.pName = "main"; + VkPipelineShaderStageCreateInfo stageInfo = {}; + stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stageInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT; + stageInfo.module = shaderModule; + stageInfo.pName = "main"; - // shaderStages.push_back(stageInfo); - //} + shaderStages.push_back(stageInfo); + } - //if (pDesc->ps != nullptr) - //{ - // VkShaderModuleCreateInfo moduleInfo = {}; - // moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - // moduleInfo.codeSize = pDesc->ps->code.size; - // moduleInfo.pCode = reinterpret_cast(pDesc->ps->code.data); - // VkShaderModule shaderModule; - // if (vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule) != VK_SUCCESS) { - // throw std::runtime_error("failed to create shader module!"); - // } + if (pDesc->ps != nullptr) + { + VkShaderModuleCreateInfo moduleInfo = {}; + moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleInfo.codeSize = pDesc->ps->code.size; + moduleInfo.pCode = reinterpret_cast(pDesc->ps->code.data); + VkShaderModule shaderModule; + if (vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule) != VK_SUCCESS) { + throw std::runtime_error("failed to create shader module!"); + } - // VkPipelineShaderStageCreateInfo stageInfo = {}; - // stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - // stageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - // stageInfo.module = shaderModule; - // stageInfo.pName = "main"; + VkPipelineShaderStageCreateInfo stageInfo = {}; + stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + stageInfo.module = shaderModule; + stageInfo.pName = "main"; - // shaderStages.push_back(stageInfo); - //} + shaderStages.push_back(stageInfo); + } - //pipelineInfo.stageCount = static_cast(shaderStages.size()); - //pipelineInfo.pStages = shaderStages.data(); + pipelineInfo.stageCount = static_cast(shaderStages.size()); + pipelineInfo.pStages = shaderStages.data(); - //// Fixed function states: + // Fixed function states: - //// Input layout: - //VkPipelineVertexInputStateCreateInfo vertexInputInfo = {}; - //vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - //if (pDesc->il != nullptr) - //{ - // vertexInputInfo.vertexBindingDescriptionCount = 0; - // vertexInputInfo.pVertexBindingDescriptions = nullptr; // Optional - // vertexInputInfo.vertexAttributeDescriptionCount = 0; - // vertexInputInfo.pVertexAttributeDescriptions = nullptr; // Optional - //} - //pipelineInfo.pVertexInputState = &vertexInputInfo; + // Input layout: + VkPipelineVertexInputStateCreateInfo vertexInputInfo = {}; + vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + std::vector bindings; + std::vector attributes; + if (pDesc->il != nullptr) + { + uint32_t lastBinding = 0xFFFFFFFF; + for (auto& x : pDesc->il->desc) + { + VkVertexInputBindingDescription bind = {}; + bind.binding = x.InputSlot; + bind.inputRate = x.InputSlotClass == INPUT_PER_VERTEX_DATA ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE; + bind.stride = x.AlignedByteOffset; + if (bind.stride == APPEND_ALIGNED_ELEMENT) + { + // need to manually resolve this from the format spec. + bind.stride = GetFormatStride(x.Format); + } - //// Primitive type: - //// TODO: This doesn't match DX12! - //VkPipelineInputAssemblyStateCreateInfo inputAssembly = {}; - //inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - //switch (pDesc->ptt) - //{ - //case PRIMITIVE_TOPOLOGY_TYPE_POINT: - // inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; - // break; - //case PRIMITIVE_TOPOLOGY_TYPE_LINE: - // inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST; - // break; - //case PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE: - // inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - // break; - //case PRIMITIVE_TOPOLOGY_TYPE_PATCH: - // inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; - // break; - //default: - // break; - //} - //inputAssembly.primitiveRestartEnable = VK_FALSE; + if (lastBinding != bind.binding) + { + bindings.push_back(bind); + lastBinding = bind.binding; + } + else + { + bindings.back().stride += bind.stride; + } + } - //pipelineInfo.pInputAssemblyState = &inputAssembly; + uint32_t i = 0; + for (auto& x : pDesc->il->desc) + { + VkVertexInputAttributeDescription attr = {}; + attr.binding = x.InputSlot; + attr.format = _ConvertFormat(x.Format); + attr.location = i; + attr.offset = x.AlignedByteOffset; + if (attr.offset == APPEND_ALIGNED_ELEMENT) + { + // need to manually resolve this from the format spec. + attr.offset = GetFormatStride(x.Format); + } + + attributes.push_back(attr); + + i++; + } + + vertexInputInfo.vertexBindingDescriptionCount = static_cast(bindings.size()); + vertexInputInfo.pVertexBindingDescriptions = bindings.data(); + vertexInputInfo.vertexAttributeDescriptionCount = static_cast(attributes.size()); + vertexInputInfo.pVertexAttributeDescriptions = attributes.data(); + } + pipelineInfo.pVertexInputState = &vertexInputInfo; + + // Primitive type: + // TODO: This doesn't match DX12! + VkPipelineInputAssemblyStateCreateInfo inputAssembly = {}; + inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + switch (pDesc->ptt) + { + case PRIMITIVE_TOPOLOGY_TYPE_POINT: + inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + break; + case PRIMITIVE_TOPOLOGY_TYPE_LINE: + inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + break; + case PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE: + inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + break; + case PRIMITIVE_TOPOLOGY_TYPE_PATCH: + inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; + break; + default: + break; + } + inputAssembly.primitiveRestartEnable = VK_FALSE; + + pipelineInfo.pInputAssemblyState = &inputAssembly; - //// Rasterizer: - //VkPipelineRasterizationStateCreateInfo rasterizer = {}; - //rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - //rasterizer.depthClampEnable = VK_FALSE; - //rasterizer.rasterizerDiscardEnable = VK_FALSE; - //rasterizer.polygonMode = VK_POLYGON_MODE_FILL; - //rasterizer.lineWidth = 1.0f; - //rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; - //rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; - //rasterizer.depthBiasEnable = VK_FALSE; - //rasterizer.depthBiasConstantFactor = 0.0f; // Optional - //rasterizer.depthBiasClamp = 0.0f; // Optional - //rasterizer.depthBiasSlopeFactor = 0.0f; // Optional + // Rasterizer: + VkPipelineRasterizationStateCreateInfo rasterizer = {}; + rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterizer.depthClampEnable = VK_FALSE; + rasterizer.rasterizerDiscardEnable = VK_FALSE; + rasterizer.polygonMode = VK_POLYGON_MODE_FILL; + rasterizer.lineWidth = 1.0f; + rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; + rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; + rasterizer.depthBiasEnable = VK_FALSE; + rasterizer.depthBiasConstantFactor = 0.0f; // Optional + rasterizer.depthBiasClamp = 0.0f; // Optional + rasterizer.depthBiasSlopeFactor = 0.0f; // Optional - //pipelineInfo.pRasterizationState = &rasterizer; + pipelineInfo.pRasterizationState = &rasterizer; - //// Depth-Stencil: - //VkPipelineDepthStencilStateCreateInfo depthstencil = {}; - //depthstencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - //if (pDesc->dss != nullptr) - //{ - // depthstencil.depthTestEnable = pDesc->dss->desc.DepthEnable ? 1 : 0; - // depthstencil.depthWriteEnable = pDesc->dss->desc.DepthWriteMask != DEPTH_WRITE_MASK_ZERO; + // Viewport, Scissor: + VkViewport viewport = {}; + viewport.x = 0; + viewport.y = 0; + viewport.width = 65535; + viewport.height = 65535; + viewport.minDepth = 0; + viewport.maxDepth = 1; - // depthstencil.stencilTestEnable = pDesc->dss->desc.StencilEnable ? 1 : 0; - //} + VkRect2D scissor = {}; + scissor.extent.width = 65535; + scissor.extent.height = 65535; - //pipelineInfo.pDepthStencilState = &depthstencil; + VkPipelineViewportStateCreateInfo viewportState = {}; + viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewportState.viewportCount = 1; + viewportState.pViewports = &viewport; + viewportState.scissorCount = 1; + viewportState.pScissors = &scissor; + + pipelineInfo.pViewportState = &viewportState; - //// MSAA: - //VkPipelineMultisampleStateCreateInfo multisampling = {}; - //multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - //multisampling.sampleShadingEnable = VK_FALSE; - //multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - //multisampling.minSampleShading = 1.0f; // Optional - //multisampling.pSampleMask = nullptr; // Optional - //multisampling.alphaToCoverageEnable = VK_FALSE; // Optional - //multisampling.alphaToOneEnable = VK_FALSE; // Optional + // Depth-Stencil: + VkPipelineDepthStencilStateCreateInfo depthstencil = {}; + depthstencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + if (pDesc->dss != nullptr) + { + depthstencil.depthTestEnable = pDesc->dss->desc.DepthEnable ? 1 : 0; + depthstencil.depthWriteEnable = pDesc->dss->desc.DepthWriteMask != DEPTH_WRITE_MASK_ZERO; - //pipelineInfo.pMultisampleState = &multisampling; + depthstencil.stencilTestEnable = pDesc->dss->desc.StencilEnable ? 1 : 0; + } + + pipelineInfo.pDepthStencilState = &depthstencil; - //// Blending: - //VkPipelineColorBlendAttachmentState colorBlendAttachment = {}; - //colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - //colorBlendAttachment.blendEnable = VK_FALSE; - //colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; // Optional - //colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional - //colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD; // Optional - //colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; // Optional - //colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional - //colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; // Optional + // MSAA: + VkPipelineMultisampleStateCreateInfo multisampling = {}; + multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisampling.sampleShadingEnable = VK_FALSE; + multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + multisampling.minSampleShading = 1.0f; // Optional + multisampling.pSampleMask = nullptr; // Optional + multisampling.alphaToCoverageEnable = VK_FALSE; // Optional + multisampling.alphaToOneEnable = VK_FALSE; // Optional - //VkPipelineColorBlendStateCreateInfo colorBlending = {}; - //colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - //colorBlending.logicOpEnable = VK_FALSE; - //colorBlending.logicOp = VK_LOGIC_OP_COPY; // Optional - //colorBlending.attachmentCount = 1; - //colorBlending.pAttachments = &colorBlendAttachment; - //colorBlending.blendConstants[0] = 0.0f; // Optional - //colorBlending.blendConstants[1] = 0.0f; // Optional - //colorBlending.blendConstants[2] = 0.0f; // Optional - //colorBlending.blendConstants[3] = 0.0f; // Optional + pipelineInfo.pMultisampleState = &multisampling; - //pipelineInfo.pColorBlendState = &colorBlending; + + // Blending: + VkPipelineColorBlendAttachmentState colorBlendAttachment = {}; + colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + colorBlendAttachment.blendEnable = VK_FALSE; + colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; // Optional + colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional + colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD; // Optional + colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; // Optional + colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional + colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; // Optional + + VkPipelineColorBlendStateCreateInfo colorBlending = {}; + colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + colorBlending.logicOpEnable = VK_FALSE; + colorBlending.logicOp = VK_LOGIC_OP_COPY; // Optional + colorBlending.attachmentCount = 1; + colorBlending.pAttachments = &colorBlendAttachment; + colorBlending.blendConstants[0] = 0.0f; // Optional + colorBlending.blendConstants[1] = 0.0f; // Optional + colorBlending.blendConstants[2] = 0.0f; // Optional + colorBlending.blendConstants[3] = 0.0f; // Optional + + pipelineInfo.pColorBlendState = &colorBlending; - //// Dynamic state will be specified at runtime: - //VkDynamicState dynamicStates[] = { - // VK_DYNAMIC_STATE_VIEWPORT, - // VK_DYNAMIC_STATE_LINE_WIDTH, - // VK_DYNAMIC_STATE_STENCIL_REFERENCE - //}; + // Dynamic state will be specified at runtime: + VkDynamicState dynamicStates[] = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + VK_DYNAMIC_STATE_LINE_WIDTH, + VK_DYNAMIC_STATE_STENCIL_REFERENCE + }; - //VkPipelineDynamicStateCreateInfo dynamicState = {}; - //dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - //dynamicState.dynamicStateCount = ARRAYSIZE(dynamicStates); - //dynamicState.pDynamicStates = dynamicStates; + VkPipelineDynamicStateCreateInfo dynamicState = {}; + dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamicState.dynamicStateCount = ARRAYSIZE(dynamicStates); + dynamicState.pDynamicStates = dynamicStates; + + pipelineInfo.pDynamicState = &dynamicState; + VkResult res = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, reinterpret_cast(&pso->pipeline_Vulkan)); + HRESULT hr = res == VK_SUCCESS ? S_OK : E_FAIL; + //assert(SUCCEEDED(hr)); - //if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, static_cast(pso->pipeline_Vulkan)) != VK_SUCCESS) { - // throw std::runtime_error("failed to create graphics pipeline!"); - //} - - return S_OK; + return hr; } HRESULT GraphicsDevice_Vulkan::CreateComputePSO(const ComputePSODesc* pDesc, ComputePSO* pso) { - //pso->pipeline_Vulkan = new VkPipeline; - - //VkComputePipelineCreateInfo pipelineInfo = {}; - //pipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; - //pipelineInfo.layout = defaultPipelineLayout_Compute; - //pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; + VkComputePipelineCreateInfo pipelineInfo = {}; + pipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + pipelineInfo.layout = defaultPipelineLayout_Compute; + pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; - //if (pDesc->cs != nullptr) - //{ - // VkShaderModuleCreateInfo moduleInfo = {}; - // moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - // moduleInfo.codeSize = pDesc->cs->code.size; - // moduleInfo.pCode = reinterpret_cast(pDesc->cs->code.data); - // VkShaderModule shaderModule; - // if (vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule) != VK_SUCCESS) { - // throw std::runtime_error("failed to create shader module!"); - // } + if (pDesc->cs != nullptr) + { + VkShaderModuleCreateInfo moduleInfo = {}; + moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleInfo.codeSize = pDesc->cs->code.size; + moduleInfo.pCode = reinterpret_cast(pDesc->cs->code.data); + VkShaderModule shaderModule; + if (vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule) != VK_SUCCESS) { + throw std::runtime_error("failed to create shader module!"); + } - // VkPipelineShaderStageCreateInfo stageInfo = {}; - // stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - // stageInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; - // stageInfo.module = shaderModule; - // stageInfo.pName = "main"; + VkPipelineShaderStageCreateInfo stageInfo = {}; + stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stageInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; + stageInfo.module = shaderModule; + stageInfo.pName = "main"; - // pipelineInfo.stage = stageInfo; - //} + pipelineInfo.stage = stageInfo; + } - //if (vkCreateComputePipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, static_cast(pso->pipeline_Vulkan)) != VK_SUCCESS) { - // throw std::runtime_error("failed to create compute pipeline!"); - //} + VkResult res = vkCreateComputePipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, reinterpret_cast(&pso->pipeline_Vulkan)); + HRESULT hr = res == VK_SUCCESS ? S_OK : E_FAIL; + //assert(SUCCEEDED(hr)); - return S_OK; + return hr; } @@ -2707,11 +2778,11 @@ namespace wiGraphicsTypes } void GraphicsDevice_Vulkan::BindGraphicsPSO(GraphicsPSO* pso, GRAPHICSTHREAD threadID) { - //vkCmdBindPipeline(GetDirectCommandList(threadID), VK_PIPELINE_BIND_POINT_GRAPHICS, static_cast(pso->pipeline_Vulkan)); + vkCmdBindPipeline(GetDirectCommandList(threadID), VK_PIPELINE_BIND_POINT_GRAPHICS, static_cast(pso->pipeline_Vulkan)); } void GraphicsDevice_Vulkan::BindComputePSO(ComputePSO* pso, GRAPHICSTHREAD threadID) { - //vkCmdBindPipeline(GetDirectCommandList(threadID), VK_PIPELINE_BIND_POINT_COMPUTE, static_cast(pso->pipeline_Vulkan)); + vkCmdBindPipeline(GetDirectCommandList(threadID), VK_PIPELINE_BIND_POINT_COMPUTE, static_cast(pso->pipeline_Vulkan)); } void GraphicsDevice_Vulkan::Draw(int vertexCount, UINT startVertexLocation, GRAPHICSTHREAD threadID) {