blob: 660bf3a77ce73f96207fcadb4ff921e1d7ca0153 [file] [log] [blame]
Greg Daniel164a9f02016-02-22 09:56:40 -05001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/gpu/GrGeometryProcessor.h"
9#include "src/gpu/GrPipeline.h"
10#include "src/gpu/GrStencilSettings.h"
11#include "src/gpu/vk/GrVkCommandBuffer.h"
12#include "src/gpu/vk/GrVkGpu.h"
13#include "src/gpu/vk/GrVkPipeline.h"
14#include "src/gpu/vk/GrVkRenderTarget.h"
15#include "src/gpu/vk/GrVkUtil.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050016
Ben Wagner6c30e742019-02-06 10:46:14 -050017#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
18#include <sanitizer/lsan_interface.h>
19#endif
20
csmartdaltonb37cb232017-02-08 14:56:27 -050021static inline VkFormat attrib_type_to_vkformat(GrVertexAttribType type) {
22 switch (type) {
23 case kFloat_GrVertexAttribType:
24 return VK_FORMAT_R32_SFLOAT;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040025 case kFloat2_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050026 return VK_FORMAT_R32G32_SFLOAT;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040027 case kFloat3_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050028 return VK_FORMAT_R32G32B32_SFLOAT;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040029 case kFloat4_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050030 return VK_FORMAT_R32G32B32A32_SFLOAT;
Brian Osmand4c29702018-09-14 16:16:55 -040031 case kHalf_GrVertexAttribType:
32 return VK_FORMAT_R16_SFLOAT;
33 case kHalf2_GrVertexAttribType:
34 return VK_FORMAT_R16G16_SFLOAT;
Brian Osmand4c29702018-09-14 16:16:55 -040035 case kHalf4_GrVertexAttribType:
36 return VK_FORMAT_R16G16B16A16_SFLOAT;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040037 case kInt2_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050038 return VK_FORMAT_R32G32_SINT;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040039 case kInt3_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050040 return VK_FORMAT_R32G32B32_SINT;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040041 case kInt4_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050042 return VK_FORMAT_R32G32B32A32_SINT;
Ruiqi Maob609e6d2018-07-17 10:19:38 -040043 case kByte_GrVertexAttribType:
44 return VK_FORMAT_R8_SINT;
45 case kByte2_GrVertexAttribType:
46 return VK_FORMAT_R8G8_SINT;
Ruiqi Maob609e6d2018-07-17 10:19:38 -040047 case kByte4_GrVertexAttribType:
48 return VK_FORMAT_R8G8B8A8_SINT;
49 case kUByte_GrVertexAttribType:
50 return VK_FORMAT_R8_UINT;
51 case kUByte2_GrVertexAttribType:
52 return VK_FORMAT_R8G8_UINT;
Ruiqi Maob609e6d2018-07-17 10:19:38 -040053 case kUByte4_GrVertexAttribType:
54 return VK_FORMAT_R8G8B8A8_UINT;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040055 case kUByte_norm_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050056 return VK_FORMAT_R8_UNORM;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040057 case kUByte4_norm_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050058 return VK_FORMAT_R8G8B8A8_UNORM;
Chris Daltona045eea2017-10-24 13:22:10 -060059 case kShort2_GrVertexAttribType:
60 return VK_FORMAT_R16G16_SINT;
Brian Osmana5c578f2018-09-19 14:19:02 -040061 case kShort4_GrVertexAttribType:
62 return VK_FORMAT_R16G16B16A16_SINT;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040063 case kUShort2_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040064 return VK_FORMAT_R16G16_UINT;
Chris Daltona045eea2017-10-24 13:22:10 -060065 case kUShort2_norm_GrVertexAttribType:
66 return VK_FORMAT_R16G16_UNORM;
csmartdaltonb37cb232017-02-08 14:56:27 -050067 case kInt_GrVertexAttribType:
68 return VK_FORMAT_R32_SINT;
69 case kUint_GrVertexAttribType:
70 return VK_FORMAT_R32_UINT;
Robert Phillipsfe18de52019-06-06 17:21:50 -040071 case kUShort_norm_GrVertexAttribType:
72 return VK_FORMAT_R16_UNORM;
Robert Phillips66a46032019-06-18 08:00:42 -040073 case kUShort4_norm_GrVertexAttribType:
74 return VK_FORMAT_R16G16B16A16_UNORM;
csmartdaltonb37cb232017-02-08 14:56:27 -050075 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -040076 SK_ABORT("Unknown vertex attrib type");
Greg Daniel164a9f02016-02-22 09:56:40 -050077}
78
79static void setup_vertex_input_state(const GrPrimitiveProcessor& primProc,
Chris Dalton1d616352017-05-31 12:51:23 -060080 VkPipelineVertexInputStateCreateInfo* vertexInputInfo,
81 SkSTArray<2, VkVertexInputBindingDescription, true>* bindingDescs,
82 VkVertexInputAttributeDescription* attributeDesc) {
Kevin Lubick42846132018-01-05 10:11:11 -050083 uint32_t vertexBinding = 0, instanceBinding = 0;
Chris Dalton1d616352017-05-31 12:51:23 -060084
Brian Salomon92be2f72018-06-19 14:33:47 -040085 int nextBinding = bindingDescs->count();
86 if (primProc.hasVertexAttributes()) {
87 vertexBinding = nextBinding++;
Chris Dalton1d616352017-05-31 12:51:23 -060088 }
89
Brian Salomon92be2f72018-06-19 14:33:47 -040090 if (primProc.hasInstanceAttributes()) {
91 instanceBinding = nextBinding;
Chris Dalton1d616352017-05-31 12:51:23 -060092 }
Greg Daniel164a9f02016-02-22 09:56:40 -050093
94 // setup attribute descriptions
Brian Salomon92be2f72018-06-19 14:33:47 -040095 int vaCount = primProc.numVertexAttributes();
96 int attribIndex = 0;
97 size_t vertexAttributeOffset = 0;
Brian Osmanf04fb3c2018-11-12 15:34:00 -050098 for (const auto& attrib : primProc.vertexAttributes()) {
Brian Salomon92be2f72018-06-19 14:33:47 -040099 VkVertexInputAttributeDescription& vkAttrib = attributeDesc[attribIndex];
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500100 vkAttrib.location = attribIndex++; // for now assume location = attribIndex
Brian Salomon92be2f72018-06-19 14:33:47 -0400101 vkAttrib.binding = vertexBinding;
Brian Osmand4c29702018-09-14 16:16:55 -0400102 vkAttrib.format = attrib_type_to_vkformat(attrib.cpuType());
Brian Salomon92be2f72018-06-19 14:33:47 -0400103 vkAttrib.offset = vertexAttributeOffset;
Brian Salomon92be2f72018-06-19 14:33:47 -0400104 vertexAttributeOffset += attrib.sizeAlign4();
105 }
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500106 SkASSERT(vertexAttributeOffset == primProc.vertexStride());
Brian Salomon92be2f72018-06-19 14:33:47 -0400107
108 int iaCount = primProc.numInstanceAttributes();
109 size_t instanceAttributeOffset = 0;
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500110 for (const auto& attrib : primProc.instanceAttributes()) {
Brian Salomon92be2f72018-06-19 14:33:47 -0400111 VkVertexInputAttributeDescription& vkAttrib = attributeDesc[attribIndex];
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500112 vkAttrib.location = attribIndex++; // for now assume location = attribIndex
Brian Salomon92be2f72018-06-19 14:33:47 -0400113 vkAttrib.binding = instanceBinding;
Brian Osmand4c29702018-09-14 16:16:55 -0400114 vkAttrib.format = attrib_type_to_vkformat(attrib.cpuType());
Brian Salomon92be2f72018-06-19 14:33:47 -0400115 vkAttrib.offset = instanceAttributeOffset;
Brian Salomon92be2f72018-06-19 14:33:47 -0400116 instanceAttributeOffset += attrib.sizeAlign4();
117 }
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500118 SkASSERT(instanceAttributeOffset == primProc.instanceStride());
Brian Salomon92be2f72018-06-19 14:33:47 -0400119
120 if (primProc.hasVertexAttributes()) {
121 bindingDescs->push_back() = {
122 vertexBinding,
123 (uint32_t) vertexAttributeOffset,
124 VK_VERTEX_INPUT_RATE_VERTEX
125 };
126 }
127 if (primProc.hasInstanceAttributes()) {
128 bindingDescs->push_back() = {
129 instanceBinding,
130 (uint32_t) instanceAttributeOffset,
131 VK_VERTEX_INPUT_RATE_INSTANCE
132 };
Greg Daniel164a9f02016-02-22 09:56:40 -0500133 }
134
135 memset(vertexInputInfo, 0, sizeof(VkPipelineVertexInputStateCreateInfo));
136 vertexInputInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
137 vertexInputInfo->pNext = nullptr;
138 vertexInputInfo->flags = 0;
Chris Dalton1d616352017-05-31 12:51:23 -0600139 vertexInputInfo->vertexBindingDescriptionCount = bindingDescs->count();
140 vertexInputInfo->pVertexBindingDescriptions = bindingDescs->begin();
Brian Salomon92be2f72018-06-19 14:33:47 -0400141 vertexInputInfo->vertexAttributeDescriptionCount = vaCount + iaCount;
Greg Daniel164a9f02016-02-22 09:56:40 -0500142 vertexInputInfo->pVertexAttributeDescriptions = attributeDesc;
143}
144
Chris Dalton3809bab2017-06-13 10:55:06 -0600145static VkPrimitiveTopology gr_primitive_type_to_vk_topology(GrPrimitiveType primitiveType) {
146 switch (primitiveType) {
147 case GrPrimitiveType::kTriangles:
148 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
149 case GrPrimitiveType::kTriangleStrip:
150 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
Chris Dalton3809bab2017-06-13 10:55:06 -0600151 case GrPrimitiveType::kPoints:
152 return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
153 case GrPrimitiveType::kLines:
154 return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
155 case GrPrimitiveType::kLineStrip:
156 return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
Chris Dalton5a2f9622019-12-27 14:56:38 -0700157 case GrPrimitiveType::kPatches:
Robert Phillips571177f2019-10-04 14:41:49 -0400158 case GrPrimitiveType::kPath:
159 SK_ABORT("Unsupported primitive type");
Chris Dalton3809bab2017-06-13 10:55:06 -0600160 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400161 SK_ABORT("invalid GrPrimitiveType");
Chris Dalton3809bab2017-06-13 10:55:06 -0600162}
Greg Daniel164a9f02016-02-22 09:56:40 -0500163
164static void setup_input_assembly_state(GrPrimitiveType primitiveType,
165 VkPipelineInputAssemblyStateCreateInfo* inputAssemblyInfo) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500166 memset(inputAssemblyInfo, 0, sizeof(VkPipelineInputAssemblyStateCreateInfo));
167 inputAssemblyInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
168 inputAssemblyInfo->pNext = nullptr;
169 inputAssemblyInfo->flags = 0;
170 inputAssemblyInfo->primitiveRestartEnable = false;
Chris Dalton3809bab2017-06-13 10:55:06 -0600171 inputAssemblyInfo->topology = gr_primitive_type_to_vk_topology(primitiveType);
Greg Daniel164a9f02016-02-22 09:56:40 -0500172}
173
174
egdanielec440992016-09-13 09:54:11 -0700175static VkStencilOp stencil_op_to_vk_stencil_op(GrStencilOp op) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500176 static const VkStencilOp gTable[] = {
cdalton93a379b2016-05-11 13:58:08 -0700177 VK_STENCIL_OP_KEEP, // kKeep
178 VK_STENCIL_OP_ZERO, // kZero
179 VK_STENCIL_OP_REPLACE, // kReplace
180 VK_STENCIL_OP_INVERT, // kInvert
181 VK_STENCIL_OP_INCREMENT_AND_WRAP, // kIncWrap
182 VK_STENCIL_OP_DECREMENT_AND_WRAP, // kDecWrap
183 VK_STENCIL_OP_INCREMENT_AND_CLAMP, // kIncClamp
184 VK_STENCIL_OP_DECREMENT_AND_CLAMP, // kDecClamp
Greg Daniel164a9f02016-02-22 09:56:40 -0500185 };
Brian Salomon4dea72a2019-12-18 10:43:10 -0500186 static_assert(SK_ARRAY_COUNT(gTable) == kGrStencilOpCount);
187 static_assert(0 == (int)GrStencilOp::kKeep);
188 static_assert(1 == (int)GrStencilOp::kZero);
189 static_assert(2 == (int)GrStencilOp::kReplace);
190 static_assert(3 == (int)GrStencilOp::kInvert);
191 static_assert(4 == (int)GrStencilOp::kIncWrap);
192 static_assert(5 == (int)GrStencilOp::kDecWrap);
193 static_assert(6 == (int)GrStencilOp::kIncClamp);
194 static_assert(7 == (int)GrStencilOp::kDecClamp);
cdalton93a379b2016-05-11 13:58:08 -0700195 SkASSERT(op < (GrStencilOp)kGrStencilOpCount);
196 return gTable[(int)op];
Greg Daniel164a9f02016-02-22 09:56:40 -0500197}
198
egdanielec440992016-09-13 09:54:11 -0700199static VkCompareOp stencil_func_to_vk_compare_op(GrStencilTest test) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500200 static const VkCompareOp gTable[] = {
cdalton93a379b2016-05-11 13:58:08 -0700201 VK_COMPARE_OP_ALWAYS, // kAlways
202 VK_COMPARE_OP_NEVER, // kNever
203 VK_COMPARE_OP_GREATER, // kGreater
204 VK_COMPARE_OP_GREATER_OR_EQUAL, // kGEqual
205 VK_COMPARE_OP_LESS, // kLess
206 VK_COMPARE_OP_LESS_OR_EQUAL, // kLEqual
207 VK_COMPARE_OP_EQUAL, // kEqual
208 VK_COMPARE_OP_NOT_EQUAL, // kNotEqual
Greg Daniel164a9f02016-02-22 09:56:40 -0500209 };
Brian Salomon4dea72a2019-12-18 10:43:10 -0500210 static_assert(SK_ARRAY_COUNT(gTable) == kGrStencilTestCount);
211 static_assert(0 == (int)GrStencilTest::kAlways);
212 static_assert(1 == (int)GrStencilTest::kNever);
213 static_assert(2 == (int)GrStencilTest::kGreater);
214 static_assert(3 == (int)GrStencilTest::kGEqual);
215 static_assert(4 == (int)GrStencilTest::kLess);
216 static_assert(5 == (int)GrStencilTest::kLEqual);
217 static_assert(6 == (int)GrStencilTest::kEqual);
218 static_assert(7 == (int)GrStencilTest::kNotEqual);
cdalton93a379b2016-05-11 13:58:08 -0700219 SkASSERT(test < (GrStencilTest)kGrStencilTestCount);
Greg Daniel164a9f02016-02-22 09:56:40 -0500220
cdalton93a379b2016-05-11 13:58:08 -0700221 return gTable[(int)test];
Greg Daniel164a9f02016-02-22 09:56:40 -0500222}
223
Chris Dalton71713f62019-04-18 12:41:03 -0600224static void setup_stencil_op_state(
225 VkStencilOpState* opState, const GrStencilSettings::Face& stencilFace) {
226 opState->failOp = stencil_op_to_vk_stencil_op(stencilFace.fFailOp);
227 opState->passOp = stencil_op_to_vk_stencil_op(stencilFace.fPassOp);
228 opState->depthFailOp = opState->failOp;
229 opState->compareOp = stencil_func_to_vk_compare_op(stencilFace.fTest);
230 opState->compareMask = stencilFace.fTestMask;
231 opState->writeMask = stencilFace.fWriteMask;
232 opState->reference = stencilFace.fRef;
233}
234
Robert Phillips6c2aa7a2019-10-17 19:06:39 +0000235static void setup_depth_stencil_state(
Robert Phillipsa87c5292019-11-12 10:12:42 -0500236 const GrProgramInfo& programInfo,
Robert Phillips6c2aa7a2019-10-17 19:06:39 +0000237 VkPipelineDepthStencilStateCreateInfo* stencilInfo) {
Robert Phillipsa87c5292019-11-12 10:12:42 -0500238 GrStencilSettings stencilSettings = programInfo.nonGLStencilSettings();
239 GrSurfaceOrigin origin = programInfo.origin();
240
Greg Daniel164a9f02016-02-22 09:56:40 -0500241 memset(stencilInfo, 0, sizeof(VkPipelineDepthStencilStateCreateInfo));
242 stencilInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
243 stencilInfo->pNext = nullptr;
244 stencilInfo->flags = 0;
245 // set depth testing defaults
246 stencilInfo->depthTestEnable = VK_FALSE;
247 stencilInfo->depthWriteEnable = VK_FALSE;
248 stencilInfo->depthCompareOp = VK_COMPARE_OP_ALWAYS;
249 stencilInfo->depthBoundsTestEnable = VK_FALSE;
250 stencilInfo->stencilTestEnable = !stencilSettings.isDisabled();
251 if (!stencilSettings.isDisabled()) {
cdalton93a379b2016-05-11 13:58:08 -0700252 if (!stencilSettings.isTwoSided()) {
Chris Dalton67d43fe2019-11-05 23:01:21 -0700253 setup_stencil_op_state(&stencilInfo->front, stencilSettings.singleSidedFace());
cdalton93a379b2016-05-11 13:58:08 -0700254 stencilInfo->back = stencilInfo->front;
255 } else {
Chris Dalton67d43fe2019-11-05 23:01:21 -0700256 setup_stencil_op_state(&stencilInfo->front, stencilSettings.postOriginCCWFace(origin));
257 setup_stencil_op_state(&stencilInfo->back, stencilSettings.postOriginCWFace(origin));
cdalton93a379b2016-05-11 13:58:08 -0700258 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500259 }
260 stencilInfo->minDepthBounds = 0.0f;
261 stencilInfo->maxDepthBounds = 1.0f;
262}
263
egdanielec440992016-09-13 09:54:11 -0700264static void setup_viewport_scissor_state(VkPipelineViewportStateCreateInfo* viewportInfo) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500265 memset(viewportInfo, 0, sizeof(VkPipelineViewportStateCreateInfo));
266 viewportInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
267 viewportInfo->pNext = nullptr;
268 viewportInfo->flags = 0;
269
Greg Daniel164a9f02016-02-22 09:56:40 -0500270 viewportInfo->viewportCount = 1;
egdaniel470d77a2016-03-18 12:50:27 -0700271 viewportInfo->pViewports = nullptr; // This is set dynamically
Greg Daniel164a9f02016-02-22 09:56:40 -0500272
egdaniel470d77a2016-03-18 12:50:27 -0700273 viewportInfo->scissorCount = 1;
274 viewportInfo->pScissors = nullptr; // This is set dynamically
Greg Daniel164a9f02016-02-22 09:56:40 -0500275
Greg Daniel164a9f02016-02-22 09:56:40 -0500276 SkASSERT(viewportInfo->viewportCount == viewportInfo->scissorCount);
277}
278
Robert Phillips901aff02019-10-08 12:32:56 -0400279static void setup_multisample_state(const GrProgramInfo& programInfo,
egdanielec440992016-09-13 09:54:11 -0700280 const GrCaps* caps,
281 VkPipelineMultisampleStateCreateInfo* multisampleInfo) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500282 memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo));
283 multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
284 multisampleInfo->pNext = nullptr;
285 multisampleInfo->flags = 0;
Chris Dalton5e8cdfd2019-11-11 15:23:30 -0700286 SkAssertResult(GrSampleCountToVkSampleCount(programInfo.numRasterSamples(),
Robert Phillips901aff02019-10-08 12:32:56 -0400287 &multisampleInfo->rasterizationSamples));
Brian Osmana63593a2018-12-06 15:54:53 -0500288 multisampleInfo->sampleShadingEnable = VK_FALSE;
289 multisampleInfo->minSampleShading = 0.0f;
Greg Daniel164a9f02016-02-22 09:56:40 -0500290 multisampleInfo->pSampleMask = nullptr;
291 multisampleInfo->alphaToCoverageEnable = VK_FALSE;
292 multisampleInfo->alphaToOneEnable = VK_FALSE;
293}
294
Chris Daltonb204e4c2019-11-07 12:43:13 -0700295static void setup_all_sample_locations_at_pixel_center(
296 const GrProgramInfo& programInfo,
297 VkPipelineSampleLocationsStateCreateInfoEXT* sampleLocations) {
298 constexpr static VkSampleLocationEXT kCenteredSampleLocations[16] = {
299 {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f},
300 {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}, {.5f,.5f}};
301 memset(sampleLocations, 0, sizeof(VkPipelineSampleLocationsStateCreateInfoEXT));
302 sampleLocations->sType = VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT;
303 sampleLocations->pNext = nullptr;
304 sampleLocations->sampleLocationsEnable = VK_TRUE;
305 sampleLocations->sampleLocationsInfo.sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT;
306 sampleLocations->sampleLocationsInfo.pNext = nullptr;
307 SkAssertResult(GrSampleCountToVkSampleCount(
Chris Dalton5e8cdfd2019-11-11 15:23:30 -0700308 programInfo.numRasterSamples(),
Chris Daltonb204e4c2019-11-07 12:43:13 -0700309 &sampleLocations->sampleLocationsInfo.sampleLocationsPerPixel));
310 sampleLocations->sampleLocationsInfo.sampleLocationGridSize.width = 1;
311 sampleLocations->sampleLocationsInfo.sampleLocationGridSize.height = 1;
Chris Dalton5e8cdfd2019-11-11 15:23:30 -0700312 SkASSERT(programInfo.numRasterSamples() < (int)SK_ARRAY_COUNT(kCenteredSampleLocations));
Chris Daltonb204e4c2019-11-07 12:43:13 -0700313 sampleLocations->sampleLocationsInfo.sampleLocationsCount = std::min(
Chris Dalton5e8cdfd2019-11-11 15:23:30 -0700314 programInfo.numRasterSamples(), (int)SK_ARRAY_COUNT(kCenteredSampleLocations));
Chris Daltonb204e4c2019-11-07 12:43:13 -0700315 sampleLocations->sampleLocationsInfo.pSampleLocations = kCenteredSampleLocations;
316}
317
Chris Dalton60061052019-11-11 16:37:24 -0700318static void setup_coverage_modulation_state(
319 VkPipelineCoverageModulationStateCreateInfoNV* coverageModulationInfo) {
320 memset(coverageModulationInfo, 0, sizeof(VkPipelineCoverageModulationStateCreateInfoNV));
321 coverageModulationInfo->sType =
322 VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV;
323 coverageModulationInfo->pNext = nullptr;
324 coverageModulationInfo->flags = 0;
325 coverageModulationInfo->coverageModulationMode = VK_COVERAGE_MODULATION_MODE_RGBA_NV;
326 coverageModulationInfo->coverageModulationTableEnable = false;
327 coverageModulationInfo->coverageModulationTableCount = 0;
328 coverageModulationInfo->pCoverageModulationTable = nullptr;
329}
330
Greg Daniel164a9f02016-02-22 09:56:40 -0500331static VkBlendFactor blend_coeff_to_vk_blend(GrBlendCoeff coeff) {
Greg Daniel6e2af5c2020-03-30 15:07:05 -0400332 switch (coeff) {
333 case kZero_GrBlendCoeff:
334 return VK_BLEND_FACTOR_ZERO;
335 case kOne_GrBlendCoeff:
336 return VK_BLEND_FACTOR_ONE;
337 case kSC_GrBlendCoeff:
338 return VK_BLEND_FACTOR_SRC_COLOR;
339 case kISC_GrBlendCoeff:
340 return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
341 case kDC_GrBlendCoeff:
342 return VK_BLEND_FACTOR_DST_COLOR;
343 case kIDC_GrBlendCoeff:
344 return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
345 case kSA_GrBlendCoeff:
346 return VK_BLEND_FACTOR_SRC_ALPHA;
347 case kISA_GrBlendCoeff:
348 return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
349 case kDA_GrBlendCoeff:
350 return VK_BLEND_FACTOR_DST_ALPHA;
351 case kIDA_GrBlendCoeff:
352 return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
353 case kConstC_GrBlendCoeff:
354 return VK_BLEND_FACTOR_CONSTANT_COLOR;
355 case kIConstC_GrBlendCoeff:
356 return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
357 case kS2C_GrBlendCoeff:
358 return VK_BLEND_FACTOR_SRC1_COLOR;
359 case kIS2C_GrBlendCoeff:
360 return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
361 case kS2A_GrBlendCoeff:
362 return VK_BLEND_FACTOR_SRC1_ALPHA;
363 case kIS2A_GrBlendCoeff:
364 return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
365 case kIllegal_GrBlendCoeff:
366 return VK_BLEND_FACTOR_ZERO;
367 }
368 SkUNREACHABLE;
Greg Daniel164a9f02016-02-22 09:56:40 -0500369}
370
Greg Daniel164a9f02016-02-22 09:56:40 -0500371static VkBlendOp blend_equation_to_vk_blend_op(GrBlendEquation equation) {
372 static const VkBlendOp gTable[] = {
Greg Daniel313c6952018-08-08 09:24:08 -0400373 // Basic blend ops
374 VK_BLEND_OP_ADD,
375 VK_BLEND_OP_SUBTRACT,
376 VK_BLEND_OP_REVERSE_SUBTRACT,
377
378 // Advanced blend ops
379 VK_BLEND_OP_SCREEN_EXT,
380 VK_BLEND_OP_OVERLAY_EXT,
381 VK_BLEND_OP_DARKEN_EXT,
382 VK_BLEND_OP_LIGHTEN_EXT,
383 VK_BLEND_OP_COLORDODGE_EXT,
384 VK_BLEND_OP_COLORBURN_EXT,
385 VK_BLEND_OP_HARDLIGHT_EXT,
386 VK_BLEND_OP_SOFTLIGHT_EXT,
387 VK_BLEND_OP_DIFFERENCE_EXT,
388 VK_BLEND_OP_EXCLUSION_EXT,
389 VK_BLEND_OP_MULTIPLY_EXT,
390 VK_BLEND_OP_HSL_HUE_EXT,
391 VK_BLEND_OP_HSL_SATURATION_EXT,
392 VK_BLEND_OP_HSL_COLOR_EXT,
Mike Klein36743362018-11-06 08:23:30 -0500393 VK_BLEND_OP_HSL_LUMINOSITY_EXT,
394
395 // Illegal.
396 VK_BLEND_OP_ADD,
Greg Daniel164a9f02016-02-22 09:56:40 -0500397 };
Brian Salomon4dea72a2019-12-18 10:43:10 -0500398 static_assert(0 == kAdd_GrBlendEquation);
399 static_assert(1 == kSubtract_GrBlendEquation);
400 static_assert(2 == kReverseSubtract_GrBlendEquation);
401 static_assert(3 == kScreen_GrBlendEquation);
402 static_assert(4 == kOverlay_GrBlendEquation);
403 static_assert(5 == kDarken_GrBlendEquation);
404 static_assert(6 == kLighten_GrBlendEquation);
405 static_assert(7 == kColorDodge_GrBlendEquation);
406 static_assert(8 == kColorBurn_GrBlendEquation);
407 static_assert(9 == kHardLight_GrBlendEquation);
408 static_assert(10 == kSoftLight_GrBlendEquation);
409 static_assert(11 == kDifference_GrBlendEquation);
410 static_assert(12 == kExclusion_GrBlendEquation);
411 static_assert(13 == kMultiply_GrBlendEquation);
412 static_assert(14 == kHSLHue_GrBlendEquation);
413 static_assert(15 == kHSLSaturation_GrBlendEquation);
414 static_assert(16 == kHSLColor_GrBlendEquation);
415 static_assert(17 == kHSLLuminosity_GrBlendEquation);
416 static_assert(SK_ARRAY_COUNT(gTable) == kGrBlendEquationCnt);
Greg Daniel164a9f02016-02-22 09:56:40 -0500417
Greg Daniel6e2af5c2020-03-30 15:07:05 -0400418 SkASSERT((unsigned)equation < kGrBlendEquationCnt);
Greg Daniel164a9f02016-02-22 09:56:40 -0500419 return gTable[equation];
420}
421
egdanielec440992016-09-13 09:54:11 -0700422static void setup_color_blend_state(const GrPipeline& pipeline,
423 VkPipelineColorBlendStateCreateInfo* colorBlendInfo,
424 VkPipelineColorBlendAttachmentState* attachmentState) {
Chris Daltonbbb3f642019-07-24 12:25:08 -0400425 const GrXferProcessor::BlendInfo& blendInfo = pipeline.getXferProcessor().getBlendInfo();
Greg Daniel164a9f02016-02-22 09:56:40 -0500426
427 GrBlendEquation equation = blendInfo.fEquation;
428 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
429 GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
Greg Daniel0a335512020-03-31 09:14:57 -0400430 bool blendOff = GrBlendShouldDisable(equation, srcCoeff, dstCoeff);
Greg Daniel164a9f02016-02-22 09:56:40 -0500431
432 memset(attachmentState, 0, sizeof(VkPipelineColorBlendAttachmentState));
433 attachmentState->blendEnable = !blendOff;
434 if (!blendOff) {
435 attachmentState->srcColorBlendFactor = blend_coeff_to_vk_blend(srcCoeff);
436 attachmentState->dstColorBlendFactor = blend_coeff_to_vk_blend(dstCoeff);
437 attachmentState->colorBlendOp = blend_equation_to_vk_blend_op(equation);
438 attachmentState->srcAlphaBlendFactor = blend_coeff_to_vk_blend(srcCoeff);
439 attachmentState->dstAlphaBlendFactor = blend_coeff_to_vk_blend(dstCoeff);
440 attachmentState->alphaBlendOp = blend_equation_to_vk_blend_op(equation);
441 }
egdaniel3d5d9ac2016-03-01 12:56:15 -0800442
443 if (!blendInfo.fWriteColor) {
444 attachmentState->colorWriteMask = 0;
445 } else {
446 attachmentState->colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
447 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
448 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500449
450 memset(colorBlendInfo, 0, sizeof(VkPipelineColorBlendStateCreateInfo));
451 colorBlendInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
452 colorBlendInfo->pNext = nullptr;
453 colorBlendInfo->flags = 0;
454 colorBlendInfo->logicOpEnable = VK_FALSE;
455 colorBlendInfo->attachmentCount = 1;
456 colorBlendInfo->pAttachments = attachmentState;
egdaniel470d77a2016-03-18 12:50:27 -0700457 // colorBlendInfo->blendConstants is set dynamically
Greg Daniel164a9f02016-02-22 09:56:40 -0500458}
459
egdanielec440992016-09-13 09:54:11 -0700460static void setup_raster_state(const GrPipeline& pipeline,
Jim Van Verthfbdc0802017-05-02 16:15:53 -0400461 const GrCaps* caps,
egdanielec440992016-09-13 09:54:11 -0700462 VkPipelineRasterizationStateCreateInfo* rasterInfo) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500463 memset(rasterInfo, 0, sizeof(VkPipelineRasterizationStateCreateInfo));
464 rasterInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
465 rasterInfo->pNext = nullptr;
466 rasterInfo->flags = 0;
467 rasterInfo->depthClampEnable = VK_FALSE;
468 rasterInfo->rasterizerDiscardEnable = VK_FALSE;
Chris Dalton1215cda2019-12-17 21:44:04 -0700469 rasterInfo->polygonMode = (caps->wireframeMode() || pipeline.isWireframe()) ?
470 VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL;
Brian Salomonf0861672017-05-08 11:10:10 -0400471 rasterInfo->cullMode = VK_CULL_MODE_NONE;
Chris Daltonb91c4662018-08-01 10:46:22 -0600472 rasterInfo->frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
Greg Daniel164a9f02016-02-22 09:56:40 -0500473 rasterInfo->depthBiasEnable = VK_FALSE;
474 rasterInfo->depthBiasConstantFactor = 0.0f;
475 rasterInfo->depthBiasClamp = 0.0f;
476 rasterInfo->depthBiasSlopeFactor = 0.0f;
477 rasterInfo->lineWidth = 1.0f;
478}
479
Chris Daltonce425af2019-12-16 10:39:03 -0700480static void setup_conservative_raster_info(
481 VkPipelineRasterizationConservativeStateCreateInfoEXT* conservativeRasterInfo) {
482 memset(conservativeRasterInfo, 0,
483 sizeof(VkPipelineRasterizationConservativeStateCreateInfoEXT));
484 conservativeRasterInfo->sType =
485 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT;
486 conservativeRasterInfo->pNext = nullptr;
487 conservativeRasterInfo->flags = 0;
488 conservativeRasterInfo->conservativeRasterizationMode =
489 VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
490 conservativeRasterInfo->extraPrimitiveOverestimationSize = 0;
491}
492
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000493static void setup_dynamic_state(VkPipelineDynamicStateCreateInfo* dynamicInfo,
494 VkDynamicState* dynamicStates) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500495 memset(dynamicInfo, 0, sizeof(VkPipelineDynamicStateCreateInfo));
496 dynamicInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
egdaniel470d77a2016-03-18 12:50:27 -0700497 dynamicInfo->pNext = VK_NULL_HANDLE;
498 dynamicInfo->flags = 0;
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000499 dynamicStates[0] = VK_DYNAMIC_STATE_VIEWPORT;
500 dynamicStates[1] = VK_DYNAMIC_STATE_SCISSOR;
501 dynamicStates[2] = VK_DYNAMIC_STATE_BLEND_CONSTANTS;
502 dynamicInfo->dynamicStateCount = 3;
503 dynamicInfo->pDynamicStates = dynamicStates;
Greg Daniel164a9f02016-02-22 09:56:40 -0500504}
505
Chris Dalton71713f62019-04-18 12:41:03 -0600506GrVkPipeline* GrVkPipeline::Create(
Robert Phillips901aff02019-10-08 12:32:56 -0400507 GrVkGpu* gpu,
508 const GrProgramInfo& programInfo,
Chris Dalton71713f62019-04-18 12:41:03 -0600509 VkPipelineShaderStageCreateInfo* shaderStageInfo, int shaderStageCount,
Robert Phillipsfcaae482019-11-07 10:17:03 -0500510 VkRenderPass compatibleRenderPass, VkPipelineLayout layout,
Chris Dalton71713f62019-04-18 12:41:03 -0600511 VkPipelineCache cache) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500512 VkPipelineVertexInputStateCreateInfo vertexInputInfo;
Chris Dalton1d616352017-05-31 12:51:23 -0600513 SkSTArray<2, VkVertexInputBindingDescription, true> bindingDescs;
egdanielb05df0f2016-06-27 07:15:20 -0700514 SkSTArray<16, VkVertexInputAttributeDescription> attributeDesc;
Robert Phillips901aff02019-10-08 12:32:56 -0400515 int totalAttributeCnt = programInfo.primProc().numVertexAttributes() +
516 programInfo.primProc().numInstanceAttributes();
Brian Salomon92be2f72018-06-19 14:33:47 -0400517 SkASSERT(totalAttributeCnt <= gpu->vkCaps().maxVertexAttributes());
518 VkVertexInputAttributeDescription* pAttribs = attributeDesc.push_back_n(totalAttributeCnt);
Robert Phillips901aff02019-10-08 12:32:56 -0400519 setup_vertex_input_state(programInfo.primProc(), &vertexInputInfo, &bindingDescs, pAttribs);
Greg Daniel164a9f02016-02-22 09:56:40 -0500520
521 VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo;
Robert Phillipsfcaae482019-11-07 10:17:03 -0500522 setup_input_assembly_state(programInfo.primitiveType(), &inputAssemblyInfo);
Greg Daniel164a9f02016-02-22 09:56:40 -0500523
524 VkPipelineDepthStencilStateCreateInfo depthStencilInfo;
Robert Phillipsa87c5292019-11-12 10:12:42 -0500525 setup_depth_stencil_state(programInfo, &depthStencilInfo);
Greg Daniel164a9f02016-02-22 09:56:40 -0500526
Greg Daniel164a9f02016-02-22 09:56:40 -0500527 VkPipelineViewportStateCreateInfo viewportInfo;
egdanielec440992016-09-13 09:54:11 -0700528 setup_viewport_scissor_state(&viewportInfo);
Greg Daniel164a9f02016-02-22 09:56:40 -0500529
530 VkPipelineMultisampleStateCreateInfo multisampleInfo;
Robert Phillips901aff02019-10-08 12:32:56 -0400531 setup_multisample_state(programInfo, gpu->caps(), &multisampleInfo);
Greg Daniel164a9f02016-02-22 09:56:40 -0500532
Chris Daltonb204e4c2019-11-07 12:43:13 -0700533 VkPipelineSampleLocationsStateCreateInfoEXT sampleLocations;
534 if (gpu->caps()->multisampleDisableSupport()) {
Chris Dalton5e8cdfd2019-11-11 15:23:30 -0700535 if (programInfo.numRasterSamples() > 1 && !programInfo.pipeline().isHWAntialiasState()) {
Chris Daltonb204e4c2019-11-07 12:43:13 -0700536 setup_all_sample_locations_at_pixel_center(programInfo, &sampleLocations);
537 sampleLocations.pNext = multisampleInfo.pNext;
538 multisampleInfo.pNext = &sampleLocations;
539 }
540 }
541
Chris Dalton60061052019-11-11 16:37:24 -0700542 VkPipelineCoverageModulationStateCreateInfoNV coverageModulationInfo;
543 if (gpu->caps()->mixedSamplesSupport()) {
544 if (programInfo.isMixedSampled()) {
545 SkASSERT(gpu->caps()->mixedSamplesSupport());
546 setup_coverage_modulation_state(&coverageModulationInfo);
547 coverageModulationInfo.pNext = multisampleInfo.pNext;
548 multisampleInfo.pNext = &coverageModulationInfo;
549 }
550 }
551
Greg Daniel164a9f02016-02-22 09:56:40 -0500552 // We will only have one color attachment per pipeline.
553 VkPipelineColorBlendAttachmentState attachmentStates[1];
554 VkPipelineColorBlendStateCreateInfo colorBlendInfo;
Robert Phillips901aff02019-10-08 12:32:56 -0400555 setup_color_blend_state(programInfo.pipeline(), &colorBlendInfo, attachmentStates);
Greg Daniel164a9f02016-02-22 09:56:40 -0500556
557 VkPipelineRasterizationStateCreateInfo rasterInfo;
Robert Phillips901aff02019-10-08 12:32:56 -0400558 setup_raster_state(programInfo.pipeline(), gpu->caps(), &rasterInfo);
Greg Daniel164a9f02016-02-22 09:56:40 -0500559
Chris Daltonce425af2019-12-16 10:39:03 -0700560 VkPipelineRasterizationConservativeStateCreateInfoEXT conservativeRasterInfo;
561 if (programInfo.pipeline().usesConservativeRaster()) {
562 SkASSERT(gpu->caps()->conservativeRasterSupport());
563 setup_conservative_raster_info(&conservativeRasterInfo);
564 conservativeRasterInfo.pNext = rasterInfo.pNext;
565 rasterInfo.pNext = &conservativeRasterInfo;
566 }
567
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000568 VkDynamicState dynamicStates[3];
Greg Daniel164a9f02016-02-22 09:56:40 -0500569 VkPipelineDynamicStateCreateInfo dynamicInfo;
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000570 setup_dynamic_state(&dynamicInfo, dynamicStates);
Greg Daniel164a9f02016-02-22 09:56:40 -0500571
572 VkGraphicsPipelineCreateInfo pipelineCreateInfo;
573 memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo));
574 pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
575 pipelineCreateInfo.pNext = nullptr;
576 pipelineCreateInfo.flags = 0;
577 pipelineCreateInfo.stageCount = shaderStageCount;
578 pipelineCreateInfo.pStages = shaderStageInfo;
579 pipelineCreateInfo.pVertexInputState = &vertexInputInfo;
580 pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo;
581 pipelineCreateInfo.pTessellationState = nullptr;
582 pipelineCreateInfo.pViewportState = &viewportInfo;
583 pipelineCreateInfo.pRasterizationState = &rasterInfo;
584 pipelineCreateInfo.pMultisampleState = &multisampleInfo;
585 pipelineCreateInfo.pDepthStencilState = &depthStencilInfo;
586 pipelineCreateInfo.pColorBlendState = &colorBlendInfo;
587 pipelineCreateInfo.pDynamicState = &dynamicInfo;
588 pipelineCreateInfo.layout = layout;
Greg Daniel99b88e02018-10-03 15:31:20 -0400589 pipelineCreateInfo.renderPass = compatibleRenderPass;
Greg Daniel164a9f02016-02-22 09:56:40 -0500590 pipelineCreateInfo.subpass = 0;
591 pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
592 pipelineCreateInfo.basePipelineIndex = -1;
593
594 VkPipeline vkPipeline;
Ben Wagner6c30e742019-02-06 10:46:14 -0500595 VkResult err;
596 {
597#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
598 // skia:8712
599 __lsan::ScopedDisabler lsanDisabler;
600#endif
Greg Danield034c622019-11-20 09:33:29 -0500601 GR_VK_CALL_RESULT(gpu, err, CreateGraphicsPipelines(gpu->device(), cache, 1,
602 &pipelineCreateInfo, nullptr,
603 &vkPipeline));
Ben Wagner6c30e742019-02-06 10:46:14 -0500604 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500605 if (err) {
Greg Daniel5ba448c2018-02-26 13:30:47 -0500606 SkDebugf("Failed to create pipeline. Error: %d\n", err);
Greg Daniel164a9f02016-02-22 09:56:40 -0500607 return nullptr;
608 }
609
Jim Van Verth5082df12020-03-11 16:14:51 -0400610 return new GrVkPipeline(gpu, vkPipeline, layout);
Greg Daniel164a9f02016-02-22 09:56:40 -0500611}
612
Jim Van Verth5082df12020-03-11 16:14:51 -0400613void GrVkPipeline::freeGPUData() const {
614 GR_VK_CALL(fGpu->vkInterface(), DestroyPipeline(fGpu->device(), fPipeline, nullptr));
615 GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), fPipelineLayout,
616 nullptr));
Greg Daniel164a9f02016-02-22 09:56:40 -0500617}
618
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000619void GrVkPipeline::SetDynamicScissorRectState(GrVkGpu* gpu,
620 GrVkCommandBuffer* cmdBuffer,
621 const GrRenderTarget* renderTarget,
622 GrSurfaceOrigin rtOrigin,
Greg Daniel4a0d36d2019-09-30 12:24:36 -0400623 const SkIRect& scissorRect) {
624 SkASSERT(scissorRect.isEmpty() ||
625 SkIRect::MakeWH(renderTarget->width(), renderTarget->height()).contains(scissorRect));
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000626
627 VkRect2D scissor;
628 scissor.offset.x = scissorRect.fLeft;
629 scissor.extent.width = scissorRect.width();
630 if (kTopLeft_GrSurfaceOrigin == rtOrigin) {
631 scissor.offset.y = scissorRect.fTop;
632 } else {
633 SkASSERT(kBottomLeft_GrSurfaceOrigin == rtOrigin);
634 scissor.offset.y = renderTarget->height() - scissorRect.fBottom;
635 }
636 scissor.extent.height = scissorRect.height();
637
638 SkASSERT(scissor.offset.x >= 0);
639 SkASSERT(scissor.offset.y >= 0);
640 cmdBuffer->setScissor(gpu, 0, 1, &scissor);
641}
642
Chris Dalton46983b72017-06-06 12:27:16 -0600643void GrVkPipeline::SetDynamicViewportState(GrVkGpu* gpu,
644 GrVkCommandBuffer* cmdBuffer,
645 const GrRenderTarget* renderTarget) {
egdaniel470d77a2016-03-18 12:50:27 -0700646 // We always use one viewport the size of the RT
647 VkViewport viewport;
648 viewport.x = 0.0f;
649 viewport.y = 0.0f;
Chris Dalton46983b72017-06-06 12:27:16 -0600650 viewport.width = SkIntToScalar(renderTarget->width());
651 viewport.height = SkIntToScalar(renderTarget->height());
egdaniel470d77a2016-03-18 12:50:27 -0700652 viewport.minDepth = 0.0f;
653 viewport.maxDepth = 1.0f;
654 cmdBuffer->setViewport(gpu, 0, 1, &viewport);
655}
656
Chris Dalton46983b72017-06-06 12:27:16 -0600657void GrVkPipeline::SetDynamicBlendConstantState(GrVkGpu* gpu,
658 GrVkCommandBuffer* cmdBuffer,
Greg Daniel2c3398d2019-06-19 11:58:01 -0400659 const GrSwizzle& swizzle,
Chris Dalton46983b72017-06-06 12:27:16 -0600660 const GrXferProcessor& xferProcessor) {
Chris Daltonbbb3f642019-07-24 12:25:08 -0400661 const GrXferProcessor::BlendInfo& blendInfo = xferProcessor.getBlendInfo();
egdaniel470d77a2016-03-18 12:50:27 -0700662 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
663 GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
664 float floatColors[4];
Greg Daniel6e2af5c2020-03-30 15:07:05 -0400665 if (GrBlendCoeffRefsConstant(srcCoeff) || GrBlendCoeffRefsConstant(dstCoeff)) {
Greg Daniel6c9f1012017-05-11 09:20:59 -0400666 // Swizzle the blend to match what the shader will output.
Brian Osman422f95b2018-11-05 16:49:04 -0500667 SkPMColor4f blendConst = swizzle.applyTo(blendInfo.fBlendConstant);
668 floatColors[0] = blendConst.fR;
669 floatColors[1] = blendConst.fG;
670 floatColors[2] = blendConst.fB;
671 floatColors[3] = blendConst.fA;
egdaniel470d77a2016-03-18 12:50:27 -0700672 } else {
673 memset(floatColors, 0, 4 * sizeof(float));
674 }
675 cmdBuffer->setBlendConstants(gpu, floatColors);
676}