Commit a99ed554 by jchen10 Committed by Commit Bot

Refactor data conversions for state commands

This mainly enforces the rules as descripted in ES 3.10, section 2.2.1 and 2.2.2, by enhancing the "queryconversions" to support more rules, removing the scattered type convertors in "utilities" , "mathutil" and "queryutils", and forcing to only use the convertors in "queryconversions". BUG=angleproject:2165 Change-Id: I73c1dc850e2b3b8a479ece1d9c5eb7ae4ce851fe Reviewed-on: https://chromium-review.googlesource.com/680094 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent d03a849d
...@@ -208,6 +208,7 @@ std::string ToString(const T &value) ...@@ -208,6 +208,7 @@ std::string ToString(const T &value)
#define GL_BGRA4_ANGLEX 0x6ABC #define GL_BGRA4_ANGLEX 0x6ABC
#define GL_BGR5_A1_ANGLEX 0x6ABD #define GL_BGR5_A1_ANGLEX 0x6ABD
#define GL_INT_64_ANGLEX 0x6ABE #define GL_INT_64_ANGLEX 0x6ABE
#define GL_UINT_64_ANGLEX 0x6ABF
// Hidden enum for the NULL D3D device type. // Hidden enum for the NULL D3D device type.
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE 0x6AC0 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE 0x6AC0
......
...@@ -60,37 +60,38 @@ inline unsigned int ceilPow2(unsigned int x) ...@@ -60,37 +60,38 @@ inline unsigned int ceilPow2(unsigned int x)
return x; return x;
} }
inline int clampToInt(unsigned int x)
{
return static_cast<int>(std::min(x, static_cast<unsigned int>(std::numeric_limits<int>::max())));
}
template <typename DestT, typename SrcT> template <typename DestT, typename SrcT>
inline DestT clampCast(SrcT value) inline DestT clampCast(SrcT value)
{ {
static const DestT destLo = std::numeric_limits<DestT>::min(); // For floating-point types with denormalization, min returns the minimum positive normalized
static const DestT destHi = std::numeric_limits<DestT>::max(); // value. To find the value that has no values less than it, use numeric_limits::lowest.
static const SrcT srcLo = static_cast<SrcT>(destLo); constexpr const long double destLo =
static const SrcT srcHi = static_cast<SrcT>(destHi); static_cast<long double>(std::numeric_limits<DestT>::lowest());
constexpr const long double destHi =
static_cast<long double>(std::numeric_limits<DestT>::max());
constexpr const long double srcLo =
static_cast<long double>(std::numeric_limits<SrcT>::lowest());
constexpr long double srcHi = static_cast<long double>(std::numeric_limits<SrcT>::max());
// When value is outside of or equal to the limits for DestT we use the DestT limit directly. if (destHi < srcHi)
// This avoids undefined behaviors due to loss of precision when converting from floats to
// integers:
// destHi for ints is 2147483647 but the closest float number is around 2147483648, so when
// doing a conversion from float to int we run into an UB because the float is outside of the
// range representable by the int.
if (value <= srcLo)
{ {
return destLo; DestT destMax = std::numeric_limits<DestT>::max();
} if (value >= static_cast<SrcT>(destMax))
else if (value >= srcHi)
{ {
return destHi; return destMax;
} }
else }
if (destLo > srcLo)
{ {
return static_cast<DestT>(value); DestT destLow = std::numeric_limits<DestT>::lowest();
if (value <= static_cast<SrcT>(destLow))
{
return destLow;
} }
}
return static_cast<DestT>(value);
} }
template<typename T, typename MIN, typename MAX> template<typename T, typename MIN, typename MAX>
......
...@@ -766,43 +766,6 @@ std::string ParseResourceName(const std::string &name, size_t *outSubscript) ...@@ -766,43 +766,6 @@ std::string ParseResourceName(const std::string &name, size_t *outSubscript)
return name.substr(0, open); return name.substr(0, open);
} }
template <>
GLuint ConvertToGLuint(GLfloat param)
{
return uiround<GLuint>(param);
}
template <>
GLint ConvertToGLint(uint32_t param)
{
uint32_t max = static_cast<uint32_t>(std::numeric_limits<GLint>::max());
return static_cast<GLint>(param >= max ? max : param);
}
template <>
GLint ConvertToGLint(uint64_t param)
{
uint64_t max = static_cast<uint64_t>(std::numeric_limits<GLint>::max());
return static_cast<GLint>(param >= max ? max : param);
}
template <>
GLint ConvertToGLint(GLfloat param)
{
return iround<GLint>(param);
}
template <>
GLint ConvertFromGLfloat(GLfloat param)
{
return iround<GLint>(param);
}
template <>
GLuint ConvertFromGLfloat(GLfloat param)
{
return uiround<GLuint>(param);
}
unsigned int ParseAndStripArrayIndex(std::string *name) unsigned int ParseAndStripArrayIndex(std::string *name)
{ {
unsigned int subscript = GL_INVALID_INDEX; unsigned int subscript = GL_INVALID_INDEX;
......
...@@ -67,94 +67,6 @@ GLuint GetPrimitiveRestartIndex(GLenum indexType); ...@@ -67,94 +67,6 @@ GLuint GetPrimitiveRestartIndex(GLenum indexType);
bool IsTriangleMode(GLenum drawMode); bool IsTriangleMode(GLenum drawMode);
bool IsIntegerFormat(GLenum unsizedFormat); bool IsIntegerFormat(GLenum unsizedFormat);
// [OpenGL ES 3.0.2] Section 2.3.1 page 14
// Data Conversion For State-Setting Commands
// Floating-point values are rounded to the nearest integer, instead of truncated, as done by static_cast.
template <typename outT> outT iround(GLfloat value) { return static_cast<outT>(value > 0.0f ? floor(value + 0.5f) : ceil(value - 0.5f)); }
template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(value + 0.5f); }
// Helper for converting arbitrary GL types to other GL types used in queries and state setting
// TODO(jie.a.chen@intel.com): Add the conversion rule for all helpers as the spec requires:
// "If a value is so large in magnitude that it cannot be represented with the requested type,"
// "then the nearest value representable using the requested type is returned."
template <typename ParamType>
GLuint ConvertToGLuint(ParamType param)
{
return static_cast<GLuint>(param);
}
template <>
GLuint ConvertToGLuint(GLfloat param);
template <typename ParamType>
GLint ConvertToGLint(ParamType param)
{
return static_cast<GLint>(param);
}
template <>
GLint ConvertToGLint(uint32_t param);
template <>
GLint ConvertToGLint(uint64_t param);
template <>
GLint ConvertToGLint(GLfloat param);
// Same conversion as uint
template <typename ParamType>
GLenum ConvertToGLenum(ParamType param)
{
return static_cast<GLenum>(ConvertToGLuint(param));
}
template <typename ParamType>
GLfloat ConvertToGLfloat(ParamType param)
{
return static_cast<GLfloat>(param);
}
template <typename ParamType>
ParamType ConvertFromGLfloat(GLfloat param)
{
return static_cast<ParamType>(param);
}
template <>
GLint ConvertFromGLfloat(GLfloat param);
template <>
GLuint ConvertFromGLfloat(GLfloat param);
template <typename ParamType>
ParamType ConvertFromGLenum(GLenum param)
{
return static_cast<ParamType>(param);
}
template <typename ParamType>
ParamType ConvertFromGLuint(GLuint param)
{
return static_cast<ParamType>(param);
}
template <typename ParamType>
ParamType ConvertFromGLint(GLint param)
{
return static_cast<ParamType>(param);
}
template <typename ParamType>
ParamType ConvertFromGLboolean(GLboolean param)
{
return static_cast<ParamType>(param ? GL_TRUE : GL_FALSE);
}
template <typename ParamType>
ParamType ConvertFromGLint64(GLint64 param)
{
return clampCast<ParamType>(param);
}
unsigned int ParseAndStripArrayIndex(std::string *name); unsigned int ParseAndStripArrayIndex(std::string *name);
struct UniformTypeInfo final : angle::NonCopyable struct UniformTypeInfo final : angle::NonCopyable
......
...@@ -118,7 +118,7 @@ gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params) ...@@ -118,7 +118,7 @@ gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
gl::Error error = query->isResultAvailable(&available); gl::Error error = query->isResultAvailable(&available);
if (!error.isError()) if (!error.isError())
{ {
*params = gl::ConvertFromGLboolean<T>(available); *params = gl::CastFromStateValue<T>(pname, static_cast<GLuint>(available));
} }
return error; return error;
} }
......
...@@ -12,16 +12,17 @@ ...@@ -12,16 +12,17 @@
#include <string.h> #include <string.h>
#include "common/bitset_utils.h" #include "common/bitset_utils.h"
#include "common/matrix_utils.h"
#include "common/mathutil.h" #include "common/mathutil.h"
#include "libANGLE/Context.h" #include "common/matrix_utils.h"
#include "libANGLE/Caps.h" #include "libANGLE/Caps.h"
#include "libANGLE/Context.h"
#include "libANGLE/Debug.h" #include "libANGLE/Debug.h"
#include "libANGLE/Framebuffer.h" #include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h" #include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Query.h" #include "libANGLE/Query.h"
#include "libANGLE/VertexArray.h" #include "libANGLE/VertexArray.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/queryconversions.h"
namespace namespace
{ {
...@@ -1851,10 +1852,14 @@ void State::getIntegerv(const Context *context, GLenum pname, GLint *params) ...@@ -1851,10 +1852,14 @@ void State::getIntegerv(const Context *context, GLenum pname, GLint *params)
break; break;
case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break; case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
case GL_STENCIL_REF: *params = mStencilRef; break; case GL_STENCIL_REF: *params = mStencilRef; break;
case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break; case GL_STENCIL_VALUE_MASK:
*params = CastMaskValue(context, mDepthStencil.stencilMask);
break;
case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break; case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break; case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break; case GL_STENCIL_BACK_VALUE_MASK:
*params = CastMaskValue(context, mDepthStencil.stencilBackMask);
break;
case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break; case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break; case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break; case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
...@@ -1868,8 +1873,12 @@ void State::getIntegerv(const Context *context, GLenum pname, GLint *params) ...@@ -1868,8 +1873,12 @@ void State::getIntegerv(const Context *context, GLenum pname, GLint *params)
case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break; case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break; case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break; case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break; case GL_STENCIL_WRITEMASK:
case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break; *params = CastMaskValue(context, mDepthStencil.stencilWritemask);
break;
case GL_STENCIL_BACK_WRITEMASK:
*params = CastMaskValue(context, mDepthStencil.stencilBackWritemask);
break;
case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break; case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
case GL_IMPLEMENTATION_COLOR_READ_TYPE: case GL_IMPLEMENTATION_COLOR_READ_TYPE:
*params = mReadFramebuffer->getImplementationColorReadType(context); *params = mReadFramebuffer->getImplementationColorReadType(context);
......
...@@ -24,18 +24,9 @@ GLint64 ExpandFloatToInteger(GLfloat value) ...@@ -24,18 +24,9 @@ GLint64 ExpandFloatToInteger(GLfloat value)
return static_cast<GLint64>((static_cast<double>(0xFFFFFFFFULL) * value - 1.0) / 2.0); return static_cast<GLint64>((static_cast<double>(0xFFFFFFFFULL) * value - 1.0) / 2.0);
} }
template <typename QueryT>
QueryT ClampToQueryRange(GLint64 value)
{
const GLint64 min = static_cast<GLint64>(std::numeric_limits<QueryT>::min());
const GLint64 max = static_cast<GLint64>(std::numeric_limits<QueryT>::max());
return static_cast<QueryT>(clamp(value, min, max));
}
template <typename QueryT, typename NativeT> template <typename QueryT, typename NativeT>
QueryT CastStateValueToInt(GLenum pname, NativeT value) QueryT CastFromStateValueToInt(GLenum pname, NativeT value)
{ {
GLenum queryType = GLTypeToGLenum<QueryT>::value;
GLenum nativeType = GLTypeToGLenum<NativeT>::value; GLenum nativeType = GLTypeToGLenum<NativeT>::value;
if (nativeType == GL_FLOAT) if (nativeType == GL_FLOAT)
...@@ -43,37 +34,70 @@ QueryT CastStateValueToInt(GLenum pname, NativeT value) ...@@ -43,37 +34,70 @@ QueryT CastStateValueToInt(GLenum pname, NativeT value)
// RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from Table 4.5 // RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from Table 4.5
if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR) if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
{ {
return ClampToQueryRange<QueryT>(ExpandFloatToInteger(static_cast<GLfloat>(value))); return clampCast<QueryT>(ExpandFloatToInteger(static_cast<GLfloat>(value)));
} }
else else
{ {
return gl::iround<QueryT>(static_cast<GLfloat>(value)); return clampCast<QueryT>(std::round(value));
} }
} }
// Clamp 64-bit int values when casting to int return clampCast<QueryT>(value);
if (nativeType == GL_INT_64_ANGLEX && queryType == GL_INT) }
template <typename NativeT, typename QueryT>
NativeT CastQueryValueToInt(GLenum pname, QueryT value)
{
GLenum queryType = GLTypeToGLenum<QueryT>::value;
if (queryType == GL_FLOAT)
{ {
GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<GLint>::min()); return static_cast<NativeT>(std::round(value));
GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<GLint>::max());
GLint64 clampedValue = std::max(std::min(static_cast<GLint64>(value), maxIntValue), minIntValue);
return static_cast<QueryT>(clampedValue);
} }
return static_cast<QueryT>(value); return static_cast<NativeT>(value);
} }
} // anonymous namespace
// ES 3.10 Section 2.2.2
// When querying bitmasks(such as SAMPLE_MASK_VALUE or STENCIL_WRITEMASK) with GetIntegerv, the
// mask value is treated as a signed integer, so that mask values with the high bit set will not be
// clamped when returned as signed integers.
GLint CastMaskValue(const Context *context, GLuint value)
{
return (context->getClientVersion() >= Version(3, 1) ? static_cast<GLint>(value)
: clampCast<GLint>(value));
}
template <typename QueryT, typename InternalT>
QueryT CastFromGLintStateValue(GLenum pname, InternalT value)
{
return CastFromStateValue<QueryT, GLint>(pname, clampCast<GLint, InternalT>(value));
}
template GLfloat CastFromGLintStateValue<GLfloat, GLenum>(GLenum pname, GLenum value);
template GLint CastFromGLintStateValue<GLint, GLenum>(GLenum pname, GLenum value);
template GLint64 CastFromGLintStateValue<GLint64, GLenum>(GLenum pname, GLenum value);
template GLuint CastFromGLintStateValue<GLuint, GLenum>(GLenum pname, GLenum value);
template GLfloat CastFromGLintStateValue<GLfloat, bool>(GLenum pname, bool value);
template GLuint CastFromGLintStateValue<GLuint, bool>(GLenum pname, bool value);
template GLint CastFromGLintStateValue<GLint, bool>(GLenum pname, bool value);
template GLfloat CastFromGLintStateValue<GLfloat, size_t>(GLenum pname, size_t value);
template GLint CastFromGLintStateValue<GLint, size_t>(GLenum pname, size_t value);
template <typename QueryT, typename NativeT> template <typename QueryT, typename NativeT>
QueryT CastStateValue(GLenum pname, NativeT value) QueryT CastFromStateValue(GLenum pname, NativeT value)
{ {
GLenum queryType = GLTypeToGLenum<QueryT>::value; GLenum queryType = GLTypeToGLenum<QueryT>::value;
switch (queryType) switch (queryType)
{ {
case GL_INT: case GL_INT:
return CastStateValueToInt<QueryT, NativeT>(pname, value);
case GL_INT_64_ANGLEX: case GL_INT_64_ANGLEX:
return CastStateValueToInt<QueryT, NativeT>(pname, value); case GL_UNSIGNED_INT:
case GL_UINT_64_ANGLEX:
return CastFromStateValueToInt<QueryT, NativeT>(pname, value);
case GL_FLOAT: case GL_FLOAT:
return static_cast<QueryT>(value); return static_cast<QueryT>(value);
case GL_BOOL: case GL_BOOL:
...@@ -83,8 +107,50 @@ QueryT CastStateValue(GLenum pname, NativeT value) ...@@ -83,8 +107,50 @@ QueryT CastStateValue(GLenum pname, NativeT value)
return 0; return 0;
} }
} }
template GLint CastFromStateValue<GLint, GLint>(GLenum pname, GLint value);
template GLint CastFromStateValue<GLint, GLint64>(GLenum pname, GLint64 value);
template GLint64 CastFromStateValue<GLint64, GLint>(GLenum pname, GLint value);
template GLint64 CastFromStateValue<GLint64, GLint64>(GLenum pname, GLint64 value);
template GLfloat CastFromStateValue<GLfloat, GLint>(GLenum pname, GLint value);
template GLfloat CastFromStateValue<GLfloat, GLfloat>(GLenum pname, GLfloat value);
template GLint CastFromStateValue<GLint, GLfloat>(GLenum pname, GLfloat value);
template GLuint CastFromStateValue<GLuint, GLint>(GLenum pname, GLint value);
template GLuint CastFromStateValue<GLuint, GLuint>(GLenum pname, GLuint value);
template GLint CastFromStateValue<GLint, GLboolean>(GLenum pname, GLboolean value);
template GLint64 CastFromStateValue<GLint64, GLboolean>(GLenum pname, GLboolean value);
template GLint CastFromStateValue<GLint, GLuint>(GLenum pname, GLuint value);
template GLint64 CastFromStateValue<GLint64, GLuint>(GLenum pname, GLuint value);
template GLuint64 CastFromStateValue<GLuint64, GLuint>(GLenum pname, GLuint value);
} // anonymous namespace template <typename NativeT, typename QueryT>
NativeT CastQueryValueTo(GLenum pname, QueryT value)
{
GLenum nativeType = GLTypeToGLenum<NativeT>::value;
switch (nativeType)
{
case GL_INT:
case GL_INT_64_ANGLEX:
case GL_UNSIGNED_INT:
case GL_UINT_64_ANGLEX:
return CastQueryValueToInt<NativeT, QueryT>(pname, value);
case GL_FLOAT:
return static_cast<NativeT>(value);
case GL_BOOL:
return static_cast<NativeT>(value == static_cast<QueryT>(0) ? GL_FALSE : GL_TRUE);
default:
UNREACHABLE();
return 0;
}
}
template GLint CastQueryValueTo<GLint, GLfloat>(GLenum pname, GLfloat value);
template GLboolean CastQueryValueTo<GLboolean, GLint>(GLenum pname, GLint value);
template GLint CastQueryValueTo<GLint, GLint>(GLenum pname, GLint value);
template GLfloat CastQueryValueTo<GLfloat, GLint>(GLenum pname, GLint value);
template GLfloat CastQueryValueTo<GLfloat, GLfloat>(GLenum pname, GLfloat value);
template GLuint CastQueryValueTo<GLuint, GLint>(GLenum pname, GLint value);
template GLuint CastQueryValueTo<GLuint, GLfloat>(GLenum pname, GLfloat value);
template <typename QueryT> template <typename QueryT>
void CastStateValues(Context *context, GLenum nativeType, GLenum pname, void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
...@@ -97,7 +163,7 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname, ...@@ -97,7 +163,7 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
for (unsigned int i = 0; i < numParams; ++i) for (unsigned int i = 0; i < numParams; ++i)
{ {
outParams[i] = CastStateValue<QueryT>(pname, intParams[i]); outParams[i] = CastFromStateValue<QueryT>(pname, intParams[i]);
} }
} }
else if (nativeType == GL_BOOL) else if (nativeType == GL_BOOL)
...@@ -117,7 +183,7 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname, ...@@ -117,7 +183,7 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
for (unsigned int i = 0; i < numParams; ++i) for (unsigned int i = 0; i < numParams; ++i)
{ {
outParams[i] = CastStateValue<QueryT>(pname, floatParams[i]); outParams[i] = CastFromStateValue<QueryT>(pname, floatParams[i]);
} }
} }
else if (nativeType == GL_INT_64_ANGLEX) else if (nativeType == GL_INT_64_ANGLEX)
...@@ -127,7 +193,7 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname, ...@@ -127,7 +193,7 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
for (unsigned int i = 0; i < numParams; ++i) for (unsigned int i = 0; i < numParams; ++i)
{ {
outParams[i] = CastStateValue<QueryT>(pname, int64Params[i]); outParams[i] = CastFromStateValue<QueryT>(pname, int64Params[i]);
} }
} }
else UNREACHABLE(); else UNREACHABLE();
...@@ -135,7 +201,7 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname, ...@@ -135,7 +201,7 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
// Explicit template instantiation (how we export template functions in different files) // Explicit template instantiation (how we export template functions in different files)
// The calls below will make CastStateValues successfully link with the GL state query types // The calls below will make CastStateValues successfully link with the GL state query types
// The GL state query API types are: bool, int, uint, float, int64 // The GL state query API types are: bool, int, uint, float, int64, uint64
template void CastStateValues<GLboolean>(Context *, GLenum, GLenum, unsigned int, GLboolean *); template void CastStateValues<GLboolean>(Context *, GLenum, GLenum, unsigned int, GLboolean *);
template void CastStateValues<GLint>(Context *, GLenum, GLenum, unsigned int, GLint *); template void CastStateValues<GLint>(Context *, GLenum, GLenum, unsigned int, GLint *);
...@@ -158,7 +224,7 @@ void CastIndexedStateValues(Context *context, ...@@ -158,7 +224,7 @@ void CastIndexedStateValues(Context *context,
for (unsigned int i = 0; i < numParams; ++i) for (unsigned int i = 0; i < numParams; ++i)
{ {
outParams[i] = CastStateValue<QueryT>(pname, intParams[i]); outParams[i] = CastFromStateValue<QueryT>(pname, intParams[i]);
} }
} }
else if (nativeType == GL_BOOL) else if (nativeType == GL_BOOL)
...@@ -179,7 +245,7 @@ void CastIndexedStateValues(Context *context, ...@@ -179,7 +245,7 @@ void CastIndexedStateValues(Context *context,
for (unsigned int i = 0; i < numParams; ++i) for (unsigned int i = 0; i < numParams; ++i)
{ {
outParams[i] = CastStateValue<QueryT>(pname, int64Params[i]); outParams[i] = CastFromStateValue<QueryT>(pname, int64Params[i]);
} }
} }
else else
......
...@@ -18,7 +18,8 @@ class Context; ...@@ -18,7 +18,8 @@ class Context;
// Helper class for converting a GL type to a GLenum: // Helper class for converting a GL type to a GLenum:
// We can't use CastStateValueEnum generally, because of GLboolean + GLubyte overlap. // We can't use CastStateValueEnum generally, because of GLboolean + GLubyte overlap.
// We restrict our use to CastStateValue, where it eliminates duplicate parameters. // We restrict our use to CastFromStateValue and CastQueryValueTo, where it eliminates
// duplicate parameters.
template <typename GLType> template <typename GLType>
struct GLTypeToGLenum struct GLTypeToGLenum
...@@ -47,17 +48,45 @@ struct GLTypeToGLenum<GLint64> ...@@ -47,17 +48,45 @@ struct GLTypeToGLenum<GLint64>
static constexpr GLenum value = GL_INT_64_ANGLEX; static constexpr GLenum value = GL_INT_64_ANGLEX;
}; };
template <> template <>
struct GLTypeToGLenum<GLuint64>
{
static constexpr GLenum value = GL_UINT_64_ANGLEX;
};
template <>
struct GLTypeToGLenum<GLfloat> struct GLTypeToGLenum<GLfloat>
{ {
static constexpr GLenum value = GL_FLOAT; static constexpr GLenum value = GL_FLOAT;
}; };
// The GL state query API types are: bool, int, uint, float, int64 GLint CastMaskValue(const Context *context, GLuint value);
template <typename QueryT, typename InternalT>
QueryT CastFromGLintStateValue(GLenum pname, InternalT value);
template <typename QueryT, typename NativeT>
QueryT CastFromStateValue(GLenum pname, NativeT value);
template <typename NativeT, typename QueryT>
NativeT CastQueryValueTo(GLenum pname, QueryT value);
template <typename ParamType>
GLenum ConvertToGLenum(GLenum pname, ParamType param)
{
return static_cast<GLenum>(CastQueryValueTo<GLuint>(pname, param));
}
template <typename ParamType>
GLenum ConvertToGLenum(ParamType param)
{
return ConvertToGLenum(GL_NONE, param);
}
// The GL state query API types are: bool, int, uint, float, int64, uint64
template <typename QueryT> template <typename QueryT>
void CastStateValues(Context *context, GLenum nativeType, GLenum pname, void CastStateValues(Context *context, GLenum nativeType, GLenum pname,
unsigned int numParams, QueryT *outParams); unsigned int numParams, QueryT *outParams);
// The GL state query API types are: bool, int, uint, float, int64 // The GL state query API types are: bool, int, uint, float, int64, uint64
template <typename QueryT> template <typename QueryT>
void CastIndexedStateValues(Context *context, void CastIndexedStateValues(Context *context,
GLenum nativeType, GLenum nativeType,
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "libANGLE/Uniform.h" #include "libANGLE/Uniform.h"
#include "libANGLE/VertexArray.h" #include "libANGLE/VertexArray.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/queryconversions.h"
#include "libANGLE/validationES2.h" #include "libANGLE/validationES2.h"
#include "libANGLE/validationES3.h" #include "libANGLE/validationES3.h"
...@@ -33,6 +34,7 @@ namespace gl ...@@ -33,6 +34,7 @@ namespace gl
{ {
namespace namespace
{ {
bool ValidateDrawAttribs(ValidationContext *context, bool ValidateDrawAttribs(ValidationContext *context,
GLint primcount, GLint primcount,
GLint maxVertex, GLint maxVertex,
......
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