Dawn: submit all command buffers in a single call.
All command buffers are now appended to a single vector, and submitted
submitted in onFinishFlush() in a single submit.
In order to do this, implement a centralized command encoder for copies.
This command encoder is used for buffer-to-buffer, buffer-to-texture and
texture-to-buffer copies.
Change-Id: If1092ae4edbe03c995d4cb80e0dc124516d63dad
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/235826
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Stephen White <senorblanco@chromium.org>
diff --git a/src/gpu/dawn/GrDawnCaps.h b/src/gpu/dawn/GrDawnCaps.h
index e96f0cd..41ca2a2 100644
--- a/src/gpu/dawn/GrDawnCaps.h
+++ b/src/gpu/dawn/GrDawnCaps.h
@@ -78,7 +78,7 @@
SupportedRead onSupportedReadPixelsColorType(GrColorType srcColorType,
const GrBackendFormat& backendFormat,
GrColorType dstColorType) const override {
- return { GrColorType::kUnknown, 0 };
+ return { srcColorType, GrColorTypeBytesPerPixel(srcColorType) };
}
typedef GrCaps INHERITED;
diff --git a/src/gpu/dawn/GrDawnGpu.cpp b/src/gpu/dawn/GrDawnGpu.cpp
index 0eb7ed8..7799f2a 100644
--- a/src/gpu/dawn/GrDawnGpu.cpp
+++ b/src/gpu/dawn/GrDawnGpu.cpp
@@ -91,7 +91,8 @@
SkASSERT(!"uploading to non-texture unimplemented");
return false;
}
- texture->upload(texels, mipLevelCount, SkIRect::MakeXYWH(left, top, width, height));
+ texture->upload(texels, mipLevelCount, SkIRect::MakeXYWH(left, top, width, height),
+ this->getCopyEncoder());
return true;
}
@@ -142,7 +143,7 @@
if (!tex) {
return nullptr;
}
- tex->upload(texels, mipLevelCount);
+ tex->upload(texels, mipLevelCount, this->getCopyEncoder());
return tex;
}
@@ -394,14 +395,20 @@
}
void GrDawnGpu::testingOnly_flushGpuAndSync() {
- SkASSERT(!"unimplemented");
+ this->flush();
}
#endif
+void GrDawnGpu::flush() {
+ this->flushCopyEncoder();
+ fQueue.Submit(fCommandBuffers.size(), &fCommandBuffers.front());
+ fCommandBuffers.clear();
+}
+
void GrDawnGpu::onFinishFlush(GrSurfaceProxy*[], int n, SkSurface::BackendSurfaceAccess access,
const GrFlushInfo& info, const GrPrepareForExternalIORequests&) {
- SkASSERT(!"unimplemented");
+ this->flush();
}
static dawn::Texture get_dawn_texture_from_surface(GrSurface* src) {
@@ -433,10 +440,7 @@
dstTextureView.origin = {(uint32_t) dstPoint.x(), (uint32_t) dstPoint.y(), 0};
dawn::Extent3D copySize = {width, height, 1};
- auto encoder = device().CreateCommandEncoder();
- encoder.CopyTextureToTexture(&srcTextureView, &dstTextureView, ©Size);
- auto commandBuffer = encoder.Finish();
- this->queue().Submit(1, &commandBuffer);
+ this->getCopyEncoder().CopyTextureToTexture(&srcTextureView, &dstTextureView, ©Size);
return true;
}
@@ -475,10 +479,8 @@
dstBuffer.imageHeight = height;
dawn::Extent3D copySize = {(uint32_t) width, (uint32_t) height, 1};
- auto encoder = device().CreateCommandEncoder();
- encoder.CopyTextureToBuffer(&srcTexture, &dstBuffer, ©Size);
- auto commandBuffer = encoder.Finish();
- queue().Submit(1, &commandBuffer);
+ this->getCopyEncoder().CopyTextureToBuffer(&srcTexture, &dstBuffer, ©Size);
+ flush();
const void *readPixelsPtr = nullptr;
buf.MapReadAsync(callback, &readPixelsPtr);
@@ -507,6 +509,7 @@
}
void GrDawnGpu::submit(GrOpsRenderPass* renderPass) {
+ this->flushCopyEncoder();
static_cast<GrDawnOpsRenderPass*>(renderPass)->submit();
}
@@ -556,3 +559,23 @@
GrDawnRingBuffer::Slice GrDawnGpu::allocateUniformRingBufferSlice(int size) {
return fUniformRingBuffer.allocate(size);
}
+
+void GrDawnGpu::appendCommandBuffer(dawn::CommandBuffer commandBuffer) {
+ if (commandBuffer) {
+ fCommandBuffers.push_back(commandBuffer);
+ }
+}
+
+dawn::CommandEncoder GrDawnGpu::getCopyEncoder() {
+ if (!fCopyEncoder) {
+ fCopyEncoder = fDevice.CreateCommandEncoder();
+ }
+ return fCopyEncoder;
+}
+
+void GrDawnGpu::flushCopyEncoder() {
+ if (fCopyEncoder) {
+ fCommandBuffers.push_back(fCopyEncoder.Finish());
+ fCopyEncoder = nullptr;
+ }
+}
diff --git a/src/gpu/dawn/GrDawnGpu.h b/src/gpu/dawn/GrDawnGpu.h
index e213d18..2098c3c 100644
--- a/src/gpu/dawn/GrDawnGpu.h
+++ b/src/gpu/dawn/GrDawnGpu.h
@@ -50,6 +50,7 @@
void testingOnly_flushGpuAndSync() override;
#endif
+ void flush();
GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget*,
int width,
@@ -82,6 +83,9 @@
sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override;
GrDawnRingBuffer::Slice allocateUniformRingBufferSlice(int size);
+ dawn::CommandEncoder getCopyEncoder();
+ void flushCopyEncoder();
+ void appendCommandBuffer(dawn::CommandBuffer commandBuffer);
private:
void onResetContext(uint32_t resetBits) override {}
@@ -147,6 +151,8 @@
std::unique_ptr<SkSL::Compiler> fCompiler;
std::unique_ptr<GrDawnOpsRenderPass> fOpsRenderPass;
GrDawnRingBuffer fUniformRingBuffer;
+ dawn::CommandEncoder fCopyEncoder;
+ std::vector<dawn::CommandBuffer> fCommandBuffers;
typedef GrGpu INHERITED;
};
diff --git a/src/gpu/dawn/GrDawnOpsRenderPass.cpp b/src/gpu/dawn/GrDawnOpsRenderPass.cpp
index dc17108..d14a88c 100644
--- a/src/gpu/dawn/GrDawnOpsRenderPass.cpp
+++ b/src/gpu/dawn/GrDawnOpsRenderPass.cpp
@@ -98,10 +98,7 @@
}
void GrDawnOpsRenderPass::submit() {
- dawn::CommandBuffer commandBuffer = fEncoder.Finish();
- if (commandBuffer) {
- fGpu->queue().Submit(1, &commandBuffer);
- }
+ fGpu->appendCommandBuffer(fEncoder.Finish());
}
void GrDawnOpsRenderPass::insertEventMarker(const char* msg) {
diff --git a/src/gpu/dawn/GrDawnTexture.cpp b/src/gpu/dawn/GrDawnTexture.cpp
index 1fc6e0a..ee9df7d 100644
--- a/src/gpu/dawn/GrDawnTexture.cpp
+++ b/src/gpu/dawn/GrDawnTexture.cpp
@@ -124,13 +124,14 @@
return GrBackendTexture(this->width(), this->height(), fInfo);
}
-void GrDawnTexture::upload(const GrMipLevel texels[], int mipLevels) {
- upload(texels, mipLevels, SkIRect::MakeWH(width(), height()));
+void GrDawnTexture::upload(const GrMipLevel texels[], int mipLevels,
+ dawn::CommandEncoder copyEncoder) {
+ this->upload(texels, mipLevels, SkIRect::MakeWH(width(), height()), copyEncoder);
}
-void GrDawnTexture::upload(const GrMipLevel texels[], int mipLevels, const SkIRect& rect) {
+void GrDawnTexture::upload(const GrMipLevel texels[], int mipLevels, const SkIRect& rect,
+ dawn::CommandEncoder copyEncoder) {
dawn::Device device = this->getDawnGpu()->device();
- dawn::Queue queue = this->getDawnGpu()->queue();
uint32_t x = rect.x();
uint32_t y = rect.y();
@@ -200,11 +201,7 @@
dstTexture.origin = {x, y, 0};
dawn::Extent3D copySize = {width, height, 1};
- dawn::CommandEncoder encoder = device.CreateCommandEncoder();
- encoder.CopyBufferToTexture(&srcBuffer, &dstTexture, ©Size);
- dawn::CommandBuffer copy = encoder.Finish();
- queue.Submit(1, ©);
-
+ copyEncoder.CopyBufferToTexture(&srcBuffer, &dstTexture, ©Size);
x /= 2;
y /= 2;
width /= 2;
diff --git a/src/gpu/dawn/GrDawnTexture.h b/src/gpu/dawn/GrDawnTexture.h
index b809124..cc69fd7 100644
--- a/src/gpu/dawn/GrDawnTexture.h
+++ b/src/gpu/dawn/GrDawnTexture.h
@@ -32,8 +32,9 @@
void textureParamsModified() override {}
- void upload(const GrMipLevel texels[], int mipLevels);
- void upload(const GrMipLevel texels[], int mipLevels, const SkIRect& dstRect);
+ void upload(const GrMipLevel texels[], int mipLevels, dawn::CommandEncoder copyEncoder);
+ void upload(const GrMipLevel texels[], int mipLevels, const SkIRect& dstRect,
+ dawn::CommandEncoder copyEncoder);
dawn::Texture texture() const { return fInfo.fTexture; }
dawn::TextureView textureView() const { return fTextureView; }