зеркало из https://github.com/AvaloniaUI/angle.git
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/198435 Reviewed-by: Shannon Woods <shannonwoods@chromium.org> Tested-by: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Родитель
14764a0928
Коммит
5fedd0174b
|
@ -82,6 +82,7 @@ class BufferStorage11::TypedBufferStorage11
|
|||
DataRevision getDataRevision() const { return mRevision; }
|
||||
BufferUsage getUsage() const { return mUsage; }
|
||||
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; }
|
||||
|
||||
|
@ -274,6 +275,17 @@ void BufferStorage11::copyData(BufferStorage* sourceStorage, size_t size, size_t
|
|||
TypedBufferStorage11 *source = sourceStorage11->getLatestStorage();
|
||||
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->setDataRevision(dest->getDataRevision() + 1);
|
||||
}
|
||||
|
@ -433,6 +445,18 @@ BufferStorage11::TypedBufferStorage11 *BufferStorage11::getStorage(BufferUsage u
|
|||
TypedBufferStorage11 *latestBuffer = getLatestStorage();
|
||||
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
|
||||
// and we should update our serial
|
||||
if (directBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0))
|
||||
|
|
|
@ -240,3 +240,56 @@ TEST_F(ReadPixelsTest, pbo_and_sub_data_offset)
|
|||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
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]);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче