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;