[graphite] Add buffer to texture copy support
Allows copying of multiple regions into a single texture, which supports both filling mipLevels and rectangles in atlases. Bug: skia:12845 Change-Id: I5fef9bda01125958a5491b4c5c8b3a66184357d2 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/504056 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
744116876e
commit
9907a8637c
@ -117,22 +117,13 @@ void CommandBuffer::bindSamplers(const SamplerBindEntry* entries, int count) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool check_max_blit_width(int widthInPixels) {
|
||||
if (widthInPixels > 32767) {
|
||||
SkASSERT(false); // surfaces should not be this wide anyway
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommandBuffer::copyTextureToBuffer(sk_sp<skgpu::Texture> texture,
|
||||
SkIRect srcRect,
|
||||
sk_sp<skgpu::Buffer> buffer,
|
||||
size_t bufferOffset,
|
||||
size_t bufferRowBytes) {
|
||||
if (!check_max_blit_width(srcRect.width())) {
|
||||
return false;
|
||||
}
|
||||
SkASSERT(texture);
|
||||
SkASSERT(buffer);
|
||||
|
||||
if (!this->onCopyTextureToBuffer(texture.get(), srcRect, buffer.get(), bufferOffset,
|
||||
bufferRowBytes)) {
|
||||
@ -147,4 +138,24 @@ bool CommandBuffer::copyTextureToBuffer(sk_sp<skgpu::Texture> texture,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommandBuffer::copyBufferToTexture(sk_sp<skgpu::Buffer> buffer,
|
||||
sk_sp<skgpu::Texture> texture,
|
||||
const BufferTextureCopyData* copyData,
|
||||
int count) {
|
||||
SkASSERT(buffer);
|
||||
SkASSERT(texture);
|
||||
SkASSERT(count > 0 && copyData);
|
||||
|
||||
if (!this->onCopyBufferToTexture(buffer.get(), texture.get(), copyData, count)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->trackResource(std::move(buffer));
|
||||
this->trackResource(std::move(texture));
|
||||
|
||||
SkDEBUGCODE(fHasWork = true;)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace skgpu
|
||||
|
@ -144,6 +144,16 @@ public:
|
||||
sk_sp<Buffer>,
|
||||
size_t bufferOffset,
|
||||
size_t bufferRowBytes);
|
||||
struct BufferTextureCopyData {
|
||||
size_t fBufferOffset;
|
||||
size_t fBufferRowBytes;
|
||||
SkIRect fRect;
|
||||
unsigned int fMipLevel;
|
||||
};
|
||||
bool copyBufferToTexture(sk_sp<Buffer>,
|
||||
sk_sp<Texture>,
|
||||
const BufferTextureCopyData*,
|
||||
int count);
|
||||
|
||||
protected:
|
||||
CommandBuffer();
|
||||
@ -193,6 +203,10 @@ private:
|
||||
const Buffer*,
|
||||
size_t bufferOffset,
|
||||
size_t bufferRowBytes) = 0;
|
||||
virtual bool onCopyBufferToTexture(const Buffer*,
|
||||
const Texture*,
|
||||
const BufferTextureCopyData*,
|
||||
int count) = 0;
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
bool fHasWork = false;
|
||||
|
@ -58,6 +58,23 @@ public:
|
||||
destinationBytesPerImage: bufferRowBytes * srcRect.height()];
|
||||
}
|
||||
|
||||
void copyFromBuffer(id<MTLBuffer> buffer,
|
||||
size_t bufferOffset,
|
||||
size_t bufferRowBytes,
|
||||
id<MTLTexture> texture,
|
||||
SkIRect dstRect,
|
||||
unsigned int dstLevel) {
|
||||
[(*fCommandEncoder) copyFromBuffer: buffer
|
||||
sourceOffset: bufferOffset
|
||||
sourceBytesPerRow: bufferRowBytes
|
||||
sourceBytesPerImage: bufferRowBytes * dstRect.height()
|
||||
sourceSize: MTLSizeMake(dstRect.width(), dstRect.height(), 1)
|
||||
toTexture: texture
|
||||
destinationSlice: 0
|
||||
destinationLevel: dstLevel
|
||||
destinationOrigin: MTLOriginMake(dstRect.left(), dstRect.top(), 0)];
|
||||
}
|
||||
|
||||
void endEncoding() {
|
||||
[(*fCommandEncoder) endEncoding];
|
||||
}
|
||||
|
@ -87,6 +87,10 @@ private:
|
||||
const skgpu::Buffer*,
|
||||
size_t bufferOffset,
|
||||
size_t bufferRowBytes) override;
|
||||
bool onCopyBufferToTexture(const skgpu::Buffer*,
|
||||
const skgpu::Texture*,
|
||||
const BufferTextureCopyData* copyData,
|
||||
int count) override;
|
||||
|
||||
BlitCommandEncoder* getBlitCommandEncoder();
|
||||
void endBlitCommandEncoder();
|
||||
|
@ -394,6 +394,14 @@ void CommandBuffer::onDrawIndexedInstanced(PrimitiveType type, unsigned int base
|
||||
}
|
||||
}
|
||||
|
||||
static bool check_max_blit_width(int widthInPixels) {
|
||||
if (widthInPixels > 32767) {
|
||||
SkASSERT(false); // surfaces should not be this wide anyway
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommandBuffer::onCopyTextureToBuffer(const skgpu::Texture* texture,
|
||||
SkIRect srcRect,
|
||||
const skgpu::Buffer* buffer,
|
||||
@ -401,6 +409,10 @@ bool CommandBuffer::onCopyTextureToBuffer(const skgpu::Texture* texture,
|
||||
size_t bufferRowBytes) {
|
||||
SkASSERT(!fActiveRenderCommandEncoder);
|
||||
|
||||
if (!check_max_blit_width(srcRect.width())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
id<MTLTexture> mtlTexture = static_cast<const Texture*>(texture)->mtlTexture();
|
||||
id<MTLBuffer> mtlBuffer = static_cast<const Buffer*>(buffer)->mtlBuffer();
|
||||
|
||||
@ -426,5 +438,41 @@ bool CommandBuffer::onCopyTextureToBuffer(const skgpu::Texture* texture,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommandBuffer::onCopyBufferToTexture(const skgpu::Buffer* buffer,
|
||||
const skgpu::Texture* texture,
|
||||
const BufferTextureCopyData* copyData,
|
||||
int count) {
|
||||
SkASSERT(!fActiveRenderCommandEncoder);
|
||||
|
||||
id<MTLBuffer> mtlBuffer = static_cast<const Buffer*>(buffer)->mtlBuffer();
|
||||
id<MTLTexture> mtlTexture = static_cast<const Texture*>(texture)->mtlTexture();
|
||||
|
||||
BlitCommandEncoder* blitCmdEncoder = this->getBlitCommandEncoder();
|
||||
if (!blitCmdEncoder) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef SK_ENABLE_MTL_DEBUG_INFO
|
||||
blitCmdEncoder->pushDebugGroup(@"uploadToTexture");
|
||||
#endif
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (!check_max_blit_width(copyData[i].fRect.width())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
blitCmdEncoder->copyFromBuffer(mtlBuffer,
|
||||
copyData[i].fBufferOffset,
|
||||
copyData[i].fBufferRowBytes,
|
||||
mtlTexture,
|
||||
copyData[i].fRect,
|
||||
copyData[i].fMipLevel);
|
||||
}
|
||||
|
||||
#ifdef SK_ENABLE_MTL_DEBUG_INFO
|
||||
blitCmdEncoder->popDebugGroup();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace skgpu::mtl
|
||||
|
Loading…
Reference in New Issue
Block a user