VkPPRenderPassSetup::VkPPRenderPassSetup(const VkPPRenderPassKey &key) { CreateDescriptorLayout(key); CreatePipelineLayout(key); CreateRenderPass(key); CreatePipeline(key); }
void VulkanQuad::CreatePipelineStateObject () { vertexShader_ = LoadShader (device_, BasicVertexShader, sizeof (BasicVertexShader)); fragmentShader_ = LoadShader (device_, BasicFragmentShader, sizeof (BasicFragmentShader)); pipelineLayout_ = CreatePipelineLayout (device_); VkExtent2D extent = { static_cast<uint32_t> (window_->GetWidth ()), static_cast<uint32_t> (window_->GetHeight ()) }; pipeline_ = CreatePipeline(device_, renderPass_, pipelineLayout_, vertexShader_, fragmentShader_, extent); }
bool Tutorial03::CreatePipeline() { Tools::AutoDeleter<VkShaderModule, PFN_vkDestroyShaderModule> vertex_shader_module = CreateShaderModule( "Data03/vert.spv" ); Tools::AutoDeleter<VkShaderModule, PFN_vkDestroyShaderModule> fragment_shader_module = CreateShaderModule( "Data03/frag.spv" ); if( !vertex_shader_module || !fragment_shader_module ) { return false; } std::vector<VkPipelineShaderStageCreateInfo> shader_stage_create_infos = { // Vertex shader { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineShaderStageCreateFlags flags VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage vertex_shader_module.Get(), // VkShaderModule module "main", // const char *pName nullptr // const VkSpecializationInfo *pSpecializationInfo }, // Fragment shader { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineShaderStageCreateFlags flags VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage fragment_shader_module.Get(), // VkShaderModule module "main", // const char *pName nullptr // const VkSpecializationInfo *pSpecializationInfo } }; VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineVertexInputStateCreateFlags flags; 0, // uint32_t vertexBindingDescriptionCount nullptr, // const VkVertexInputBindingDescription *pVertexBindingDescriptions 0, // uint32_t vertexAttributeDescriptionCount nullptr // const VkVertexInputAttributeDescription *pVertexAttributeDescriptions }; VkPipelineInputAssemblyStateCreateInfo input_assembly_state_create_info = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineInputAssemblyStateCreateFlags flags VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology VK_FALSE // VkBool32 primitiveRestartEnable }; VkViewport viewport = { 0.0f, // float x 0.0f, // float y 300.0f, // float width 300.0f, // float height 0.0f, // float minDepth 1.0f // float maxDepth }; VkRect2D scissor = { { // VkOffset2D offset 0, // int32_t x 0 // int32_t y }, { // VkExtent2D extent 300, // int32_t width 300 // int32_t height } }; VkPipelineViewportStateCreateInfo viewport_state_create_info = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineViewportStateCreateFlags flags 1, // uint32_t viewportCount &viewport, // const VkViewport *pViewports 1, // uint32_t scissorCount &scissor // const VkRect2D *pScissors }; VkPipelineRasterizationStateCreateInfo rasterization_state_create_info = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineRasterizationStateCreateFlags flags VK_FALSE, // VkBool32 depthClampEnable VK_FALSE, // VkBool32 rasterizerDiscardEnable VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode VK_CULL_MODE_BACK_BIT, // VkCullModeFlags cullMode VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace VK_FALSE, // VkBool32 depthBiasEnable 0.0f, // float depthBiasConstantFactor 0.0f, // float depthBiasClamp 0.0f, // float depthBiasSlopeFactor 1.0f // float lineWidth }; VkPipelineMultisampleStateCreateInfo multisample_state_create_info = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineMultisampleStateCreateFlags flags VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples VK_FALSE, // VkBool32 sampleShadingEnable 1.0f, // float minSampleShading nullptr, // const VkSampleMask *pSampleMask VK_FALSE, // VkBool32 alphaToCoverageEnable VK_FALSE // VkBool32 alphaToOneEnable }; VkPipelineColorBlendAttachmentState color_blend_attachment_state = { VK_FALSE, // VkBool32 blendEnable VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT }; VkPipelineColorBlendStateCreateInfo color_blend_state_create_info = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineColorBlendStateCreateFlags flags VK_FALSE, // VkBool32 logicOpEnable VK_LOGIC_OP_COPY, // VkLogicOp logicOp 1, // uint32_t attachmentCount &color_blend_attachment_state, // const VkPipelineColorBlendAttachmentState *pAttachments { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4] }; Tools::AutoDeleter<VkPipelineLayout, PFN_vkDestroyPipelineLayout> pipeline_layout = CreatePipelineLayout(); if( !pipeline_layout ) { return false; } VkGraphicsPipelineCreateInfo pipeline_create_info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType nullptr, // const void *pNext 0, // VkPipelineCreateFlags flags static_cast<uint32_t>(shader_stage_create_infos.size()), // uint32_t stageCount &shader_stage_create_infos[0], // const VkPipelineShaderStageCreateInfo *pStages &vertex_input_state_create_info, // const VkPipelineVertexInputStateCreateInfo *pVertexInputState; &input_assembly_state_create_info, // const VkPipelineInputAssemblyStateCreateInfo *pInputAssemblyState nullptr, // const VkPipelineTessellationStateCreateInfo *pTessellationState &viewport_state_create_info, // const VkPipelineViewportStateCreateInfo *pViewportState &rasterization_state_create_info, // const VkPipelineRasterizationStateCreateInfo *pRasterizationState &multisample_state_create_info, // const VkPipelineMultisampleStateCreateInfo *pMultisampleState nullptr, // const VkPipelineDepthStencilStateCreateInfo *pDepthStencilState &color_blend_state_create_info, // const VkPipelineColorBlendStateCreateInfo *pColorBlendState nullptr, // const VkPipelineDynamicStateCreateInfo *pDynamicState pipeline_layout.Get(), // VkPipelineLayout layout Vulkan.RenderPass, // VkRenderPass renderPass 0, // uint32_t subpass VK_NULL_HANDLE, // VkPipeline basePipelineHandle -1 // int32_t basePipelineIndex }; if( vkCreateGraphicsPipelines( GetDevice(), VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, &Vulkan.GraphicsPipeline ) != VK_SUCCESS ) { std::cout << "Could not create graphics pipeline!" << std::endl; return false; } return true; }
GrVkPipelineState* GrVkPipelineStateBuilder::finalize(GrPrimitiveType primitiveType, const GrVkRenderPass& renderPass, const GrVkPipelineState::Desc& desc) { VkDescriptorSetLayout dsLayout[2]; VkPipelineLayout pipelineLayout; VkShaderModule vertShaderModule; VkShaderModule fragShaderModule; uint32_t numSamplers = (uint32_t)fUniformHandler.numSamplers(); SkAutoTDeleteArray<VkDescriptorSetLayoutBinding> dsSamplerBindings( new VkDescriptorSetLayoutBinding[numSamplers]); for (uint32_t i = 0; i < numSamplers; ++i) { const GrVkGLSLSampler& sampler = static_cast<const GrVkGLSLSampler&>(fUniformHandler.getSampler(i)); SkASSERT(sampler.binding() == i); dsSamplerBindings[i].binding = sampler.binding(); dsSamplerBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; dsSamplerBindings[i].descriptorCount = 1; dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(sampler.visibility()); dsSamplerBindings[i].pImmutableSamplers = nullptr; } VkDescriptorSetLayoutCreateInfo dsSamplerLayoutCreateInfo; memset(&dsSamplerLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo)); dsSamplerLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; dsSamplerLayoutCreateInfo.pNext = nullptr; dsSamplerLayoutCreateInfo.flags = 0; dsSamplerLayoutCreateInfo.bindingCount = numSamplers; // Setting to nullptr fixes an error in the param checker validation layer. Even though // bindingCount is 0 (which is valid), it still tries to validate pBindings unless it is null. dsSamplerLayoutCreateInfo.pBindings = numSamplers ? dsSamplerBindings.get() : nullptr; GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreateDescriptorSetLayout(fGpu->device(), &dsSamplerLayoutCreateInfo, nullptr, &dsLayout[GrVkUniformHandler::kSamplerDescSet])); // Create Uniform Buffer Descriptor // We always attach uniform buffers to descriptor set 1. The vertex uniform buffer will have // binding 0 and the fragment binding 1. VkDescriptorSetLayoutBinding dsUniBindings[2]; memset(&dsUniBindings, 0, 2 * sizeof(VkDescriptorSetLayoutBinding)); dsUniBindings[0].binding = GrVkUniformHandler::kVertexBinding; dsUniBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; dsUniBindings[0].descriptorCount = 1; dsUniBindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; dsUniBindings[0].pImmutableSamplers = nullptr; dsUniBindings[1].binding = GrVkUniformHandler::kFragBinding; dsUniBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; dsUniBindings[1].descriptorCount = 1; dsUniBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; dsUniBindings[1].pImmutableSamplers = nullptr; VkDescriptorSetLayoutCreateInfo dsUniformLayoutCreateInfo; memset(&dsUniformLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo)); dsUniformLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; dsUniformLayoutCreateInfo.pNext = nullptr; dsUniformLayoutCreateInfo.flags = 0; dsUniformLayoutCreateInfo.bindingCount = 2; dsUniformLayoutCreateInfo.pBindings = dsUniBindings; GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreateDescriptorSetLayout( fGpu->device(), &dsUniformLayoutCreateInfo, nullptr, &dsLayout[GrVkUniformHandler::kUniformBufferDescSet])); // Create the VkPipelineLayout VkPipelineLayoutCreateInfo layoutCreateInfo; memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags)); layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; layoutCreateInfo.pNext = 0; layoutCreateInfo.flags = 0; layoutCreateInfo.setLayoutCount = 2; layoutCreateInfo.pSetLayouts = dsLayout; layoutCreateInfo.pushConstantRangeCount = 0; layoutCreateInfo.pPushConstantRanges = nullptr; GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreatePipelineLayout(fGpu->device(), &layoutCreateInfo, nullptr, &pipelineLayout)); // We need to enable the following extensions so that the compiler can correctly make spir-v // from our glsl shaders. fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n"); fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n"); fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n"); fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n"); this->finalizeShaders(); VkPipelineShaderStageCreateInfo shaderStageInfo[2]; SkAssertResult(CreateVkShaderModule(fGpu, VK_SHADER_STAGE_VERTEX_BIT, fVS, &vertShaderModule, &shaderStageInfo[0])); SkAssertResult(CreateVkShaderModule(fGpu, VK_SHADER_STAGE_FRAGMENT_BIT, fFS, &fragShaderModule, &shaderStageInfo[1])); GrVkResourceProvider& resourceProvider = fGpu->resourceProvider(); GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline, fPrimProc, shaderStageInfo, 2, primitiveType, renderPass, pipelineLayout); GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), vertShaderModule, nullptr)); GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), fragShaderModule, nullptr)); if (!pipeline) { GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pipelineLayout, nullptr)); GR_VK_CALL(fGpu->vkInterface(), DestroyDescriptorSetLayout(fGpu->device(), dsLayout[0], nullptr)); GR_VK_CALL(fGpu->vkInterface(), DestroyDescriptorSetLayout(fGpu->device(), dsLayout[1], nullptr)); this->cleanupFragmentProcessors(); return nullptr; } return new GrVkPipelineState(fGpu, desc, pipeline, pipelineLayout, dsLayout, fUniformHandles, fUniformHandler.fUniforms, fUniformHandler.fCurrentVertexUBOOffset, fUniformHandler.fCurrentFragmentUBOOffset, numSamplers, fGeometryProcessor, fXferProcessor, fFragmentProcessors); }
GrVkProgram* GrVkProgramBuilder::finalize(const DrawArgs& args, GrPrimitiveType primitiveType, const GrVkRenderPass& renderPass) { VkDescriptorSetLayout dsLayout[2]; VkPipelineLayout pipelineLayout; VkShaderModule vertShaderModule; VkShaderModule fragShaderModule; uint32_t numSamplers = fSamplerUniforms.count(); SkAutoTDeleteArray<VkDescriptorSetLayoutBinding> dsSamplerBindings( new VkDescriptorSetLayoutBinding[numSamplers]); for (uint32_t i = 0; i < numSamplers; ++i) { UniformHandle uniHandle = fSamplerUniforms[i]; GrVkUniformHandler::UniformInfo uniformInfo = fUniformHandler.getUniformInfo(uniHandle); SkASSERT(kSampler2D_GrSLType == uniformInfo.fVariable.getType()); SkASSERT(0 == uniformInfo.fSetNumber); SkASSERT(uniformInfo.fBinding == i); dsSamplerBindings[i].binding = uniformInfo.fBinding; dsSamplerBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; dsSamplerBindings[i].descriptorCount = 1; dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(uniformInfo.fVisibility); dsSamplerBindings[i].pImmutableSamplers = nullptr; } VkDescriptorSetLayoutCreateInfo dsSamplerLayoutCreateInfo; memset(&dsSamplerLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo)); dsSamplerLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; dsSamplerLayoutCreateInfo.pNext = nullptr; dsSamplerLayoutCreateInfo.flags = 0; dsSamplerLayoutCreateInfo.bindingCount = fSamplerUniforms.count(); // Setting to nullptr fixes an error in the param checker validation layer. Even though // bindingCount is 0 (which is valid), it still tries to validate pBindings unless it is null. dsSamplerLayoutCreateInfo.pBindings = fSamplerUniforms.count() ? dsSamplerBindings.get() : nullptr; GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreateDescriptorSetLayout(fGpu->device(), &dsSamplerLayoutCreateInfo, nullptr, &dsLayout[GrVkUniformHandler::kSamplerDescSet])); // Create Uniform Buffer Descriptor // We always attach uniform buffers to descriptor set 1. The vertex uniform buffer will have // binding 0 and the fragment binding 1. VkDescriptorSetLayoutBinding dsUniBindings[2]; memset(&dsUniBindings, 0, 2 * sizeof(VkDescriptorSetLayoutBinding)); dsUniBindings[0].binding = GrVkUniformHandler::kVertexBinding; dsUniBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; dsUniBindings[0].descriptorCount = fUniformHandler.hasVertexUniforms() ? 1 : 0; dsUniBindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; dsUniBindings[0].pImmutableSamplers = nullptr; dsUniBindings[1].binding = GrVkUniformHandler::kFragBinding; dsUniBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; dsUniBindings[1].descriptorCount = fUniformHandler.hasFragmentUniforms() ? 1 : 0; dsUniBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; dsUniBindings[1].pImmutableSamplers = nullptr; VkDescriptorSetLayoutCreateInfo dsUniformLayoutCreateInfo; memset(&dsUniformLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo)); dsUniformLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; dsUniformLayoutCreateInfo.pNext = nullptr; dsUniformLayoutCreateInfo.flags = 0; dsUniformLayoutCreateInfo.bindingCount = 2; dsUniformLayoutCreateInfo.pBindings = dsUniBindings; GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreateDescriptorSetLayout( fGpu->device(), &dsUniformLayoutCreateInfo, nullptr, &dsLayout[GrVkUniformHandler::kUniformBufferDescSet])); // Create the VkPipelineLayout VkPipelineLayoutCreateInfo layoutCreateInfo; memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags)); layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; layoutCreateInfo.pNext = 0; layoutCreateInfo.flags = 0; layoutCreateInfo.setLayoutCount = 2; layoutCreateInfo.pSetLayouts = dsLayout; layoutCreateInfo.pushConstantRangeCount = 0; layoutCreateInfo.pPushConstantRanges = nullptr; GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreatePipelineLayout(fGpu->device(), &layoutCreateInfo, nullptr, &pipelineLayout)); // We need to enable the following extensions so that the compiler can correctly make spir-v // from our glsl shaders. fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n"); fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n"); fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n"); fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n"); this->finalizeShaders(); VkPipelineShaderStageCreateInfo shaderStageInfo[2]; SkAssertResult(CreateVkShaderModule(fGpu, VK_SHADER_STAGE_VERTEX_BIT, fVS, &vertShaderModule, &shaderStageInfo[0])); SkAssertResult(CreateVkShaderModule(fGpu, VK_SHADER_STAGE_FRAGMENT_BIT, fFS, &fragShaderModule, &shaderStageInfo[1])); GrVkResourceProvider& resourceProvider = fGpu->resourceProvider(); GrVkPipeline* pipeline = resourceProvider.createPipeline(*args.fPipeline, *args.fPrimitiveProcessor, shaderStageInfo, 2, primitiveType, renderPass, pipelineLayout); GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), vertShaderModule, nullptr)); GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), fragShaderModule, nullptr)); if (!pipeline) { GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pipelineLayout, nullptr)); GR_VK_CALL(fGpu->vkInterface(), DestroyDescriptorSetLayout(fGpu->device(), dsLayout[0], nullptr)); GR_VK_CALL(fGpu->vkInterface(), DestroyDescriptorSetLayout(fGpu->device(), dsLayout[1], nullptr)); return nullptr; } GrVkDescriptorPool::DescriptorTypeCounts typeCounts; typeCounts.setTypeCount(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2); SkASSERT(numSamplers < 256); typeCounts.setTypeCount(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, (uint8_t)numSamplers); GrVkDescriptorPool* descriptorPool = fGpu->resourceProvider().findOrCreateCompatibleDescriptorPool(typeCounts); VkDescriptorSetAllocateInfo dsAllocateInfo; memset(&dsAllocateInfo, 0, sizeof(VkDescriptorSetAllocateInfo)); dsAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; dsAllocateInfo.pNext = nullptr; dsAllocateInfo.descriptorPool = descriptorPool->descPool(); dsAllocateInfo.descriptorSetCount = 2; dsAllocateInfo.pSetLayouts = dsLayout; VkDescriptorSet descriptorSets[2]; GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), AllocateDescriptorSets(fGpu->device(), &dsAllocateInfo, descriptorSets)); return new GrVkProgram(fGpu, pipeline, pipelineLayout, dsLayout, descriptorPool, descriptorSets, fUniformHandles, fUniformHandler.fUniforms, fUniformHandler.fCurrentVertexUBOOffset, fUniformHandler.fCurrentFragmentUBOOffset, numSamplers, fGeometryProcessor, fXferProcessor, fFragmentProcessors); }
GrVkPipelineState* GrVkPipelineStateBuilder::finalize(GrPrimitiveType primitiveType, const GrVkRenderPass& renderPass, const GrVkPipelineState::Desc& desc) { VkDescriptorSetLayout dsLayout[2]; VkPipelineLayout pipelineLayout; VkShaderModule vertShaderModule; VkShaderModule fragShaderModule; GrVkResourceProvider& resourceProvider = fGpu->resourceProvider(); // This layout is not owned by the PipelineStateBuilder and thus should no be destroyed dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUniformDSLayout(); GrVkDescriptorSetManager::Handle samplerDSHandle; resourceProvider.getSamplerDescriptorSetHandle(fUniformHandler, &samplerDSHandle); dsLayout[GrVkUniformHandler::kSamplerDescSet] = resourceProvider.getSamplerDSLayout(samplerDSHandle); // Create the VkPipelineLayout VkPipelineLayoutCreateInfo layoutCreateInfo; memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags)); layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; layoutCreateInfo.pNext = 0; layoutCreateInfo.flags = 0; layoutCreateInfo.setLayoutCount = 2; layoutCreateInfo.pSetLayouts = dsLayout; layoutCreateInfo.pushConstantRangeCount = 0; layoutCreateInfo.pPushConstantRanges = nullptr; GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreatePipelineLayout(fGpu->device(), &layoutCreateInfo, nullptr, &pipelineLayout)); // We need to enable the following extensions so that the compiler can correctly make spir-v // from our glsl shaders. fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n"); fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n"); fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n"); fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n"); this->finalizeShaders(); VkPipelineShaderStageCreateInfo shaderStageInfo[2]; SkAssertResult(CreateVkShaderModule(fGpu, VK_SHADER_STAGE_VERTEX_BIT, fVS, &vertShaderModule, &shaderStageInfo[0])); SkAssertResult(CreateVkShaderModule(fGpu, VK_SHADER_STAGE_FRAGMENT_BIT, fFS, &fragShaderModule, &shaderStageInfo[1])); GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline, fPrimProc, shaderStageInfo, 2, primitiveType, renderPass, pipelineLayout); GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), vertShaderModule, nullptr)); GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), fragShaderModule, nullptr)); if (!pipeline) { GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pipelineLayout, nullptr)); GR_VK_CALL(fGpu->vkInterface(), DestroyDescriptorSetLayout(fGpu->device(), dsLayout[GrVkUniformHandler::kSamplerDescSet], nullptr)); this->cleanupFragmentProcessors(); return nullptr; } return new GrVkPipelineState(fGpu, desc, pipeline, pipelineLayout, samplerDSHandle, fUniformHandles, fUniformHandler.fUniforms, fUniformHandler.fCurrentVertexUBOOffset, fUniformHandler.fCurrentFragmentUBOOffset, (uint32_t)fUniformHandler.numSamplers(), fGeometryProcessor, fXferProcessor, fFragmentProcessors); }
bool GrVkCopyManager::createCopyProgram(GrVkGpu* gpu) { TRACE_EVENT0("skia", TRACE_FUNC); const GrShaderCaps* shaderCaps = gpu->caps()->shaderCaps(); const char* version = shaderCaps->versionDeclString(); SkSL::String vertShaderText(version); vertShaderText.append( "#extension GL_ARB_separate_shader_objects : enable\n" "#extension GL_ARB_shading_language_420pack : enable\n" "layout(set = 0, binding = 0) uniform vertexUniformBuffer {" "half4 uPosXform;" "half4 uTexCoordXform;" "};" "layout(location = 0) in float2 inPosition;" "layout(location = 1) out half2 vTexCoord;" "// Copy Program VS\n" "void main() {" "vTexCoord = half2(inPosition * uTexCoordXform.xy + uTexCoordXform.zw);" "sk_Position.xy = inPosition * uPosXform.xy + uPosXform.zw;" "sk_Position.zw = half2(0, 1);" "}" ); SkSL::String fragShaderText(version); fragShaderText.append( "#extension GL_ARB_separate_shader_objects : enable\n" "#extension GL_ARB_shading_language_420pack : enable\n" "layout(set = 1, binding = 0) uniform sampler2D uTextureSampler;" "layout(location = 1) in half2 vTexCoord;" "// Copy Program FS\n" "void main() {" "sk_FragColor = texture(uTextureSampler, vTexCoord);" "}" ); SkSL::Program::Settings settings; SkSL::String spirv; SkSL::Program::Inputs inputs; if (!GrCompileVkShaderModule(gpu, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT, &fVertShaderModule, &fShaderStageInfo[0], settings, &spirv, &inputs)) { this->destroyResources(gpu); return false; } SkASSERT(inputs.isEmpty()); if (!GrCompileVkShaderModule(gpu, fragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, &fFragShaderModule, &fShaderStageInfo[1], settings, &spirv, &inputs)) { this->destroyResources(gpu); return false; } SkASSERT(inputs.isEmpty()); VkDescriptorSetLayout dsLayout[2]; GrVkResourceProvider& resourceProvider = gpu->resourceProvider(); dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUniformDSLayout(); uint32_t samplerVisibility = kFragment_GrShaderFlag; SkTArray<uint32_t> visibilityArray(&samplerVisibility, 1); resourceProvider.getSamplerDescriptorSetHandle(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, visibilityArray, &fSamplerDSHandle); dsLayout[GrVkUniformHandler::kSamplerDescSet] = resourceProvider.getSamplerDSLayout(fSamplerDSHandle); // Create the VkPipelineLayout VkPipelineLayoutCreateInfo layoutCreateInfo; memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags)); layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; layoutCreateInfo.pNext = 0; layoutCreateInfo.flags = 0; layoutCreateInfo.setLayoutCount = 2; layoutCreateInfo.pSetLayouts = dsLayout; layoutCreateInfo.pushConstantRangeCount = 0; layoutCreateInfo.pPushConstantRanges = nullptr; VkPipelineLayout pipelineLayout; VkResult err = GR_VK_CALL(gpu->vkInterface(), CreatePipelineLayout(gpu->device(), &layoutCreateInfo, nullptr, &pipelineLayout)); if (err) { this->destroyResources(gpu); return false; } fPipelineLayout = new GrVkPipelineLayout(pipelineLayout); static const float vdata[] = { 0, 0, 0, 1, 1, 0, 1, 1 }; fVertexBuffer = GrVkVertexBuffer::Make(gpu, sizeof(vdata), false); SkASSERT(fVertexBuffer.get()); fVertexBuffer->updateData(vdata, sizeof(vdata)); // We use 2 float4's for uniforms fUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, 8 * sizeof(float))); SkASSERT(fUniformBuffer.get()); return true; }