Commit 5164b797 by Luc Ferron Committed by Commit Bot

Vulkan: Support GL_LUMINANCE and GL_LUMINANCE_ALPHA

The dEQP tests cannot be turned on before immediate data for drawElements is supported. Bug:angleproject:2364 Change-Id: Id5fd6fbc0c74f2dba08341f36ca0091d540f4ed8 Reviewed-on: https://chromium-review.googlesource.com/951402Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Luc Ferron <lucferron@chromium.org>
parent ed8b4919
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
# found in the LICENSE file. # found in the LICENSE file.
# #
# gen_load_functions_table.py: # gen_load_functions_table.py:
# Code generation for the load function tables used for texture formats # Code generation for the load function tables used for texture formats. These mappings are
# not renderer specific. The mappings are done from the GL internal format, to the ANGLE
# format ID, and then for the specific data type.
# #
import json, sys import json, sys
......
...@@ -113,7 +113,10 @@ ...@@ -113,7 +113,10 @@
} }
}, },
"GL_LUMINANCE8_EXT": { "GL_LUMINANCE8_EXT": {
"NONE": { "R8_UNORM": {
"GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 1>"
},
"R8G8B8A8_UNORM": {
"GL_UNSIGNED_BYTE": "LoadL8ToRGBA8" "GL_UNSIGNED_BYTE": "LoadL8ToRGBA8"
} }
}, },
...@@ -166,7 +169,10 @@ ...@@ -166,7 +169,10 @@
} }
}, },
"GL_LUMINANCE8_ALPHA8_EXT": { "GL_LUMINANCE8_ALPHA8_EXT": {
"NONE": { "R8G8_UNORM": {
"GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 2>"
},
"R8G8B8A8_UNORM": {
"GL_UNSIGNED_BYTE": "LoadLA8ToRGBA8" "GL_UNSIGNED_BYTE": "LoadLA8ToRGBA8"
} }
}, },
......
...@@ -648,7 +648,7 @@ LoadImageFunctionInfo LUMINANCE32F_EXT_to_default(GLenum type) ...@@ -648,7 +648,7 @@ LoadImageFunctionInfo LUMINANCE32F_EXT_to_default(GLenum type)
} }
} }
LoadImageFunctionInfo LUMINANCE8_ALPHA8_EXT_to_default(GLenum type) LoadImageFunctionInfo LUMINANCE8_ALPHA8_EXT_to_R8G8B8A8_UNORM(GLenum type)
{ {
switch (type) switch (type)
{ {
...@@ -660,7 +660,19 @@ LoadImageFunctionInfo LUMINANCE8_ALPHA8_EXT_to_default(GLenum type) ...@@ -660,7 +660,19 @@ LoadImageFunctionInfo LUMINANCE8_ALPHA8_EXT_to_default(GLenum type)
} }
} }
LoadImageFunctionInfo LUMINANCE8_EXT_to_default(GLenum type) LoadImageFunctionInfo LUMINANCE8_ALPHA8_EXT_to_R8G8_UNORM(GLenum type)
{
switch (type)
{
case GL_UNSIGNED_BYTE:
return LoadImageFunctionInfo(LoadToNative<GLubyte, 2>, false);
default:
UNREACHABLE();
return LoadImageFunctionInfo(UnreachableLoadFunction, true);
}
}
LoadImageFunctionInfo LUMINANCE8_EXT_to_R8G8B8A8_UNORM(GLenum type)
{ {
switch (type) switch (type)
{ {
...@@ -672,6 +684,18 @@ LoadImageFunctionInfo LUMINANCE8_EXT_to_default(GLenum type) ...@@ -672,6 +684,18 @@ LoadImageFunctionInfo LUMINANCE8_EXT_to_default(GLenum type)
} }
} }
LoadImageFunctionInfo LUMINANCE8_EXT_to_R8_UNORM(GLenum type)
{
switch (type)
{
case GL_UNSIGNED_BYTE:
return LoadImageFunctionInfo(LoadToNative<GLubyte, 1>, false);
default:
UNREACHABLE();
return LoadImageFunctionInfo(UnreachableLoadFunction, true);
}
}
LoadImageFunctionInfo LUMINANCE_ALPHA_to_R16G16B16A16_FLOAT(GLenum type) LoadImageFunctionInfo LUMINANCE_ALPHA_to_R16G16B16A16_FLOAT(GLenum type)
{ {
switch (type) switch (type)
...@@ -1867,9 +1891,31 @@ LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, Format::ID angleForma ...@@ -1867,9 +1891,31 @@ LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, Format::ID angleForma
case GL_LUMINANCE32F_EXT: case GL_LUMINANCE32F_EXT:
return LUMINANCE32F_EXT_to_default; return LUMINANCE32F_EXT_to_default;
case GL_LUMINANCE8_ALPHA8_EXT: case GL_LUMINANCE8_ALPHA8_EXT:
return LUMINANCE8_ALPHA8_EXT_to_default; {
switch (angleFormat)
{
case Format::ID::R8G8B8A8_UNORM:
return LUMINANCE8_ALPHA8_EXT_to_R8G8B8A8_UNORM;
case Format::ID::R8G8_UNORM:
return LUMINANCE8_ALPHA8_EXT_to_R8G8_UNORM;
default:
break;
}
break;
}
case GL_LUMINANCE8_EXT: case GL_LUMINANCE8_EXT:
return LUMINANCE8_EXT_to_default; {
switch (angleFormat)
{
case Format::ID::R8G8B8A8_UNORM:
return LUMINANCE8_EXT_to_R8G8B8A8_UNORM;
case Format::ID::R8_UNORM:
return LUMINANCE8_EXT_to_R8_UNORM;
default:
break;
}
break;
}
case GL_LUMINANCE_ALPHA: case GL_LUMINANCE_ALPHA:
{ {
switch (angleFormat) switch (angleFormat)
......
...@@ -17,6 +17,57 @@ ...@@ -17,6 +17,57 @@
namespace rx namespace rx
{ {
namespace
{
VkComponentSwizzle ConvertSwizzleStateToVkSwizzle(const GLenum swizzle)
{
switch (swizzle)
{
case GL_ALPHA:
return VK_COMPONENT_SWIZZLE_A;
case GL_RED:
return VK_COMPONENT_SWIZZLE_R;
case GL_GREEN:
return VK_COMPONENT_SWIZZLE_G;
case GL_BLUE:
return VK_COMPONENT_SWIZZLE_B;
case GL_ZERO:
return VK_COMPONENT_SWIZZLE_ZERO;
case GL_ONE:
return VK_COMPONENT_SWIZZLE_ONE;
default:
UNREACHABLE();
return VK_COMPONENT_SWIZZLE_IDENTITY;
}
}
void FillComponentsSwizzleParameters(GLenum internalFormat,
const gl::SwizzleState &swizzleState,
VkComponentMapping *componentMapping)
{
switch (internalFormat)
{
case GL_LUMINANCE:
componentMapping->r = ConvertSwizzleStateToVkSwizzle(swizzleState.swizzleRed);
componentMapping->g = ConvertSwizzleStateToVkSwizzle(swizzleState.swizzleRed);
componentMapping->b = ConvertSwizzleStateToVkSwizzle(swizzleState.swizzleRed);
componentMapping->a = ConvertSwizzleStateToVkSwizzle(swizzleState.swizzleAlpha);
break;
case GL_LUMINANCE_ALPHA:
componentMapping->r = ConvertSwizzleStateToVkSwizzle(swizzleState.swizzleRed);
componentMapping->g = ConvertSwizzleStateToVkSwizzle(swizzleState.swizzleRed);
componentMapping->b = ConvertSwizzleStateToVkSwizzle(swizzleState.swizzleRed);
componentMapping->a = ConvertSwizzleStateToVkSwizzle(swizzleState.swizzleGreen);
break;
default:
componentMapping->r = ConvertSwizzleStateToVkSwizzle(swizzleState.swizzleRed);
componentMapping->g = ConvertSwizzleStateToVkSwizzle(swizzleState.swizzleGreen);
componentMapping->b = ConvertSwizzleStateToVkSwizzle(swizzleState.swizzleBlue);
componentMapping->a = ConvertSwizzleStateToVkSwizzle(swizzleState.swizzleAlpha);
break;
}
}
} // anonymous namespace
TextureVk::TextureVk(const gl::TextureState &state) : TextureImpl(state) TextureVk::TextureVk(const gl::TextureState &state) : TextureImpl(state)
{ {
...@@ -128,16 +179,15 @@ gl::Error TextureVk::setImage(const gl::Context *context, ...@@ -128,16 +179,15 @@ gl::Error TextureVk::setImage(const gl::Context *context,
viewInfo.image = mImage.getHandle(); viewInfo.image = mImage.getHandle();
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = vkFormat.vkTextureFormat; viewInfo.format = vkFormat.vkTextureFormat;
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
viewInfo.subresourceRange.baseMipLevel = 0; viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = 1; viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0; viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = 1; viewInfo.subresourceRange.layerCount = 1;
FillComponentsSwizzleParameters(internalFormat, mState.getSwizzleState(),
&viewInfo.components);
ANGLE_TRY(mImageView.init(device, viewInfo)); ANGLE_TRY(mImageView.init(device, viewInfo));
// TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361 // TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361
......
...@@ -27,7 +27,7 @@ template_table_autogen_cpp = """// GENERATED FILE - DO NOT EDIT. ...@@ -27,7 +27,7 @@ template_table_autogen_cpp = """// GENERATED FILE - DO NOT EDIT.
// {out_file_name}: // {out_file_name}:
// Queries for full Vulkan format information based on GL format. // Queries for full Vulkan format information based on GL format.
#include "libANGLE/renderer/vulkan/formatutilsvk.h" #include "libANGLE/renderer/vulkan/vk_format_utils.h"
#include "image_util/copyimage.h" #include "image_util/copyimage.h"
#include "image_util/generatemip.h" #include "image_util/generatemip.h"
...@@ -90,21 +90,20 @@ def gen_format_case(angle, internal_format, vk_map): ...@@ -90,21 +90,20 @@ def gen_format_case(angle, internal_format, vk_map):
if isinstance(vk_format_name, dict): if isinstance(vk_format_name, dict):
info = vk_format_name info = vk_format_name
vk_format_name = info["native"]
if "buffer" in info: if "buffer" in info:
buffer_format_id = info["buffer"] buffer_format_id = info["buffer"]
vk_buffer_format = vk_map[buffer_format_id] vk_buffer_format = vk_map[buffer_format_id]
assert(not isinstance(vk_buffer_format, dict)) assert(not isinstance(vk_buffer_format, dict))
else: else:
vk_buffer_format = vk_format_name vk_buffer_format = info["native"]
if "texture" in info: if "texture" in info:
texture_format_id = info["texture"] texture_format_id = info["texture"]
vk_texture_format = vk_map[texture_format_id] vk_texture_format = vk_map[texture_format_id]
assert(not isinstance(vk_texture_format, dict)) assert(not isinstance(vk_texture_format, dict))
else: else:
vk_texture_format = vk_format_name vk_texture_format = info["native"]
initializer = angle_format.get_internal_format_initializer( initializer = angle_format.get_internal_format_initializer(
internal_format, texture_format_id) internal_format, texture_format_id)
......
...@@ -98,6 +98,14 @@ ...@@ -98,6 +98,14 @@
"R64G64B64A64_UINT": "VK_FORMAT_R64G64B64A64_UINT", "R64G64B64A64_UINT": "VK_FORMAT_R64G64B64A64_UINT",
"R64G64B64A64_SINT": "VK_FORMAT_R64G64B64A64_SINT", "R64G64B64A64_SINT": "VK_FORMAT_R64G64B64A64_SINT",
"R64G64B64A64_FLOAT": "VK_FORMAT_R64G64B64A64_SFLOAT", "R64G64B64A64_FLOAT": "VK_FORMAT_R64G64B64A64_SFLOAT",
"L8_UNORM": {
"buffer": "NONE",
"texture": "R8_UNORM"
},
"L8A8_UNORM": {
"buffer": "NONE",
"texture": "R8G8_UNORM"
},
"B10G11R11_UFLOAT_PACK32": "VK_FORMAT_B10G11R11_UFLOAT_PACK32", "B10G11R11_UFLOAT_PACK32": "VK_FORMAT_B10G11R11_UFLOAT_PACK32",
"E5B9G9R9_UFLOAT_PACK32": "VK_FORMAT_E5B9G9R9_UFLOAT_PACK32", "E5B9G9R9_UFLOAT_PACK32": "VK_FORMAT_E5B9G9R9_UFLOAT_PACK32",
"D16_UNORM": "VK_FORMAT_D16_UNORM", "D16_UNORM": "VK_FORMAT_D16_UNORM",
......
...@@ -625,12 +625,26 @@ void Format::initialize(VkPhysicalDevice physicalDevice, const angle::Format &an ...@@ -625,12 +625,26 @@ void Format::initialize(VkPhysicalDevice physicalDevice, const angle::Format &an
break; break;
case angle::Format::ID::L8A8_UNORM: case angle::Format::ID::L8A8_UNORM:
// This format is not implemented in Vulkan. {
internalFormat = GL_LUMINANCE8_ALPHA8_EXT;
textureFormatID = angle::Format::ID::R8G8_UNORM;
vkTextureFormat = VK_FORMAT_R8G8_UNORM;
bufferFormatID = angle::Format::ID::NONE;
vkBufferFormat = VK_FORMAT_UNDEFINED;
dataInitializerFunction = nullptr;
break; break;
}
case angle::Format::ID::L8_UNORM: case angle::Format::ID::L8_UNORM:
// This format is not implemented in Vulkan. {
internalFormat = GL_LUMINANCE8_EXT;
textureFormatID = angle::Format::ID::R8_UNORM;
vkTextureFormat = VK_FORMAT_R8_UNORM;
bufferFormatID = angle::Format::ID::NONE;
vkBufferFormat = VK_FORMAT_UNDEFINED;
dataInitializerFunction = nullptr;
break; break;
}
case angle::Format::ID::NONE: case angle::Format::ID::NONE:
// This format is not implemented in Vulkan. // This format is not implemented in Vulkan.
......
...@@ -1237,6 +1237,10 @@ TEST_P(Texture2DTest, QueryBinding) ...@@ -1237,6 +1237,10 @@ TEST_P(Texture2DTest, QueryBinding)
TEST_P(Texture2DTest, ZeroSizedUploads) TEST_P(Texture2DTest, ZeroSizedUploads)
{ {
// TODO(lucferron): Enable this test on Vulkan after this bug is done.
// http://anglebug.com/2392
ANGLE_SKIP_TEST_IF(IsVulkan());
glBindTexture(GL_TEXTURE_2D, mTexture2D); glBindTexture(GL_TEXTURE_2D, mTexture2D);
EXPECT_GL_ERROR(GL_NO_ERROR); EXPECT_GL_ERROR(GL_NO_ERROR);
...@@ -1570,6 +1574,9 @@ TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA) ...@@ -1570,6 +1574,9 @@ TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA)
// Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly handles GL_ALPHA // Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly handles GL_ALPHA
TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE) TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
{ {
// TODO(lucferron): DIRTY_BIT_UNPACK_STATE isn't implemented on Vulkan yet.
ANGLE_SKIP_TEST_IF(IsVulkan());
const int npotTexSize = 5; const int npotTexSize = 5;
const int potTexSize = 4; // Should be less than npotTexSize const int potTexSize = 4; // Should be less than npotTexSize
GLuint tex2D; GLuint tex2D;
...@@ -1658,6 +1665,10 @@ TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE) ...@@ -1658,6 +1665,10 @@ TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE)
// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect. // ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect.
TEST_P(Texture2DTest, NPOTSubImageParameters) TEST_P(Texture2DTest, NPOTSubImageParameters)
{ {
// TODO(lucferron): Generate mipmap on vulkan isn't implemented yet. Re-enable this when it
// is.
ANGLE_SKIP_TEST_IF(IsVulkan());
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture2D); glBindTexture(GL_TEXTURE_2D, mTexture2D);
...@@ -2379,8 +2390,10 @@ TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1) ...@@ -2379,8 +2390,10 @@ TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1)
// When sampling a texture without an alpha channel, "1" is returned as the alpha value. // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
// ES 3.0.4 table 3.24 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3, TextureLuminanceImplicitAlpha1) TEST_P(Texture2DTest, TextureLuminanceImplicitAlpha1)
{ {
setUpProgram();
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture2D); glBindTexture(GL_TEXTURE_2D, mTexture2D);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
...@@ -2391,10 +2404,50 @@ TEST_P(Texture2DTestES3, TextureLuminanceImplicitAlpha1) ...@@ -2391,10 +2404,50 @@ TEST_P(Texture2DTestES3, TextureLuminanceImplicitAlpha1)
EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); EXPECT_PIXEL_ALPHA_EQ(0, 0, 255);
} }
// Validate that every component of the pixel will be equal to the luminance value we've set
// and that the alpha channel will be 1 (or 255 to be exact).
TEST_P(Texture2DTest, TextureLuminanceRGBSame)
{
setUpProgram();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture2D);
uint8_t pixel = 50;
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pixel);
EXPECT_GL_NO_ERROR();
drawQuad(mProgram, "position", 0.5f);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel, pixel, pixel, 255));
}
// Validate that every component of the pixel will be equal to the luminance value we've set
// and that the alpha channel will be the second component.
TEST_P(Texture2DTest, TextureLuminanceAlphaRGBSame)
{
setUpProgram();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture2D);
uint8_t pixel[] = {50, 25};
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE, pixel);
EXPECT_GL_NO_ERROR();
drawQuad(mProgram, "position", 0.5f);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(pixel[0], pixel[0], pixel[0], pixel[1]));
}
// When sampling a texture without an alpha channel, "1" is returned as the alpha value. // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
// ES 3.0.4 table 3.24 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3, TextureLuminance32ImplicitAlpha1) TEST_P(Texture2DTest, TextureLuminance32ImplicitAlpha1)
{ {
// TODO(lucferron): Enable Vulkan when we implement float support in ES3.0.
ANGLE_SKIP_TEST_IF(IsVulkan() || IsD3D9());
setUpProgram();
if (extensionEnabled("GL_OES_texture_float")) if (extensionEnabled("GL_OES_texture_float"))
{ {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
...@@ -2410,10 +2463,15 @@ TEST_P(Texture2DTestES3, TextureLuminance32ImplicitAlpha1) ...@@ -2410,10 +2463,15 @@ TEST_P(Texture2DTestES3, TextureLuminance32ImplicitAlpha1)
// When sampling a texture without an alpha channel, "1" is returned as the alpha value. // When sampling a texture without an alpha channel, "1" is returned as the alpha value.
// ES 3.0.4 table 3.24 // ES 3.0.4 table 3.24
TEST_P(Texture2DTestES3, TextureLuminance16ImplicitAlpha1) TEST_P(Texture2DTest, TextureLuminance16ImplicitAlpha1)
{ {
// TODO(lucferron): Enable Vulkan when we implement float support in ES3.0.
ANGLE_SKIP_TEST_IF(IsVulkan() || IsD3D9());
if (extensionEnabled("GL_OES_texture_half_float")) if (extensionEnabled("GL_OES_texture_half_float"))
{ {
setUpProgram();
ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsOpenGLES()); ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsOpenGLES());
// TODO(ynovikov): re-enable once root cause of http://anglebug.com/1420 is fixed // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1420 is fixed
...@@ -3677,7 +3735,8 @@ ANGLE_INSTANTIATE_TEST(Texture2DTest, ...@@ -3677,7 +3735,8 @@ ANGLE_INSTANTIATE_TEST(Texture2DTest,
ES2_D3D11(), ES2_D3D11(),
ES2_D3D11_FL9_3(), ES2_D3D11_FL9_3(),
ES2_OPENGL(), ES2_OPENGL(),
ES2_OPENGLES()); ES2_OPENGLES(),
ES2_VULKAN());
ANGLE_INSTANTIATE_TEST(TextureCubeTest, ANGLE_INSTANTIATE_TEST(TextureCubeTest,
ES2_D3D9(), ES2_D3D9(),
ES2_D3D11(), ES2_D3D11(),
......
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