Implement backend texture->buffer and buffer->texture copies with row pitch
This commit is contained in:
parent
51ff013ee2
commit
33560ef015
|
@ -202,7 +202,7 @@ namespace d3d12 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION D3D12PlacedTextureCopyLocation(BufferCopyLocation& bufferLocation, Texture* texture, const TextureCopyLocation& textureLocation) {
|
D3D12_TEXTURE_COPY_LOCATION D3D12PlacedTextureCopyLocation(BufferCopyLocation& bufferLocation, Texture* texture, const TextureCopyLocation& textureLocation, uint32_t rowPitch) {
|
||||||
D3D12_TEXTURE_COPY_LOCATION d3d12Location;
|
D3D12_TEXTURE_COPY_LOCATION d3d12Location;
|
||||||
d3d12Location.pResource = ToBackend(bufferLocation.buffer.Get())->GetD3D12Resource().Get();
|
d3d12Location.pResource = ToBackend(bufferLocation.buffer.Get())->GetD3D12Resource().Get();
|
||||||
d3d12Location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
d3d12Location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||||
|
@ -211,10 +211,7 @@ namespace d3d12 {
|
||||||
d3d12Location.PlacedFootprint.Footprint.Width = textureLocation.width;
|
d3d12Location.PlacedFootprint.Footprint.Width = textureLocation.width;
|
||||||
d3d12Location.PlacedFootprint.Footprint.Height = textureLocation.height;
|
d3d12Location.PlacedFootprint.Footprint.Height = textureLocation.height;
|
||||||
d3d12Location.PlacedFootprint.Footprint.Depth = textureLocation.depth;
|
d3d12Location.PlacedFootprint.Footprint.Depth = textureLocation.depth;
|
||||||
|
d3d12Location.PlacedFootprint.Footprint.RowPitch = rowPitch;
|
||||||
size_t texelSize = TextureFormatPixelSize(texture->GetFormat());
|
|
||||||
uint32_t rowSize = textureLocation.width * texelSize;
|
|
||||||
d3d12Location.PlacedFootprint.Footprint.RowPitch = ((rowSize - 1) / D3D12_TEXTURE_DATA_PITCH_ALIGNMENT + 1) * D3D12_TEXTURE_DATA_PITCH_ALIGNMENT;
|
|
||||||
|
|
||||||
return d3d12Location;
|
return d3d12Location;
|
||||||
}
|
}
|
||||||
|
@ -320,12 +317,10 @@ namespace d3d12 {
|
||||||
Buffer* buffer = ToBackend(copy->source.buffer.Get());
|
Buffer* buffer = ToBackend(copy->source.buffer.Get());
|
||||||
Texture* texture = ToBackend(copy->destination.texture.Get());
|
Texture* texture = ToBackend(copy->destination.texture.Get());
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION srcLocation = D3D12PlacedTextureCopyLocation(copy->source, texture, copy->destination);
|
D3D12_TEXTURE_COPY_LOCATION srcLocation = D3D12PlacedTextureCopyLocation(copy->source, texture, copy->destination, copy->rowPitch);
|
||||||
D3D12_TEXTURE_COPY_LOCATION dstLocation = D3D12TextureCopyLocation(copy->destination);
|
D3D12_TEXTURE_COPY_LOCATION dstLocation = D3D12TextureCopyLocation(copy->destination);
|
||||||
|
|
||||||
// TODO(enga@google.com): This assertion will not be true if the number of bytes in each row of the texture is not a multiple of 256
|
uint64_t totalBytes = (copy->rowPitch * (copy->destination.height - 1) + copy->destination.width) * copy->destination.depth;
|
||||||
// To resolve this we would need to create an intermediate resource or force all textures to be 256-byte aligned
|
|
||||||
uint64_t totalBytes = srcLocation.PlacedFootprint.Footprint.RowPitch * copy->destination.height * copy->destination.depth;
|
|
||||||
ASSERT(totalBytes <= buffer->GetD3D12Size());
|
ASSERT(totalBytes <= buffer->GetD3D12Size());
|
||||||
|
|
||||||
commandList->CopyTextureRegion(&dstLocation, copy->destination.x, copy->destination.y, copy->destination.z, &srcLocation, nullptr);
|
commandList->CopyTextureRegion(&dstLocation, copy->destination.x, copy->destination.y, copy->destination.z, &srcLocation, nullptr);
|
||||||
|
@ -339,11 +334,9 @@ namespace d3d12 {
|
||||||
Buffer* buffer = ToBackend(copy->destination.buffer.Get());
|
Buffer* buffer = ToBackend(copy->destination.buffer.Get());
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION srcLocation = D3D12TextureCopyLocation(copy->source);
|
D3D12_TEXTURE_COPY_LOCATION srcLocation = D3D12TextureCopyLocation(copy->source);
|
||||||
D3D12_TEXTURE_COPY_LOCATION dstLocation = D3D12PlacedTextureCopyLocation(copy->destination, texture, copy->source);
|
D3D12_TEXTURE_COPY_LOCATION dstLocation = D3D12PlacedTextureCopyLocation(copy->destination, texture, copy->source, copy->rowPitch);
|
||||||
|
|
||||||
// TODO(enga@google.com): This assertion will not be true if the number of bytes in each row of the texture is not a multiple of 256
|
uint64_t totalBytes = (copy->rowPitch * (copy->source.height - 1) + copy->source.width) * copy->source.depth;
|
||||||
// To resolve this we would need to create an intermediate resource or force all textures to be 256-byte aligned
|
|
||||||
uint64_t totalBytes = dstLocation.PlacedFootprint.Footprint.RowPitch * copy->source.height * copy->source.depth;
|
|
||||||
ASSERT(totalBytes <= buffer->GetD3D12Size());
|
ASSERT(totalBytes <= buffer->GetD3D12Size());
|
||||||
|
|
||||||
D3D12_BOX sourceRegion;
|
D3D12_BOX sourceRegion;
|
||||||
|
|
|
@ -207,7 +207,6 @@ namespace metal {
|
||||||
Buffer* buffer = ToBackend(src.buffer.Get());
|
Buffer* buffer = ToBackend(src.buffer.Get());
|
||||||
Texture* texture = ToBackend(dst.texture.Get());
|
Texture* texture = ToBackend(dst.texture.Get());
|
||||||
|
|
||||||
unsigned rowSize = dst.width * TextureFormatPixelSize(texture->GetFormat());
|
|
||||||
MTLOrigin origin;
|
MTLOrigin origin;
|
||||||
origin.x = dst.x;
|
origin.x = dst.x;
|
||||||
origin.y = dst.y;
|
origin.y = dst.y;
|
||||||
|
@ -222,8 +221,8 @@ namespace metal {
|
||||||
[encoders.blit
|
[encoders.blit
|
||||||
copyFromBuffer:buffer->GetMTLBuffer()
|
copyFromBuffer:buffer->GetMTLBuffer()
|
||||||
sourceOffset:src.offset
|
sourceOffset:src.offset
|
||||||
sourceBytesPerRow:rowSize
|
sourceBytesPerRow:copy->rowPitch
|
||||||
sourceBytesPerImage:(rowSize * dst.height)
|
sourceBytesPerImage:(copy->rowPitch * dst.height)
|
||||||
sourceSize:size
|
sourceSize:size
|
||||||
toTexture:texture->GetMTLTexture()
|
toTexture:texture->GetMTLTexture()
|
||||||
destinationSlice:0
|
destinationSlice:0
|
||||||
|
@ -240,7 +239,6 @@ namespace metal {
|
||||||
Texture* texture = ToBackend(src.texture.Get());
|
Texture* texture = ToBackend(src.texture.Get());
|
||||||
Buffer* buffer = ToBackend(dst.buffer.Get());
|
Buffer* buffer = ToBackend(dst.buffer.Get());
|
||||||
|
|
||||||
unsigned rowSize = src.width * TextureFormatPixelSize(texture->GetFormat());
|
|
||||||
MTLOrigin origin;
|
MTLOrigin origin;
|
||||||
origin.x = src.x;
|
origin.x = src.x;
|
||||||
origin.y = src.y;
|
origin.y = src.y;
|
||||||
|
@ -260,8 +258,8 @@ namespace metal {
|
||||||
sourceSize:size
|
sourceSize:size
|
||||||
toBuffer:buffer->GetMTLBuffer()
|
toBuffer:buffer->GetMTLBuffer()
|
||||||
destinationOffset:dst.offset
|
destinationOffset:dst.offset
|
||||||
destinationBytesPerRow:rowSize
|
destinationBytesPerRow:copy->rowPitch
|
||||||
destinationBytesPerImage:rowSize * src.height];
|
destinationBytesPerImage:copy->rowPitch * src.height];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -181,9 +181,11 @@ namespace opengl {
|
||||||
glBindTexture(target, texture->GetHandle());
|
glBindTexture(target, texture->GetHandle());
|
||||||
|
|
||||||
ASSERT(texture->GetDimension() == nxt::TextureDimension::e2D);
|
ASSERT(texture->GetDimension() == nxt::TextureDimension::e2D);
|
||||||
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, copy->rowPitch / static_cast<uint32_t>(TextureFormatPixelSize(texture->GetFormat())));
|
||||||
glTexSubImage2D(target, dst.level, dst.x, dst.y, dst.width, dst.height,
|
glTexSubImage2D(target, dst.level, dst.x, dst.y, dst.width, dst.height,
|
||||||
format.format, format.type,
|
format.format, format.type,
|
||||||
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
|
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
|
||||||
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -210,9 +212,11 @@ namespace opengl {
|
||||||
texture->GetHandle(), src.level);
|
texture->GetHandle(), src.level);
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer->GetHandle());
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer->GetHandle());
|
||||||
|
glPixelStorei(GL_PACK_ROW_LENGTH, copy->rowPitch / static_cast<uint32_t>(TextureFormatPixelSize(texture->GetFormat())));
|
||||||
ASSERT(src.depth == 1 && src.z == 0);
|
ASSERT(src.depth == 1 && src.z == 0);
|
||||||
void* offset = reinterpret_cast<void*>(static_cast<uintptr_t>(dst.offset));
|
void* offset = reinterpret_cast<void*>(static_cast<uintptr_t>(dst.offset));
|
||||||
glReadPixels(src.x, src.y, src.width, src.height, format.format, format.type, offset);
|
glReadPixels(src.x, src.y, src.width, src.height, format.format, format.type, offset);
|
||||||
|
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
glDeleteFramebuffers(1, &readFBO);
|
glDeleteFramebuffers(1, &readFBO);
|
||||||
|
|
Loading…
Reference in New Issue