1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "GrVkCopyPipeline.h"
9 
10 #include "GrVkGpu.h"
11 #include "GrVkUtil.h"
12 #include "SkOnce.h"
13 
14 static void setup_multisample_state(int numSamples,
15                                     VkPipelineMultisampleStateCreateInfo* multisampleInfo) {
16     memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo));
17     multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
18     multisampleInfo->pNext = nullptr;
19     multisampleInfo->flags = 0;
20     SkAssertResult(GrSampleCountToVkSampleCount(numSamples,
21                                                 &multisampleInfo->rasterizationSamples));
22     multisampleInfo->sampleShadingEnable = VK_FALSE;
23     multisampleInfo->minSampleShading = 0.0f;
24     multisampleInfo->pSampleMask = nullptr;
25     multisampleInfo->alphaToCoverageEnable = VK_FALSE;
26     multisampleInfo->alphaToOneEnable = VK_FALSE;
27 }
28 
29 GrVkCopyPipeline* GrVkCopyPipeline::Create(GrVkGpu* gpu,
30                                            VkPipelineShaderStageCreateInfo* shaderStageInfo,
31                                            VkPipelineLayout pipelineLayout,
32                                            int numSamples,
33                                            const GrVkRenderPass& renderPass,
34                                            VkPipelineCache cache) {
35 
36     static const VkVertexInputAttributeDescription attributeDesc = {
37         0,                        // location
38         0,                        // binding
39         VK_FORMAT_R32G32_SFLOAT,  // format
40         0,                        // offset
41     };
42 
43     static const VkVertexInputBindingDescription bindingDesc = {
44         0,                           // binding
45         2 * sizeof(float),           // stride
46         VK_VERTEX_INPUT_RATE_VERTEX  // inputRate
47     };
48 
49     static const VkPipelineVertexInputStateCreateInfo vertexInputInfo = {
50         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,  // sType
51         nullptr,                                                    // pNext
52         0,                                                          // flags
53         1,                                                          // vertexBindingDescriptionCount
54         &bindingDesc,                                               // pVertexBindingDescriptions
55         1,                                                          // vertexAttributeDescriptionCnt
56         &attributeDesc,                                             // pVertexAttributeDescriptions
57     };
58 
59     static const VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = {
60         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,  // sType
61         nullptr,                                                      // pNext
62         0,                                                            // flags
63         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,                         // topology
64         VK_FALSE                                                      // primitiveRestartEnable
65     };
66 
67     static const VkStencilOpState dummyStencilState = {
68         VK_STENCIL_OP_KEEP,   // failOp
69         VK_STENCIL_OP_KEEP,   // passOp
70         VK_STENCIL_OP_KEEP,   // depthFailOp
71         VK_COMPARE_OP_NEVER,  // compareOp
72         0,                    // compareMask
73         0,                    // writeMask
74         0                     // reference
75     };
76 
77     static const VkPipelineDepthStencilStateCreateInfo stencilInfo = {
78         VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,  // sType
79         nullptr,                                                     // pNext
80         0,                                                           // flags
81         VK_FALSE,                                                    // depthTestEnable
82         VK_FALSE,                                                    // depthWriteEnable
83         VK_COMPARE_OP_ALWAYS,                                        // depthCompareOp
84         VK_FALSE,                                                    // depthBoundsTestEnable
85         VK_FALSE,                                                    // stencilTestEnable
86         dummyStencilState,                                           // front
87         dummyStencilState,                                           // bakc
88         0.0f,                                                        // minDepthBounds
89         1.0f                                                         // maxDepthBounds
90     };
91 
92     static const VkPipelineViewportStateCreateInfo viewportInfo = {
93         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // sType
94         nullptr,                                                // pNext
95         0,                                                      // flags
96         1,                                                      // viewportCount
97         nullptr,                                                // pViewports
98         1,                                                      // scissorCount
99         nullptr                                                 // pScissors
100     };
101 
102     static const VkPipelineColorBlendAttachmentState attachmentState = {
103         VK_TRUE,                                             // belndEnable
104         VK_BLEND_FACTOR_ONE,                                 // srcColorBlendFactor
105         VK_BLEND_FACTOR_ZERO,                                 // dstColorBlendFactor
106         VK_BLEND_OP_ADD,                                      // colorBlendOp
107         VK_BLEND_FACTOR_ONE,                                 // srcAlphaBlendFactor
108         VK_BLEND_FACTOR_ZERO,                                 // dstAlphaBlendFactor
109         VK_BLEND_OP_ADD,                                      // alphaBlendOp
110         VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // colorWriteMask
111         VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT   // colorWriteMask
112     };
113 
114     static const VkPipelineColorBlendStateCreateInfo colorBlendInfo = {
115         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,  // sType
116         nullptr,                                                   // pNext
117         0,                                                         // flags
118         VK_FALSE,                                                  // logicOpEnable
119         VK_LOGIC_OP_CLEAR,                                         // logicOp
120         1,                                                         // attachmentCount
121         &attachmentState,                                          // pAttachments
122         { 0.f, 0.f, 0.f, 0.f }                                       // blendConstants[4]
123     };
124 
125     static const VkPipelineRasterizationStateCreateInfo rasterInfo = {
126         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,  // sType
127         nullptr,                                                     // pNext
128         0,                                                           // flags
129         VK_FALSE,                                                    // depthClampEnable
130         VK_FALSE,                                                    // rasterizerDiscardEnabled
131         VK_POLYGON_MODE_FILL,                                        // polygonMode
132         VK_CULL_MODE_NONE,                                           // cullMode
133         VK_FRONT_FACE_COUNTER_CLOCKWISE,                             // frontFace
134         VK_FALSE,                                                    // depthBiasEnable
135         0.0f,                                                        // depthBiasConstantFactor
136         0.0f,                                                        // depthBiasClamp
137         0.0f,                                                        // depthBiasSlopeFactor
138         1.0f                                                         // lineWidth
139     };
140 
141     static const VkDynamicState dynamicStates[2] = { VK_DYNAMIC_STATE_VIEWPORT,
142         VK_DYNAMIC_STATE_SCISSOR };
143     static const VkPipelineDynamicStateCreateInfo dynamicInfo = {
144         VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,  // sType
145         nullptr,                                               // pNext
146         0,                                                     // flags
147         2,                                                     // dynamicStateCount
148         dynamicStates                                          // pDynamicStates
149     };
150 
151     VkPipelineMultisampleStateCreateInfo multisampleInfo;
152     setup_multisample_state(numSamples, &multisampleInfo);
153 
154     VkGraphicsPipelineCreateInfo pipelineCreateInfo;
155     memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo));
156     pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
157     pipelineCreateInfo.pNext = nullptr;
158     pipelineCreateInfo.flags = 0;
159     pipelineCreateInfo.stageCount = 2;
160     pipelineCreateInfo.pStages = shaderStageInfo;
161     pipelineCreateInfo.pVertexInputState = &vertexInputInfo;
162     pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo;
163     pipelineCreateInfo.pTessellationState = nullptr;
164     pipelineCreateInfo.pViewportState = &viewportInfo;
165     pipelineCreateInfo.pRasterizationState = &rasterInfo;
166     pipelineCreateInfo.pMultisampleState = &multisampleInfo;
167     pipelineCreateInfo.pDepthStencilState = &stencilInfo;
168     pipelineCreateInfo.pColorBlendState = &colorBlendInfo;
169     pipelineCreateInfo.pDynamicState = &dynamicInfo;
170     pipelineCreateInfo.layout = pipelineLayout;
171     pipelineCreateInfo.renderPass = renderPass.vkRenderPass();
172     pipelineCreateInfo.subpass = 0;
173     pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
174     pipelineCreateInfo.basePipelineIndex = -1;
175 
176     VkPipeline vkPipeline;
177     VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateGraphicsPipelines(gpu->device(),
178                                                                           cache, 1,
179                                                                           &pipelineCreateInfo,
180                                                                           nullptr, &vkPipeline));
181     if (err) {
182         SkDebugf("Failed to create copy pipeline. Error: %d\n", err);
183         return nullptr;
184     }
185 
186     return new GrVkCopyPipeline(vkPipeline, &renderPass);
187 }
188 
189 bool GrVkCopyPipeline::isCompatible(const GrVkRenderPass& rp) const {
190     return rp.isCompatible(*fRenderPass);
191 }
192