Commit 5fedd017 by Jamie Madill

Implement copies from pack buffers to native buffers.

Full support for using pack buffers as vertex buffers or other binding points requires us to copy through the staging buffer. BUG=angle:511 Change-Id: Ife0f5390a1a83dfbe0fa0b19db72f3a8b82b6b83 Reviewed-on: https://chromium-review.googlesource.com/198435Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 14764a09
...@@ -82,6 +82,7 @@ class BufferStorage11::TypedBufferStorage11 ...@@ -82,6 +82,7 @@ class BufferStorage11::TypedBufferStorage11
DataRevision getDataRevision() const { return mRevision; } DataRevision getDataRevision() const { return mRevision; }
BufferUsage getUsage() const { return mUsage; } BufferUsage getUsage() const { return mUsage; }
size_t getSize() const { return mBufferSize; } size_t getSize() const { return mBufferSize; }
bool isMappable() const { return (mUsage == BUFFER_USAGE_STAGING || mUsage == BUFFER_USAGE_PIXEL_PACK); }
void setDataRevision(DataRevision rev) { mRevision = rev; } void setDataRevision(DataRevision rev) { mRevision = rev; }
...@@ -274,6 +275,17 @@ void BufferStorage11::copyData(BufferStorage* sourceStorage, size_t size, size_t ...@@ -274,6 +275,17 @@ void BufferStorage11::copyData(BufferStorage* sourceStorage, size_t size, size_t
TypedBufferStorage11 *source = sourceStorage11->getLatestStorage(); TypedBufferStorage11 *source = sourceStorage11->getLatestStorage();
if (source && dest) if (source && dest)
{ {
// If copying to/from a pixel pack buffer, we must have a staging or
// pack buffer partner, because other native buffers can't be mapped
if (dest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !source->isMappable())
{
source = sourceStorage11->getStagingBuffer();
}
else if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK && !dest->isMappable())
{
dest = getStagingBuffer();
}
dest->copyFromStorage(source, sourceOffset, size, destOffset); dest->copyFromStorage(source, sourceOffset, size, destOffset);
dest->setDataRevision(dest->getDataRevision() + 1); dest->setDataRevision(dest->getDataRevision() + 1);
} }
...@@ -433,6 +445,18 @@ BufferStorage11::TypedBufferStorage11 *BufferStorage11::getStorage(BufferUsage u ...@@ -433,6 +445,18 @@ BufferStorage11::TypedBufferStorage11 *BufferStorage11::getStorage(BufferUsage u
TypedBufferStorage11 *latestBuffer = getLatestStorage(); TypedBufferStorage11 *latestBuffer = getLatestStorage();
if (latestBuffer && latestBuffer->getDataRevision() > directBuffer->getDataRevision()) if (latestBuffer && latestBuffer->getDataRevision() > directBuffer->getDataRevision())
{ {
// if copying from a pack buffer to a non-staging native buffer, we must first
// copy through the staging buffer, because other native buffers can't be mapped
if (latestBuffer->getUsage() == BUFFER_USAGE_PIXEL_PACK && !directBuffer->isMappable())
{
NativeBuffer11 *stagingBuffer = getStagingBuffer();
stagingBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0);
directBuffer->setDataRevision(latestBuffer->getDataRevision());
latestBuffer = stagingBuffer;
}
// if copyFromStorage returns true, the D3D buffer has been recreated // if copyFromStorage returns true, the D3D buffer has been recreated
// and we should update our serial // and we should update our serial
if (directBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0)) if (directBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0))
......
...@@ -240,3 +240,56 @@ TEST_F(ReadPixelsTest, pbo_and_sub_data_offset) ...@@ -240,3 +240,56 @@ TEST_F(ReadPixelsTest, pbo_and_sub_data_offset)
glUnmapBuffer(GL_ARRAY_BUFFER); glUnmapBuffer(GL_ARRAY_BUFFER);
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
TEST_F(ReadPixelsTest, draw_with_pbo)
{
unsigned char data[4] = { 1, 2, 3, 4 };
glBindTexture(GL_TEXTURE_2D, mTexture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
EXPECT_GL_NO_ERROR();
// glReadBuffer(GL_COLOR_ATTACHMENT0); // FIXME: currently UNIMPLEMENTED
glBindFramebuffer(GL_READ_FRAMEBUFFER, mFBO);
EXPECT_GL_NO_ERROR();
glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
EXPECT_GL_NO_ERROR();
float positionData[] = { 0.5f, 0.5f };
glUseProgram(mProgram);
glViewport(0, 0, 1, 1);
glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, 1 * 2 * 4, positionData);
EXPECT_GL_NO_ERROR();
GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
EXPECT_NE(-1, positionLocation);
GLint testLocation = glGetAttribLocation(mProgram, "aTest");
EXPECT_NE(-1, testLocation);
glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(positionLocation);
EXPECT_GL_NO_ERROR();
glBindBuffer(GL_ARRAY_BUFFER, mPBO);
glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
glEnableVertexAttribArray(testLocation);
EXPECT_GL_NO_ERROR();
glDrawArrays(GL_POINTS, 0, 1);
EXPECT_GL_NO_ERROR();
memset(data, 0, 4);
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(1, data[0]);
EXPECT_EQ(2, data[1]);
EXPECT_EQ(3, data[2]);
EXPECT_EQ(4, data[3]);
}
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