webgpuClearQuad.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import { WebGPUCacheRenderPipelineTree } from "./webgpuCacheRenderPipelineTree.js";
  2. import { WebGPUShaderProcessingContext } from "./webgpuShaderProcessingContext.js";
  3. import { WebGPUTextureHelper } from "./webgpuTextureHelper.js";
  4. import { renderableTextureFormatToIndex } from "./webgpuTextureManager.js";
  5. import "../../ShadersWGSL/clearQuad.vertex.js";
  6. import "../../ShadersWGSL/clearQuad.fragment.js";
  7. import { ShaderLanguage } from "../../Materials/shaderLanguage.js";
  8. /** @internal */
  9. export class WebGPUClearQuad {
  10. setDepthStencilFormat(format) {
  11. this._depthTextureFormat = format;
  12. this._cacheRenderPipeline.setDepthStencilFormat(format);
  13. }
  14. setColorFormat(format) {
  15. this._cacheRenderPipeline.setColorFormat(format);
  16. }
  17. setMRTAttachments(attachments, textureArray, textureCount) {
  18. this._cacheRenderPipeline.setMRT(textureArray, textureCount);
  19. this._cacheRenderPipeline.setMRTAttachments(attachments);
  20. }
  21. constructor(device, engine, emptyVertexBuffer) {
  22. this._bindGroups = {};
  23. this._bundleCache = {};
  24. this._keyTemp = [];
  25. this._device = device;
  26. this._engine = engine;
  27. this._cacheRenderPipeline = new WebGPUCacheRenderPipelineTree(this._device, emptyVertexBuffer);
  28. this._cacheRenderPipeline.setDepthTestEnabled(false);
  29. this._cacheRenderPipeline.setStencilReadMask(0xff);
  30. this._effect = engine.createEffect("clearQuad", [], ["color", "depthValue"], undefined, undefined, undefined, undefined, undefined, undefined, ShaderLanguage.WGSL);
  31. }
  32. clear(renderPass, clearColor, clearDepth, clearStencil, sampleCount = 1) {
  33. let renderPass2;
  34. let bundle = null;
  35. let bundleKey;
  36. const isRTTPass = !!this._engine._currentRenderTarget;
  37. if (renderPass) {
  38. renderPass2 = renderPass;
  39. }
  40. else {
  41. let idx = 0;
  42. this._keyTemp.length = 0;
  43. for (let i = 0; i < this._cacheRenderPipeline.colorFormats.length; ++i) {
  44. this._keyTemp[idx++] = renderableTextureFormatToIndex[this._cacheRenderPipeline.colorFormats[i] ?? ""];
  45. }
  46. const depthStencilFormatIndex = renderableTextureFormatToIndex[this._depthTextureFormat ?? 0];
  47. this._keyTemp[idx] =
  48. (clearColor ? clearColor.r + clearColor.g * 256 + clearColor.b * 256 * 256 + clearColor.a * 256 * 256 * 256 : 0) +
  49. (clearDepth ? 2 ** 32 : 0) +
  50. (clearStencil ? 2 ** 33 : 0) +
  51. (this._engine.useReverseDepthBuffer ? 2 ** 34 : 0) +
  52. (isRTTPass ? 2 ** 35 : 0) +
  53. (sampleCount > 1 ? 2 ** 36 : 0) +
  54. depthStencilFormatIndex * 2 ** 37;
  55. bundleKey = this._keyTemp.join("_");
  56. bundle = this._bundleCache[bundleKey];
  57. if (bundle) {
  58. return bundle;
  59. }
  60. renderPass2 = this._device.createRenderBundleEncoder({
  61. label: "clearQuadRenderBundle",
  62. colorFormats: this._cacheRenderPipeline.colorFormats,
  63. depthStencilFormat: this._depthTextureFormat,
  64. sampleCount: WebGPUTextureHelper.GetSample(sampleCount),
  65. });
  66. }
  67. this._cacheRenderPipeline.setDepthWriteEnabled(!!clearDepth);
  68. this._cacheRenderPipeline.setStencilEnabled(!!clearStencil && !!this._depthTextureFormat && WebGPUTextureHelper.HasStencilAspect(this._depthTextureFormat));
  69. this._cacheRenderPipeline.setStencilWriteMask(clearStencil ? 0xff : 0);
  70. this._cacheRenderPipeline.setStencilCompare(clearStencil ? 519 : 512);
  71. this._cacheRenderPipeline.setStencilPassOp(clearStencil ? 7681 : 7680);
  72. this._cacheRenderPipeline.setWriteMask(clearColor ? 0xf : 0);
  73. const pipeline = this._cacheRenderPipeline.getRenderPipeline(7, this._effect, sampleCount);
  74. const webgpuPipelineContext = this._effect._pipelineContext;
  75. if (clearColor) {
  76. this._effect.setDirectColor4("color", clearColor);
  77. }
  78. this._effect.setFloat("depthValue", this._engine.useReverseDepthBuffer ? this._engine._clearReverseDepthValue : this._engine._clearDepthValue);
  79. webgpuPipelineContext.uniformBuffer.update();
  80. const bufferInternals = isRTTPass ? this._engine._ubInvertY : this._engine._ubDontInvertY;
  81. const bufferLeftOver = webgpuPipelineContext.uniformBuffer.getBuffer();
  82. const key = bufferLeftOver.uniqueId + "-" + bufferInternals.uniqueId;
  83. let bindGroups = this._bindGroups[key];
  84. if (!bindGroups) {
  85. const bindGroupLayouts = webgpuPipelineContext.bindGroupLayouts[0];
  86. bindGroups = this._bindGroups[key] = [];
  87. bindGroups.push(this._device.createBindGroup({
  88. label: `clearQuadBindGroup0-${key}`,
  89. layout: bindGroupLayouts[0],
  90. entries: [],
  91. }));
  92. if (!WebGPUShaderProcessingContext._SimplifiedKnownBindings) {
  93. bindGroups.push(this._device.createBindGroup({
  94. label: `clearQuadBindGroup1-${key}`,
  95. layout: bindGroupLayouts[1],
  96. entries: [],
  97. }));
  98. }
  99. bindGroups.push(this._device.createBindGroup({
  100. label: `clearQuadBindGroup${WebGPUShaderProcessingContext._SimplifiedKnownBindings ? 1 : 2}-${key}`,
  101. layout: bindGroupLayouts[WebGPUShaderProcessingContext._SimplifiedKnownBindings ? 1 : 2],
  102. entries: [
  103. {
  104. binding: 0,
  105. resource: {
  106. buffer: bufferInternals.underlyingResource,
  107. size: bufferInternals.capacity,
  108. },
  109. },
  110. {
  111. binding: 1,
  112. resource: {
  113. buffer: bufferLeftOver.underlyingResource,
  114. size: bufferLeftOver.capacity,
  115. },
  116. },
  117. ],
  118. }));
  119. }
  120. renderPass2.setPipeline(pipeline);
  121. for (let i = 0; i < bindGroups.length; ++i) {
  122. renderPass2.setBindGroup(i, bindGroups[i]);
  123. }
  124. renderPass2.draw(4, 1, 0, 0);
  125. if (!renderPass) {
  126. bundle = renderPass2.finish();
  127. this._bundleCache[bundleKey] = bundle;
  128. }
  129. return bundle;
  130. }
  131. }
  132. //# sourceMappingURL=webgpuClearQuad.js.map