29using IntrinsicConstant =
float[4];
31constexpr int kBufferBindingOffsetAlignment = 256;
33constexpr int kIntrinsicConstantAlignedSize =
34 SkAlignTo(
sizeof(IntrinsicConstant), kBufferBindingOffsetAlignment);
36#if defined(__EMSCRIPTEN__)
40constexpr int kNumSlotsForIntrinsicConstantBuffer = 8;
44constexpr int kNumSlotsForIntrinsicConstantBuffer = 0;
51 std::unique_ptr<DawnCommandBuffer> cmdBuffer(
53 if (!cmdBuffer->setNewCommandBufferResources()) {
61 : fSharedContext(sharedContext)
62 , fResourceProvider(resourceProvider) {}
68 wgpu::CommandBuffer cmdBuffer = fCommandEncoder.Finish();
70 fCommandEncoder =
nullptr;
76 fIntrinsicConstantBuffer =
nullptr;
78 fActiveGraphicsPipeline =
nullptr;
79 fActiveRenderPassEncoder =
nullptr;
80 fActiveComputePassEncoder =
nullptr;
81 fCommandEncoder =
nullptr;
83 for (
auto& bufferSlot : fBoundUniformBuffers) {
86 fBoundUniformBuffersDirty =
true;
91 fCommandEncoder = fSharedContext->
device().CreateCommandEncoder();
99 const Texture* depthStencilTexture,
103 this->preprocessViewport(viewport);
105 if (!this->beginRenderPass(renderPassDesc, colorTexture, resolveTexture, depthStencilTexture)) {
109 this->setViewport(viewport);
111 for (
const auto& drawPass : drawPasses) {
112 this->addDrawPass(drawPass.get());
115 this->endRenderPass();
120 this->beginComputePass();
121 for (
const auto& group : groups) {
122 group->addResourceRefs(
this);
123 for (
const auto& dispatch : group->dispatches()) {
124 this->bindComputePipeline(group->getPipeline(dispatch.fPipelineIndex));
125 this->bindDispatchResources(*group, dispatch);
127 std::get_if<WorkgroupSize>(&dispatch.fGlobalSizeOrIndirect)) {
128 this->dispatchWorkgroups(*globalSize);
130 SkASSERT(std::holds_alternative<BufferView>(dispatch.fGlobalSizeOrIndirect));
132 *std::get_if<BufferView>(&dispatch.fGlobalSizeOrIndirect);
137 this->endComputePass();
141bool DawnCommandBuffer::beginRenderPass(
const RenderPassDesc& renderPassDesc,
144 const Texture* depthStencilTexture) {
145 SkASSERT(!fActiveRenderPassEncoder);
146 SkASSERT(!fActiveComputePassEncoder);
148 constexpr static wgpu::LoadOp wgpuLoadActionMap[]{
156 static_assert(std::size(wgpuLoadActionMap) ==
kLoadOpCount);
158 constexpr static wgpu::StoreOp wgpuStoreActionMap[]{wgpu::StoreOp::Store,
159 wgpu::StoreOp::Discard};
162 static_assert(std::size(wgpuStoreActionMap) ==
kStoreOpCount);
164 wgpu::RenderPassDescriptor wgpuRenderPass = {};
165 wgpu::RenderPassColorAttachment wgpuColorAttachment;
166 wgpu::RenderPassDepthStencilAttachment wgpuDepthStencilAttachment;
169#ifndef __EMSCRIPTEN__
170 wgpu::DawnRenderPassColorAttachmentRenderToSingleSampled mssaRenderToSingleSampledDesc;
174 bool loadMSAAFromResolveExplicitly =
false;
176 wgpuRenderPass.colorAttachments = &wgpuColorAttachment;
177 wgpuRenderPass.colorAttachmentCount = 1;
180 const auto* dawnColorTexture =
static_cast<const DawnTexture*
>(colorTexture);
181 SkASSERT(dawnColorTexture->renderTextureView());
182 wgpuColorAttachment.view = dawnColorTexture->renderTextureView();
184 const std::array<float, 4>& clearColor = renderPassDesc.
fClearColor;
185 wgpuColorAttachment.clearValue = {
186 clearColor[0], clearColor[1], clearColor[2], clearColor[3]};
187 wgpuColorAttachment.loadOp = wgpuLoadActionMap[
static_cast<int>(colorInfo.fLoadOp)];
188 wgpuColorAttachment.storeOp = wgpuStoreActionMap[
static_cast<int>(colorInfo.fStoreOp)];
191 if (resolveTexture) {
194 const auto* dawnResolveTexture =
static_cast<const DawnTexture*
>(resolveTexture);
195 SkASSERT(dawnResolveTexture->renderTextureView());
196 wgpuColorAttachment.resolveTarget = dawnResolveTexture->renderTextureView();
200 SkASSERT(wgpuColorAttachment.storeOp == wgpu::StoreOp::Discard);
203 loadMSAAFromResolveExplicitly =
209 [[maybe_unused]]
bool isMSAAToSingleSampled = renderPassDesc.
fSampleCount > 1 &&
211#if defined(__EMSCRIPTEN__)
214 if (isMSAAToSingleSampled) {
219 wgpu::FeatureName::MSAARenderToSingleSampled));
221 wgpuColorAttachment.nextInChain = &mssaRenderToSingleSampledDesc;
222 mssaRenderToSingleSampledDesc.implicitSampleCount = renderPassDesc.
fSampleCount;
230 if (depthStencilTexture) {
231 const auto* dawnDepthStencilTexture =
static_cast<const DawnTexture*
>(depthStencilTexture);
232 auto format = dawnDepthStencilTexture->textureInfo().dawnTextureSpec().getViewFormat();
236 SkASSERT(dawnDepthStencilTexture->renderTextureView());
237 wgpuDepthStencilAttachment.view = dawnDepthStencilTexture->renderTextureView();
240 wgpuDepthStencilAttachment.depthClearValue = renderPassDesc.
fClearDepth;
241 wgpuDepthStencilAttachment.depthLoadOp =
242 wgpuLoadActionMap[
static_cast<int>(depthStencilInfo.fLoadOp)];
243 wgpuDepthStencilAttachment.depthStoreOp =
244 wgpuStoreActionMap[
static_cast<int>(depthStencilInfo.fStoreOp)];
248 wgpuDepthStencilAttachment.stencilClearValue = renderPassDesc.
fClearStencil;
249 wgpuDepthStencilAttachment.stencilLoadOp =
250 wgpuLoadActionMap[
static_cast<int>(depthStencilInfo.fLoadOp)];
251 wgpuDepthStencilAttachment.stencilStoreOp =
252 wgpuStoreActionMap[
static_cast<int>(depthStencilInfo.fStoreOp)];
255 wgpuRenderPass.depthStencilAttachment = &wgpuDepthStencilAttachment;
257 SkASSERT(!depthStencilInfo.fTextureInfo.isValid());
260 if (loadMSAAFromResolveExplicitly) {
264 if (!this->loadMSAAFromResolveAndBeginRenderPassEncoder(
267 static_cast<const DawnTexture*
>(colorTexture))) {
272 fActiveRenderPassEncoder = fCommandEncoder.BeginRenderPass(&wgpuRenderPass);
278bool DawnCommandBuffer::loadMSAAFromResolveAndBeginRenderPassEncoder(
279 const RenderPassDesc& frontendRenderPassDesc,
280 const wgpu::RenderPassDescriptor& wgpuRenderPassDesc,
281 const DawnTexture* msaaTexture) {
282 SkASSERT(!fActiveRenderPassEncoder);
289 msaaTexture->dimensions(), msaaTexture->textureInfo());
290 if (!msaaLoadTexture) {
291 SKGPU_LOG_E(
"DawnCommandBuffer::loadMSAAFromResolveAndBeginRenderPassEncoder: "
292 "Can't create MSAA Load Texture.");
299 RenderPassDesc intermediateRenderPassDesc = {};
301 intermediateRenderPassDesc.fColorAttachment.fStoreOp =
StoreOp::kStore;
302 intermediateRenderPassDesc.fColorAttachment.fTextureInfo =
303 frontendRenderPassDesc.fColorResolveAttachment.fTextureInfo;
305 wgpu::RenderPassColorAttachment wgpuIntermediateColorAttachment;
307 wgpuIntermediateColorAttachment.loadOp = wgpu::LoadOp::Clear;
308 wgpuIntermediateColorAttachment.clearValue = {1, 1, 1, 1};
309 wgpuIntermediateColorAttachment.storeOp = wgpu::StoreOp::Store;
310 wgpuIntermediateColorAttachment.view = msaaLoadTexture->renderTextureView();
312 wgpu::RenderPassDescriptor wgpuIntermediateRenderPassDesc;
313 wgpuIntermediateRenderPassDesc.colorAttachmentCount = 1;
314 wgpuIntermediateRenderPassDesc.colorAttachments = &wgpuIntermediateColorAttachment;
316 auto renderPassEncoder = fCommandEncoder.BeginRenderPass(&wgpuIntermediateRenderPassDesc);
318 bool blitSucceeded = this->doBlitWithDraw(
320 intermediateRenderPassDesc,
321 wgpuRenderPassDesc.colorAttachments[0].resolveTarget,
322 msaaTexture->dimensions().width(),
323 msaaTexture->dimensions().height());
325 renderPassEncoder.End();
327 if (!blitSucceeded) {
332 renderPassEncoder = fCommandEncoder.BeginRenderPass(&wgpuRenderPassDesc);
334 if (!this->doBlitWithDraw(renderPassEncoder,
335 frontendRenderPassDesc,
336 msaaLoadTexture->renderTextureView(),
337 msaaTexture->dimensions().width(),
338 msaaTexture->dimensions().height())) {
339 renderPassEncoder.End();
343 fActiveRenderPassEncoder = renderPassEncoder;
348bool DawnCommandBuffer::doBlitWithDraw(
const wgpu::RenderPassEncoder& renderEncoder,
349 const RenderPassDesc& frontendRenderPassDesc,
350 const wgpu::TextureView& sourceTextureView,
355 SKGPU_LOG_E(
"Unable to create pipeline to blit with draw");
361 renderEncoder.SetPipeline(loadPipeline);
368 wgpu::BindGroupEntry entry;
370 entry.textureView = sourceTextureView;
372 wgpu::BindGroupDescriptor
desc;
373 desc.layout = loadPipeline.GetBindGroupLayout(0);
375 desc.entries = &entry;
377 auto bindGroup = fSharedContext->
device().CreateBindGroup(&desc);
379 renderEncoder.SetBindGroup(0, bindGroup);
382 renderEncoder.SetViewport(0, 0,
width,
height, 0, 1);
385 renderEncoder.Draw(3);
390void DawnCommandBuffer::endRenderPass() {
392 fActiveRenderPassEncoder.End();
393 fActiveRenderPassEncoder =
nullptr;
396void DawnCommandBuffer::addDrawPass(
const DrawPass* drawPass) {
397 drawPass->addResourceRefs(
this);
400 case DrawPassCommands::Type::kBindGraphicsPipeline: {
401 auto bgp =
static_cast<DrawPassCommands::BindGraphicsPipeline*
>(cmdPtr);
402 this->bindGraphicsPipeline(drawPass->getPipeline(bgp->fPipelineIndex));
405 case DrawPassCommands::Type::kSetBlendConstants: {
406 auto sbc =
static_cast<DrawPassCommands::SetBlendConstants*
>(cmdPtr);
407 this->setBlendConstants(sbc->fBlendConstants);
410 case DrawPassCommands::Type::kBindUniformBuffer: {
411 auto bub =
static_cast<DrawPassCommands::BindUniformBuffer*
>(cmdPtr);
412 this->bindUniformBuffer(bub->fInfo, bub->fSlot);
415 case DrawPassCommands::Type::kBindDrawBuffers: {
416 auto bdb =
static_cast<DrawPassCommands::BindDrawBuffers*
>(cmdPtr);
417 this->bindDrawBuffers(
418 bdb->fVertices, bdb->fInstances, bdb->fIndices, bdb->fIndirect);
421 case DrawPassCommands::Type::kBindTexturesAndSamplers: {
422 auto bts =
static_cast<DrawPassCommands::BindTexturesAndSamplers*
>(cmdPtr);
423 bindTextureAndSamplers(*drawPass, *bts);
426 case DrawPassCommands::Type::kSetScissor: {
427 auto ss =
static_cast<DrawPassCommands::SetScissor*
>(cmdPtr);
432 case DrawPassCommands::Type::kDraw: {
433 auto draw =
static_cast<DrawPassCommands::Draw*
>(cmdPtr);
434 this->draw(draw->fType, draw->fBaseVertex, draw->fVertexCount);
437 case DrawPassCommands::Type::kDrawIndexed: {
438 auto draw =
static_cast<DrawPassCommands::DrawIndexed*
>(cmdPtr);
440 draw->fType, draw->fBaseIndex, draw->fIndexCount, draw->fBaseVertex);
443 case DrawPassCommands::Type::kDrawInstanced: {
444 auto draw =
static_cast<DrawPassCommands::DrawInstanced*
>(cmdPtr);
445 this->drawInstanced(draw->fType,
449 draw->fInstanceCount);
452 case DrawPassCommands::Type::kDrawIndexedInstanced: {
453 auto draw =
static_cast<DrawPassCommands::DrawIndexedInstanced*
>(cmdPtr);
454 this->drawIndexedInstanced(draw->fType,
459 draw->fInstanceCount);
462 case DrawPassCommands::Type::kDrawIndirect: {
463 auto draw =
static_cast<DrawPassCommands::DrawIndirect*
>(cmdPtr);
464 this->drawIndirect(draw->fType);
467 case DrawPassCommands::Type::kDrawIndexedIndirect: {
468 auto draw =
static_cast<DrawPassCommands::DrawIndexedIndirect*
>(cmdPtr);
469 this->drawIndexedIndirect(draw->fType);
476void DawnCommandBuffer::bindGraphicsPipeline(
const GraphicsPipeline* graphicsPipeline) {
479 fActiveGraphicsPipeline =
static_cast<const DawnGraphicsPipeline*
>(graphicsPipeline);
481 fBoundUniformBuffersDirty =
true;
484void DawnCommandBuffer::bindUniformBuffer(
const BindUniformBufferInfo&
info,
UniformSlot slot) {
487 auto dawnBuffer =
static_cast<const DawnBuffer*
>(
info.fBuffer);
489 unsigned int bufferIndex = 0;
501 fBoundUniformBuffers[bufferIndex] = dawnBuffer;
502 fBoundUniformBufferOffsets[bufferIndex] =
static_cast<uint32_t
>(
info.fOffset);
503 fBoundUniformBufferSizes[bufferIndex] =
info.fBindingSize;
505 fBoundUniformBuffersDirty =
true;
508void DawnCommandBuffer::bindDrawBuffers(
const BindBufferInfo& vertices,
509 const BindBufferInfo& instances,
510 const BindBufferInfo& indices,
511 const BindBufferInfo& indirect) {
514 if (vertices.fBuffer) {
515 auto dawnBuffer =
static_cast<const DawnBuffer*
>(vertices.fBuffer)->dawnBuffer();
516 fActiveRenderPassEncoder.SetVertexBuffer(
519 if (instances.fBuffer) {
520 auto dawnBuffer =
static_cast<const DawnBuffer*
>(instances.fBuffer)->dawnBuffer();
521 fActiveRenderPassEncoder.SetVertexBuffer(
524 if (indices.fBuffer) {
525 auto dawnBuffer =
static_cast<const DawnBuffer*
>(indices.fBuffer)->dawnBuffer();
526 fActiveRenderPassEncoder.SetIndexBuffer(
527 dawnBuffer, wgpu::IndexFormat::Uint16, indices.fOffset);
529 if (indirect.fBuffer) {
530 fCurrentIndirectBuffer =
static_cast<const DawnBuffer*
>(indirect.fBuffer)->dawnBuffer();
531 fCurrentIndirectBufferOffset = indirect.fOffset;
533 fCurrentIndirectBuffer =
nullptr;
534 fCurrentIndirectBufferOffset = 0;
538void DawnCommandBuffer::bindTextureAndSamplers(
539 const DrawPass& drawPass,
const DrawPassCommands::BindTexturesAndSamplers& command) {
543 wgpu::BindGroup bindGroup;
544 if (
command.fNumTexSamplers == 1) {
549 static_cast<const DawnTexture*
>(drawPass.getTexture(
command.fTextureIndices[0]));
550 const auto* sampler =
551 static_cast<const DawnSampler*
>(drawPass.getSampler(
command.fSamplerIndices[0]));
555 std::vector<wgpu::BindGroupEntry> entries(2 *
command.fNumTexSamplers);
557 for (
int i = 0; i <
command.fNumTexSamplers; ++i) {
558 const auto*
texture =
static_cast<const DawnTexture*
>(
559 drawPass.getTexture(
command.fTextureIndices[i]));
560 const auto* sampler =
static_cast<const DawnSampler*
>(
561 drawPass.getSampler(
command.fSamplerIndices[i]));
562 auto& wgpuTextureView =
texture->sampleTextureView();
563 auto& wgpuSampler = sampler->dawnSampler();
570 entries[2 * i].binding = 2 * i;
571 entries[2 * i].sampler = wgpuSampler;
573 entries[2 * i + 1].binding = 2 * i + 1;
574 entries[2 * i + 1].textureView = wgpuTextureView;
577 wgpu::BindGroupDescriptor
desc;
580 desc.entryCount = entries.size();
581 desc.entries = entries.data();
583 bindGroup = fSharedContext->
device().CreateBindGroup(&desc);
589void DawnCommandBuffer::syncUniformBuffers() {
590 if (fBoundUniformBuffersDirty) {
591 fBoundUniformBuffersDirty =
false;
593 std::array<uint32_t, 3> dynamicOffsets;
594 std::array<std::pair<const DawnBuffer*, uint32_t>, 3> boundBuffersAndSizes;
595 boundBuffersAndSizes[0].first = fIntrinsicConstantBuffer.get();
596 boundBuffersAndSizes[0].second =
sizeof(IntrinsicConstant);
598 int activeIntrinsicBufferSlot = fIntrinsicConstantBufferSlotsUsed - 1;
599 dynamicOffsets[0] = activeIntrinsicBufferSlot * kIntrinsicConstantAlignedSize;
603 boundBuffersAndSizes[1].first =
605 boundBuffersAndSizes[1].second =
611 boundBuffersAndSizes[1].first =
nullptr;
612 dynamicOffsets[1] = 0;
617 boundBuffersAndSizes[2].first =
619 boundBuffersAndSizes[2].second =
625 boundBuffersAndSizes[2].first =
nullptr;
626 dynamicOffsets[2] = 0;
634 dynamicOffsets.size(),
635 dynamicOffsets.data());
639void DawnCommandBuffer::setScissor(
unsigned int left,
649 fActiveRenderPassEncoder.SetScissorRect(
650 scissor.
x(), scissor.
y(), scissor.
width(), scissor.
height());
653void DawnCommandBuffer::preprocessViewport(
const SkRect& viewport) {
659 const float invTwoW = 2.f / viewport.
width();
660 const float invTwoH = 2.f / viewport.
height();
661 const IntrinsicConstant rtAdjust = {invTwoW, -invTwoH, -1.f -
x * invTwoW, 1.f +
y * invTwoH};
663 bool needNewBuffer = !fIntrinsicConstantBuffer;
664 if (!needNewBuffer && kNumSlotsForIntrinsicConstantBuffer > 0) {
665 needNewBuffer = (fIntrinsicConstantBufferSlotsUsed == kNumSlotsForIntrinsicConstantBuffer);
671 if constexpr (kNumSlotsForIntrinsicConstantBuffer > 1) {
674 bufferSize = kIntrinsicConstantAlignedSize * kNumSlotsForIntrinsicConstantBuffer;
677 bufferSize =
sizeof(IntrinsicConstant);
680 fIntrinsicConstantBuffer =
684 "InstrinsicConstantBuffer");
686 fIntrinsicConstantBufferSlotsUsed = 0;
697 SkASSERT(!fActiveRenderPassEncoder);
698 SkASSERT(!fActiveComputePassEncoder);
700 if constexpr (kNumSlotsForIntrinsicConstantBuffer > 0) {
701 uint64_t
offset = fIntrinsicConstantBufferSlotsUsed * kIntrinsicConstantAlignedSize;
702 fSharedContext->
queue().WriteBuffer(fIntrinsicConstantBuffer->dawnBuffer(),
706 fIntrinsicConstantBufferSlotsUsed++;
708#if !defined(__EMSCRIPTEN__)
709 fCommandEncoder.WriteBuffer(fIntrinsicConstantBuffer->dawnBuffer(),
711 reinterpret_cast<const uint8_t*
>(rtAdjust),
714 fIntrinsicConstantBufferSlotsUsed = 1;
718void DawnCommandBuffer::setViewport(
const SkRect& viewport) {
720 fActiveRenderPassEncoder.SetViewport(
721 viewport.
x(), viewport.
y(), viewport.
width(), viewport.
height(), 0, 1);
724void DawnCommandBuffer::setBlendConstants(
float* blendConstants) {
726 wgpu::Color blendConst = {
727 blendConstants[0], blendConstants[1], blendConstants[2], blendConstants[3]};
728 fActiveRenderPassEncoder.SetBlendConstant(&blendConst);
732 unsigned int baseVertex,
733 unsigned int vertexCount) {
737 this->syncUniformBuffers();
739 fActiveRenderPassEncoder.Draw(vertexCount, 1, baseVertex);
743 unsigned int baseIndex,
744 unsigned int indexCount,
745 unsigned int baseVertex) {
749 this->syncUniformBuffers();
751 fActiveRenderPassEncoder.DrawIndexed(indexCount, 1, baseIndex, baseVertex);
755 unsigned int baseVertex,
756 unsigned int vertexCount,
757 unsigned int baseInstance,
758 unsigned int instanceCount) {
762 this->syncUniformBuffers();
764 fActiveRenderPassEncoder.Draw(vertexCount, instanceCount, baseVertex, baseInstance);
768 unsigned int baseIndex,
769 unsigned int indexCount,
770 unsigned int baseVertex,
771 unsigned int baseInstance,
772 unsigned int instanceCount) {
776 this->syncUniformBuffers();
778 fActiveRenderPassEncoder.DrawIndexed(
779 indexCount, instanceCount, baseIndex, baseVertex, baseInstance);
787 this->syncUniformBuffers();
789 fActiveRenderPassEncoder.DrawIndirect(fCurrentIndirectBuffer, fCurrentIndirectBufferOffset);
797 this->syncUniformBuffers();
799 fActiveRenderPassEncoder.DrawIndexedIndirect(fCurrentIndirectBuffer,
800 fCurrentIndirectBufferOffset);
803void DawnCommandBuffer::beginComputePass() {
804 SkASSERT(!fActiveRenderPassEncoder);
805 SkASSERT(!fActiveComputePassEncoder);
806 fActiveComputePassEncoder = fCommandEncoder.BeginComputePass();
809void DawnCommandBuffer::bindComputePipeline(
const ComputePipeline* computePipeline) {
810 SkASSERT(fActiveComputePassEncoder);
812 fActiveComputePipeline =
static_cast<const DawnComputePipeline*
>(computePipeline);
816void DawnCommandBuffer::bindDispatchResources(
const DispatchGroup& group,
817 const DispatchGroup::Dispatch& dispatch) {
818 SkASSERT(fActiveComputePassEncoder);
826 entries.
reserve(dispatch.fBindings.size());
828 for (
const ResourceBinding& binding : dispatch.fBindings) {
829 wgpu::BindGroupEntry& entry = entries.
push_back();
830 entry.binding = binding.fIndex;
831 if (
const BufferView*
buffer = std::get_if<BufferView>(&binding.fResource)) {
832 entry.buffer =
static_cast<const DawnBuffer*
>(
buffer->fInfo.fBuffer)->dawnBuffer();
833 entry.offset =
buffer->fInfo.fOffset;
834 entry.size =
buffer->fSize;
835 }
else if (
const TextureIndex* texIdx = std::get_if<TextureIndex>(&binding.fResource)) {
837 static_cast<const DawnTexture*
>(
group.getTexture(texIdx->fValue));
839 entry.textureView =
texture->sampleTextureView();
840 }
else if (
const SamplerIndex* samplerIdx = std::get_if<SamplerIndex>(&binding.fResource)) {
841 const DawnSampler* sampler =
842 static_cast<const DawnSampler*
>(
group.getSampler(samplerIdx->fValue));
843 entry.sampler = sampler->dawnSampler();
845 SK_ABORT(
"unsupported dispatch resource type");
849 wgpu::BindGroupDescriptor
desc;
854 auto bindGroup = fSharedContext->
device().CreateBindGroup(&desc);
855 fActiveComputePassEncoder.SetBindGroup(0, bindGroup);
858void DawnCommandBuffer::dispatchWorkgroups(
const WorkgroupSize& globalSize) {
859 SkASSERT(fActiveComputePassEncoder);
862 fActiveComputePassEncoder.DispatchWorkgroups(
863 globalSize.fWidth, globalSize.fHeight, globalSize.fDepth);
866void DawnCommandBuffer::dispatchWorkgroupsIndirect(
const Buffer* indirectBuffer,
867 size_t indirectBufferOffset) {
868 SkASSERT(fActiveComputePassEncoder);
871 auto& wgpuIndirectBuffer =
static_cast<const DawnBuffer*
>(indirectBuffer)->dawnBuffer();
872 fActiveComputePassEncoder.DispatchWorkgroupsIndirect(wgpuIndirectBuffer, indirectBufferOffset);
875void DawnCommandBuffer::endComputePass() {
876 SkASSERT(fActiveComputePassEncoder);
877 fActiveComputePassEncoder.End();
878 fActiveComputePassEncoder =
nullptr;
886 SkASSERT(!fActiveRenderPassEncoder);
887 SkASSERT(!fActiveComputePassEncoder);
889 auto& wgpuBufferSrc =
static_cast<const DawnBuffer*
>(srcBuffer)->dawnBuffer();
890 auto& wgpuBufferDst =
static_cast<const DawnBuffer*
>(dstBuffer)->dawnBuffer();
892 fCommandEncoder.CopyBufferToBuffer(wgpuBufferSrc, srcOffset, wgpuBufferDst, dstOffset, size);
900 size_t bufferRowBytes) {
901 SkASSERT(!fActiveRenderPassEncoder);
902 SkASSERT(!fActiveComputePassEncoder);
907 wgpu::ImageCopyTexture src;
908 src.texture = wgpuTexture->dawnTexture();
909 src.origin.x = srcRect.
x();
910 src.origin.y = srcRect.
y();
911 src.aspect = wgpuTexture->textureInfo().dawnTextureSpec().fAspect;
913 wgpu::ImageCopyBuffer dst;
914 dst.buffer = wgpuBuffer;
915 dst.layout.offset = bufferOffset;
918 SkASSERT((bufferRowBytes & 0xFF) == 0);
919 dst.layout.bytesPerRow = bufferRowBytes;
921 wgpu::Extent3D copySize = {
922 static_cast<uint32_t
>(srcRect.
width()),
static_cast<uint32_t
>(srcRect.
height()), 1};
923 fCommandEncoder.CopyTextureToBuffer(&src, &dst, ©Size);
932 SkASSERT(!fActiveRenderPassEncoder);
933 SkASSERT(!fActiveComputePassEncoder);
938 wgpu::ImageCopyBuffer src;
939 src.buffer = wgpuBuffer;
941 wgpu::ImageCopyTexture dst;
942 dst.texture = wgpuTexture;
944 for (
int i = 0; i <
count; ++i) {
948 SkASSERT((copyData[i].fBufferRowBytes & 0xFF) == 0);
951 dst.origin.x = copyData[i].
fRect.
x();
952 dst.origin.y = copyData[i].
fRect.
y();
955 wgpu::Extent3D copySize = {
static_cast<uint32_t
>(copyData[i].
fRect.
width()),
958 fCommandEncoder.CopyBufferToTexture(&src, &dst, ©Size);
969 SkASSERT(!fActiveRenderPassEncoder);
970 SkASSERT(!fActiveComputePassEncoder);
972 auto& wgpuTextureSrc =
static_cast<const DawnTexture*
>(src)->dawnTexture();
973 auto& wgpuTextureDst =
static_cast<const DawnTexture*
>(dst)->dawnTexture();
975 wgpu::ImageCopyTexture srcArgs;
976 srcArgs.texture = wgpuTextureSrc;
977 srcArgs.origin.x = srcRect.
fLeft;
978 srcArgs.origin.y = srcRect.
fTop;
980 wgpu::ImageCopyTexture dstArgs;
981 dstArgs.texture = wgpuTextureDst;
982 dstArgs.origin.x = dstPoint.
fX;
983 dstArgs.origin.y = dstPoint.
fY;
984 dstArgs.mipLevel = mipLevel;
986 wgpu::Extent3D copySize = {
987 static_cast<uint32_t
>(srcRect.
width()),
static_cast<uint32_t
>(srcRect.
height()), 1};
989 fCommandEncoder.CopyTextureToTexture(&srcArgs, &dstArgs, ©Size);
999 SkASSERT(!fActiveRenderPassEncoder);
1000 SkASSERT(!fActiveComputePassEncoder);
1003 fCommandEncoder.ClearBuffer(wgpuBuffer,
offset, size);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
#define SKGPU_LOG_E(fmt,...)
static constexpr size_t SkAlignTo(size_t x, size_t alignment)
#define SK_ABORT(message,...)
static bool left(const SkPoint &p0, const SkPoint &p1)
Type::kYUV Type::kRGBA() int(0.7 *637)
SkIVector fReplayTranslation
void trackResource(sk_sp< Resource > resource)
void trackCommandBufferResource(sk_sp< Resource > resource)
wgpu::CommandBuffer finishEncoding()
bool onClearBuffer(const Buffer *, size_t offset, size_t size) override
bool onAddRenderPass(const RenderPassDesc &, const Texture *colorTexture, const Texture *resolveTexture, const Texture *depthStencilTexture, SkRect viewport, const DrawPassList &) override
bool onCopyBufferToTexture(const Buffer *, const Texture *, const BufferTextureCopyData *copyData, int count) override
bool onCopyBufferToBuffer(const Buffer *srcBuffer, size_t srcOffset, const Buffer *dstBuffer, size_t dstOffset, size_t size) override
bool onSynchronizeBufferToCpu(const Buffer *, bool *outDidResultInWork) override
void onResetCommandBuffer() override
static std::unique_ptr< DawnCommandBuffer > Make(const DawnSharedContext *, DawnResourceProvider *)
~DawnCommandBuffer() override
bool setNewCommandBufferResources() override
bool onCopyTextureToTexture(const Texture *src, SkIRect srcRect, const Texture *dst, SkIPoint dstPoint, int mipLevel) override
bool onAddComputePass(DispatchGroupSpan) override
bool onCopyTextureToBuffer(const Texture *, SkIRect srcRect, const Buffer *, size_t bufferOffset, size_t bufferRowBytes) override
const wgpu::BindGroupLayout & dawnGroupLayout() const
const wgpu::ComputePipeline & dawnComputePipeline() const
bool hasStepUniforms() const
static constexpr unsigned int kUniformBufferBindGroupIndex
static constexpr unsigned int kTextureBindGroupIndex
static constexpr unsigned int kRenderStepUniformBufferIndex
const wgpu::RenderPipeline & dawnRenderPipeline() const
static constexpr unsigned int kPaintUniformBufferIndex
int numTexturesAndSamplers() const
static constexpr unsigned int kInstanceBufferIndex
const BindGroupLayouts & dawnGroupLayouts() const
bool hasPaintUniforms() const
PrimitiveType primitiveType() const
static constexpr unsigned int kVertexBufferIndex
const wgpu::BindGroup & findOrCreateSingleTextureSamplerBindGroup(const DawnSampler *sampler, const DawnTexture *texture)
sk_sp< DawnTexture > findOrCreateDiscardableMSAALoadTexture(SkISize dimensions, const TextureInfo &msaaInfo)
const wgpu::BindGroup & findOrCreateUniformBuffersBindGroup(const std::array< std::pair< const DawnBuffer *, uint32_t >, 3 > &boundBuffersAndSizes)
wgpu::RenderPipeline findOrCreateBlitWithDrawPipeline(const RenderPassDesc &renderPassDesc)
sk_sp< DawnBuffer > findOrCreateDawnBuffer(size_t size, BufferType type, AccessPattern, std::string_view label)
const wgpu::Device & device() const
const wgpu::Queue & queue() const
static const uint8_t buffer[]
uint32_t uint32_t * format
sk_sp< SkBlender > blender SkRect rect
static constexpr int kLoadOpCount
bool DawnFormatIsDepthOrStencil(wgpu::TextureFormat format)
bool DawnFormatIsDepth(wgpu::TextureFormat format)
static constexpr int kStoreOpCount
bool DawnFormatIsStencil(wgpu::TextureFormat format)
constexpr int32_t y() const
constexpr int32_t x() const
constexpr int32_t x() const
constexpr int32_t y() const
bool intersect(const SkIRect &r)
constexpr int32_t height() const
int32_t fTop
smaller y-axis bounds
static constexpr SkIRect MakeSize(const SkISize &size)
constexpr int32_t width() const
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
int32_t fLeft
smaller x-axis bounds
constexpr float x() const
constexpr float y() const
constexpr float height() const
constexpr float width() const
AttachmentDesc fDepthStencilAttachment
AttachmentDesc fColorResolveAttachment
std::array< float, 4 > fClearColor
AttachmentDesc fColorAttachment