Implements more pack/unpack states.
Pack: row length, skip rows, skip pixels.
Unpack: image height, skip images, skip rows, skip pixels.
BUG=angleproject:512
BUG=angleproject:1095
Change-Id: I11e3bc05d23419b72c92b96aabd3f0bacd983626
Reviewed-on: https://chromium-review.googlesource.com/304370
Tryjob-Request: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
index b5cc1be..c41b3a6 100644
--- a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
+++ b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -250,17 +250,15 @@
{
const gl::PixelPackState &packState = state.getPackState();
- if (packState.rowLength != 0 || packState.skipRows != 0 || packState.skipPixels != 0)
- {
- UNIMPLEMENTED();
- return gl::Error(GL_INVALID_OPERATION, "invalid pixel store parameters in readPixels");
- }
-
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, type);
const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(sizedInternalFormat);
- GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, area.width, packState.alignment, 0);
+ GLuint outputPitch =
+ sizedFormatInfo.computeRowPitch(type, area.width, packState.alignment, packState.rowLength);
+ GLsizei outputSkipBytes = sizedFormatInfo.computeSkipPixels(
+ outputPitch, 0, 0, packState.skipRows, packState.skipPixels);
- return readPixels(area, format, type, outputPitch, packState, reinterpret_cast<uint8_t*>(pixels));
+ return readPixelsImpl(area, format, type, outputPitch, packState,
+ reinterpret_cast<uint8_t *>(pixels) + outputSkipBytes);
}
gl::Error FramebufferD3D::blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
diff --git a/src/libANGLE/renderer/d3d/FramebufferD3D.h b/src/libANGLE/renderer/d3d/FramebufferD3D.h
index 42f76ff..ff51db0 100644
--- a/src/libANGLE/renderer/d3d/FramebufferD3D.h
+++ b/src/libANGLE/renderer/d3d/FramebufferD3D.h
@@ -91,8 +91,12 @@
private:
virtual gl::Error clear(const gl::State &state, const ClearParameters &clearParams) = 0;
- virtual gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch,
- const gl::PixelPackState &pack, uint8_t *pixels) const = 0;
+ virtual gl::Error readPixelsImpl(const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ size_t outputPitch,
+ const gl::PixelPackState &pack,
+ uint8_t *pixels) const = 0;
virtual gl::Error blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor,
bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter,
diff --git a/src/libANGLE/renderer/d3d/TextureD3D.cpp b/src/libANGLE/renderer/d3d/TextureD3D.cpp
index 0687ac8..cdb2c47 100644
--- a/src/libANGLE/renderer/d3d/TextureD3D.cpp
+++ b/src/libANGLE/renderer/d3d/TextureD3D.cpp
@@ -165,14 +165,6 @@
const uint8_t *pixels,
ptrdiff_t layerOffset)
{
- if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || unpack.skipImages != 0)
- {
- // TODO(jmadill): additional unpack parameters
- // return no error here to work around dEQP-GLES3 failing to state reset.
- UNIMPLEMENTED();
- return gl::Error(GL_NO_ERROR);
- }
-
ImageD3D *image = getImage(index);
ASSERT(image);
@@ -258,12 +250,6 @@
const uint8_t *pixels,
ptrdiff_t layerOffset)
{
- if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || unpack.skipImages != 0)
- {
- UNIMPLEMENTED();
- return gl::Error(GL_INVALID_OPERATION, "unimplemented pixel store state");
- }
-
// We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
// From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
const uint8_t *pixelData = NULL;
@@ -295,12 +281,6 @@
const gl::PixelUnpackState &unpack, const uint8_t *pixels,
ptrdiff_t layerOffset)
{
- if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || unpack.skipImages != 0)
- {
- UNIMPLEMENTED();
- return gl::Error(GL_INVALID_OPERATION, "unimplemented pixel store state");
- }
-
const uint8_t *pixelData = NULL;
gl::Error error = GetUnpackPointer(unpack, pixels, layerOffset, &pixelData);
if (error.isError())
@@ -333,6 +313,15 @@
gl::Error TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const uint8_t *pixels, const gl::Box &destArea,
GLenum sizedInternalFormat, GLenum type, RenderTargetD3D *destRenderTarget)
{
+ if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 ||
+ unpack.skipImages != 0)
+ {
+ // TODO(jmadill): additional unpack parameters
+ UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION,
+ "Unimplemented pixel store parameters in fastUnpackPixels");
+ }
+
// No-op
if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0)
{
@@ -765,12 +754,6 @@
{
ASSERT(target == GL_TEXTURE_2D && area.depth == 1 && area.z == 0);
- if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || unpack.skipImages != 0)
- {
- UNIMPLEMENTED();
- return gl::Error(GL_INVALID_OPERATION, "unimplemented pixel store state");
- }
-
GLint level = static_cast<GLint>(imageLevel);
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level))
@@ -2563,7 +2546,8 @@
redefineImage(level, sizedInternalFormat, size);
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedInternalFormat);
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, size.width, size.height, unpack.alignment, unpack.rowLength);
+ GLsizei inputDepthPitch = formatInfo.computeDepthPitch(
+ type, size.width, size.height, unpack.alignment, unpack.rowLength, unpack.imageHeight);
for (int i = 0; i < size.depth; i++)
{
@@ -2590,7 +2574,8 @@
ASSERT(target == GL_TEXTURE_2D_ARRAY);
GLint level = static_cast<GLint>(imageLevel);
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(level));
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, area.width, area.height, unpack.alignment, unpack.rowLength);
+ GLsizei inputDepthPitch = formatInfo.computeDepthPitch(
+ type, area.width, area.height, unpack.alignment, unpack.rowLength, unpack.imageHeight);
for (int i = 0; i < area.depth; i++)
{
@@ -2625,7 +2610,8 @@
redefineImage(level, internalFormat, size);
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, size.width, size.height, 1, 0);
+ GLsizei inputDepthPitch =
+ formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, size.width, size.height, 1, 0, 0);
for (int i = 0; i < size.depth; i++)
{
@@ -2648,7 +2634,8 @@
ASSERT(target == GL_TEXTURE_2D_ARRAY);
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0);
+ GLsizei inputDepthPitch =
+ formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0);
for (int i = 0; i < area.depth; i++)
{
diff --git a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
index 76bb15c..cedcc08 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
@@ -289,7 +289,12 @@
return gl::Error(GL_NO_ERROR);
}
-gl::Error Framebuffer11::readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) const
+gl::Error Framebuffer11::readPixelsImpl(const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ size_t outputPitch,
+ const gl::PixelPackState &pack,
+ uint8_t *pixels) const
{
ID3D11Texture2D *colorBufferTexture = nullptr;
unsigned int subresourceIndex = 0;
@@ -306,6 +311,13 @@
gl::Buffer *packBuffer = pack.pixelBuffer.get();
if (packBuffer != nullptr)
{
+ if (pack.rowLength != 0 || pack.skipRows != 0 || pack.skipPixels != 0)
+ {
+ UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION,
+ "Unimplemented pixel store parameters in readPixelsImpl");
+ }
+
Buffer11 *packBufferStorage = GetImplAs<Buffer11>(packBuffer);
PackPixelsParams packParams(area, format, type, static_cast<GLuint>(outputPitch), pack,
reinterpret_cast<ptrdiff_t>(pixels));
diff --git a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
index dfadd58..b4b4e03 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
@@ -31,8 +31,12 @@
private:
gl::Error clear(const gl::State &state, const ClearParameters &clearParams) override;
- gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch,
- const gl::PixelPackState &pack, uint8_t *pixels) const override;
+ gl::Error readPixelsImpl(const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ size_t outputPitch,
+ const gl::PixelPackState &pack,
+ uint8_t *pixels) const override;
gl::Error blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor,
bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter,
diff --git a/src/libANGLE/renderer/d3d/d3d11/Image11.cpp b/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
index 0d7ae74..8d5efed 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
@@ -247,7 +247,10 @@
{
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
GLsizei inputRowPitch = formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength);
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, area.width, area.height, unpack.alignment, unpack.rowLength);
+ GLsizei inputDepthPitch = formatInfo.computeDepthPitch(
+ type, area.width, area.height, unpack.alignment, unpack.rowLength, unpack.imageHeight);
+ GLsizei inputSkipBytes = formatInfo.computeSkipPixels(
+ inputRowPitch, inputDepthPitch, unpack.skipImages, unpack.skipRows, unpack.skipPixels);
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat);
GLuint outputPixelSize = dxgiFormatInfo.pixelBytes;
@@ -264,8 +267,8 @@
uint8_t *offsetMappedData = (reinterpret_cast<uint8_t*>(mappedImage.pData) + (area.y * mappedImage.RowPitch + area.x * outputPixelSize + area.z * mappedImage.DepthPitch));
loadFunction(area.width, area.height, area.depth,
- reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch,
- offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
+ reinterpret_cast<const uint8_t *>(input) + inputSkipBytes, inputRowPitch,
+ inputDepthPitch, offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
unmap();
@@ -276,7 +279,8 @@
{
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0);
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0);
+ GLsizei inputDepthPitch =
+ formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0);
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat);
GLuint outputPixelSize = dxgiFormatInfo.pixelBytes;
diff --git a/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp b/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
index 42b1b3b..3913b59 100644
--- a/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -649,7 +649,10 @@
int height = destBox ? destBox->height : static_cast<int>(image->getHeight());
int depth = destBox ? destBox->depth : static_cast<int>(image->getDepth());
UINT srcRowPitch = internalFormatInfo.computeRowPitch(type, width, unpack.alignment, unpack.rowLength);
- UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment, unpack.rowLength);
+ UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment,
+ unpack.rowLength, unpack.imageHeight);
+ GLsizei srcSkipBytes = internalFormatInfo.computeSkipPixels(
+ srcRowPitch, srcDepthPitch, unpack.skipImages, unpack.skipRows, unpack.skipPixels);
const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(image->getInternalFormat(), mRenderer->getRenderer11DeviceCaps());
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11Format.texFormat);
@@ -669,8 +672,7 @@
// TODO: fast path
LoadImageFunction loadFunction = d3d11Format.loadFunctions.at(type);
- loadFunction(width, height, depth,
- pixelData, srcRowPitch, srcDepthPitch,
+ loadFunction(width, height, depth, pixelData + srcSkipBytes, srcRowPitch, srcDepthPitch,
conversionBuffer->data(), bufferRowPitch, bufferDepthPitch);
ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
diff --git a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
index 26b1026..1499bf2 100644
--- a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -1213,6 +1213,8 @@
extensions->fboRenderMipmap = false;
extensions->debugMarker = true;
extensions->eglImage = true;
+ extensions->unpackSubimage = true;
+ extensions->packSubimage = true;
// D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing.
// D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't support gl_FrontFacing.
diff --git a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
index e4dfd41..15e3167 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
@@ -73,7 +73,12 @@
return mRenderer->clear(clearParams, colorAttachment, depthStencilAttachment);
}
-gl::Error Framebuffer9::readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) const
+gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ size_t outputPitch,
+ const gl::PixelPackState &pack,
+ uint8_t *pixels) const
{
ASSERT(pack.pixelBuffer.get() == nullptr);
diff --git a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
index 223259d..88055d3 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
@@ -28,8 +28,12 @@
private:
gl::Error clear(const gl::State &state, const ClearParameters &clearParams) override;
- gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch,
- const gl::PixelPackState &pack, uint8_t *pixels) const override;
+ gl::Error readPixelsImpl(const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ size_t outputPitch,
+ const gl::PixelPackState &pack,
+ uint8_t *pixels) const override;
gl::Error blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor,
bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter,
diff --git a/src/libANGLE/renderer/d3d/d3d9/Image9.cpp b/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
index a64f6ca..df0fae4 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
@@ -480,6 +480,8 @@
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
GLsizei inputRowPitch = formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength);
+ GLsizei inputSkipBytes = formatInfo.computeSkipPixels(inputRowPitch, 0, unpack.skipImages,
+ unpack.skipRows, unpack.skipPixels);
const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
ASSERT(d3dFormatInfo.loadFunction != NULL);
@@ -498,8 +500,9 @@
}
d3dFormatInfo.loadFunction(area.width, area.height, area.depth,
- reinterpret_cast<const uint8_t*>(input), inputRowPitch, 0,
- reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
+ reinterpret_cast<const uint8_t *>(input) + inputSkipBytes,
+ inputRowPitch, 0, reinterpret_cast<uint8_t *>(locked.pBits),
+ locked.Pitch, 0);
unlock();
@@ -513,7 +516,8 @@
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0);
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0);
+ GLsizei inputDepthPitch =
+ formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0);
const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
diff --git a/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp b/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
index afa0181..ed9c146 100644
--- a/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
@@ -574,6 +574,8 @@
extensions->colorBufferFloat = false;
extensions->debugMarker = true;
extensions->eglImage = true;
+ extensions->unpackSubimage = true;
+ extensions->packSubimage = true;
// D3D9 has no concept of separate masks and refs for front and back faces in the depth stencil
// state.
diff --git a/src/libANGLE/renderer/gl/StateManagerGL.cpp b/src/libANGLE/renderer/gl/StateManagerGL.cpp
index 12db094..1519472 100644
--- a/src/libANGLE/renderer/gl/StateManagerGL.cpp
+++ b/src/libANGLE/renderer/gl/StateManagerGL.cpp
@@ -1353,6 +1353,22 @@
// TODO(jmadill): split this
setPixelUnpackState(state.getUnpackState());
break;
+ case gl::State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT:
+ // TODO(jmadill): split this
+ setPixelUnpackState(state.getUnpackState());
+ break;
+ case gl::State::DIRTY_BIT_UNPACK_SKIP_IMAGES:
+ // TODO(jmadill): split this
+ setPixelUnpackState(state.getUnpackState());
+ break;
+ case gl::State::DIRTY_BIT_UNPACK_SKIP_ROWS:
+ // TODO(jmadill): split this
+ setPixelUnpackState(state.getUnpackState());
+ break;
+ case gl::State::DIRTY_BIT_UNPACK_SKIP_PIXELS:
+ // TODO(jmadill): split this
+ setPixelUnpackState(state.getUnpackState());
+ break;
case gl::State::DIRTY_BIT_PACK_ALIGNMENT:
// TODO(jmadill): split this
setPixelPackState(state.getPackState());
@@ -1361,6 +1377,18 @@
// TODO(jmadill): split this
setPixelPackState(state.getPackState());
break;
+ case gl::State::DIRTY_BIT_PACK_ROW_LENGTH:
+ // TODO(jmadill): split this
+ setPixelPackState(state.getPackState());
+ break;
+ case gl::State::DIRTY_BIT_PACK_SKIP_ROWS:
+ // TODO(jmadill): split this
+ setPixelPackState(state.getPackState());
+ break;
+ case gl::State::DIRTY_BIT_PACK_SKIP_PIXELS:
+ // TODO(jmadill): split this
+ setPixelPackState(state.getPackState());
+ break;
case gl::State::DIRTY_BIT_DITHER_ENABLED:
// TODO(jmadill): implement this
break;