Commit 21b786b1 by Jamie Madill Committed by Commit Bot

ES3: Make copy conversion set a static switch.

This removes the global std::set initialization. BUG=angleproject:1389 BUG=angleproject:1459 Change-Id: I6a7f4211905ea4a83e0e2337977e2f6fb375a7dd Reviewed-on: https://chromium-review.googlesource.com/405368Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent b0817d17
{
"From ES 3.0.1 spec, table 3.15":
[
[ "GL_ALPHA", "GL_RGBA" ],
[ "GL_LUMINANCE", "GL_RED" ],
[ "GL_LUMINANCE", "GL_RG" ],
[ "GL_LUMINANCE", "GL_RGB" ],
[ "GL_LUMINANCE", "GL_RGBA" ],
[ "GL_LUMINANCE_ALPHA", "GL_RGBA" ],
[ "GL_RED", "GL_RED" ],
[ "GL_RED", "GL_RG" ],
[ "GL_RED", "GL_RGB" ],
[ "GL_RED", "GL_RGBA" ],
[ "GL_RG", "GL_RG" ],
[ "GL_RG", "GL_RGB" ],
[ "GL_RG", "GL_RGBA" ],
[ "GL_RGB", "GL_RGB" ],
[ "GL_RGB", "GL_RGBA" ],
[ "GL_RGBA", "GL_RGBA" ]
],
"Necessary for ANGLE back-buffers":
[
[ "GL_ALPHA", "GL_BGRA_EXT" ],
[ "GL_LUMINANCE", "GL_BGRA_EXT" ],
[ "GL_LUMINANCE_ALPHA", "GL_BGRA_EXT" ],
[ "GL_RED", "GL_BGRA_EXT" ],
[ "GL_RG", "GL_BGRA_EXT" ],
[ "GL_RGB", "GL_BGRA_EXT" ],
[ "GL_RGBA", "GL_BGRA_EXT" ],
[ "GL_BGRA_EXT", "GL_BGRA_EXT" ],
[ "GL_RED_INTEGER", "GL_RED_INTEGER" ],
[ "GL_RED_INTEGER", "GL_RG_INTEGER" ],
[ "GL_RED_INTEGER", "GL_RGB_INTEGER" ],
[ "GL_RED_INTEGER", "GL_RGBA_INTEGER" ],
[ "GL_RG_INTEGER", "GL_RG_INTEGER" ],
[ "GL_RG_INTEGER", "GL_RGB_INTEGER" ],
[ "GL_RG_INTEGER", "GL_RGBA_INTEGER" ],
[ "GL_RGB_INTEGER", "GL_RGB_INTEGER" ],
[ "GL_RGB_INTEGER", "GL_RGBA_INTEGER" ],
[ "GL_RGBA_INTEGER", "GL_RGBA_INTEGER" ]
]
}
// GENERATED FILE - DO NOT EDIT.
// Generated by gen_copy_conversion_table.py using data from es3_copy_conversion_formats.json.
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// format_map:
// Determining the sized internal format from a (format,type) pair.
// Also check es3 format combinations for validity.
#include "angle_gl.h"
#include "common/debug.h"
namespace gl
{
bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
{
switch (textureFormat)
{
case GL_ALPHA:
switch (framebufferFormat)
{
case GL_BGRA_EXT:
case GL_RGBA:
return true;
default:
break;
}
break;
case GL_BGRA_EXT:
switch (framebufferFormat)
{
case GL_BGRA_EXT:
return true;
default:
break;
}
break;
case GL_LUMINANCE:
switch (framebufferFormat)
{
case GL_BGRA_EXT:
case GL_RED:
case GL_RG:
case GL_RGB:
case GL_RGBA:
return true;
default:
break;
}
break;
case GL_LUMINANCE_ALPHA:
switch (framebufferFormat)
{
case GL_BGRA_EXT:
case GL_RGBA:
return true;
default:
break;
}
break;
case GL_RED:
switch (framebufferFormat)
{
case GL_BGRA_EXT:
case GL_RED:
case GL_RG:
case GL_RGB:
case GL_RGBA:
return true;
default:
break;
}
break;
case GL_RED_INTEGER:
switch (framebufferFormat)
{
case GL_RED_INTEGER:
case GL_RGBA_INTEGER:
case GL_RGB_INTEGER:
case GL_RG_INTEGER:
return true;
default:
break;
}
break;
case GL_RG:
switch (framebufferFormat)
{
case GL_BGRA_EXT:
case GL_RG:
case GL_RGB:
case GL_RGBA:
return true;
default:
break;
}
break;
case GL_RGB:
switch (framebufferFormat)
{
case GL_BGRA_EXT:
case GL_RGB:
case GL_RGBA:
return true;
default:
break;
}
break;
case GL_RGBA:
switch (framebufferFormat)
{
case GL_BGRA_EXT:
case GL_RGBA:
return true;
default:
break;
}
break;
case GL_RGBA_INTEGER:
switch (framebufferFormat)
{
case GL_RGBA_INTEGER:
return true;
default:
break;
}
break;
case GL_RGB_INTEGER:
switch (framebufferFormat)
{
case GL_RGBA_INTEGER:
case GL_RGB_INTEGER:
return true;
default:
break;
}
break;
case GL_RG_INTEGER:
switch (framebufferFormat)
{
case GL_RGBA_INTEGER:
case GL_RGB_INTEGER:
case GL_RG_INTEGER:
return true;
default:
break;
}
break;
default:
break;
}
return false;
}
} // namespace gl
......@@ -299,6 +299,9 @@ bool ValidES3Format(GLenum format);
bool ValidES3Type(GLenum type);
bool ValidES3FormatCombination(GLenum format, GLenum type, GLenum internalFormat);
// Implemented in es3_copy_conversion_table_autogen.cpp
bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat);
} // namespace gl
#endif // LIBANGLE_FORMATUTILS_H_
#!/usr/bin/python
# Copyright 2016 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# gen_copy_conversion_table.py:
# Code generation for ES3 valid copy conversions table format map.
from datetime import date
import sys
sys.path.append('renderer')
import angle_format
template_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name}.
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// format_map:
// Determining the sized internal format from a (format,type) pair.
// Also check es3 format combinations for validity.
#include "angle_gl.h"
#include "common/debug.h"
namespace gl
{{
bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
{{
switch (textureFormat)
{{
{texture_format_cases} default:
break;
}}
return false;
}}
}} // namespace gl
"""
template_format_case = """ case {texture_format}:
switch (framebufferFormat)
{{
{framebuffer_format_cases} return true;
default:
break;
}}
break;
"""
template_simple_case = """ case {key}:
"""
def parse_texture_format_case(texture_format, framebuffer_formats):
framebuffer_format_cases = ""
for framebuffer_format in sorted(framebuffer_formats):
framebuffer_format_cases += template_simple_case.format(key = framebuffer_format)
return template_format_case.format(
texture_format = texture_format, framebuffer_format_cases = framebuffer_format_cases)
data_source_name = 'es3_copy_conversion_formats.json'
json_data = angle_format.load_json(data_source_name)
format_map = {}
for description, data in json_data.iteritems():
for texture_format, framebuffer_format in data:
if texture_format not in format_map:
format_map[texture_format] = []
format_map[texture_format] += [ framebuffer_format ]
texture_format_cases = ""
for texture_format, framebuffer_formats in sorted(format_map.iteritems()):
texture_format_cases += parse_texture_format_case(texture_format, framebuffer_formats)
with open('es3_copy_conversion_table_autogen.cpp', 'wt') as out_file:
output_cpp = template_cpp.format(
script_name = sys.argv[0],
data_source_name = data_source_name,
copyright_year = date.today().year,
texture_format_cases = texture_format_cases)
out_file.write(output_cpp)
out_file.close()
......@@ -449,68 +449,6 @@ static bool GetEffectiveInternalFormat(const InternalFormat &srcFormat, const In
}
}
struct CopyConversion
{
GLenum mTextureFormat;
GLenum mFramebufferFormat;
CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
: mTextureFormat(textureFormat), mFramebufferFormat(framebufferFormat) { }
bool operator<(const CopyConversion& other) const
{
return memcmp(this, &other, sizeof(CopyConversion)) < 0;
}
};
typedef std::set<CopyConversion> CopyConversionSet;
static CopyConversionSet BuildValidES3CopyTexImageCombinations()
{
CopyConversionSet set;
// From ES 3.0.1 spec, table 3.15
set.insert(CopyConversion(GL_ALPHA, GL_RGBA));
set.insert(CopyConversion(GL_LUMINANCE, GL_RED));
set.insert(CopyConversion(GL_LUMINANCE, GL_RG));
set.insert(CopyConversion(GL_LUMINANCE, GL_RGB));
set.insert(CopyConversion(GL_LUMINANCE, GL_RGBA));
set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_RGBA));
set.insert(CopyConversion(GL_RED, GL_RED));
set.insert(CopyConversion(GL_RED, GL_RG));
set.insert(CopyConversion(GL_RED, GL_RGB));
set.insert(CopyConversion(GL_RED, GL_RGBA));
set.insert(CopyConversion(GL_RG, GL_RG));
set.insert(CopyConversion(GL_RG, GL_RGB));
set.insert(CopyConversion(GL_RG, GL_RGBA));
set.insert(CopyConversion(GL_RGB, GL_RGB));
set.insert(CopyConversion(GL_RGB, GL_RGBA));
set.insert(CopyConversion(GL_RGBA, GL_RGBA));
// Necessary for ANGLE back-buffers
set.insert(CopyConversion(GL_ALPHA, GL_BGRA_EXT));
set.insert(CopyConversion(GL_LUMINANCE, GL_BGRA_EXT));
set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_BGRA_EXT));
set.insert(CopyConversion(GL_RED, GL_BGRA_EXT));
set.insert(CopyConversion(GL_RG, GL_BGRA_EXT));
set.insert(CopyConversion(GL_RGB, GL_BGRA_EXT));
set.insert(CopyConversion(GL_RGBA, GL_BGRA_EXT));
set.insert(CopyConversion(GL_BGRA_EXT, GL_BGRA_EXT));
set.insert(CopyConversion(GL_RED_INTEGER, GL_RED_INTEGER));
set.insert(CopyConversion(GL_RED_INTEGER, GL_RG_INTEGER));
set.insert(CopyConversion(GL_RED_INTEGER, GL_RGB_INTEGER));
set.insert(CopyConversion(GL_RED_INTEGER, GL_RGBA_INTEGER));
set.insert(CopyConversion(GL_RG_INTEGER, GL_RG_INTEGER));
set.insert(CopyConversion(GL_RG_INTEGER, GL_RGB_INTEGER));
set.insert(CopyConversion(GL_RG_INTEGER, GL_RGBA_INTEGER));
set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGB_INTEGER));
set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGBA_INTEGER));
set.insert(CopyConversion(GL_RGBA_INTEGER, GL_RGBA_INTEGER));
return set;
}
static bool EqualOrFirstZero(GLuint first, GLuint second)
{
return first == 0 || first == second;
......@@ -523,129 +461,129 @@ static bool IsValidES3CopyTexImageCombination(const Format &textureFormat,
const auto &textureFormatInfo = *textureFormat.info;
const auto &framebufferFormatInfo = *framebufferFormat.info;
static const CopyConversionSet conversionSet = BuildValidES3CopyTexImageCombinations();
if (conversionSet.find(CopyConversion(textureFormatInfo.format,
framebufferFormatInfo.format)) != conversionSet.end())
if (!ValidES3CopyConversion(textureFormatInfo.format, framebufferFormatInfo.format))
{
// Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats
// must both be signed, unsigned, or fixed point and both source and destinations
// must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed
// conversion between fixed and floating point.
return false;
}
if ((textureFormatInfo.colorEncoding == GL_SRGB) !=
(framebufferFormatInfo.colorEncoding == GL_SRGB))
{
return false;
}
// Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats
// must both be signed, unsigned, or fixed point and both source and destinations
// must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed
// conversion between fixed and floating point.
if (((textureFormatInfo.componentType == GL_INT) !=
(framebufferFormatInfo.componentType == GL_INT)) ||
((textureFormatInfo.componentType == GL_UNSIGNED_INT) !=
(framebufferFormatInfo.componentType == GL_UNSIGNED_INT)))
if ((textureFormatInfo.colorEncoding == GL_SRGB) !=
(framebufferFormatInfo.colorEncoding == GL_SRGB))
{
return false;
}
if (((textureFormatInfo.componentType == GL_INT) !=
(framebufferFormatInfo.componentType == GL_INT)) ||
((textureFormatInfo.componentType == GL_UNSIGNED_INT) !=
(framebufferFormatInfo.componentType == GL_UNSIGNED_INT)))
{
return false;
}
if ((textureFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
textureFormatInfo.componentType == GL_SIGNED_NORMALIZED ||
textureFormatInfo.componentType == GL_FLOAT) &&
!(framebufferFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
framebufferFormatInfo.componentType == GL_SIGNED_NORMALIZED ||
framebufferFormatInfo.componentType == GL_FLOAT))
{
return false;
}
// GLES specification 3.0.3, sec 3.8.5, pg 139-140:
// The effective internal format of the source buffer is determined with the following rules
// applied in order:
// * If the source buffer is a texture or renderbuffer that was created with a sized internal
// format then the effective internal format is the source buffer's sized internal format.
// * If the source buffer is a texture that was created with an unsized base internal format,
// then the effective internal format is the source image array's effective internal
// format, as specified by table 3.12, which is determined from the <format> and <type>
// that were used when the source image array was specified by TexImage*.
// * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18
// where Destination Internal Format matches internalformat and where the [source channel
// sizes] are consistent with the values of the source buffer's [channel sizes]. Table 3.17
// is used if the FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the
// FRAMEBUFFER_ATTACHMENT_ENCODING is SRGB.
const InternalFormat *sourceEffectiveFormat = NULL;
if (readBufferHandle != 0)
{
// Not the default framebuffer, therefore the read buffer must be a user-created texture or
// renderbuffer
if (framebufferFormat.sized)
{
return false;
sourceEffectiveFormat = &framebufferFormatInfo;
}
if ((textureFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
textureFormatInfo.componentType == GL_SIGNED_NORMALIZED ||
textureFormatInfo.componentType == GL_FLOAT) &&
!(framebufferFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
framebufferFormatInfo.componentType == GL_SIGNED_NORMALIZED ||
framebufferFormatInfo.componentType == GL_FLOAT))
else
{
return false;
// Renderbuffers cannot be created with an unsized internal format, so this must be an
// unsized-format texture. We can use the same table we use when creating textures to
// get its effective sized format.
GLenum sizedInternalFormat =
GetSizedInternalFormat(framebufferFormatInfo.format, framebufferFormatInfo.type);
sourceEffectiveFormat = &GetInternalFormatInfo(sizedInternalFormat);
}
// GLES specification 3.0.3, sec 3.8.5, pg 139-140:
// The effective internal format of the source buffer is determined with the following rules applied in order:
// * If the source buffer is a texture or renderbuffer that was created with a sized internal format then the
// effective internal format is the source buffer's sized internal format.
// * If the source buffer is a texture that was created with an unsized base internal format, then the
// effective internal format is the source image array's effective internal format, as specified by table
// 3.12, which is determined from the <format> and <type> that were used when the source image array was
// specified by TexImage*.
// * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18 where
// Destination Internal Format matches internalformat and where the [source channel sizes] are consistent
// with the values of the source buffer's [channel sizes]. Table 3.17 is used if the
// FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the FRAMEBUFFER_ATTACHMENT_ENCODING
// is SRGB.
const InternalFormat *sourceEffectiveFormat = NULL;
if (readBufferHandle != 0)
}
else
{
// The effective internal format must be derived from the source framebuffer's channel
// sizes. This is done in GetEffectiveInternalFormat for linear buffers (table 3.17)
if (framebufferFormatInfo.colorEncoding == GL_LINEAR)
{
// Not the default framebuffer, therefore the read buffer must be a user-created texture or renderbuffer
if (framebufferFormat.sized)
GLenum effectiveFormat;
if (GetEffectiveInternalFormat(framebufferFormatInfo, textureFormatInfo,
&effectiveFormat))
{
sourceEffectiveFormat = &framebufferFormatInfo;
sourceEffectiveFormat = &GetInternalFormatInfo(effectiveFormat);
}
else
{
// Renderbuffers cannot be created with an unsized internal format, so this must be an unsized-format
// texture. We can use the same table we use when creating textures to get its effective sized format.
GLenum sizedInternalFormat = GetSizedInternalFormat(framebufferFormatInfo.format,
framebufferFormatInfo.type);
sourceEffectiveFormat = &GetInternalFormatInfo(sizedInternalFormat);
return false;
}
}
else
else if (framebufferFormatInfo.colorEncoding == GL_SRGB)
{
// The effective internal format must be derived from the source framebuffer's channel sizes.
// This is done in GetEffectiveInternalFormat for linear buffers (table 3.17)
if (framebufferFormatInfo.colorEncoding == GL_LINEAR)
// SRGB buffers can only be copied to sized format destinations according to table 3.18
if (textureFormat.sized &&
(framebufferFormatInfo.redBits >= 1 && framebufferFormatInfo.redBits <= 8) &&
(framebufferFormatInfo.greenBits >= 1 && framebufferFormatInfo.greenBits <= 8) &&
(framebufferFormatInfo.blueBits >= 1 && framebufferFormatInfo.blueBits <= 8) &&
(framebufferFormatInfo.alphaBits >= 1 && framebufferFormatInfo.alphaBits <= 8))
{
GLenum effectiveFormat;
if (GetEffectiveInternalFormat(framebufferFormatInfo, textureFormatInfo,
&effectiveFormat))
{
sourceEffectiveFormat = &GetInternalFormatInfo(effectiveFormat);
}
else
{
return false;
}
}
else if (framebufferFormatInfo.colorEncoding == GL_SRGB)
{
// SRGB buffers can only be copied to sized format destinations according to table 3.18
if (textureFormat.sized &&
(framebufferFormatInfo.redBits >= 1 && framebufferFormatInfo.redBits <= 8) &&
(framebufferFormatInfo.greenBits >= 1 &&
framebufferFormatInfo.greenBits <= 8) &&
(framebufferFormatInfo.blueBits >= 1 && framebufferFormatInfo.blueBits <= 8) &&
(framebufferFormatInfo.alphaBits >= 1 && framebufferFormatInfo.alphaBits <= 8))
{
sourceEffectiveFormat = &GetInternalFormatInfo(GL_SRGB8_ALPHA8);
}
else
{
return false;
}
sourceEffectiveFormat = &GetInternalFormatInfo(GL_SRGB8_ALPHA8);
}
else
{
UNREACHABLE();
return false;
}
}
if (textureFormat.sized)
else
{
// Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination
// format is sized, component sizes of the source and destination formats must exactly
// match if the destination format exists.
if (!EqualOrFirstZero(textureFormatInfo.redBits, sourceEffectiveFormat->redBits) ||
!EqualOrFirstZero(textureFormatInfo.greenBits, sourceEffectiveFormat->greenBits) ||
!EqualOrFirstZero(textureFormatInfo.blueBits, sourceEffectiveFormat->blueBits) ||
!EqualOrFirstZero(textureFormatInfo.alphaBits, sourceEffectiveFormat->alphaBits))
{
return false;
}
UNREACHABLE();
return false;
}
}
return true; // A conversion function exists, and no rule in the specification has precluded conversion
// between these formats.
if (textureFormat.sized)
{
// Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is
// sized, component sizes of the source and destination formats must exactly match if the
// destination format exists.
if (!EqualOrFirstZero(textureFormatInfo.redBits, sourceEffectiveFormat->redBits) ||
!EqualOrFirstZero(textureFormatInfo.greenBits, sourceEffectiveFormat->greenBits) ||
!EqualOrFirstZero(textureFormatInfo.blueBits, sourceEffectiveFormat->blueBits) ||
!EqualOrFirstZero(textureFormatInfo.alphaBits, sourceEffectiveFormat->alphaBits))
{
return false;
}
}
return false;
return true; // A conversion function exists, and no rule in the specification has precluded
// conversion between these formats.
}
bool ValidateES3CopyTexImageParametersBase(ValidationContext *context,
......
......@@ -152,6 +152,7 @@
'libANGLE/angletypes.cpp',
'libANGLE/angletypes.h',
'libANGLE/angletypes.inl',
'libANGLE/es3_copy_conversion_table_autogen.cpp',
'libANGLE/features.h',
'libANGLE/format_map_autogen.cpp',
'libANGLE/formatutils.cpp',
......
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