Add buffer to buffer copies

This commit is contained in:
Corentin Wallez 2017-06-12 18:12:29 -04:00 committed by Corentin Wallez
parent 367cb3515c
commit d84d107076
7 changed files with 101 additions and 0 deletions

View File

@ -260,6 +260,19 @@
{ {
"name": "end render pass" "name": "end render pass"
}, },
{
"name": "copy buffer to buffer",
"args": [
{"name": "source", "type": "buffer"},
{"name": "source offset", "type": "uint32_t"},
{"name": "destination", "type": "buffer"},
{"name": "destination offset", "type": "uint32_t"},
{"name": "size", "type": "uint32_t"}
],
"TODO": [
"Restrictions on the alignment of the copy? Cf Metal on OSX"
]
},
{ {
"name": "copy buffer to texture", "name": "copy buffer to texture",
"args": [ "args": [

View File

@ -67,6 +67,12 @@ namespace backend {
begin->~BeginRenderPassCmd(); begin->~BeginRenderPassCmd();
} }
break; break;
case Command::CopyBufferToBuffer:
{
CopyBufferToBufferCmd* copy = commands->NextCommand<CopyBufferToBufferCmd>();
copy->~CopyBufferToBufferCmd();
}
break;
case Command::CopyBufferToTexture: case Command::CopyBufferToTexture:
{ {
CopyBufferToTextureCmd* copy = commands->NextCommand<CopyBufferToTextureCmd>(); CopyBufferToTextureCmd* copy = commands->NextCommand<CopyBufferToTextureCmd>();
@ -201,6 +207,35 @@ namespace backend {
} }
break; break;
case Command::CopyBufferToBuffer:
{
CopyBufferToBufferCmd* copy = iterator.NextCommand<CopyBufferToBufferCmd>();
BufferBase* source = copy->source.Get();
BufferBase* destination = copy->destination.Get();
uint32_t sourceOffset = copy->sourceOffset;
uint32_t destinationOffset = copy->destinationOffset;
uint32_t size = copy->size;
uint64_t sourceEnd = uint64_t(sourceOffset) + uint64_t(size);
if (sourceEnd > uint64_t(source->GetSize())) {
HandleError("Copy would read after end of the source buffer");
return false;
}
uint64_t destinationEnd = uint64_t(destinationOffset) + uint64_t(size);
if (destinationEnd > uint64_t(destination->GetSize())) {
HandleError("Copy would read after end of the destination buffer");
return false;
}
if (!state->ValidateCanCopy() ||
!state->ValidateCanUseBufferAs(source, nxt::BufferUsageBit::TransferSrc) ||
!state->ValidateCanUseBufferAs(destination, nxt::BufferUsageBit::TransferDst)) {
return false;
}
}
break;
case Command::CopyBufferToTexture: case Command::CopyBufferToTexture:
{ {
CopyBufferToTextureCmd* copy = iterator.NextCommand<CopyBufferToTextureCmd>(); CopyBufferToTextureCmd* copy = iterator.NextCommand<CopyBufferToTextureCmd>();
@ -391,6 +426,16 @@ namespace backend {
cmd->framebuffer = framebuffer; cmd->framebuffer = framebuffer;
} }
void CommandBufferBuilder::CopyBufferToBuffer(BufferBase* source, uint32_t sourceOffset, BufferBase* destination, uint32_t destinationOffset, uint32_t size) {
CopyBufferToBufferCmd* copy = allocator.Allocate<CopyBufferToBufferCmd>(Command::CopyBufferToBuffer);
new(copy) CopyBufferToBufferCmd;
copy->source = source;
copy->sourceOffset = sourceOffset;
copy->destination = destination;
copy->destinationOffset = destinationOffset;
copy->size = size;
}
void CommandBufferBuilder::CopyBufferToTexture(BufferBase* buffer, uint32_t bufferOffset, void CommandBufferBuilder::CopyBufferToTexture(BufferBase* buffer, uint32_t bufferOffset,
TextureBase* texture, uint32_t x, uint32_t y, uint32_t z, TextureBase* texture, uint32_t x, uint32_t y, uint32_t z,
uint32_t width, uint32_t height, uint32_t depth, uint32_t level) { uint32_t width, uint32_t height, uint32_t depth, uint32_t level) {

View File

@ -61,6 +61,7 @@ namespace backend {
// NXT API // NXT API
void AdvanceSubpass(); void AdvanceSubpass();
void BeginRenderPass(RenderPassBase* renderPass, FramebufferBase* framebuffer); void BeginRenderPass(RenderPassBase* renderPass, FramebufferBase* framebuffer);
void CopyBufferToBuffer(BufferBase* source, uint32_t sourceOffset, BufferBase* destination, uint32_t destinationOffset, uint32_t size);
void CopyBufferToTexture(BufferBase* buffer, uint32_t bufferOffset, void CopyBufferToTexture(BufferBase* buffer, uint32_t bufferOffset,
TextureBase* texture, uint32_t x, uint32_t y, uint32_t z, TextureBase* texture, uint32_t x, uint32_t y, uint32_t z,
uint32_t width, uint32_t height, uint32_t depth, uint32_t level); uint32_t width, uint32_t height, uint32_t depth, uint32_t level);

View File

@ -30,6 +30,7 @@ namespace backend {
enum class Command { enum class Command {
AdvanceSubpass, AdvanceSubpass,
BeginRenderPass, BeginRenderPass,
CopyBufferToBuffer,
CopyBufferToTexture, CopyBufferToTexture,
Dispatch, Dispatch,
DrawArrays, DrawArrays,
@ -53,6 +54,14 @@ namespace backend {
Ref<FramebufferBase> framebuffer; Ref<FramebufferBase> framebuffer;
}; };
struct CopyBufferToBufferCmd {
Ref<BufferBase> source;
Ref<BufferBase> destination;
uint32_t sourceOffset;
uint32_t destinationOffset;
uint32_t size;
};
struct CopyBufferToTextureCmd { struct CopyBufferToTextureCmd {
Ref<BufferBase> buffer; Ref<BufferBase> buffer;
uint32_t bufferOffset; uint32_t bufferOffset;

View File

@ -61,6 +61,12 @@ namespace d3d12 {
} }
break; break;
case Command::CopyBufferToBuffer:
{
CopyBufferToBufferCmd* copy = commands.NextCommand<CopyBufferToBufferCmd>();
}
break;
case Command::CopyBufferToTexture: case Command::CopyBufferToTexture:
{ {
CopyBufferToTextureCmd* copy = commands.NextCommand<CopyBufferToTextureCmd>(); CopyBufferToTextureCmd* copy = commands.NextCommand<CopyBufferToTextureCmd>();

View File

@ -376,6 +376,20 @@ namespace metal {
} }
break; break;
case Command::CopyBufferToBuffer:
{
CopyBufferToBufferCmd* copy = commands.NextCommand<CopyBufferToBufferCmd>();
encoders.EnsureBlit(commandBuffer);
[encoders.blit
copyFromBuffer:ToBackend(copy->source)->GetMTLBuffer()
sourceOffset:copy->sourceOffset
toBuffer:ToBackend(copy->destination)->GetMTLBuffer()
destinationOffset:copy->destinationOffset
size:copy->size];
}
break;
case Command::CopyBufferToTexture: case Command::CopyBufferToTexture:
{ {
CopyBufferToTextureCmd* copy = commands.NextCommand<CopyBufferToTextureCmd>(); CopyBufferToTextureCmd* copy = commands.NextCommand<CopyBufferToTextureCmd>();

View File

@ -78,6 +78,19 @@ namespace opengl {
} }
break; break;
case Command::CopyBufferToBuffer:
{
CopyBufferToBufferCmd* copy = commands.NextCommand<CopyBufferToBufferCmd>();
glBindBuffer(GL_PIXEL_PACK_BUFFER, ToBackend(copy->source)->GetHandle());
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, ToBackend(copy->destination)->GetHandle());
glCopyBufferSubData(GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, copy->sourceOffset, copy->destinationOffset, copy->size);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
break;
case Command::CopyBufferToTexture: case Command::CopyBufferToTexture:
{ {
CopyBufferToTextureCmd* copy = commands.NextCommand<CopyBufferToTextureCmd>(); CopyBufferToTextureCmd* copy = commands.NextCommand<CopyBufferToTextureCmd>();