OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrVkPipeline.h" | 8 #include "GrVkPipeline.h" |
9 | 9 |
10 #include "GrGeometryProcessor.h" | 10 #include "GrGeometryProcessor.h" |
11 #include "GrPipeline.h" | 11 #include "GrPipeline.h" |
12 | 12 #include "GrVkCommandBuffer.h" |
13 #include "GrVkGpu.h" | 13 #include "GrVkGpu.h" |
14 #include "GrVkProgramDesc.h" | 14 #include "GrVkProgramDesc.h" |
15 #include "GrVkRenderTarget.h" | 15 #include "GrVkRenderTarget.h" |
16 #include "GrVkUtil.h" | 16 #include "GrVkUtil.h" |
17 | 17 |
18 static inline const VkFormat& attrib_type_to_vkformat(GrVertexAttribType type) { | 18 static inline const VkFormat& attrib_type_to_vkformat(GrVertexAttribType type) { |
19 SkASSERT(type >= 0 && type < kGrVertexAttribTypeCount); | 19 SkASSERT(type >= 0 && type < kGrVertexAttribTypeCount); |
20 static const VkFormat kFormats[kGrVertexAttribTypeCount] = { | 20 static const VkFormat kFormats[kGrVertexAttribTypeCount] = { |
21 VK_FORMAT_R32_SFLOAT, // kFloat_GrVertexAttribType | 21 VK_FORMAT_R32_SFLOAT, // kFloat_GrVertexAttribType |
22 VK_FORMAT_R32G32_SFLOAT, // kVec2f_GrVertexAttribType | 22 VK_FORMAT_R32G32_SFLOAT, // kVec2f_GrVertexAttribType |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 stencilInfo->back.writeMask = stencilSettings.writeMask(face); | 181 stencilInfo->back.writeMask = stencilSettings.writeMask(face); |
182 stencilInfo->back.reference = stencilSettings.funcRef(face); | 182 stencilInfo->back.reference = stencilSettings.funcRef(face); |
183 } | 183 } |
184 stencilInfo->minDepthBounds = 0.0f; | 184 stencilInfo->minDepthBounds = 0.0f; |
185 stencilInfo->maxDepthBounds = 1.0f; | 185 stencilInfo->maxDepthBounds = 1.0f; |
186 } | 186 } |
187 | 187 |
188 void setup_viewport_scissor_state(const GrVkGpu* gpu, | 188 void setup_viewport_scissor_state(const GrVkGpu* gpu, |
189 const GrPipeline& pipeline, | 189 const GrPipeline& pipeline, |
190 const GrVkRenderTarget* vkRT, | 190 const GrVkRenderTarget* vkRT, |
191 VkPipelineViewportStateCreateInfo* viewportInf
o, | 191 VkPipelineViewportStateCreateInfo* viewportInf
o) { |
192 VkViewport* viewport, | |
193 VkRect2D* scissor) { | |
194 memset(viewportInfo, 0, sizeof(VkPipelineViewportStateCreateInfo)); | 192 memset(viewportInfo, 0, sizeof(VkPipelineViewportStateCreateInfo)); |
195 viewportInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; | 193 viewportInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; |
196 viewportInfo->pNext = nullptr; | 194 viewportInfo->pNext = nullptr; |
197 viewportInfo->flags = 0; | 195 viewportInfo->flags = 0; |
198 | 196 |
199 viewport->x = 0.0f; | |
200 viewport->y = 0.0f; | |
201 viewport->width = SkIntToScalar(vkRT->width()); | |
202 viewport->height = SkIntToScalar(vkRT->height()); | |
203 viewport->minDepth = 0.0f; | |
204 viewport->maxDepth = 1.0f; | |
205 viewportInfo->viewportCount = 1; | 197 viewportInfo->viewportCount = 1; |
206 viewportInfo->pViewports = viewport; | 198 viewportInfo->pViewports = nullptr; // This is set dynamically |
207 | 199 |
208 const GrScissorState& scissorState = pipeline.getScissorState(); | 200 viewportInfo->scissorCount = 1; |
209 if (scissorState.enabled() && | 201 viewportInfo->pScissors = nullptr; // This is set dynamically |
210 !scissorState.rect().contains(0, 0, vkRT->width(), vkRT->height())) { | |
211 // This all assumes the scissorState has previously been clipped to the
device space render | |
212 // target. | |
213 scissor->offset.x = scissorState.rect().fLeft; | |
214 scissor->extent.width = scissorState.rect().width(); | |
215 if (kTopLeft_GrSurfaceOrigin == vkRT->origin()) { | |
216 scissor->offset.y = scissorState.rect().fTop; | |
217 } else { | |
218 SkASSERT(kBottomLeft_GrSurfaceOrigin == vkRT->origin()); | |
219 scissor->offset.y = vkRT->height() - scissorState.rect().fBottom; | |
220 } | |
221 scissor->extent.height = scissorState.rect().height(); | |
222 | 202 |
223 viewportInfo->scissorCount = 1; | |
224 viewportInfo->pScissors = scissor; | |
225 SkASSERT(scissor->offset.x >= 0); | |
226 SkASSERT(scissor->offset.x + scissor->extent.width <= (uint32_t)vkRT->wi
dth()); | |
227 SkASSERT(scissor->offset.y >= 0); | |
228 SkASSERT(scissor->offset.y + scissor->extent.height <= (uint32_t)vkRT->h
eight()); | |
229 } else { | |
230 scissor->extent.width = vkRT->width(); | |
231 scissor->extent.height = vkRT->height(); | |
232 scissor->offset.x = 0; | |
233 scissor->offset.y = 0; | |
234 viewportInfo->scissorCount = 1; | |
235 viewportInfo->pScissors = scissor; | |
236 } | |
237 SkASSERT(viewportInfo->viewportCount == viewportInfo->scissorCount); | 203 SkASSERT(viewportInfo->viewportCount == viewportInfo->scissorCount); |
238 } | 204 } |
239 | 205 |
240 void setup_multisample_state(const GrPipeline& pipeline, | 206 void setup_multisample_state(const GrPipeline& pipeline, |
241 VkPipelineMultisampleStateCreateInfo* multisampleIn
fo) { | 207 VkPipelineMultisampleStateCreateInfo* multisampleIn
fo) { |
242 memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo)); | 208 memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo)); |
243 multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE
_INFO; | 209 multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE
_INFO; |
244 multisampleInfo->pNext = nullptr; | 210 multisampleInfo->pNext = nullptr; |
245 multisampleInfo->flags = 0; | 211 multisampleInfo->flags = 0; |
246 int numSamples = pipeline.getRenderTarget()->numColorSamples(); | 212 int numSamples = pipeline.getRenderTarget()->numColorSamples(); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_CO
MPONENT_A_BIT; | 340 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_CO
MPONENT_A_BIT; |
375 } | 341 } |
376 | 342 |
377 memset(colorBlendInfo, 0, sizeof(VkPipelineColorBlendStateCreateInfo)); | 343 memset(colorBlendInfo, 0, sizeof(VkPipelineColorBlendStateCreateInfo)); |
378 colorBlendInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_
INFO; | 344 colorBlendInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_
INFO; |
379 colorBlendInfo->pNext = nullptr; | 345 colorBlendInfo->pNext = nullptr; |
380 colorBlendInfo->flags = 0; | 346 colorBlendInfo->flags = 0; |
381 colorBlendInfo->logicOpEnable = VK_FALSE; | 347 colorBlendInfo->logicOpEnable = VK_FALSE; |
382 colorBlendInfo->attachmentCount = 1; | 348 colorBlendInfo->attachmentCount = 1; |
383 colorBlendInfo->pAttachments = attachmentState; | 349 colorBlendInfo->pAttachments = attachmentState; |
384 if (blend_coeff_refs_constant(srcCoeff) || blend_coeff_refs_constant(dstCoef
f)) { | 350 // colorBlendInfo->blendConstants is set dynamically |
385 GrColorToRGBAFloat(blendInfo.fBlendConstant, colorBlendInfo->blendConsta
nts); | |
386 } | |
387 } | 351 } |
388 | 352 |
389 VkCullModeFlags draw_face_to_vk_cull_mode(GrPipelineBuilder::DrawFace drawFace)
{ | 353 VkCullModeFlags draw_face_to_vk_cull_mode(GrPipelineBuilder::DrawFace drawFace)
{ |
390 // Assumes that we've set the front face to be ccw | 354 // Assumes that we've set the front face to be ccw |
391 static const VkCullModeFlags gTable[] = { | 355 static const VkCullModeFlags gTable[] = { |
392 VK_CULL_MODE_NONE, // kBoth_DrawFace | 356 VK_CULL_MODE_NONE, // kBoth_DrawFace |
393 VK_CULL_MODE_BACK_BIT, // kCCW_DrawFace, cull back face | 357 VK_CULL_MODE_BACK_BIT, // kCCW_DrawFace, cull back face |
394 VK_CULL_MODE_FRONT_BIT, // kCW_DrawFace, cull front face | 358 VK_CULL_MODE_FRONT_BIT, // kCW_DrawFace, cull front face |
395 }; | 359 }; |
396 GR_STATIC_ASSERT(0 == GrPipelineBuilder::kBoth_DrawFace); | 360 GR_STATIC_ASSERT(0 == GrPipelineBuilder::kBoth_DrawFace); |
(...skipping 18 matching lines...) Expand all Loading... |
415 rasterInfo->frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; | 379 rasterInfo->frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; |
416 rasterInfo->depthBiasEnable = VK_FALSE; | 380 rasterInfo->depthBiasEnable = VK_FALSE; |
417 rasterInfo->depthBiasConstantFactor = 0.0f; | 381 rasterInfo->depthBiasConstantFactor = 0.0f; |
418 rasterInfo->depthBiasClamp = 0.0f; | 382 rasterInfo->depthBiasClamp = 0.0f; |
419 rasterInfo->depthBiasSlopeFactor = 0.0f; | 383 rasterInfo->depthBiasSlopeFactor = 0.0f; |
420 rasterInfo->lineWidth = 1.0f; | 384 rasterInfo->lineWidth = 1.0f; |
421 } | 385 } |
422 | 386 |
423 void setup_dynamic_state(const GrVkGpu* gpu, | 387 void setup_dynamic_state(const GrVkGpu* gpu, |
424 const GrPipeline& pipeline, | 388 const GrPipeline& pipeline, |
425 VkPipelineDynamicStateCreateInfo* dynamicInfo) { | 389 VkPipelineDynamicStateCreateInfo* dynamicInfo, |
| 390 VkDynamicState* dynamicStates) { |
426 memset(dynamicInfo, 0, sizeof(VkPipelineDynamicStateCreateInfo)); | 391 memset(dynamicInfo, 0, sizeof(VkPipelineDynamicStateCreateInfo)); |
427 dynamicInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; | 392 dynamicInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; |
428 // TODO: mask out any state we might want to set dynamically | 393 dynamicInfo->pNext = VK_NULL_HANDLE; |
429 dynamicInfo->dynamicStateCount = 0; | 394 dynamicInfo->flags = 0; |
| 395 dynamicStates[0] = VK_DYNAMIC_STATE_VIEWPORT; |
| 396 dynamicStates[1] = VK_DYNAMIC_STATE_SCISSOR; |
| 397 dynamicStates[2] = VK_DYNAMIC_STATE_BLEND_CONSTANTS; |
| 398 dynamicInfo->dynamicStateCount = 3; |
| 399 dynamicInfo->pDynamicStates = dynamicStates; |
430 } | 400 } |
431 | 401 |
432 GrVkPipeline* GrVkPipeline::Create(GrVkGpu* gpu, const GrPipeline& pipeline, | 402 GrVkPipeline* GrVkPipeline::Create(GrVkGpu* gpu, const GrPipeline& pipeline, |
433 const GrPrimitiveProcessor& primProc, | 403 const GrPrimitiveProcessor& primProc, |
434 VkPipelineShaderStageCreateInfo* shaderStageI
nfo, | 404 VkPipelineShaderStageCreateInfo* shaderStageI
nfo, |
435 int shaderStageCount, | 405 int shaderStageCount, |
436 GrPrimitiveType primitiveType, | 406 GrPrimitiveType primitiveType, |
437 const GrVkRenderPass& renderPass, | 407 const GrVkRenderPass& renderPass, |
438 VkPipelineLayout layout, | 408 VkPipelineLayout layout, |
439 VkPipelineCache cache) { | 409 VkPipelineCache cache) { |
440 VkPipelineVertexInputStateCreateInfo vertexInputInfo; | 410 VkPipelineVertexInputStateCreateInfo vertexInputInfo; |
441 VkVertexInputBindingDescription bindingDesc; | 411 VkVertexInputBindingDescription bindingDesc; |
442 // TODO: allocate this based on VkPhysicalDeviceLimits::maxVertexInputAttrib
utes | 412 // TODO: allocate this based on VkPhysicalDeviceLimits::maxVertexInputAttrib
utes |
443 static const int kMaxVertexAttributes = 16; | 413 static const int kMaxVertexAttributes = 16; |
444 static VkVertexInputAttributeDescription attributeDesc[kMaxVertexAttributes]
; | 414 static VkVertexInputAttributeDescription attributeDesc[kMaxVertexAttributes]
; |
445 setup_vertex_input_state(primProc, &vertexInputInfo, &bindingDesc, 1, | 415 setup_vertex_input_state(primProc, &vertexInputInfo, &bindingDesc, 1, |
446 attributeDesc, kMaxVertexAttributes); | 416 attributeDesc, kMaxVertexAttributes); |
447 | 417 |
448 VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo; | 418 VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo; |
449 setup_input_assembly_state(primitiveType, &inputAssemblyInfo); | 419 setup_input_assembly_state(primitiveType, &inputAssemblyInfo); |
450 | 420 |
451 VkPipelineDepthStencilStateCreateInfo depthStencilInfo; | 421 VkPipelineDepthStencilStateCreateInfo depthStencilInfo; |
452 setup_depth_stencil_state(gpu, pipeline.getStencil(), &depthStencilInfo); | 422 setup_depth_stencil_state(gpu, pipeline.getStencil(), &depthStencilInfo); |
453 | 423 |
454 GrRenderTarget* rt = pipeline.getRenderTarget(); | 424 GrRenderTarget* rt = pipeline.getRenderTarget(); |
455 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt); | 425 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt); |
456 VkPipelineViewportStateCreateInfo viewportInfo; | 426 VkPipelineViewportStateCreateInfo viewportInfo; |
457 VkViewport viewport; | 427 setup_viewport_scissor_state(gpu, pipeline, vkRT, &viewportInfo); |
458 VkRect2D scissor; | |
459 setup_viewport_scissor_state(gpu, pipeline, vkRT, &viewportInfo, &viewport,
&scissor); | |
460 | 428 |
461 VkPipelineMultisampleStateCreateInfo multisampleInfo; | 429 VkPipelineMultisampleStateCreateInfo multisampleInfo; |
462 setup_multisample_state(pipeline, &multisampleInfo); | 430 setup_multisample_state(pipeline, &multisampleInfo); |
463 | 431 |
464 // We will only have one color attachment per pipeline. | 432 // We will only have one color attachment per pipeline. |
465 VkPipelineColorBlendAttachmentState attachmentStates[1]; | 433 VkPipelineColorBlendAttachmentState attachmentStates[1]; |
466 VkPipelineColorBlendStateCreateInfo colorBlendInfo; | 434 VkPipelineColorBlendStateCreateInfo colorBlendInfo; |
467 setup_color_blend_state(gpu, pipeline, &colorBlendInfo, attachmentStates); | 435 setup_color_blend_state(gpu, pipeline, &colorBlendInfo, attachmentStates); |
468 | 436 |
469 VkPipelineRasterizationStateCreateInfo rasterInfo; | 437 VkPipelineRasterizationStateCreateInfo rasterInfo; |
470 setup_raster_state(gpu, pipeline, &rasterInfo); | 438 setup_raster_state(gpu, pipeline, &rasterInfo); |
471 | 439 |
| 440 VkDynamicState dynamicStates[3]; |
472 VkPipelineDynamicStateCreateInfo dynamicInfo; | 441 VkPipelineDynamicStateCreateInfo dynamicInfo; |
473 setup_dynamic_state(gpu, pipeline, &dynamicInfo); | 442 setup_dynamic_state(gpu, pipeline, &dynamicInfo, dynamicStates); |
474 | 443 |
475 VkGraphicsPipelineCreateInfo pipelineCreateInfo; | 444 VkGraphicsPipelineCreateInfo pipelineCreateInfo; |
476 memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo)); | 445 memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo)); |
477 pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; | 446 pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; |
478 pipelineCreateInfo.pNext = nullptr; | 447 pipelineCreateInfo.pNext = nullptr; |
479 pipelineCreateInfo.flags = 0; | 448 pipelineCreateInfo.flags = 0; |
480 pipelineCreateInfo.stageCount = shaderStageCount; | 449 pipelineCreateInfo.stageCount = shaderStageCount; |
481 pipelineCreateInfo.pStages = shaderStageInfo; | 450 pipelineCreateInfo.pStages = shaderStageInfo; |
482 pipelineCreateInfo.pVertexInputState = &vertexInputInfo; | 451 pipelineCreateInfo.pVertexInputState = &vertexInputInfo; |
483 pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo; | 452 pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo; |
(...skipping 20 matching lines...) Expand all Loading... |
504 } | 473 } |
505 | 474 |
506 return new GrVkPipeline(vkPipeline); | 475 return new GrVkPipeline(vkPipeline); |
507 } | 476 } |
508 | 477 |
509 void GrVkPipeline::freeGPUData(const GrVkGpu* gpu) const { | 478 void GrVkPipeline::freeGPUData(const GrVkGpu* gpu) const { |
510 GR_VK_CALL(gpu->vkInterface(), DestroyPipeline(gpu->device(), fPipeline, nul
lptr)); | 479 GR_VK_CALL(gpu->vkInterface(), DestroyPipeline(gpu->device(), fPipeline, nul
lptr)); |
511 } | 480 } |
512 | 481 |
513 | 482 |
| 483 void set_dynamic_scissor_state(GrVkGpu* gpu, |
| 484 GrVkCommandBuffer* cmdBuffer, |
| 485 const GrPipeline& pipeline, |
| 486 const GrRenderTarget& target) { |
| 487 // We always use one scissor and if it is disabled we just make it the size
of the RT |
| 488 const GrScissorState& scissorState = pipeline.getScissorState(); |
| 489 VkRect2D scissor; |
| 490 if (scissorState.enabled() && |
| 491 !scissorState.rect().contains(0, 0, target.width(), target.height())) { |
| 492 // This all assumes the scissorState has previously been clipped to the
device space render |
| 493 // target. |
| 494 scissor.offset.x = scissorState.rect().fLeft; |
| 495 scissor.extent.width = scissorState.rect().width(); |
| 496 if (kTopLeft_GrSurfaceOrigin == target.origin()) { |
| 497 scissor.offset.y = scissorState.rect().fTop; |
| 498 } else { |
| 499 SkASSERT(kBottomLeft_GrSurfaceOrigin == target.origin()); |
| 500 scissor.offset.y = target.height() - scissorState.rect().fBottom; |
| 501 } |
| 502 scissor.extent.height = scissorState.rect().height(); |
| 503 |
| 504 SkASSERT(scissor.offset.x >= 0); |
| 505 SkASSERT(scissor.offset.x + scissor.extent.width <= (uint32_t)target.wid
th()); |
| 506 SkASSERT(scissor.offset.y >= 0); |
| 507 SkASSERT(scissor.offset.y + scissor.extent.height <= (uint32_t)target.he
ight()); |
| 508 } else { |
| 509 scissor.extent.width = target.width(); |
| 510 scissor.extent.height = target.height(); |
| 511 scissor.offset.x = 0; |
| 512 scissor.offset.y = 0; |
| 513 } |
| 514 cmdBuffer->setScissor(gpu, 0, 1, &scissor); |
| 515 } |
| 516 |
| 517 void set_dynamic_viewport_state(GrVkGpu* gpu, |
| 518 GrVkCommandBuffer* cmdBuffer, |
| 519 const GrRenderTarget& target) { |
| 520 // We always use one viewport the size of the RT |
| 521 VkViewport viewport; |
| 522 viewport.x = 0.0f; |
| 523 viewport.y = 0.0f; |
| 524 viewport.width = SkIntToScalar(target.width()); |
| 525 viewport.height = SkIntToScalar(target.height()); |
| 526 viewport.minDepth = 0.0f; |
| 527 viewport.maxDepth = 1.0f; |
| 528 cmdBuffer->setViewport(gpu, 0, 1, &viewport); |
| 529 } |
| 530 |
| 531 void set_dynamic_blend_constant_state(GrVkGpu* gpu, |
| 532 GrVkCommandBuffer* cmdBuffer, |
| 533 const GrPipeline& pipeline) { |
| 534 GrXferProcessor::BlendInfo blendInfo; |
| 535 pipeline.getXferProcessor().getBlendInfo(&blendInfo); |
| 536 GrBlendCoeff srcCoeff = blendInfo.fSrcBlend; |
| 537 GrBlendCoeff dstCoeff = blendInfo.fDstBlend; |
| 538 float floatColors[4]; |
| 539 if (blend_coeff_refs_constant(srcCoeff) || blend_coeff_refs_constant(dstCoef
f)) { |
| 540 GrColorToRGBAFloat(blendInfo.fBlendConstant, floatColors); |
| 541 } else { |
| 542 memset(floatColors, 0, 4 * sizeof(float)); |
| 543 } |
| 544 cmdBuffer->setBlendConstants(gpu, floatColors); |
| 545 } |
| 546 |
| 547 |
| 548 |
| 549 void GrVkPipeline::SetDynamicState(GrVkGpu* gpu, |
| 550 GrVkCommandBuffer* cmdBuffer, |
| 551 const GrPipeline& pipeline) { |
| 552 const GrRenderTarget& target = *pipeline.getRenderTarget(); |
| 553 set_dynamic_scissor_state(gpu, cmdBuffer, pipeline, target); |
| 554 set_dynamic_viewport_state(gpu, cmdBuffer, target); |
| 555 set_dynamic_blend_constant_state(gpu, cmdBuffer, pipeline); |
| 556 } |
OLD | NEW |