|
37 | 37 | #pragma mark MVKPipelineCommandEncoderState |
38 | 38 |
|
39 | 39 | void MVKPipelineCommandEncoderState::bindPipeline(MVKPipeline* pipeline) { |
| 40 | + if (pipeline != _pipeline) markDirty(); |
40 | 41 | _pipeline = pipeline; |
41 | | - markDirty(); |
42 | 42 | } |
43 | 43 |
|
44 | 44 | MVKPipeline* MVKPipelineCommandEncoderState::getPipeline() { return _pipeline; } |
|
71 | 71 | usingViewports.resize(firstViewport + vpCnt); |
72 | 72 | } |
73 | 73 |
|
| 74 | + bool dirty; |
74 | 75 | bool mustSetDynamically = _cmdEncoder->supportsDynamicState(VK_DYNAMIC_STATE_VIEWPORT); |
75 | 76 | if (isSettingDynamically || (!mustSetDynamically && vpCnt > 0)) { |
| 77 | + dirty = memcmp(&usingViewports[firstViewport], &viewports[0], vpCnt * sizeof(VkViewport)) != 0; |
76 | 78 | std::copy(viewports.begin(), viewports.end(), usingViewports.begin() + firstViewport); |
77 | 79 | } else { |
| 80 | + dirty = !usingViewports.empty(); |
78 | 81 | usingViewports.clear(); |
79 | 82 | } |
80 | 83 |
|
81 | | - markDirty(); |
| 84 | + if (dirty) markDirty(); |
82 | 85 | } |
83 | 86 |
|
84 | 87 | void MVKViewportCommandEncoderState::encodeImpl(uint32_t stage) { |
|
121 | 124 | usingScissors.resize(firstScissor + sCnt); |
122 | 125 | } |
123 | 126 |
|
| 127 | + bool dirty; |
124 | 128 | bool mustSetDynamically = _cmdEncoder->supportsDynamicState(VK_DYNAMIC_STATE_SCISSOR); |
125 | 129 | if (isSettingDynamically || (!mustSetDynamically && sCnt > 0)) { |
| 130 | + dirty = memcmp(&usingScissors[firstScissor], &scissors[0], sCnt * sizeof(VkRect2D)) != 0; |
126 | 131 | std::copy(scissors.begin(), scissors.end(), usingScissors.begin() + firstScissor); |
127 | 132 | } else { |
| 133 | + dirty = !usingScissors.empty(); |
128 | 134 | usingScissors.clear(); |
129 | 135 | } |
130 | 136 |
|
131 | | - markDirty(); |
| 137 | + if (dirty) markDirty(); |
132 | 138 | } |
133 | 139 |
|
134 | 140 | void MVKScissorCommandEncoderState::encodeImpl(uint32_t stage) { |
|
248 | 254 | #pragma mark MVKDepthStencilCommandEncoderState |
249 | 255 |
|
250 | 256 | void MVKDepthStencilCommandEncoderState:: setDepthStencilState(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo) { |
| 257 | + auto oldData = _depthStencilData; |
251 | 258 |
|
252 | 259 | if (vkDepthStencilInfo.depthTestEnable) { |
253 | 260 | _depthStencilData.depthCompareFunction = mvkMTLCompareFunctionFromVkCompareOp(vkDepthStencilInfo.depthCompareOp); |
|
260 | 267 | setStencilState(_depthStencilData.frontFaceStencilData, vkDepthStencilInfo.front, vkDepthStencilInfo.stencilTestEnable); |
261 | 268 | setStencilState(_depthStencilData.backFaceStencilData, vkDepthStencilInfo.back, vkDepthStencilInfo.stencilTestEnable); |
262 | 269 |
|
263 | | - markDirty(); |
| 270 | + if (!(oldData == _depthStencilData)) markDirty(); |
264 | 271 | } |
265 | 272 |
|
266 | 273 | void MVKDepthStencilCommandEncoderState::setStencilState(MVKMTLStencilDescriptorData& stencilInfo, |
|
289 | 296 | // it may not be accurate, and if not dynamic, pipeline will override when it is encoded anyway. |
290 | 297 | void MVKDepthStencilCommandEncoderState::setStencilCompareMask(VkStencilFaceFlags faceMask, |
291 | 298 | uint32_t stencilCompareMask) { |
| 299 | + auto oldData = _depthStencilData; |
| 300 | + |
292 | 301 | if (mvkAreAllFlagsEnabled(faceMask, VK_STENCIL_FACE_FRONT_BIT)) { |
293 | 302 | _depthStencilData.frontFaceStencilData.readMask = stencilCompareMask; |
294 | 303 | } |
295 | 304 | if (mvkAreAllFlagsEnabled(faceMask, VK_STENCIL_FACE_BACK_BIT)) { |
296 | 305 | _depthStencilData.backFaceStencilData.readMask = stencilCompareMask; |
297 | 306 | } |
298 | 307 |
|
299 | | - markDirty(); |
| 308 | + if (!(oldData == _depthStencilData)) markDirty(); |
300 | 309 | } |
301 | 310 |
|
302 | 311 | // We don't check for dynamic state here, because if this is called before pipeline is set, |
303 | 312 | // it may not be accurate, and if not dynamic, pipeline will override when it is encoded anyway. |
304 | 313 | void MVKDepthStencilCommandEncoderState::setStencilWriteMask(VkStencilFaceFlags faceMask, |
305 | 314 | uint32_t stencilWriteMask) { |
| 315 | + auto oldData = _depthStencilData; |
| 316 | + |
306 | 317 | if (mvkAreAllFlagsEnabled(faceMask, VK_STENCIL_FACE_FRONT_BIT)) { |
307 | 318 | _depthStencilData.frontFaceStencilData.writeMask = stencilWriteMask; |
308 | 319 | } |
309 | 320 | if (mvkAreAllFlagsEnabled(faceMask, VK_STENCIL_FACE_BACK_BIT)) { |
310 | 321 | _depthStencilData.backFaceStencilData.writeMask = stencilWriteMask; |
311 | 322 | } |
312 | 323 |
|
313 | | - markDirty(); |
| 324 | + if (!(oldData == _depthStencilData)) markDirty(); |
314 | 325 | } |
315 | 326 |
|
316 | 327 | void MVKDepthStencilCommandEncoderState::beginMetalRenderPass() { |
| 328 | + MVKCommandEncoderState::beginMetalRenderPass(); |
| 329 | + |
317 | 330 | MVKRenderSubpass* mvkSubpass = _cmdEncoder->getSubpass(); |
318 | 331 | MVKPixelFormats* pixFmts = _cmdEncoder->getPixelFormats(); |
319 | 332 | MTLPixelFormat mtlDSFormat = pixFmts->getMTLPixelFormat(mvkSubpass->getDepthStencilFormat()); |
|
351 | 364 | // If ref values are to be set dynamically, don't set them here. |
352 | 365 | if (_cmdEncoder->supportsDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE)) { return; } |
353 | 366 |
|
| 367 | + if (_frontFaceValue != vkDepthStencilInfo.front.reference || _backFaceValue != vkDepthStencilInfo.back.reference) |
| 368 | + markDirty(); |
| 369 | + |
354 | 370 | _frontFaceValue = vkDepthStencilInfo.front.reference; |
355 | 371 | _backFaceValue = vkDepthStencilInfo.back.reference; |
356 | | - markDirty(); |
357 | 372 | } |
358 | 373 |
|
359 | 374 | // We don't check for dynamic state here, because if this is called before pipeline is set, |
360 | 375 | // it may not be accurate, and if not dynamic, pipeline will override when it is encoded anyway. |
361 | 376 | void MVKStencilReferenceValueCommandEncoderState::setReferenceValues(VkStencilFaceFlags faceMask, |
362 | 377 | uint32_t stencilReference) { |
| 378 | + bool dirty = false; |
363 | 379 | if (mvkAreAllFlagsEnabled(faceMask, VK_STENCIL_FACE_FRONT_BIT)) { |
| 380 | + dirty |= (_frontFaceValue != stencilReference); |
364 | 381 | _frontFaceValue = stencilReference; |
365 | 382 | } |
366 | 383 | if (mvkAreAllFlagsEnabled(faceMask, VK_STENCIL_FACE_BACK_BIT)) { |
| 384 | + dirty |= (_backFaceValue != stencilReference); |
367 | 385 | _backFaceValue = stencilReference; |
368 | 386 | } |
369 | | - markDirty(); |
| 387 | + if (dirty) markDirty(); |
370 | 388 | } |
371 | 389 |
|
372 | 390 | void MVKStencilReferenceValueCommandEncoderState::encodeImpl(uint32_t stage) { |
|
381 | 399 |
|
382 | 400 | void MVKDepthBiasCommandEncoderState::setDepthBias(const VkPipelineRasterizationStateCreateInfo& vkRasterInfo) { |
383 | 401 |
|
| 402 | + auto wasEnabled = _isEnabled; |
384 | 403 | _isEnabled = vkRasterInfo.depthBiasEnable; |
385 | 404 |
|
386 | 405 | // If ref values are to be set dynamically, don't set them here. |
387 | 406 | if (_cmdEncoder->supportsDynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS)) { return; } |
388 | 407 |
|
389 | | - _depthBiasConstantFactor = vkRasterInfo.depthBiasConstantFactor; |
390 | | - _depthBiasSlopeFactor = vkRasterInfo.depthBiasSlopeFactor; |
391 | | - _depthBiasClamp = vkRasterInfo.depthBiasClamp; |
| 408 | + if (_isEnabled != wasEnabled || _depthBiasConstantFactor != vkRasterInfo.depthBiasConstantFactor |
| 409 | + || _depthBiasSlopeFactor != vkRasterInfo.depthBiasSlopeFactor || _depthBiasClamp != vkRasterInfo.depthBiasClamp) { |
392 | 410 |
|
393 | | - markDirty(); |
| 411 | + markDirty(); |
| 412 | + _depthBiasConstantFactor = vkRasterInfo.depthBiasConstantFactor; |
| 413 | + _depthBiasSlopeFactor = vkRasterInfo.depthBiasSlopeFactor; |
| 414 | + _depthBiasClamp = vkRasterInfo.depthBiasClamp; |
| 415 | + } |
394 | 416 | } |
395 | 417 |
|
396 | 418 | // We don't check for dynamic state here, because if this is called before pipeline is set, |
397 | 419 | // it may not be accurate, and if not dynamic, pipeline will override when it is encoded anyway. |
398 | 420 | void MVKDepthBiasCommandEncoderState::setDepthBias(float depthBiasConstantFactor, |
399 | 421 | float depthBiasSlopeFactor, |
400 | 422 | float depthBiasClamp) { |
401 | | - _depthBiasConstantFactor = depthBiasConstantFactor; |
402 | | - _depthBiasSlopeFactor = depthBiasSlopeFactor; |
403 | | - _depthBiasClamp = depthBiasClamp; |
404 | 423 |
|
405 | | - markDirty(); |
| 424 | + if (_depthBiasConstantFactor != depthBiasConstantFactor || _depthBiasSlopeFactor != depthBiasSlopeFactor |
| 425 | + || _depthBiasClamp != depthBiasClamp) { |
| 426 | + |
| 427 | + markDirty(); |
| 428 | + _depthBiasConstantFactor = depthBiasConstantFactor; |
| 429 | + _depthBiasSlopeFactor = depthBiasSlopeFactor; |
| 430 | + _depthBiasClamp = depthBiasClamp; |
| 431 | + } |
406 | 432 | } |
407 | 433 |
|
408 | 434 | void MVKDepthBiasCommandEncoderState::encodeImpl(uint32_t stage) { |
|
426 | 452 | // Abort if we are using dynamic, but call is not dynamic. |
427 | 453 | if ( !isDynamic && _cmdEncoder->supportsDynamicState(VK_DYNAMIC_STATE_BLEND_CONSTANTS) ) { return; } |
428 | 454 |
|
429 | | - _red = red; |
430 | | - _green = green; |
431 | | - _blue = blue; |
432 | | - _alpha = alpha; |
433 | | - |
434 | | - markDirty(); |
| 455 | + if (_red != red || _green != green || _blue != blue || _alpha != alpha) { |
| 456 | + markDirty(); |
| 457 | + _red = red; |
| 458 | + _green = green; |
| 459 | + _blue = blue; |
| 460 | + _alpha = alpha; |
| 461 | + } |
435 | 462 | } |
436 | 463 |
|
437 | 464 | void MVKBlendColorCommandEncoderState::encodeImpl(uint32_t stage) { |
|
752 | 779 | b.mtlBytes, |
753 | 780 | b.size, |
754 | 781 | b.index); |
| 782 | + else if (b.justOffset) |
| 783 | + [cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationVertexTessCtl) |
| 784 | + setBufferOffset: b.offset |
| 785 | + atIndex: b.index]; |
755 | 786 | else |
756 | 787 | [cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationVertexTessCtl) setBuffer: b.mtlBuffer |
757 | 788 | offset: b.offset |
|
785 | 816 | b.size, |
786 | 817 | b.index); |
787 | 818 | } else { |
788 | | - [cmdEncoder->_mtlRenderEncoder setVertexBuffer: b.mtlBuffer |
789 | | - offset: b.offset |
790 | | - atIndex: b.index]; |
| 819 | + if (b.justOffset) { |
| 820 | + [cmdEncoder->_mtlRenderEncoder setVertexBufferOffset: b.offset |
| 821 | + atIndex: b.index]; |
| 822 | + } else { |
| 823 | + [cmdEncoder->_mtlRenderEncoder setVertexBuffer: b.mtlBuffer |
| 824 | + offset: b.offset |
| 825 | + atIndex: b.index]; |
| 826 | + } |
791 | 827 |
|
792 | 828 | // Add any translated vertex bindings for this binding |
793 | 829 | auto xltdVtxBindings = pipeline->getTranslatedVertexBindings(); |
|
828 | 864 | b.mtlBytes, |
829 | 865 | b.size, |
830 | 866 | b.index); |
| 867 | + else if (b.justOffset) |
| 868 | + [cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationVertexTessCtl) setBufferOffset: b.offset |
| 869 | + atIndex: b.index]; |
831 | 870 | else |
832 | 871 | [cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationVertexTessCtl) setBuffer: b.mtlBuffer |
833 | 872 | offset: b.offset |
|
858 | 897 | b.mtlBytes, |
859 | 898 | b.size, |
860 | 899 | b.index); |
| 900 | + else if (b.justOffset) |
| 901 | + [cmdEncoder->_mtlRenderEncoder setVertexBufferOffset: b.offset |
| 902 | + atIndex: b.index]; |
861 | 903 | else |
862 | 904 | [cmdEncoder->_mtlRenderEncoder setVertexBuffer: b.mtlBuffer |
863 | 905 | offset: b.offset |
|
888 | 930 | b.mtlBytes, |
889 | 931 | b.size, |
890 | 932 | b.index); |
| 933 | + else if (b.justOffset) |
| 934 | + [cmdEncoder->_mtlRenderEncoder setFragmentBufferOffset: b.offset |
| 935 | + atIndex: b.index]; |
891 | 936 | else |
892 | 937 | [cmdEncoder->_mtlRenderEncoder setFragmentBuffer: b.mtlBuffer |
893 | 938 | offset: b.offset |
|
1027 | 1072 | b.mtlBytes, |
1028 | 1073 | b.size, |
1029 | 1074 | b.index); |
1030 | | - } else { |
| 1075 | + } else if (b.justOffset) { |
| 1076 | + [cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch) |
| 1077 | + setBufferOffset: b.offset |
| 1078 | + atIndex: b.index]; |
| 1079 | + |
| 1080 | + } else { |
1031 | 1081 | [cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch) setBuffer: b.mtlBuffer |
1032 | 1082 | offset: b.offset |
1033 | 1083 | atIndex: b.index]; |
|
0 commit comments