1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci* Copyright 2016 Google Inc.
3cb93a386Sopenharmony_ci*
4cb93a386Sopenharmony_ci* Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci* found in the LICENSE file.
6cb93a386Sopenharmony_ci*/
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkPipeline.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "src/core/SkTraceEvent.h"
11cb93a386Sopenharmony_ci#include "src/gpu/GrGeometryProcessor.h"
12cb93a386Sopenharmony_ci#include "src/gpu/GrPipeline.h"
13cb93a386Sopenharmony_ci#include "src/gpu/GrStencilSettings.h"
14cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkCommandBuffer.h"
15cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkGpu.h"
16cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkRenderTarget.h"
17cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkUtil.h"
18cb93a386Sopenharmony_ci
19cb93a386Sopenharmony_ci#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
20cb93a386Sopenharmony_ci#include <sanitizer/lsan_interface.h>
21cb93a386Sopenharmony_ci#endif
22cb93a386Sopenharmony_ci
23cb93a386Sopenharmony_cistatic inline VkFormat attrib_type_to_vkformat(GrVertexAttribType type) {
24cb93a386Sopenharmony_ci    switch (type) {
25cb93a386Sopenharmony_ci        case kFloat_GrVertexAttribType:
26cb93a386Sopenharmony_ci            return VK_FORMAT_R32_SFLOAT;
27cb93a386Sopenharmony_ci        case kFloat2_GrVertexAttribType:
28cb93a386Sopenharmony_ci            return VK_FORMAT_R32G32_SFLOAT;
29cb93a386Sopenharmony_ci        case kFloat3_GrVertexAttribType:
30cb93a386Sopenharmony_ci            return VK_FORMAT_R32G32B32_SFLOAT;
31cb93a386Sopenharmony_ci        case kFloat4_GrVertexAttribType:
32cb93a386Sopenharmony_ci            return VK_FORMAT_R32G32B32A32_SFLOAT;
33cb93a386Sopenharmony_ci        case kHalf_GrVertexAttribType:
34cb93a386Sopenharmony_ci            return VK_FORMAT_R16_SFLOAT;
35cb93a386Sopenharmony_ci        case kHalf2_GrVertexAttribType:
36cb93a386Sopenharmony_ci            return VK_FORMAT_R16G16_SFLOAT;
37cb93a386Sopenharmony_ci        case kHalf4_GrVertexAttribType:
38cb93a386Sopenharmony_ci            return VK_FORMAT_R16G16B16A16_SFLOAT;
39cb93a386Sopenharmony_ci        case kInt2_GrVertexAttribType:
40cb93a386Sopenharmony_ci            return VK_FORMAT_R32G32_SINT;
41cb93a386Sopenharmony_ci        case kInt3_GrVertexAttribType:
42cb93a386Sopenharmony_ci            return VK_FORMAT_R32G32B32_SINT;
43cb93a386Sopenharmony_ci        case kInt4_GrVertexAttribType:
44cb93a386Sopenharmony_ci            return VK_FORMAT_R32G32B32A32_SINT;
45cb93a386Sopenharmony_ci        case kByte_GrVertexAttribType:
46cb93a386Sopenharmony_ci            return VK_FORMAT_R8_SINT;
47cb93a386Sopenharmony_ci        case kByte2_GrVertexAttribType:
48cb93a386Sopenharmony_ci            return VK_FORMAT_R8G8_SINT;
49cb93a386Sopenharmony_ci        case kByte4_GrVertexAttribType:
50cb93a386Sopenharmony_ci            return VK_FORMAT_R8G8B8A8_SINT;
51cb93a386Sopenharmony_ci        case kUByte_GrVertexAttribType:
52cb93a386Sopenharmony_ci            return VK_FORMAT_R8_UINT;
53cb93a386Sopenharmony_ci        case kUByte2_GrVertexAttribType:
54cb93a386Sopenharmony_ci            return VK_FORMAT_R8G8_UINT;
55cb93a386Sopenharmony_ci        case kUByte4_GrVertexAttribType:
56cb93a386Sopenharmony_ci            return VK_FORMAT_R8G8B8A8_UINT;
57cb93a386Sopenharmony_ci        case kUByte_norm_GrVertexAttribType:
58cb93a386Sopenharmony_ci            return VK_FORMAT_R8_UNORM;
59cb93a386Sopenharmony_ci        case kUByte4_norm_GrVertexAttribType:
60cb93a386Sopenharmony_ci            return VK_FORMAT_R8G8B8A8_UNORM;
61cb93a386Sopenharmony_ci        case kShort2_GrVertexAttribType:
62cb93a386Sopenharmony_ci            return VK_FORMAT_R16G16_SINT;
63cb93a386Sopenharmony_ci        case kShort4_GrVertexAttribType:
64cb93a386Sopenharmony_ci            return VK_FORMAT_R16G16B16A16_SINT;
65cb93a386Sopenharmony_ci        case kUShort2_GrVertexAttribType:
66cb93a386Sopenharmony_ci            return VK_FORMAT_R16G16_UINT;
67cb93a386Sopenharmony_ci        case kUShort2_norm_GrVertexAttribType:
68cb93a386Sopenharmony_ci            return VK_FORMAT_R16G16_UNORM;
69cb93a386Sopenharmony_ci        case kInt_GrVertexAttribType:
70cb93a386Sopenharmony_ci            return VK_FORMAT_R32_SINT;
71cb93a386Sopenharmony_ci        case kUInt_GrVertexAttribType:
72cb93a386Sopenharmony_ci            return VK_FORMAT_R32_UINT;
73cb93a386Sopenharmony_ci        case kUShort_norm_GrVertexAttribType:
74cb93a386Sopenharmony_ci            return VK_FORMAT_R16_UNORM;
75cb93a386Sopenharmony_ci        case kUShort4_norm_GrVertexAttribType:
76cb93a386Sopenharmony_ci            return VK_FORMAT_R16G16B16A16_UNORM;
77cb93a386Sopenharmony_ci    }
78cb93a386Sopenharmony_ci    SK_ABORT("Unknown vertex attrib type");
79cb93a386Sopenharmony_ci}
80cb93a386Sopenharmony_ci
81cb93a386Sopenharmony_cistatic void setup_vertex_input_state(
82cb93a386Sopenharmony_ci        const GrGeometryProcessor::AttributeSet& vertexAttribs,
83cb93a386Sopenharmony_ci        const GrGeometryProcessor::AttributeSet& instanceAttribs,
84cb93a386Sopenharmony_ci        VkPipelineVertexInputStateCreateInfo* vertexInputInfo,
85cb93a386Sopenharmony_ci        SkSTArray<2, VkVertexInputBindingDescription, true>* bindingDescs,
86cb93a386Sopenharmony_ci        VkVertexInputAttributeDescription* attributeDesc) {
87cb93a386Sopenharmony_ci    int vaCount = vertexAttribs.count();
88cb93a386Sopenharmony_ci    int iaCount = instanceAttribs.count();
89cb93a386Sopenharmony_ci
90cb93a386Sopenharmony_ci    uint32_t vertexBinding = 0, instanceBinding = 0;
91cb93a386Sopenharmony_ci
92cb93a386Sopenharmony_ci    int nextBinding = bindingDescs->count();
93cb93a386Sopenharmony_ci    if (vaCount) {
94cb93a386Sopenharmony_ci        vertexBinding = nextBinding++;
95cb93a386Sopenharmony_ci    }
96cb93a386Sopenharmony_ci
97cb93a386Sopenharmony_ci    if (iaCount) {
98cb93a386Sopenharmony_ci        instanceBinding = nextBinding;
99cb93a386Sopenharmony_ci    }
100cb93a386Sopenharmony_ci
101cb93a386Sopenharmony_ci    // setup attribute descriptions
102cb93a386Sopenharmony_ci    int attribIndex = 0;
103cb93a386Sopenharmony_ci    size_t vertexAttributeOffset = 0;
104cb93a386Sopenharmony_ci    for (const auto& attrib : vertexAttribs) {
105cb93a386Sopenharmony_ci        VkVertexInputAttributeDescription& vkAttrib = attributeDesc[attribIndex];
106cb93a386Sopenharmony_ci        vkAttrib.location = attribIndex++;  // for now assume location = attribIndex
107cb93a386Sopenharmony_ci        vkAttrib.binding = vertexBinding;
108cb93a386Sopenharmony_ci        vkAttrib.format = attrib_type_to_vkformat(attrib.cpuType());
109cb93a386Sopenharmony_ci        vkAttrib.offset = vertexAttributeOffset;
110cb93a386Sopenharmony_ci        vertexAttributeOffset += attrib.sizeAlign4();
111cb93a386Sopenharmony_ci    }
112cb93a386Sopenharmony_ci    SkASSERT(vertexAttributeOffset == vertexAttribs.stride());
113cb93a386Sopenharmony_ci
114cb93a386Sopenharmony_ci    size_t instanceAttributeOffset = 0;
115cb93a386Sopenharmony_ci    for (const auto& attrib : instanceAttribs) {
116cb93a386Sopenharmony_ci        VkVertexInputAttributeDescription& vkAttrib = attributeDesc[attribIndex];
117cb93a386Sopenharmony_ci        vkAttrib.location = attribIndex++;  // for now assume location = attribIndex
118cb93a386Sopenharmony_ci        vkAttrib.binding = instanceBinding;
119cb93a386Sopenharmony_ci        vkAttrib.format = attrib_type_to_vkformat(attrib.cpuType());
120cb93a386Sopenharmony_ci        vkAttrib.offset = instanceAttributeOffset;
121cb93a386Sopenharmony_ci        instanceAttributeOffset += attrib.sizeAlign4();
122cb93a386Sopenharmony_ci    }
123cb93a386Sopenharmony_ci    SkASSERT(instanceAttributeOffset == instanceAttribs.stride());
124cb93a386Sopenharmony_ci
125cb93a386Sopenharmony_ci    if (vaCount) {
126cb93a386Sopenharmony_ci        bindingDescs->push_back() = {
127cb93a386Sopenharmony_ci                vertexBinding,
128cb93a386Sopenharmony_ci                (uint32_t) vertexAttributeOffset,
129cb93a386Sopenharmony_ci                VK_VERTEX_INPUT_RATE_VERTEX
130cb93a386Sopenharmony_ci        };
131cb93a386Sopenharmony_ci    }
132cb93a386Sopenharmony_ci    if (iaCount) {
133cb93a386Sopenharmony_ci        bindingDescs->push_back() = {
134cb93a386Sopenharmony_ci                instanceBinding,
135cb93a386Sopenharmony_ci                (uint32_t) instanceAttributeOffset,
136cb93a386Sopenharmony_ci                VK_VERTEX_INPUT_RATE_INSTANCE
137cb93a386Sopenharmony_ci        };
138cb93a386Sopenharmony_ci    }
139cb93a386Sopenharmony_ci
140cb93a386Sopenharmony_ci    memset(vertexInputInfo, 0, sizeof(VkPipelineVertexInputStateCreateInfo));
141cb93a386Sopenharmony_ci    vertexInputInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
142cb93a386Sopenharmony_ci    vertexInputInfo->pNext = nullptr;
143cb93a386Sopenharmony_ci    vertexInputInfo->flags = 0;
144cb93a386Sopenharmony_ci    vertexInputInfo->vertexBindingDescriptionCount = bindingDescs->count();
145cb93a386Sopenharmony_ci    vertexInputInfo->pVertexBindingDescriptions = bindingDescs->begin();
146cb93a386Sopenharmony_ci    vertexInputInfo->vertexAttributeDescriptionCount = vaCount + iaCount;
147cb93a386Sopenharmony_ci    vertexInputInfo->pVertexAttributeDescriptions = attributeDesc;
148cb93a386Sopenharmony_ci}
149cb93a386Sopenharmony_ci
150cb93a386Sopenharmony_cistatic VkPrimitiveTopology gr_primitive_type_to_vk_topology(GrPrimitiveType primitiveType) {
151cb93a386Sopenharmony_ci    switch (primitiveType) {
152cb93a386Sopenharmony_ci        case GrPrimitiveType::kTriangles:
153cb93a386Sopenharmony_ci            return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
154cb93a386Sopenharmony_ci        case GrPrimitiveType::kTriangleStrip:
155cb93a386Sopenharmony_ci            return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
156cb93a386Sopenharmony_ci        case GrPrimitiveType::kPoints:
157cb93a386Sopenharmony_ci            return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
158cb93a386Sopenharmony_ci        case GrPrimitiveType::kLines:
159cb93a386Sopenharmony_ci            return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
160cb93a386Sopenharmony_ci        case GrPrimitiveType::kLineStrip:
161cb93a386Sopenharmony_ci            return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
162cb93a386Sopenharmony_ci        case GrPrimitiveType::kPatches:
163cb93a386Sopenharmony_ci        case GrPrimitiveType::kPath:
164cb93a386Sopenharmony_ci            SK_ABORT("Unsupported primitive type");
165cb93a386Sopenharmony_ci    }
166cb93a386Sopenharmony_ci    SkUNREACHABLE;
167cb93a386Sopenharmony_ci}
168cb93a386Sopenharmony_ci
169cb93a386Sopenharmony_cistatic void setup_input_assembly_state(GrPrimitiveType primitiveType,
170cb93a386Sopenharmony_ci                                       VkPipelineInputAssemblyStateCreateInfo* inputAssemblyInfo) {
171cb93a386Sopenharmony_ci    memset(inputAssemblyInfo, 0, sizeof(VkPipelineInputAssemblyStateCreateInfo));
172cb93a386Sopenharmony_ci    inputAssemblyInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
173cb93a386Sopenharmony_ci    inputAssemblyInfo->pNext = nullptr;
174cb93a386Sopenharmony_ci    inputAssemblyInfo->flags = 0;
175cb93a386Sopenharmony_ci    inputAssemblyInfo->primitiveRestartEnable = false;
176cb93a386Sopenharmony_ci    inputAssemblyInfo->topology = gr_primitive_type_to_vk_topology(primitiveType);
177cb93a386Sopenharmony_ci}
178cb93a386Sopenharmony_ci
179cb93a386Sopenharmony_cistatic VkStencilOp stencil_op_to_vk_stencil_op(GrStencilOp op) {
180cb93a386Sopenharmony_ci    static const VkStencilOp gTable[] = {
181cb93a386Sopenharmony_ci        VK_STENCIL_OP_KEEP,                 // kKeep
182cb93a386Sopenharmony_ci        VK_STENCIL_OP_ZERO,                 // kZero
183cb93a386Sopenharmony_ci        VK_STENCIL_OP_REPLACE,              // kReplace
184cb93a386Sopenharmony_ci        VK_STENCIL_OP_INVERT,               // kInvert
185cb93a386Sopenharmony_ci        VK_STENCIL_OP_INCREMENT_AND_WRAP,   // kIncWrap
186cb93a386Sopenharmony_ci        VK_STENCIL_OP_DECREMENT_AND_WRAP,   // kDecWrap
187cb93a386Sopenharmony_ci        VK_STENCIL_OP_INCREMENT_AND_CLAMP,  // kIncClamp
188cb93a386Sopenharmony_ci        VK_STENCIL_OP_DECREMENT_AND_CLAMP,  // kDecClamp
189cb93a386Sopenharmony_ci    };
190cb93a386Sopenharmony_ci    static_assert(SK_ARRAY_COUNT(gTable) == kGrStencilOpCount);
191cb93a386Sopenharmony_ci    static_assert(0 == (int)GrStencilOp::kKeep);
192cb93a386Sopenharmony_ci    static_assert(1 == (int)GrStencilOp::kZero);
193cb93a386Sopenharmony_ci    static_assert(2 == (int)GrStencilOp::kReplace);
194cb93a386Sopenharmony_ci    static_assert(3 == (int)GrStencilOp::kInvert);
195cb93a386Sopenharmony_ci    static_assert(4 == (int)GrStencilOp::kIncWrap);
196cb93a386Sopenharmony_ci    static_assert(5 == (int)GrStencilOp::kDecWrap);
197cb93a386Sopenharmony_ci    static_assert(6 == (int)GrStencilOp::kIncClamp);
198cb93a386Sopenharmony_ci    static_assert(7 == (int)GrStencilOp::kDecClamp);
199cb93a386Sopenharmony_ci    SkASSERT(op < (GrStencilOp)kGrStencilOpCount);
200cb93a386Sopenharmony_ci    return gTable[(int)op];
201cb93a386Sopenharmony_ci}
202cb93a386Sopenharmony_ci
203cb93a386Sopenharmony_cistatic VkCompareOp stencil_func_to_vk_compare_op(GrStencilTest test) {
204cb93a386Sopenharmony_ci    static const VkCompareOp gTable[] = {
205cb93a386Sopenharmony_ci        VK_COMPARE_OP_ALWAYS,              // kAlways
206cb93a386Sopenharmony_ci        VK_COMPARE_OP_NEVER,               // kNever
207cb93a386Sopenharmony_ci        VK_COMPARE_OP_GREATER,             // kGreater
208cb93a386Sopenharmony_ci        VK_COMPARE_OP_GREATER_OR_EQUAL,    // kGEqual
209cb93a386Sopenharmony_ci        VK_COMPARE_OP_LESS,                // kLess
210cb93a386Sopenharmony_ci        VK_COMPARE_OP_LESS_OR_EQUAL,       // kLEqual
211cb93a386Sopenharmony_ci        VK_COMPARE_OP_EQUAL,               // kEqual
212cb93a386Sopenharmony_ci        VK_COMPARE_OP_NOT_EQUAL,           // kNotEqual
213cb93a386Sopenharmony_ci    };
214cb93a386Sopenharmony_ci    static_assert(SK_ARRAY_COUNT(gTable) == kGrStencilTestCount);
215cb93a386Sopenharmony_ci    static_assert(0 == (int)GrStencilTest::kAlways);
216cb93a386Sopenharmony_ci    static_assert(1 == (int)GrStencilTest::kNever);
217cb93a386Sopenharmony_ci    static_assert(2 == (int)GrStencilTest::kGreater);
218cb93a386Sopenharmony_ci    static_assert(3 == (int)GrStencilTest::kGEqual);
219cb93a386Sopenharmony_ci    static_assert(4 == (int)GrStencilTest::kLess);
220cb93a386Sopenharmony_ci    static_assert(5 == (int)GrStencilTest::kLEqual);
221cb93a386Sopenharmony_ci    static_assert(6 == (int)GrStencilTest::kEqual);
222cb93a386Sopenharmony_ci    static_assert(7 == (int)GrStencilTest::kNotEqual);
223cb93a386Sopenharmony_ci    SkASSERT(test < (GrStencilTest)kGrStencilTestCount);
224cb93a386Sopenharmony_ci
225cb93a386Sopenharmony_ci    return gTable[(int)test];
226cb93a386Sopenharmony_ci}
227cb93a386Sopenharmony_ci
228cb93a386Sopenharmony_cistatic void setup_stencil_op_state(
229cb93a386Sopenharmony_ci        VkStencilOpState* opState, const GrStencilSettings::Face& stencilFace) {
230cb93a386Sopenharmony_ci    opState->failOp = stencil_op_to_vk_stencil_op(stencilFace.fFailOp);
231cb93a386Sopenharmony_ci    opState->passOp = stencil_op_to_vk_stencil_op(stencilFace.fPassOp);
232cb93a386Sopenharmony_ci    opState->depthFailOp = opState->failOp;
233cb93a386Sopenharmony_ci    opState->compareOp = stencil_func_to_vk_compare_op(stencilFace.fTest);
234cb93a386Sopenharmony_ci    opState->compareMask = stencilFace.fTestMask;
235cb93a386Sopenharmony_ci    opState->writeMask = stencilFace.fWriteMask;
236cb93a386Sopenharmony_ci    opState->reference = stencilFace.fRef;
237cb93a386Sopenharmony_ci}
238cb93a386Sopenharmony_ci
239cb93a386Sopenharmony_cistatic void setup_depth_stencil_state(
240cb93a386Sopenharmony_ci        const GrStencilSettings& stencilSettings,
241cb93a386Sopenharmony_ci        GrSurfaceOrigin origin,
242cb93a386Sopenharmony_ci        VkPipelineDepthStencilStateCreateInfo* stencilInfo) {
243cb93a386Sopenharmony_ci
244cb93a386Sopenharmony_ci    memset(stencilInfo, 0, sizeof(VkPipelineDepthStencilStateCreateInfo));
245cb93a386Sopenharmony_ci    stencilInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
246cb93a386Sopenharmony_ci    stencilInfo->pNext = nullptr;
247cb93a386Sopenharmony_ci    stencilInfo->flags = 0;
248cb93a386Sopenharmony_ci    // set depth testing defaults
249cb93a386Sopenharmony_ci    stencilInfo->depthTestEnable = VK_FALSE;
250cb93a386Sopenharmony_ci    stencilInfo->depthWriteEnable = VK_FALSE;
251cb93a386Sopenharmony_ci    stencilInfo->depthCompareOp = VK_COMPARE_OP_ALWAYS;
252cb93a386Sopenharmony_ci    stencilInfo->depthBoundsTestEnable = VK_FALSE;
253cb93a386Sopenharmony_ci    stencilInfo->stencilTestEnable = !stencilSettings.isDisabled();
254cb93a386Sopenharmony_ci    if (!stencilSettings.isDisabled()) {
255cb93a386Sopenharmony_ci        if (!stencilSettings.isTwoSided()) {
256cb93a386Sopenharmony_ci            setup_stencil_op_state(&stencilInfo->front, stencilSettings.singleSidedFace());
257cb93a386Sopenharmony_ci            stencilInfo->back = stencilInfo->front;
258cb93a386Sopenharmony_ci        } else {
259cb93a386Sopenharmony_ci            setup_stencil_op_state(&stencilInfo->front, stencilSettings.postOriginCCWFace(origin));
260cb93a386Sopenharmony_ci            setup_stencil_op_state(&stencilInfo->back, stencilSettings.postOriginCWFace(origin));
261cb93a386Sopenharmony_ci        }
262cb93a386Sopenharmony_ci    }
263cb93a386Sopenharmony_ci    stencilInfo->minDepthBounds = 0.0f;
264cb93a386Sopenharmony_ci    stencilInfo->maxDepthBounds = 1.0f;
265cb93a386Sopenharmony_ci}
266cb93a386Sopenharmony_ci
267cb93a386Sopenharmony_cistatic void setup_viewport_scissor_state(VkPipelineViewportStateCreateInfo* viewportInfo) {
268cb93a386Sopenharmony_ci    memset(viewportInfo, 0, sizeof(VkPipelineViewportStateCreateInfo));
269cb93a386Sopenharmony_ci    viewportInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
270cb93a386Sopenharmony_ci    viewportInfo->pNext = nullptr;
271cb93a386Sopenharmony_ci    viewportInfo->flags = 0;
272cb93a386Sopenharmony_ci
273cb93a386Sopenharmony_ci    viewportInfo->viewportCount = 1;
274cb93a386Sopenharmony_ci    viewportInfo->pViewports = nullptr; // This is set dynamically
275cb93a386Sopenharmony_ci
276cb93a386Sopenharmony_ci    viewportInfo->scissorCount = 1;
277cb93a386Sopenharmony_ci    viewportInfo->pScissors = nullptr; // This is set dynamically
278cb93a386Sopenharmony_ci
279cb93a386Sopenharmony_ci    SkASSERT(viewportInfo->viewportCount == viewportInfo->scissorCount);
280cb93a386Sopenharmony_ci}
281cb93a386Sopenharmony_ci
282cb93a386Sopenharmony_cistatic void setup_multisample_state(int numSamples,
283cb93a386Sopenharmony_ci                                    const GrCaps* caps,
284cb93a386Sopenharmony_ci                                    VkPipelineMultisampleStateCreateInfo* multisampleInfo) {
285cb93a386Sopenharmony_ci    memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo));
286cb93a386Sopenharmony_ci    multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
287cb93a386Sopenharmony_ci    multisampleInfo->pNext = nullptr;
288cb93a386Sopenharmony_ci    multisampleInfo->flags = 0;
289cb93a386Sopenharmony_ci    SkAssertResult(GrSampleCountToVkSampleCount(numSamples,
290cb93a386Sopenharmony_ci                                                &multisampleInfo->rasterizationSamples));
291cb93a386Sopenharmony_ci    multisampleInfo->sampleShadingEnable = VK_FALSE;
292cb93a386Sopenharmony_ci    multisampleInfo->minSampleShading = 0.0f;
293cb93a386Sopenharmony_ci    multisampleInfo->pSampleMask = nullptr;
294cb93a386Sopenharmony_ci    multisampleInfo->alphaToCoverageEnable = VK_FALSE;
295cb93a386Sopenharmony_ci    multisampleInfo->alphaToOneEnable = VK_FALSE;
296cb93a386Sopenharmony_ci}
297cb93a386Sopenharmony_ci
298cb93a386Sopenharmony_cistatic VkBlendFactor blend_coeff_to_vk_blend(GrBlendCoeff coeff) {
299cb93a386Sopenharmony_ci    switch (coeff) {
300cb93a386Sopenharmony_ci        case kZero_GrBlendCoeff:
301cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_ZERO;
302cb93a386Sopenharmony_ci        case kOne_GrBlendCoeff:
303cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_ONE;
304cb93a386Sopenharmony_ci        case kSC_GrBlendCoeff:
305cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_SRC_COLOR;
306cb93a386Sopenharmony_ci        case kISC_GrBlendCoeff:
307cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
308cb93a386Sopenharmony_ci        case kDC_GrBlendCoeff:
309cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_DST_COLOR;
310cb93a386Sopenharmony_ci        case kIDC_GrBlendCoeff:
311cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
312cb93a386Sopenharmony_ci        case kSA_GrBlendCoeff:
313cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_SRC_ALPHA;
314cb93a386Sopenharmony_ci        case kISA_GrBlendCoeff:
315cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
316cb93a386Sopenharmony_ci        case kDA_GrBlendCoeff:
317cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_DST_ALPHA;
318cb93a386Sopenharmony_ci        case kIDA_GrBlendCoeff:
319cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
320cb93a386Sopenharmony_ci        case kConstC_GrBlendCoeff:
321cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_CONSTANT_COLOR;
322cb93a386Sopenharmony_ci        case kIConstC_GrBlendCoeff:
323cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
324cb93a386Sopenharmony_ci        case kS2C_GrBlendCoeff:
325cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_SRC1_COLOR;
326cb93a386Sopenharmony_ci        case kIS2C_GrBlendCoeff:
327cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
328cb93a386Sopenharmony_ci        case kS2A_GrBlendCoeff:
329cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_SRC1_ALPHA;
330cb93a386Sopenharmony_ci        case kIS2A_GrBlendCoeff:
331cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
332cb93a386Sopenharmony_ci        case kIllegal_GrBlendCoeff:
333cb93a386Sopenharmony_ci            return VK_BLEND_FACTOR_ZERO;
334cb93a386Sopenharmony_ci    }
335cb93a386Sopenharmony_ci    SkUNREACHABLE;
336cb93a386Sopenharmony_ci}
337cb93a386Sopenharmony_ci
338cb93a386Sopenharmony_cistatic VkBlendOp blend_equation_to_vk_blend_op(GrBlendEquation equation) {
339cb93a386Sopenharmony_ci    static const VkBlendOp gTable[] = {
340cb93a386Sopenharmony_ci        // Basic blend ops
341cb93a386Sopenharmony_ci        VK_BLEND_OP_ADD,
342cb93a386Sopenharmony_ci        VK_BLEND_OP_SUBTRACT,
343cb93a386Sopenharmony_ci        VK_BLEND_OP_REVERSE_SUBTRACT,
344cb93a386Sopenharmony_ci
345cb93a386Sopenharmony_ci        // Advanced blend ops
346cb93a386Sopenharmony_ci        VK_BLEND_OP_SCREEN_EXT,
347cb93a386Sopenharmony_ci        VK_BLEND_OP_OVERLAY_EXT,
348cb93a386Sopenharmony_ci        VK_BLEND_OP_DARKEN_EXT,
349cb93a386Sopenharmony_ci        VK_BLEND_OP_LIGHTEN_EXT,
350cb93a386Sopenharmony_ci        VK_BLEND_OP_COLORDODGE_EXT,
351cb93a386Sopenharmony_ci        VK_BLEND_OP_COLORBURN_EXT,
352cb93a386Sopenharmony_ci        VK_BLEND_OP_HARDLIGHT_EXT,
353cb93a386Sopenharmony_ci        VK_BLEND_OP_SOFTLIGHT_EXT,
354cb93a386Sopenharmony_ci        VK_BLEND_OP_DIFFERENCE_EXT,
355cb93a386Sopenharmony_ci        VK_BLEND_OP_EXCLUSION_EXT,
356cb93a386Sopenharmony_ci        VK_BLEND_OP_MULTIPLY_EXT,
357cb93a386Sopenharmony_ci        VK_BLEND_OP_HSL_HUE_EXT,
358cb93a386Sopenharmony_ci        VK_BLEND_OP_HSL_SATURATION_EXT,
359cb93a386Sopenharmony_ci        VK_BLEND_OP_HSL_COLOR_EXT,
360cb93a386Sopenharmony_ci        VK_BLEND_OP_HSL_LUMINOSITY_EXT,
361cb93a386Sopenharmony_ci
362cb93a386Sopenharmony_ci        // Illegal.
363cb93a386Sopenharmony_ci        VK_BLEND_OP_ADD,
364cb93a386Sopenharmony_ci    };
365cb93a386Sopenharmony_ci    static_assert(0 == kAdd_GrBlendEquation);
366cb93a386Sopenharmony_ci    static_assert(1 == kSubtract_GrBlendEquation);
367cb93a386Sopenharmony_ci    static_assert(2 == kReverseSubtract_GrBlendEquation);
368cb93a386Sopenharmony_ci    static_assert(3 == kScreen_GrBlendEquation);
369cb93a386Sopenharmony_ci    static_assert(4 == kOverlay_GrBlendEquation);
370cb93a386Sopenharmony_ci    static_assert(5 == kDarken_GrBlendEquation);
371cb93a386Sopenharmony_ci    static_assert(6 == kLighten_GrBlendEquation);
372cb93a386Sopenharmony_ci    static_assert(7 == kColorDodge_GrBlendEquation);
373cb93a386Sopenharmony_ci    static_assert(8 == kColorBurn_GrBlendEquation);
374cb93a386Sopenharmony_ci    static_assert(9 == kHardLight_GrBlendEquation);
375cb93a386Sopenharmony_ci    static_assert(10 == kSoftLight_GrBlendEquation);
376cb93a386Sopenharmony_ci    static_assert(11 == kDifference_GrBlendEquation);
377cb93a386Sopenharmony_ci    static_assert(12 == kExclusion_GrBlendEquation);
378cb93a386Sopenharmony_ci    static_assert(13 == kMultiply_GrBlendEquation);
379cb93a386Sopenharmony_ci    static_assert(14 == kHSLHue_GrBlendEquation);
380cb93a386Sopenharmony_ci    static_assert(15 == kHSLSaturation_GrBlendEquation);
381cb93a386Sopenharmony_ci    static_assert(16 == kHSLColor_GrBlendEquation);
382cb93a386Sopenharmony_ci    static_assert(17 == kHSLLuminosity_GrBlendEquation);
383cb93a386Sopenharmony_ci    static_assert(SK_ARRAY_COUNT(gTable) == kGrBlendEquationCnt);
384cb93a386Sopenharmony_ci
385cb93a386Sopenharmony_ci    SkASSERT((unsigned)equation < kGrBlendEquationCnt);
386cb93a386Sopenharmony_ci    return gTable[equation];
387cb93a386Sopenharmony_ci}
388cb93a386Sopenharmony_ci
389cb93a386Sopenharmony_cistatic void setup_color_blend_state(const GrXferProcessor::BlendInfo& blendInfo,
390cb93a386Sopenharmony_ci                                    VkPipelineColorBlendStateCreateInfo* colorBlendInfo,
391cb93a386Sopenharmony_ci                                    VkPipelineColorBlendAttachmentState* attachmentState) {
392cb93a386Sopenharmony_ci    GrBlendEquation equation = blendInfo.fEquation;
393cb93a386Sopenharmony_ci    GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
394cb93a386Sopenharmony_ci    GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
395cb93a386Sopenharmony_ci    bool blendOff = GrBlendShouldDisable(equation, srcCoeff, dstCoeff);
396cb93a386Sopenharmony_ci
397cb93a386Sopenharmony_ci    memset(attachmentState, 0, sizeof(VkPipelineColorBlendAttachmentState));
398cb93a386Sopenharmony_ci    attachmentState->blendEnable = !blendOff;
399cb93a386Sopenharmony_ci    if (!blendOff) {
400cb93a386Sopenharmony_ci        attachmentState->srcColorBlendFactor = blend_coeff_to_vk_blend(srcCoeff);
401cb93a386Sopenharmony_ci        attachmentState->dstColorBlendFactor = blend_coeff_to_vk_blend(dstCoeff);
402cb93a386Sopenharmony_ci        attachmentState->colorBlendOp = blend_equation_to_vk_blend_op(equation);
403cb93a386Sopenharmony_ci        attachmentState->srcAlphaBlendFactor = blend_coeff_to_vk_blend(srcCoeff);
404cb93a386Sopenharmony_ci        attachmentState->dstAlphaBlendFactor = blend_coeff_to_vk_blend(dstCoeff);
405cb93a386Sopenharmony_ci        attachmentState->alphaBlendOp = blend_equation_to_vk_blend_op(equation);
406cb93a386Sopenharmony_ci    }
407cb93a386Sopenharmony_ci
408cb93a386Sopenharmony_ci    if (!blendInfo.fWriteColor) {
409cb93a386Sopenharmony_ci        attachmentState->colorWriteMask = 0;
410cb93a386Sopenharmony_ci    } else {
411cb93a386Sopenharmony_ci        attachmentState->colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
412cb93a386Sopenharmony_ci                                          VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
413cb93a386Sopenharmony_ci    }
414cb93a386Sopenharmony_ci
415cb93a386Sopenharmony_ci    memset(colorBlendInfo, 0, sizeof(VkPipelineColorBlendStateCreateInfo));
416cb93a386Sopenharmony_ci    colorBlendInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
417cb93a386Sopenharmony_ci    colorBlendInfo->pNext = nullptr;
418cb93a386Sopenharmony_ci    colorBlendInfo->flags = 0;
419cb93a386Sopenharmony_ci    colorBlendInfo->logicOpEnable = VK_FALSE;
420cb93a386Sopenharmony_ci    colorBlendInfo->attachmentCount = 1;
421cb93a386Sopenharmony_ci    colorBlendInfo->pAttachments = attachmentState;
422cb93a386Sopenharmony_ci    // colorBlendInfo->blendConstants is set dynamically
423cb93a386Sopenharmony_ci}
424cb93a386Sopenharmony_ci
425cb93a386Sopenharmony_cistatic void setup_raster_state(bool isWireframe,
426cb93a386Sopenharmony_ci                               const GrCaps* caps,
427cb93a386Sopenharmony_ci                               VkPipelineRasterizationStateCreateInfo* rasterInfo) {
428cb93a386Sopenharmony_ci    memset(rasterInfo, 0, sizeof(VkPipelineRasterizationStateCreateInfo));
429cb93a386Sopenharmony_ci    rasterInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
430cb93a386Sopenharmony_ci    rasterInfo->pNext = nullptr;
431cb93a386Sopenharmony_ci    rasterInfo->flags = 0;
432cb93a386Sopenharmony_ci    rasterInfo->depthClampEnable = VK_FALSE;
433cb93a386Sopenharmony_ci    rasterInfo->rasterizerDiscardEnable = VK_FALSE;
434cb93a386Sopenharmony_ci    rasterInfo->polygonMode = (caps->wireframeMode() || isWireframe) ?
435cb93a386Sopenharmony_ci            VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL;
436cb93a386Sopenharmony_ci    rasterInfo->cullMode = VK_CULL_MODE_NONE;
437cb93a386Sopenharmony_ci    rasterInfo->frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
438cb93a386Sopenharmony_ci    rasterInfo->depthBiasEnable = VK_FALSE;
439cb93a386Sopenharmony_ci    rasterInfo->depthBiasConstantFactor = 0.0f;
440cb93a386Sopenharmony_ci    rasterInfo->depthBiasClamp = 0.0f;
441cb93a386Sopenharmony_ci    rasterInfo->depthBiasSlopeFactor = 0.0f;
442cb93a386Sopenharmony_ci    rasterInfo->lineWidth = 1.0f;
443cb93a386Sopenharmony_ci}
444cb93a386Sopenharmony_ci
445cb93a386Sopenharmony_cistatic void setup_conservative_raster_info(
446cb93a386Sopenharmony_ci        VkPipelineRasterizationConservativeStateCreateInfoEXT* conservativeRasterInfo) {
447cb93a386Sopenharmony_ci    memset(conservativeRasterInfo, 0,
448cb93a386Sopenharmony_ci           sizeof(VkPipelineRasterizationConservativeStateCreateInfoEXT));
449cb93a386Sopenharmony_ci    conservativeRasterInfo->sType =
450cb93a386Sopenharmony_ci            VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT;
451cb93a386Sopenharmony_ci    conservativeRasterInfo->pNext = nullptr;
452cb93a386Sopenharmony_ci    conservativeRasterInfo->flags = 0;
453cb93a386Sopenharmony_ci    conservativeRasterInfo->conservativeRasterizationMode =
454cb93a386Sopenharmony_ci            VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
455cb93a386Sopenharmony_ci    conservativeRasterInfo->extraPrimitiveOverestimationSize = 0;
456cb93a386Sopenharmony_ci}
457cb93a386Sopenharmony_ci
458cb93a386Sopenharmony_cistatic void setup_dynamic_state(VkPipelineDynamicStateCreateInfo* dynamicInfo,
459cb93a386Sopenharmony_ci                                VkDynamicState* dynamicStates) {
460cb93a386Sopenharmony_ci    memset(dynamicInfo, 0, sizeof(VkPipelineDynamicStateCreateInfo));
461cb93a386Sopenharmony_ci    dynamicInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
462cb93a386Sopenharmony_ci    dynamicInfo->pNext = VK_NULL_HANDLE;
463cb93a386Sopenharmony_ci    dynamicInfo->flags = 0;
464cb93a386Sopenharmony_ci    dynamicStates[0] = VK_DYNAMIC_STATE_VIEWPORT;
465cb93a386Sopenharmony_ci    dynamicStates[1] = VK_DYNAMIC_STATE_SCISSOR;
466cb93a386Sopenharmony_ci    dynamicStates[2] = VK_DYNAMIC_STATE_BLEND_CONSTANTS;
467cb93a386Sopenharmony_ci    dynamicInfo->dynamicStateCount = 3;
468cb93a386Sopenharmony_ci    dynamicInfo->pDynamicStates = dynamicStates;
469cb93a386Sopenharmony_ci}
470cb93a386Sopenharmony_ci
471cb93a386Sopenharmony_cisk_sp<GrVkPipeline> GrVkPipeline::Make(GrVkGpu* gpu,
472cb93a386Sopenharmony_ci                                   const GrGeometryProcessor::AttributeSet& vertexAttribs,
473cb93a386Sopenharmony_ci                                   const GrGeometryProcessor::AttributeSet& instanceAttribs,
474cb93a386Sopenharmony_ci                                   GrPrimitiveType primitiveType,
475cb93a386Sopenharmony_ci                                   GrSurfaceOrigin origin,
476cb93a386Sopenharmony_ci                                   const GrStencilSettings& stencilSettings,
477cb93a386Sopenharmony_ci                                   int numSamples,
478cb93a386Sopenharmony_ci                                   bool isHWAntialiasState,
479cb93a386Sopenharmony_ci                                   const GrXferProcessor::BlendInfo& blendInfo,
480cb93a386Sopenharmony_ci                                   bool isWireframe,
481cb93a386Sopenharmony_ci                                   bool useConservativeRaster,
482cb93a386Sopenharmony_ci                                   uint32_t subpass,
483cb93a386Sopenharmony_ci                                   VkPipelineShaderStageCreateInfo* shaderStageInfo,
484cb93a386Sopenharmony_ci                                   int shaderStageCount,
485cb93a386Sopenharmony_ci                                   VkRenderPass compatibleRenderPass,
486cb93a386Sopenharmony_ci                                   VkPipelineLayout layout,
487cb93a386Sopenharmony_ci                                   bool ownsLayout,
488cb93a386Sopenharmony_ci                                   VkPipelineCache cache) {
489cb93a386Sopenharmony_ci    VkPipelineVertexInputStateCreateInfo vertexInputInfo;
490cb93a386Sopenharmony_ci    SkSTArray<2, VkVertexInputBindingDescription, true> bindingDescs;
491cb93a386Sopenharmony_ci    SkSTArray<16, VkVertexInputAttributeDescription> attributeDesc;
492cb93a386Sopenharmony_ci    int totalAttributeCnt = vertexAttribs.count() + instanceAttribs.count();
493cb93a386Sopenharmony_ci    SkASSERT(totalAttributeCnt <= gpu->vkCaps().maxVertexAttributes());
494cb93a386Sopenharmony_ci    VkVertexInputAttributeDescription* pAttribs = attributeDesc.push_back_n(totalAttributeCnt);
495cb93a386Sopenharmony_ci    setup_vertex_input_state(vertexAttribs, instanceAttribs, &vertexInputInfo, &bindingDescs,
496cb93a386Sopenharmony_ci                             pAttribs);
497cb93a386Sopenharmony_ci
498cb93a386Sopenharmony_ci    VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo;
499cb93a386Sopenharmony_ci    setup_input_assembly_state(primitiveType, &inputAssemblyInfo);
500cb93a386Sopenharmony_ci
501cb93a386Sopenharmony_ci    VkPipelineDepthStencilStateCreateInfo depthStencilInfo;
502cb93a386Sopenharmony_ci    setup_depth_stencil_state(stencilSettings, origin, &depthStencilInfo);
503cb93a386Sopenharmony_ci
504cb93a386Sopenharmony_ci    VkPipelineViewportStateCreateInfo viewportInfo;
505cb93a386Sopenharmony_ci    setup_viewport_scissor_state(&viewportInfo);
506cb93a386Sopenharmony_ci
507cb93a386Sopenharmony_ci    VkPipelineMultisampleStateCreateInfo multisampleInfo;
508cb93a386Sopenharmony_ci    setup_multisample_state(numSamples, gpu->caps(), &multisampleInfo);
509cb93a386Sopenharmony_ci
510cb93a386Sopenharmony_ci    // We will only have one color attachment per pipeline.
511cb93a386Sopenharmony_ci    VkPipelineColorBlendAttachmentState attachmentStates[1];
512cb93a386Sopenharmony_ci    VkPipelineColorBlendStateCreateInfo colorBlendInfo;
513cb93a386Sopenharmony_ci    setup_color_blend_state(blendInfo, &colorBlendInfo, attachmentStates);
514cb93a386Sopenharmony_ci
515cb93a386Sopenharmony_ci    VkPipelineRasterizationStateCreateInfo rasterInfo;
516cb93a386Sopenharmony_ci    setup_raster_state(isWireframe, gpu->caps(), &rasterInfo);
517cb93a386Sopenharmony_ci
518cb93a386Sopenharmony_ci    VkPipelineRasterizationConservativeStateCreateInfoEXT conservativeRasterInfo;
519cb93a386Sopenharmony_ci    if (useConservativeRaster) {
520cb93a386Sopenharmony_ci        SkASSERT(gpu->caps()->conservativeRasterSupport());
521cb93a386Sopenharmony_ci        setup_conservative_raster_info(&conservativeRasterInfo);
522cb93a386Sopenharmony_ci        conservativeRasterInfo.pNext = rasterInfo.pNext;
523cb93a386Sopenharmony_ci        rasterInfo.pNext = &conservativeRasterInfo;
524cb93a386Sopenharmony_ci    }
525cb93a386Sopenharmony_ci
526cb93a386Sopenharmony_ci    VkDynamicState dynamicStates[3];
527cb93a386Sopenharmony_ci    VkPipelineDynamicStateCreateInfo dynamicInfo;
528cb93a386Sopenharmony_ci    setup_dynamic_state(&dynamicInfo, dynamicStates);
529cb93a386Sopenharmony_ci
530cb93a386Sopenharmony_ci    VkGraphicsPipelineCreateInfo pipelineCreateInfo;
531cb93a386Sopenharmony_ci    memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo));
532cb93a386Sopenharmony_ci    pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
533cb93a386Sopenharmony_ci    pipelineCreateInfo.pNext = nullptr;
534cb93a386Sopenharmony_ci    pipelineCreateInfo.flags = 0;
535cb93a386Sopenharmony_ci    pipelineCreateInfo.stageCount = shaderStageCount;
536cb93a386Sopenharmony_ci    pipelineCreateInfo.pStages = shaderStageInfo;
537cb93a386Sopenharmony_ci    pipelineCreateInfo.pVertexInputState = &vertexInputInfo;
538cb93a386Sopenharmony_ci    pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo;
539cb93a386Sopenharmony_ci    pipelineCreateInfo.pTessellationState = nullptr;
540cb93a386Sopenharmony_ci    pipelineCreateInfo.pViewportState = &viewportInfo;
541cb93a386Sopenharmony_ci    pipelineCreateInfo.pRasterizationState = &rasterInfo;
542cb93a386Sopenharmony_ci    pipelineCreateInfo.pMultisampleState = &multisampleInfo;
543cb93a386Sopenharmony_ci    pipelineCreateInfo.pDepthStencilState = &depthStencilInfo;
544cb93a386Sopenharmony_ci    pipelineCreateInfo.pColorBlendState = &colorBlendInfo;
545cb93a386Sopenharmony_ci    pipelineCreateInfo.pDynamicState = &dynamicInfo;
546cb93a386Sopenharmony_ci    pipelineCreateInfo.layout = layout;
547cb93a386Sopenharmony_ci    pipelineCreateInfo.renderPass = compatibleRenderPass;
548cb93a386Sopenharmony_ci    pipelineCreateInfo.subpass = subpass;
549cb93a386Sopenharmony_ci    pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
550cb93a386Sopenharmony_ci    pipelineCreateInfo.basePipelineIndex = -1;
551cb93a386Sopenharmony_ci
552cb93a386Sopenharmony_ci    VkPipeline vkPipeline;
553cb93a386Sopenharmony_ci    VkResult err;
554cb93a386Sopenharmony_ci    {
555cb93a386Sopenharmony_ci        TRACE_EVENT0("skia.shaders", "CreateGraphicsPipeline");
556cb93a386Sopenharmony_ci#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
557cb93a386Sopenharmony_ci        // skia:8712
558cb93a386Sopenharmony_ci        __lsan::ScopedDisabler lsanDisabler;
559cb93a386Sopenharmony_ci#endif
560cb93a386Sopenharmony_ci        GR_VK_CALL_RESULT(gpu, err, CreateGraphicsPipelines(gpu->device(), cache, 1,
561cb93a386Sopenharmony_ci                                                            &pipelineCreateInfo, nullptr,
562cb93a386Sopenharmony_ci                                                            &vkPipeline));
563cb93a386Sopenharmony_ci    }
564cb93a386Sopenharmony_ci    if (err) {
565cb93a386Sopenharmony_ci        SkDebugf("Failed to create pipeline. Error: %d\n", err);
566cb93a386Sopenharmony_ci        return nullptr;
567cb93a386Sopenharmony_ci    }
568cb93a386Sopenharmony_ci
569cb93a386Sopenharmony_ci    if (!ownsLayout) {
570cb93a386Sopenharmony_ci        layout = VK_NULL_HANDLE;
571cb93a386Sopenharmony_ci    }
572cb93a386Sopenharmony_ci    return sk_sp<GrVkPipeline>(new GrVkPipeline(gpu, vkPipeline, layout));
573cb93a386Sopenharmony_ci}
574cb93a386Sopenharmony_ci
575cb93a386Sopenharmony_cisk_sp<GrVkPipeline> GrVkPipeline::Make(GrVkGpu* gpu,
576cb93a386Sopenharmony_ci                                       const GrProgramInfo& programInfo,
577cb93a386Sopenharmony_ci                                       VkPipelineShaderStageCreateInfo* shaderStageInfo,
578cb93a386Sopenharmony_ci                                       int shaderStageCount,
579cb93a386Sopenharmony_ci                                       VkRenderPass compatibleRenderPass,
580cb93a386Sopenharmony_ci                                       VkPipelineLayout layout,
581cb93a386Sopenharmony_ci                                       VkPipelineCache cache,
582cb93a386Sopenharmony_ci                                       uint32_t subpass) {
583cb93a386Sopenharmony_ci    const GrGeometryProcessor& geomProc = programInfo.geomProc();
584cb93a386Sopenharmony_ci    const GrPipeline& pipeline = programInfo.pipeline();
585cb93a386Sopenharmony_ci
586cb93a386Sopenharmony_ci    return Make(gpu,
587cb93a386Sopenharmony_ci                geomProc.vertexAttributes(),
588cb93a386Sopenharmony_ci                geomProc.instanceAttributes(),
589cb93a386Sopenharmony_ci                programInfo.primitiveType(),
590cb93a386Sopenharmony_ci                programInfo.origin(),
591cb93a386Sopenharmony_ci                programInfo.nonGLStencilSettings(),
592cb93a386Sopenharmony_ci                programInfo.numSamples(),
593cb93a386Sopenharmony_ci                programInfo.numSamples() > 1,
594cb93a386Sopenharmony_ci                pipeline.getXferProcessor().getBlendInfo(),
595cb93a386Sopenharmony_ci                pipeline.isWireframe(),
596cb93a386Sopenharmony_ci                pipeline.usesConservativeRaster(),
597cb93a386Sopenharmony_ci                subpass,
598cb93a386Sopenharmony_ci                shaderStageInfo,
599cb93a386Sopenharmony_ci                shaderStageCount,
600cb93a386Sopenharmony_ci                compatibleRenderPass,
601cb93a386Sopenharmony_ci                layout,
602cb93a386Sopenharmony_ci                /*ownsLayout=*/true,
603cb93a386Sopenharmony_ci                cache);
604cb93a386Sopenharmony_ci}
605cb93a386Sopenharmony_ci
606cb93a386Sopenharmony_civoid GrVkPipeline::freeGPUData() const {
607cb93a386Sopenharmony_ci    GR_VK_CALL(fGpu->vkInterface(), DestroyPipeline(fGpu->device(), fPipeline, nullptr));
608cb93a386Sopenharmony_ci    if (fPipelineLayout != VK_NULL_HANDLE) {
609cb93a386Sopenharmony_ci        GR_VK_CALL(fGpu->vkInterface(),
610cb93a386Sopenharmony_ci                   DestroyPipelineLayout(fGpu->device(), fPipelineLayout, nullptr));
611cb93a386Sopenharmony_ci    }
612cb93a386Sopenharmony_ci}
613cb93a386Sopenharmony_ci
614cb93a386Sopenharmony_civoid GrVkPipeline::SetDynamicScissorRectState(GrVkGpu* gpu,
615cb93a386Sopenharmony_ci                                              GrVkCommandBuffer* cmdBuffer,
616cb93a386Sopenharmony_ci                                              SkISize colorAttachmentDimensions,
617cb93a386Sopenharmony_ci                                              GrSurfaceOrigin rtOrigin,
618cb93a386Sopenharmony_ci                                              const SkIRect& scissorRect) {
619cb93a386Sopenharmony_ci    SkASSERT(scissorRect.isEmpty() ||
620cb93a386Sopenharmony_ci             SkIRect::MakeSize(colorAttachmentDimensions).contains(scissorRect));
621cb93a386Sopenharmony_ci
622cb93a386Sopenharmony_ci    VkRect2D scissor;
623cb93a386Sopenharmony_ci    scissor.offset.x = scissorRect.fLeft;
624cb93a386Sopenharmony_ci    scissor.extent.width = scissorRect.width();
625cb93a386Sopenharmony_ci    if (kTopLeft_GrSurfaceOrigin == rtOrigin) {
626cb93a386Sopenharmony_ci        scissor.offset.y = scissorRect.fTop;
627cb93a386Sopenharmony_ci    } else {
628cb93a386Sopenharmony_ci        SkASSERT(kBottomLeft_GrSurfaceOrigin == rtOrigin);
629cb93a386Sopenharmony_ci        scissor.offset.y = colorAttachmentDimensions.height() - scissorRect.fBottom;
630cb93a386Sopenharmony_ci    }
631cb93a386Sopenharmony_ci    scissor.extent.height = scissorRect.height();
632cb93a386Sopenharmony_ci
633cb93a386Sopenharmony_ci    SkASSERT(scissor.offset.x >= 0);
634cb93a386Sopenharmony_ci    SkASSERT(scissor.offset.y >= 0);
635cb93a386Sopenharmony_ci    cmdBuffer->setScissor(gpu, 0, 1, &scissor);
636cb93a386Sopenharmony_ci}
637cb93a386Sopenharmony_ci
638cb93a386Sopenharmony_civoid GrVkPipeline::SetDynamicViewportState(GrVkGpu* gpu,
639cb93a386Sopenharmony_ci                                           GrVkCommandBuffer* cmdBuffer,
640cb93a386Sopenharmony_ci                                           SkISize colorAttachmentDimensions) {
641cb93a386Sopenharmony_ci    // We always use one viewport the size of the RT
642cb93a386Sopenharmony_ci    VkViewport viewport;
643cb93a386Sopenharmony_ci    viewport.x = 0.0f;
644cb93a386Sopenharmony_ci    viewport.y = 0.0f;
645cb93a386Sopenharmony_ci    viewport.width = SkIntToScalar(colorAttachmentDimensions.width());
646cb93a386Sopenharmony_ci    viewport.height = SkIntToScalar(colorAttachmentDimensions.height());
647cb93a386Sopenharmony_ci    viewport.minDepth = 0.0f;
648cb93a386Sopenharmony_ci    viewport.maxDepth = 1.0f;
649cb93a386Sopenharmony_ci    cmdBuffer->setViewport(gpu, 0, 1, &viewport);
650cb93a386Sopenharmony_ci}
651cb93a386Sopenharmony_ci
652cb93a386Sopenharmony_civoid GrVkPipeline::SetDynamicBlendConstantState(GrVkGpu* gpu,
653cb93a386Sopenharmony_ci                                                GrVkCommandBuffer* cmdBuffer,
654cb93a386Sopenharmony_ci                                                const GrSwizzle& swizzle,
655cb93a386Sopenharmony_ci                                                const GrXferProcessor& xferProcessor) {
656cb93a386Sopenharmony_ci    const GrXferProcessor::BlendInfo& blendInfo = xferProcessor.getBlendInfo();
657cb93a386Sopenharmony_ci    GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
658cb93a386Sopenharmony_ci    GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
659cb93a386Sopenharmony_ci    float floatColors[4];
660cb93a386Sopenharmony_ci    if (GrBlendCoeffRefsConstant(srcCoeff) || GrBlendCoeffRefsConstant(dstCoeff)) {
661cb93a386Sopenharmony_ci        // Swizzle the blend to match what the shader will output.
662cb93a386Sopenharmony_ci        SkPMColor4f blendConst = swizzle.applyTo(blendInfo.fBlendConstant);
663cb93a386Sopenharmony_ci        floatColors[0] = blendConst.fR;
664cb93a386Sopenharmony_ci        floatColors[1] = blendConst.fG;
665cb93a386Sopenharmony_ci        floatColors[2] = blendConst.fB;
666cb93a386Sopenharmony_ci        floatColors[3] = blendConst.fA;
667cb93a386Sopenharmony_ci        cmdBuffer->setBlendConstants(gpu, floatColors);
668cb93a386Sopenharmony_ci    }
669cb93a386Sopenharmony_ci}
670