Commit 5b18f487 by Jamie Madill Committed by Commit Bot

Vulkan: Implement basic TexSubImage2D.

This also adds a test for updating a Texture that is in-use. This will ensure our Texture updates occur at the right time when we're implementing command re-ordering. Bug: angleproject:2264 Bug: angleproject:2200 Change-Id: Id6040d7238eca031e3cc7b27564d8ea815bf3d73 Reviewed-on: https://chromium-review.googlesource.com/801031 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org>
parent 37584b36
...@@ -180,6 +180,38 @@ gl::Error TextureVk::setImage(const gl::Context *context, ...@@ -180,6 +180,38 @@ gl::Error TextureVk::setImage(const gl::Context *context,
// TODO(jmadill): Consider re-using staging texture. // TODO(jmadill): Consider re-using staging texture.
if (pixels) if (pixels)
{ {
ANGLE_TRY(setSubImageImpl(contextVk, formatInfo, unpack, type, pixels));
}
return gl::NoError();
}
gl::Error TextureVk::setSubImage(const gl::Context *context,
GLenum target,
size_t level,
const gl::Box &area,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
const uint8_t *pixels)
{
ContextVk *contextVk = vk::GetImpl(context);
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format, type);
ANGLE_TRY(setSubImageImpl(contextVk, formatInfo, unpack, type, pixels));
return gl::NoError();
}
gl::Error TextureVk::setSubImageImpl(ContextVk *contextVk,
const gl::InternalFormat &formatInfo,
const gl::PixelUnpackState &unpack,
GLenum type,
const uint8_t *pixels)
{
RendererVk *renderer = contextVk->getRenderer();
VkDevice device = renderer->getDevice();
const gl::Extents &size = mRenderTarget.extents;
const vk::Format &vkFormat = *mRenderTarget.format;
vk::StagingImage stagingImage; vk::StagingImage stagingImage;
ANGLE_TRY(renderer->createStagingImage(TextureDimension::TEX_2D, vkFormat, size, ANGLE_TRY(renderer->createStagingImage(TextureDimension::TEX_2D, vkFormat, size,
vk::StagingUsage::Write, &stagingImage)); vk::StagingUsage::Write, &stagingImage));
...@@ -190,8 +222,7 @@ gl::Error TextureVk::setImage(const gl::Context *context, ...@@ -190,8 +222,7 @@ gl::Error TextureVk::setImage(const gl::Context *context,
inputRowPitch); inputRowPitch);
GLuint inputDepthPitch = 0; GLuint inputDepthPitch = 0;
ANGLE_TRY_RESULT( ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(size.height, unpack.imageHeight, inputRowPitch),
formatInfo.computeDepthPitch(size.height, unpack.imageHeight, inputRowPitch),
inputDepthPitch); inputDepthPitch);
// TODO(jmadill): skip images for 3D Textures. // TODO(jmadill): skip images for 3D Textures.
...@@ -238,9 +269,9 @@ gl::Error TextureVk::setImage(const gl::Context *context, ...@@ -238,9 +269,9 @@ gl::Error TextureVk::setImage(const gl::Context *context,
stagingImage.getImage().changeLayoutWithStages( stagingImage.getImage().changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer); VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
mImage.changeLayoutWithStages( mImage.changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer); VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
gl::Box wholeRegion(0, 0, 0, size.width, size.height, size.depth); gl::Box wholeRegion(0, 0, 0, size.width, size.height, size.depth);
commandBuffer->copySingleImage(stagingImage.getImage(), mImage, wholeRegion, commandBuffer->copySingleImage(stagingImage.getImage(), mImage, wholeRegion,
...@@ -248,24 +279,9 @@ gl::Error TextureVk::setImage(const gl::Context *context, ...@@ -248,24 +279,9 @@ gl::Error TextureVk::setImage(const gl::Context *context,
// TODO(jmadill): Re-use staging images. // TODO(jmadill): Re-use staging images.
renderer->releaseObject(renderer->getCurrentQueueSerial(), &stagingImage); renderer->releaseObject(renderer->getCurrentQueueSerial(), &stagingImage);
}
return gl::NoError(); return gl::NoError();
} }
gl::Error TextureVk::setSubImage(const gl::Context *context,
GLenum target,
size_t level,
const gl::Box &area,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
const uint8_t *pixels)
{
UNIMPLEMENTED();
return gl::InternalError();
}
gl::Error TextureVk::setCompressedImage(const gl::Context *context, gl::Error TextureVk::setCompressedImage(const gl::Context *context,
GLenum target, GLenum target,
size_t level, size_t level,
......
...@@ -116,6 +116,12 @@ class TextureVk : public TextureImpl, public ResourceVk ...@@ -116,6 +116,12 @@ class TextureVk : public TextureImpl, public ResourceVk
const vk::Sampler &getSampler() const; const vk::Sampler &getSampler() const;
private: private:
gl::Error setSubImageImpl(ContextVk *contextVk,
const gl::InternalFormat &formatInfo,
const gl::PixelUnpackState &unpack,
GLenum type,
const uint8_t *pixels);
// TODO(jmadill): support a more flexible storage back-end. // TODO(jmadill): support a more flexible storage back-end.
vk::Image mImage; vk::Image mImage;
vk::DeviceMemory mDeviceMemory; vk::DeviceMemory mDeviceMemory;
......
...@@ -950,6 +950,44 @@ TEST_P(SimpleStateChangeTest, RedefineTextureInUse) ...@@ -950,6 +950,44 @@ TEST_P(SimpleStateChangeTest, RedefineTextureInUse)
EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::white); EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::white);
} }
// Test updating a Texture's contents while in use by GL works as expected.
TEST_P(SimpleStateChangeTest, UpdateTextureInUse)
{
std::array<GLColor, 4> rgby = {{GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
GLTexture tex;
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgby.data());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Draw RGBY to the Framebuffer. The texture is now in-use by GL.
draw2DTexturedQuad(0.5f, 1.0f, true);
// Update the texture to be YBGR, while the Texture is in-use. Should not affect the draw.
std::array<GLColor, 4> ybgr = {{GLColor::yellow, GLColor::blue, GLColor::green, GLColor::red}};
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, ybgr.data());
ASSERT_GL_NO_ERROR();
// Check the Framebuffer. The draw call should have completed with the original RGBY data.
int w = getWindowWidth() - 2;
int h = getWindowHeight() - 2;
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
// Draw again to the Framebuffer. The second draw call should use the updated YBGR data.
draw2DTexturedQuad(0.5f, 1.0f, true);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::green);
EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::red);
ASSERT_GL_NO_ERROR();
}
const char kSolidColorVertexShader[] = R"(attribute vec2 position; const char kSolidColorVertexShader[] = R"(attribute vec2 position;
void main() void main()
{ {
......
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