Vulkan: Implement simple render-to-texture.
This was mostly working already, just needed to set up a few entry
points.
BUG=angleproject:2200
Change-Id: I9c13d6d4dd42f23c69a58e42e07e3e28877671a1
Reviewed-on: https://chromium-review.googlesource.com/734237
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index 9c8d155..2931e63 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -359,8 +359,7 @@
bool FramebufferVk::checkStatus(const gl::Context *context) const
{
- UNIMPLEMENTED();
- return bool();
+ return true;
}
void FramebufferVk::syncState(const gl::Context *context,
@@ -618,7 +617,6 @@
// Updated the cached image layout of the attachments in this FBO.
// For a default FBO, we need to call through to the WindowSurfaceVk
// TODO(jmadill): Iterate over all attachments.
- ASSERT(mBackbuffer);
RenderTargetVk *renderTarget = nullptr;
ANGLE_TRY(mState.getFirstColorAttachment()->getRenderTarget(context, &renderTarget));
renderTarget->image->updateLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp
index 9580e35..749733b 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp
@@ -533,6 +533,7 @@
outCaps->maxElementIndex = std::numeric_limits<GLuint>::max() - 1;
outCaps->maxFragmentUniformVectors = 8;
outCaps->maxVertexUniformVectors = 8;
+ outCaps->maxColorAttachments = 1;
// Enable this for simple buffer readback testing, but some functionality is missing.
// TODO(jmadill): Support full mapBufferRange extension.
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index 58c0626..28d9f64 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -150,6 +150,13 @@
ANGLE_TRY(mSampler.init(device, samplerInfo));
+ mRenderTarget.image = &mImage;
+ mRenderTarget.imageView = &mImageView;
+ mRenderTarget.format = &vkFormat;
+ mRenderTarget.extents = size;
+ mRenderTarget.samples = VK_SAMPLE_COUNT_1_BIT;
+ mRenderTarget.resource = this;
+
// Handle initial data.
// TODO(jmadill): Consider re-using staging texture.
if (pixels)
@@ -336,8 +343,10 @@
const gl::ImageIndex &imageIndex,
FramebufferAttachmentRenderTarget **rtOut)
{
- UNIMPLEMENTED();
- return gl::InternalError();
+ ASSERT(imageIndex.type == GL_TEXTURE_2D);
+ ASSERT(imageIndex.mipIndex == 0 && imageIndex.layerIndex == gl::ImageIndex::ENTIRE_LEVEL);
+ *rtOut = &mRenderTarget;
+ return gl::NoError();
}
void TextureVk::syncState(const gl::Texture::DirtyBits &dirtyBits)
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.h b/src/libANGLE/renderer/vulkan/TextureVk.h
index f2b6910..10be485 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.h
+++ b/src/libANGLE/renderer/vulkan/TextureVk.h
@@ -11,6 +11,7 @@
#define LIBANGLE_RENDERER_VULKAN_TEXTUREVK_H_
#include "libANGLE/renderer/TextureImpl.h"
+#include "libANGLE/renderer/vulkan/RenderTargetVk.h"
#include "libANGLE/renderer/vulkan/renderervk_utils.h"
namespace rx
@@ -120,6 +121,8 @@
vk::DeviceMemory mDeviceMemory;
vk::ImageView mImageView;
vk::Sampler mSampler;
+
+ RenderTargetVk mRenderTarget;
};
} // namespace rx
diff --git a/src/tests/gl_tests/SimpleOperationTest.cpp b/src/tests/gl_tests/SimpleOperationTest.cpp
index 8f0d4e8..7701ac4 100644
--- a/src/tests/gl_tests/SimpleOperationTest.cpp
+++ b/src/tests/gl_tests/SimpleOperationTest.cpp
@@ -494,6 +494,41 @@
EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
}
+// Tests rendering to a user framebuffer.
+TEST_P(SimpleOperationTest, RenderToTexture)
+{
+ constexpr int kSize = 16;
+
+ GLTexture texture;
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ ASSERT_GL_NO_ERROR();
+
+ GLFramebuffer framebuffer;
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
+ ASSERT_GL_NO_ERROR();
+ ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ glViewport(0, 0, kSize, kSize);
+
+ const std::string &vertexShader =
+ "attribute vec3 position;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(position, 1);\n"
+ "}";
+ const std::string &fragmentShader =
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = vec4(0, 1, 0, 1);\n"
+ "}";
+ ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
+ drawQuad(program, "position", 0.5f, 1.0f, true);
+ ASSERT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(SimpleOperationTest,
ES2_D3D9(),