Commit 20610901 by Luc Ferron Committed by Commit Bot

Vulkan: Implement Texture wrap modes and non-mipmapped filtering modes

Also added a test to validate we can change the filter mode between two draws successfully. Bug: angleproject:2478 Change-Id: I80730cdafc6bbdbf61839c6c8eb98d85f7423d92 Reviewed-on: https://chromium-review.googlesource.com/1020084 Commit-Queue: Luc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent c6a0618f
...@@ -215,7 +215,6 @@ gl::Error TextureVk::setImage(const gl::Context *context, ...@@ -215,7 +215,6 @@ gl::Error TextureVk::setImage(const gl::Context *context,
{ {
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
VkDevice device = contextVk->getDevice();
// TODO(jmadill): support multi-level textures. // TODO(jmadill): support multi-level textures.
if (index.getLevelIndex() != 0) if (index.getLevelIndex() != 0)
...@@ -243,33 +242,6 @@ gl::Error TextureVk::setImage(const gl::Context *context, ...@@ -243,33 +242,6 @@ gl::Error TextureVk::setImage(const gl::Context *context,
return gl::NoError(); return gl::NoError();
} }
if (!mSampler.valid())
{
// Create a simple sampler. Force basic parameter settings.
// TODO(jmadill): Sampler parameters.
VkSamplerCreateInfo samplerInfo;
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
samplerInfo.pNext = nullptr;
samplerInfo.flags = 0;
samplerInfo.magFilter = VK_FILTER_NEAREST;
samplerInfo.minFilter = VK_FILTER_NEAREST;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerInfo.mipLodBias = 0.0f;
samplerInfo.anisotropyEnable = VK_FALSE;
samplerInfo.maxAnisotropy = 1.0f;
samplerInfo.compareEnable = VK_FALSE;
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = 1.0f;
samplerInfo.borderColor = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
samplerInfo.unnormalizedCoordinates = VK_FALSE;
ANGLE_TRY(mSampler.init(device, samplerInfo));
}
// Create a new graph node to store image initialization commands. // Create a new graph node to store image initialization commands.
getNewWritingNode(renderer); getNewWritingNode(renderer);
...@@ -470,7 +442,42 @@ vk::Error TextureVk::ensureImageInitialized(RendererVk *renderer) ...@@ -470,7 +442,42 @@ vk::Error TextureVk::ensureImageInitialized(RendererVk *renderer)
gl::Error TextureVk::syncState(const gl::Context *context, const gl::Texture::DirtyBits &dirtyBits) gl::Error TextureVk::syncState(const gl::Context *context, const gl::Texture::DirtyBits &dirtyBits)
{ {
// TODO(jmadill): Texture sync state. if (dirtyBits.none() && mSampler.valid())
{
return gl::NoError();
}
ContextVk *contextVk = vk::GetImpl(context);
if (mSampler.valid())
{
RendererVk *renderer = contextVk->getRenderer();
renderer->releaseResource(*this, &mSampler);
}
const gl::SamplerState &samplerState = mState.getSamplerState();
// Create a simple sampler. Force basic parameter settings.
VkSamplerCreateInfo samplerInfo;
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
samplerInfo.pNext = nullptr;
samplerInfo.flags = 0;
samplerInfo.magFilter = gl_vk::GetFilter(samplerState.magFilter);
samplerInfo.minFilter = gl_vk::GetFilter(samplerState.minFilter);
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
samplerInfo.addressModeU = gl_vk::GetSamplerAddressMode(samplerState.wrapS);
samplerInfo.addressModeV = gl_vk::GetSamplerAddressMode(samplerState.wrapT);
samplerInfo.addressModeW = gl_vk::GetSamplerAddressMode(samplerState.wrapR);
samplerInfo.mipLodBias = 0.0f;
samplerInfo.anisotropyEnable = VK_FALSE;
samplerInfo.maxAnisotropy = 1.0f;
samplerInfo.compareEnable = VK_FALSE;
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = 1.0f;
samplerInfo.borderColor = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
samplerInfo.unnormalizedCoordinates = VK_FALSE;
ANGLE_TRY(mSampler.init(contextVk->getDevice(), samplerInfo));
return gl::NoError(); return gl::NoError();
} }
......
...@@ -1139,6 +1139,43 @@ void GarbageObject::destroy(VkDevice device) ...@@ -1139,6 +1139,43 @@ void GarbageObject::destroy(VkDevice device)
namespace gl_vk namespace gl_vk
{ {
VkFilter GetFilter(const GLenum filter)
{
switch (filter)
{
case GL_LINEAR_MIPMAP_LINEAR:
case GL_LINEAR_MIPMAP_NEAREST:
case GL_LINEAR:
return VK_FILTER_LINEAR;
case GL_NEAREST_MIPMAP_LINEAR:
case GL_NEAREST_MIPMAP_NEAREST:
case GL_NEAREST:
return VK_FILTER_NEAREST;
default:
UNIMPLEMENTED();
return VK_FILTER_MAX_ENUM;
}
}
VkSamplerAddressMode GetSamplerAddressMode(const GLenum wrap)
{
switch (wrap)
{
case GL_REPEAT:
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
case GL_MIRRORED_REPEAT:
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case GL_CLAMP_TO_BORDER:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
case GL_CLAMP_TO_EDGE:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
default:
UNIMPLEMENTED();
return VK_SAMPLER_ADDRESS_MODE_MAX_ENUM;
}
}
VkRect2D GetRect(const gl::Rectangle &source) VkRect2D GetRect(const gl::Rectangle &source)
{ {
return {{source.x, source.y}, return {{source.x, source.y},
......
...@@ -650,6 +650,8 @@ Error AllocateImageMemory(VkDevice device, ...@@ -650,6 +650,8 @@ Error AllocateImageMemory(VkDevice device,
namespace gl_vk namespace gl_vk
{ {
VkRect2D GetRect(const gl::Rectangle &source); VkRect2D GetRect(const gl::Rectangle &source);
VkFilter GetFilter(const GLenum filter);
VkSamplerAddressMode GetSamplerAddressMode(const GLenum wrap);
VkPrimitiveTopology GetPrimitiveTopology(GLenum mode); VkPrimitiveTopology GetPrimitiveTopology(GLenum mode);
VkCullModeFlags GetCullMode(const gl::RasterizerState &rasterState); VkCullModeFlags GetCullMode(const gl::RasterizerState &rasterState);
VkFrontFace GetFrontFace(GLenum frontFace); VkFrontFace GetFrontFace(GLenum frontFace);
......
...@@ -230,8 +230,9 @@ ...@@ -230,8 +230,9 @@
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.512x512_l8_mipmap = SKIP 2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.512x512_l8_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.512x512_rgb888_mipmap = SKIP 2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.512x512_rgb888_mipmap = SKIP
2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.512x512_rgba8888_mipmap = SKIP 2479 VULKAN : dEQP-GLES2.functional.texture.size.cube.512x512_rgba8888_mipmap = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.wrap.* = SKIP 2161 VULKAN : dEQP-GLES2.functional.texture.filtering.cube.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.filtering.* = SKIP 2161 VULKAN : dEQP-GLES2.functional.texture.filtering.nearest_mipmap_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.filtering.linear_mipmap_* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.mipmap.* = SKIP 2161 VULKAN : dEQP-GLES2.functional.texture.mipmap.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.specification.* = SKIP 2161 VULKAN : dEQP-GLES2.functional.texture.specification.* = SKIP
2161 VULKAN : dEQP-GLES2.functional.texture.completeness.* = SKIP 2161 VULKAN : dEQP-GLES2.functional.texture.completeness.* = SKIP
......
...@@ -1285,6 +1285,46 @@ TEST_P(SimpleStateChangeTest, DeleteTextureInUse) ...@@ -1285,6 +1285,46 @@ TEST_P(SimpleStateChangeTest, DeleteTextureInUse)
EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow); EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
} }
// Tests that modifying a texture parameter in-flight does not cause problems.
TEST_P(SimpleStateChangeTest, ChangeTextureFilterModeBetweenTwoDraws)
{
std::array<GLColor, 4> colors = {
{GLColor::black, GLColor::white, GLColor::black, GLColor::white}};
GLTexture tex;
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw to the left side of the window only with NEAREST.
glViewport(0, 0, getWindowWidth() / 2, getWindowHeight());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
draw2DTexturedQuad(0.5f, 1.0f, true);
// Draw to the right side of the window only with LINEAR.
glViewport(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
draw2DTexturedQuad(0.5f, 1.0f, true);
EXPECT_GL_NO_ERROR();
glViewport(0, 0, getWindowWidth(), getWindowHeight());
// The first half (left) should be only black followed by plain white.
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::black);
EXPECT_PIXEL_COLOR_EQ((getWindowWidth() / 2) - 3, 0, GLColor::white);
EXPECT_PIXEL_COLOR_EQ((getWindowWidth() / 2) - 4, 0, GLColor::white);
// The second half (right) should be a gradient so we shouldn't find plain black/white in the
// middle.
EXPECT_NE(angle::ReadColor((getWindowWidth() / 4) * 3, 0), GLColor::black);
EXPECT_NE(angle::ReadColor((getWindowWidth() / 4) * 3, 0), GLColor::white);
}
// Tests that redefining an in-flight Texture does not affect the in-flight resource. // Tests that redefining an in-flight Texture does not affect the in-flight resource.
TEST_P(SimpleStateChangeTest, RedefineTextureInUse) TEST_P(SimpleStateChangeTest, RedefineTextureInUse)
{ {
......
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