Commit 2b5c9cbc by Jamie Madill

Store current pack operation as a queued command.

The pack pixels operation is split in two halves: a GPU copy then a CPU readback. We defer the CPU readback until we can't wait any longer. That is, we do the readback when the user maps the buffer, or there's another readback or internal operation. This offers the benefits of doing as much GPU work as asynchronously as possible, and only doing the readback work on related API calls (map or subsequent pack calls). BUG=angle:511 Change-Id: I95a01da2b0e842438b180e8cdbb382c9a46ae210 Reviewed-on: https://chromium-review.googlesource.com/197836Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 7a29e4ae
...@@ -142,11 +142,14 @@ class BufferStorage11::PackStorage11 : public BufferStorage11::TypedBufferStorag ...@@ -142,11 +142,14 @@ class BufferStorage11::PackStorage11 : public BufferStorage11::TypedBufferStorag
void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params); void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
private: private:
void flushQueuedPackCommand();
ID3D11Texture2D *mStagingTexture; ID3D11Texture2D *mStagingTexture;
DXGI_FORMAT mTextureFormat; DXGI_FORMAT mTextureFormat;
gl::Extents mTextureSize; gl::Extents mTextureSize;
unsigned char *mMemoryBuffer; unsigned char *mMemoryBuffer;
PackPixelsParams mPackParams; PackPixelsParams *mQueuedPackCommand;
bool mDataModified; bool mDataModified;
}; };
...@@ -634,6 +637,7 @@ BufferStorage11::PackStorage11::PackStorage11(Renderer11 *renderer) ...@@ -634,6 +637,7 @@ BufferStorage11::PackStorage11::PackStorage11(Renderer11 *renderer)
mStagingTexture(NULL), mStagingTexture(NULL),
mTextureFormat(DXGI_FORMAT_UNKNOWN), mTextureFormat(DXGI_FORMAT_UNKNOWN),
mMemoryBuffer(NULL), mMemoryBuffer(NULL),
mQueuedPackCommand(NULL),
mDataModified(false) mDataModified(false)
{ {
} }
...@@ -642,6 +646,7 @@ BufferStorage11::PackStorage11::~PackStorage11() ...@@ -642,6 +646,7 @@ BufferStorage11::PackStorage11::~PackStorage11()
{ {
SafeRelease(mStagingTexture); SafeRelease(mStagingTexture);
SafeDeleteArray(mMemoryBuffer); SafeDeleteArray(mMemoryBuffer);
SafeDelete(mQueuedPackCommand);
} }
bool BufferStorage11::PackStorage11::copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset, bool BufferStorage11::PackStorage11::copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
...@@ -677,10 +682,8 @@ void *BufferStorage11::PackStorage11::map(GLbitfield access) ...@@ -677,10 +682,8 @@ void *BufferStorage11::PackStorage11::map(GLbitfield access)
// and if D3D packs the staging texture memory identically to how we would fill // and if D3D packs the staging texture memory identically to how we would fill
// the pack buffer according to the current pack state. // the pack buffer according to the current pack state.
ASSERT(mMemoryBuffer); flushQueuedPackCommand();
mRenderer->packPixels(mStagingTexture, mPackParams, mMemoryBuffer);
mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0); mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0);
return mMemoryBuffer; return mMemoryBuffer;
} }
...@@ -691,7 +694,8 @@ void BufferStorage11::PackStorage11::unmap() ...@@ -691,7 +694,8 @@ void BufferStorage11::PackStorage11::unmap()
void BufferStorage11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params) void BufferStorage11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params)
{ {
mPackParams = params; flushQueuedPackCommand();
mQueuedPackCommand = new PackPixelsParams(params);
D3D11_TEXTURE2D_DESC textureDesc; D3D11_TEXTURE2D_DESC textureDesc;
srcTexure->GetDesc(&textureDesc); srcTexure->GetDesc(&textureDesc);
...@@ -752,4 +756,15 @@ void BufferStorage11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT ...@@ -752,4 +756,15 @@ void BufferStorage11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT
immediateContext->CopySubresourceRegion(mStagingTexture, 0, 0, 0, 0, srcTexure, srcSubresource, &srcBox); immediateContext->CopySubresourceRegion(mStagingTexture, 0, 0, 0, 0, srcTexure, srcSubresource, &srcBox);
} }
void BufferStorage11::PackStorage11::flushQueuedPackCommand()
{
ASSERT(mMemoryBuffer);
if (mQueuedPackCommand)
{
mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer);
SafeDelete(mQueuedPackCommand);
}
}
} }
...@@ -141,3 +141,41 @@ TEST_F(ReadPixelsTest, pbo_with_other_target) ...@@ -141,3 +141,41 @@ TEST_F(ReadPixelsTest, pbo_with_other_target)
glUnmapBuffer(GL_ARRAY_BUFFER); glUnmapBuffer(GL_ARRAY_BUFFER);
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
TEST_F(ReadPixelsTest, pbo_with_existing_data)
{
// Clear backbuffer to red
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_GL_NO_ERROR();
// Read 16x16 region from red backbuffer to PBO
glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
// Clear backbuffer to green
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_GL_NO_ERROR();
// Read 16x16 region from green backbuffer to PBO at offset 16
glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(16));
GLvoid * mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
EXPECT_GL_NO_ERROR();
// Test pixel 0 is red (existing data)
EXPECT_EQ(255, dataPtr[0]);
EXPECT_EQ(0, dataPtr[1]);
EXPECT_EQ(0, dataPtr[2]);
EXPECT_EQ(255, dataPtr[3]);
// Test pixel 16 is green (new data)
EXPECT_EQ(0, dataPtr[16 * 4 + 0]);
EXPECT_EQ(255, dataPtr[16 * 4 + 1]);
EXPECT_EQ(0, dataPtr[16 * 4 + 2]);
EXPECT_EQ(255, dataPtr[16 * 4 + 3]);
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
EXPECT_GL_NO_ERROR();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment