Add row pitch validation and default computation

This commit is contained in:
Austin Eng 2017-07-13 10:23:26 -04:00 committed by Austin Eng
parent c5f8e7ae77
commit 3f47729df6
1 changed files with 32 additions and 5 deletions

View File

@ -70,10 +70,29 @@ namespace backend {
return true; return true;
} }
bool ComputeTextureCopyBufferSize(CommandBufferBuilder*, const TextureCopyLocation& location, uint32_t* bufferSize) { bool ComputeTextureCopyBufferSize(CommandBufferBuilder*, const TextureCopyLocation& location, uint32_t rowPitch, uint32_t* bufferSize) {
// TODO(cwallez@chromium.org): check for overflows // TODO(cwallez@chromium.org): check for overflows
uint32_t pixelSize = static_cast<uint32_t>(TextureFormatPixelSize(location.texture->GetFormat())); *bufferSize = (rowPitch * (location.height - 1) + location.width) * location.depth;
*bufferSize = location.width * location.height * location.depth * pixelSize;
return true;
}
uint32_t ComputeDefaultRowPitch(TextureBase* texture, uint32_t width) {
uint32_t texelSize = static_cast<uint32_t>(TextureFormatPixelSize(texture->GetFormat()));
return texelSize * width;
}
bool ValidateRowPitch(CommandBufferBuilder* builder, const TextureCopyLocation& location, uint32_t rowPitch) {
if (rowPitch % kTextureRowPitchAlignment != 0) {
builder->HandleError("Row pitch must be a multiple of 256");
return false;
}
uint32_t texelSize = static_cast<uint32_t>(TextureFormatPixelSize(location.texture.Get()->GetFormat()));
if (rowPitch < location.width * texelSize) {
builder->HandleError("Row pitch must not be less than the number of bytes per row");
return false;
}
return true; return true;
} }
@ -414,7 +433,8 @@ namespace backend {
CopyBufferToTextureCmd* copy = iterator.NextCommand<CopyBufferToTextureCmd>(); CopyBufferToTextureCmd* copy = iterator.NextCommand<CopyBufferToTextureCmd>();
uint32_t bufferCopySize = 0; uint32_t bufferCopySize = 0;
if (!ComputeTextureCopyBufferSize(this, copy->destination, &bufferCopySize) || if (!ValidateRowPitch(this, copy->destination, copy->rowPitch) ||
!ComputeTextureCopyBufferSize(this, copy->destination, copy->rowPitch, &bufferCopySize) ||
!ValidateCopyLocationFitsInTexture(this, copy->destination) || !ValidateCopyLocationFitsInTexture(this, copy->destination) ||
!ValidateCopySizeFitsInBuffer(this, copy->source, bufferCopySize) || !ValidateCopySizeFitsInBuffer(this, copy->source, bufferCopySize) ||
!state->ValidateCanCopy() || !state->ValidateCanCopy() ||
@ -430,7 +450,8 @@ namespace backend {
CopyTextureToBufferCmd* copy = iterator.NextCommand<CopyTextureToBufferCmd>(); CopyTextureToBufferCmd* copy = iterator.NextCommand<CopyTextureToBufferCmd>();
uint32_t bufferCopySize = 0; uint32_t bufferCopySize = 0;
if (!ComputeTextureCopyBufferSize(this, copy->source, &bufferCopySize) || if (!ValidateRowPitch(this, copy->source, copy->rowPitch) ||
!ComputeTextureCopyBufferSize(this, copy->source, copy->rowPitch, &bufferCopySize) ||
!ValidateCopyLocationFitsInTexture(this, copy->source) || !ValidateCopyLocationFitsInTexture(this, copy->source) ||
!ValidateCopySizeFitsInBuffer(this, copy->destination, bufferCopySize) || !ValidateCopySizeFitsInBuffer(this, copy->destination, bufferCopySize) ||
!state->ValidateCanCopy() || !state->ValidateCanCopy() ||
@ -633,6 +654,9 @@ namespace backend {
void CommandBufferBuilder::CopyBufferToTexture(BufferBase* buffer, uint32_t bufferOffset, uint32_t rowPitch, void CommandBufferBuilder::CopyBufferToTexture(BufferBase* buffer, uint32_t bufferOffset, uint32_t rowPitch,
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) {
if (rowPitch == 0) {
rowPitch = ComputeDefaultRowPitch(texture, width);
}
CopyBufferToTextureCmd* copy = allocator.Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture); CopyBufferToTextureCmd* copy = allocator.Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture);
new(copy) CopyBufferToTextureCmd; new(copy) CopyBufferToTextureCmd;
copy->source.buffer = buffer; copy->source.buffer = buffer;
@ -651,6 +675,9 @@ namespace backend {
void CommandBufferBuilder::CopyTextureToBuffer(TextureBase* texture, uint32_t x, uint32_t y, uint32_t z, void CommandBufferBuilder::CopyTextureToBuffer(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,
BufferBase* buffer, uint32_t bufferOffset, uint32_t rowPitch) { BufferBase* buffer, uint32_t bufferOffset, uint32_t rowPitch) {
if (rowPitch == 0) {
rowPitch = ComputeDefaultRowPitch(texture, width);
}
CopyTextureToBufferCmd* copy = allocator.Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer); CopyTextureToBufferCmd* copy = allocator.Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
new(copy) CopyTextureToBufferCmd; new(copy) CopyTextureToBufferCmd;
copy->source.texture = texture; copy->source.texture = texture;