Consolidation of various GL context limits into RegalEmu.h and ContextInfo

Improved array bounds checking for emulation
More querable states for GL database
This commit is contained in:
Nigel Stewart 2013-09-06 09:40:29 -05:00
parent 89ff20c375
commit b92e6bb26a
44 changed files with 4206 additions and 2201 deletions

View file

@ -99,6 +99,27 @@ endif
ifeq ($(MODE),custom)
endif
# Emscripten options
ifneq ($(filter nacl% emscripten%,$(SYSTEM)),)
REGAL.CFLAGS += -DREGAL_SYS_EMSCRIPTEN=1 -DREGAL_SYS_EGL=1 -DREGAL_SYS_ES2=1
REGAL.CFLAGS += -DREGAL_NO_HTTP=1
REGAL.CFLAGS += -DREGAL_STATISTICS=0
REGAL.CFLAGS += -Wno-constant-logical-operand
REGAL.CFLAGS += -DREGAL_PLUGIN=0
REGAL.CFLAGS += -DREGAL_TRACE=0
REGAL.CFLAGS += -DREGAL_NAMESPACE=1 -DREGAL_STATIC_ES2 -DREGAL_STATIC_EGL
REGAL_LOG = 0
REGAL_NO_TLS = 1
# Enabling this requires the library to be built with it, as well as all code
# that uses it. Defining this means that Regal will link statically to GL
# and EGL, and code will have to #include <GL/Regal.h> before any GL
# includes to pull in a bunch of #defines (e.g. #define glGetError rglGetError)
#LIB.CFLAGS += -DREGAL_SYS_EMSCRIPTEN_STATIC=1
endif
#
# Emscripten-specific
#

View file

@ -384,6 +384,10 @@ Related Efforts
* Mesa3D mail thread: `Mesa as part of OpenGL-on-OpenGL ES 2.0 <http://lists.freedesktop.org/archives/mesa-dev/2012-March/019692.html>`_
* `glshim <https://github.com/lunixbochs/glshim>`_, `Pandora forum thread <http://boards.openpandora.org/index.php/topic/11506-opengl-implementation-tldr-more-games/>`_.
* Runtime OpenGL to OpenGL ES translator: `glesport <http://unrealvoodoo.org/cgi-bin/cgit/glesport.git/log/>`_, `OpenGL ES for Maemo <http://unrealvoodoo.org/hiteck/blog/2007/07/opengl-es-for-maemo/>`_.
License and Credits
===================

View file

@ -118,7 +118,8 @@ include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := apitrace
LOCAL_SRC_FILES := $(apitrace_src_files)
LOCAL_CFLAGS := $(regal_cflags) -DAPITRACE_TLS=0 -DTRACE_OS_LOG=0 -DTRACE_BACKTRACE=0
LOCAL_CFLAGS := $(regal_cflags) -DAPITRACE_TLS=0 -DTRACE_OS_LOG=0 -DTRACE_BACKTRACE=0 -DTRACE_ENABLED_CHECK=0
LOCAL_C_INCLUDES := $(apitrace_c_includes)
LOCAL_EXPORT_C_INCLUDES := $(apitrace_export_c_includes)
LOCAL_EXPORT_LDLIBS :=

View file

@ -61,6 +61,7 @@
43FC5FA315C4619B00D0177C /* RegalUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 43FC5F7615C4619B00D0177C /* RegalUtil.h */; };
43FC5FA415C4619B00D0177C /* RegalVao.h in Headers */ = {isa = PBXBuildFile; fileRef = 43FC5F7715C4619B00D0177C /* RegalVao.h */; };
43FC5FA715C461AC00D0177C /* mongoose.c in Sources */ = {isa = PBXBuildFile; fileRef = 43FC5FA615C461AC00D0177C /* mongoose.c */; };
754D3C9517CFFD7200E4C0E0 /* RegalEmu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 754D3C9417CFFD7200E4C0E0 /* RegalEmu.cpp */; };
BC020947160D1919003FAB99 /* RegalMarker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC020946160D1919003FAB99 /* RegalMarker.cpp */; };
BC020958160D1C73003FAB99 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = BC020957160D1C73003FAB99 /* md5.c */; };
BC3209D416F3A0E600D1A9E0 /* RegalCacheShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC3209D016F3A0E600D1A9E0 /* RegalCacheShader.cpp */; };
@ -226,6 +227,7 @@
43FC5F7615C4619B00D0177C /* RegalUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegalUtil.h; path = ../../../src/regal/RegalUtil.h; sourceTree = "<group>"; };
43FC5F7715C4619B00D0177C /* RegalVao.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegalVao.h; path = ../../../src/regal/RegalVao.h; sourceTree = "<group>"; };
43FC5FA615C461AC00D0177C /* mongoose.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mongoose.c; path = ../../../src/mongoose/mongoose.c; sourceTree = "<group>"; };
754D3C9417CFFD7200E4C0E0 /* RegalEmu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegalEmu.cpp; path = ../../../src/regal/RegalEmu.cpp; sourceTree = "<group>"; };
BC020946160D1919003FAB99 /* RegalMarker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegalMarker.cpp; path = ../../../src/regal/RegalMarker.cpp; sourceTree = "<group>"; };
BC020957160D1C73003FAB99 /* md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = md5.c; path = ../../../src/md5/src/md5.c; sourceTree = "<group>"; };
BC3209D016F3A0E600D1A9E0 /* RegalCacheShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegalCacheShader.cpp; path = ../../../src/regal/RegalCacheShader.cpp; sourceTree = "<group>"; };
@ -424,6 +426,7 @@
BCBF1846175EBB3000CB653A /* RegalDispatchTrace.cpp */,
43FC5F5D15C4619B00D0177C /* RegalDllMain.cpp */,
43FC5F5E15C4619B00D0177C /* RegalDsa.h */,
754D3C9417CFFD7200E4C0E0 /* RegalEmu.cpp */,
43FC5F5F15C4619B00D0177C /* RegalEmu.h */,
4366EEEA15C9B54E00211205 /* RegalEnum.h */,
4366EEEB15C9B54E00211205 /* RegalFavicon.cpp */,
@ -806,6 +809,7 @@
BCDF670D178F179800EE9569 /* gltrace_state.cpp in Sources */,
BCDF670F178F179800EE9569 /* regaltrace.cpp in Sources */,
BCDF6710178F179800EE9569 /* trace.cpp in Sources */,
754D3C9517CFFD7200E4C0E0 /* RegalEmu.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View file

@ -12,6 +12,7 @@ REGAL.CXX += src/regal/RegalLog.cpp
REGAL.CXX += src/regal/RegalInit.cpp
REGAL.CXX += src/regal/RegalBreak.cpp
REGAL.CXX += src/regal/RegalUtil.cpp
REGAL.CXX += src/regal/RegalEmu.cpp
REGAL.CXX += src/regal/RegalFrame.cpp
REGAL.CXX += src/regal/RegalHelper.cpp
REGAL.CXX += src/regal/RegalMarker.cpp

View file

@ -274,6 +274,7 @@
<ClInclude Include="..\..\..\..\src\regal\RegalDispatcherGlobal.h" />
<ClCompile Include="..\..\..\..\src\regal\RegalDllMain.cpp" />
<ClInclude Include="..\..\..\..\src\regal\RegalDsa.h" />
<ClCompile Include="..\..\..\..\src\regal\RegalEmu.cpp" />
<ClInclude Include="..\..\..\..\src\regal\RegalEmu.h" />
<ClInclude Include="..\..\..\..\src\regal\RegalEnum.h" />
<ClCompile Include="..\..\..\..\src\regal\RegalFavicon.cpp" />

View file

@ -274,6 +274,7 @@
<ClInclude Include="..\..\..\..\src\regal\RegalDispatcherGlobal.h" />
<ClCompile Include="..\..\..\..\src\regal\RegalDllMain.cpp" />
<ClInclude Include="..\..\..\..\src\regal\RegalDsa.h" />
<ClCompile Include="..\..\..\..\src\regal\RegalEmu.cpp" />
<ClInclude Include="..\..\..\..\src\regal\RegalEmu.h" />
<ClInclude Include="..\..\..\..\src\regal\RegalEnum.h" />
<ClCompile Include="..\..\..\..\src\regal\RegalFavicon.cpp" />

View file

@ -274,6 +274,7 @@
<ClInclude Include="..\..\..\..\src\regal\RegalDispatcherGlobal.h" />
<ClCompile Include="..\..\..\..\src\regal\RegalDllMain.cpp" />
<ClInclude Include="..\..\..\..\src\regal\RegalDsa.h" />
<ClCompile Include="..\..\..\..\src\regal\RegalEmu.cpp" />
<ClInclude Include="..\..\..\..\src\regal\RegalEmu.h" />
<ClInclude Include="..\..\..\..\src\regal\RegalEnum.h" />
<ClCompile Include="..\..\..\..\src\regal\RegalFavicon.cpp" />

View file

@ -274,6 +274,7 @@
<ClInclude Include="..\..\..\..\src\regal\RegalDispatcherGlobal.h" />
<ClCompile Include="..\..\..\..\src\regal\RegalDllMain.cpp" />
<ClInclude Include="..\..\..\..\src\regal\RegalDsa.h" />
<ClCompile Include="..\..\..\..\src\regal\RegalEmu.cpp" />
<ClInclude Include="..\..\..\..\src\regal\RegalEmu.h" />
<ClInclude Include="..\..\..\..\src\regal\RegalEnum.h" />
<ClCompile Include="..\..\..\..\src\regal\RegalFavicon.cpp" />

View file

@ -6,7 +6,7 @@ hintFormulae = {
'impl' : [
'if( ! _context->hint->glHint( *_context, ${arg0plus} ) ) {',
' _context->dispatcher.emulation.glHint( ${arg0plus} );',
'}',
'}',
],
},
'Get' : {

View file

@ -99,11 +99,7 @@ iffFormulae = {
'FfnShadowARB' : {
'entries' : [ 'glActiveTexture(ARB|)' ],
'impl' : [
'if( ! _context->iff->ShadowActiveTexture( ${arg0plus} ) ) {',
' _context->dispatcher.emulation.glActiveTexture${m1}( ${arg0plus} );',
'}',
],
'prefix' : [ '_context->iff->ShadowActiveTexture( ${arg0} ); ', ],
},
'FfnShadeModel' : {
'entries' : [ 'glShadeModel' ],
@ -169,7 +165,11 @@ iffFormulae = {
},
'FfnTexGen' : {
'entries' : [ 'glTexGen(i|f|d)(v|)' ],
'impl' : [ '_context->iff->TexGen( ${arg0plus} );', ],
'impl' : [
'if ( ! _context->iff->TexGen( ${arg0plus} ) ) {',
' _context->dispatcher.emulation.glTexGen${m1}${m2}( ${arg0plus} );',
'}',
],
},
'FfnAlphaFunc' : {
'entries' : [ 'glAlphaFunc' ],

View file

@ -12,11 +12,11 @@
formulae = {
'EmuInit' : {
'entries' : [
'CGLChoosePixelFormat', 'CGLGetCurrentContext',
'entries' : [
'CGLChoosePixelFormat', 'CGLGetCurrentContext',
'eglGetDisplay', 'eglGetCurrentContext',
'glXGetProcAddress', 'glXQueryExtension', 'glXGetProcAddressARB'
# 'glX.*'
# 'glX.*'
],
'prefix' : [ 'Init::init();' ]
}
@ -65,8 +65,11 @@ formulaeGlobal = {
'eglMakeCurrent' : {
'entries' : [ 'eglMakeCurrent' ],
'init' : [ 'if (ret)',
' Init::makeCurrent(ctx);' ]
'init' : '''
#if !REGAL_SYS_PPAPI
if (ret)
Init::makeCurrent(ctx);
#endif'''
},
'eglDestroyContext' : {

View file

@ -44,79 +44,61 @@ they are so as to convert the texture correctly."""
texCFormulae = {
'ShadowActiveTextureUnit' : {
'entries' : [ 'glActiveTexture(ARB|)' ],
'impl' : [
'_context->texc->ShadowActiveTexture( ${arg0plus} );',
'_context->dispatcher.emulation.glActiveTexture( ${arg0plus} );',
],
'prefix' : '_context->texc->ShadowActiveTexture( ${arg0plus} );',
},
'ShadowBindTexture' : {
'entries' : [ 'glBindTexture(EXT|)' ],
'impl' : [
'_context->texc->ShadowBindTexture( ${arg0plus} );',
'_context->dispatcher.emulation.glBindTexture( ${arg0plus} );',
],
'prefix' : '_context->texc->ShadowBindTexture( ${arg0plus} );',
},
'ShadowDeleteTexture' : {
'entries' : [ 'glDeleteTextures(EXT|)' ],
'impl' : [
'_context->texc->ShadowDeleteTextures( ${arg0plus} );',
'_context->dispatcher.emulation.glDeleteTextures( ${arg0plus} );',
],
'prefix' : '_context->texc->ShadowDeleteTextures( ${arg0plus} );',
},
'ShadowGenTextures' : {
'entries' : [ 'glGenTextures(EXT|)' ],
'impl' : [
'_context->dispatcher.emulation.glGenTextures( ${arg0plus} );',
'_context->texc->ShadowGenTextures( ${arg0}, ${arg1} );',
],
'impl' :
'''
_context->dispatcher.emulation.glGenTextures( ${arg0plus} );
_context->texc->ShadowGenTextures( ${arg0}, ${arg1} );'''
},
'ShadowGenerateMipmap' : {
'entries' : [ 'glGenerateMipmap(EXT|)' ],
'impl' : [
'_context->texc->ShadowGenerateMipmap( ${arg0plus} );',
'_context->dispatcher.emulation.glGenerateMipmap( ${arg0plus} );',
],
'prefix' : '_context->texc->ShadowGenerateMipmap( ${arg0plus} );',
},
'ShadowPixelStorei' : {
'entries' : [ 'glPixelStorei' ],
'impl' : [
'_context->texc->ShadowPixelStore( ${arg0plus} );',
'_context->dispatcher.emulation.glPixelStorei( ${arg0plus} );',
],
'prefix' : '_context->texc->ShadowPixelStore( ${arg0plus} );',
},
'ShadowTexImage2D' : {
'entries' : [ 'glTexImage2D' ],
'impl' : [
'_context->texc->ShadowTexImage2D( ${arg0}, ${arg1}, ${arg6}, ${arg7} );',
'_context->dispatcher.emulation.glTexImage2D( ${arg0plus} );',
],
'prefix' : '_context->texc->ShadowTexImage2D( ${arg0}, ${arg1}, ${arg6}, ${arg7} );',
},
'ConvertTexSubImage2D' : {
'entries' : [ 'glTexSubImage2D' ],
'impl' : [
'GLenum targetFormat;',
'GLenum targetType;',
'_context->texc->GetFormatAndType( ${arg0}, ${arg1}, &targetFormat, &targetType );',
'Emu::ConvertedBuffer _buffer( _context->texc->unpackPSS, targetFormat, targetType );',
'if ( _buffer.ConvertFrom( ${arg4}, ${arg5}, ${arg6}, ${arg7}, ${arg8} ) )',
'{',
' if (_context->texc->unpackPSS.alignment != 4)',
' _context->dispatcher.emulation.glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );',
' _context->dispatcher.emulation.glTexSubImage2D( ${arg0}, ${arg1}, ${arg2}, ${arg3}, ${arg4}, ${arg5}, targetFormat, targetType, _buffer.Get() );',
' if (_context->texc->unpackPSS.alignment != 4)',
' _context->dispatcher.emulation.glPixelStorei( GL_UNPACK_ALIGNMENT, _context->texc->unpackPSS.alignment );',
'}',
'else',
'{',
' _context->dispatcher.emulation.glTexSubImage2D( ${arg0plus} );',
'}',
],
'impl' :
'''
GLenum targetFormat;
GLenum targetType;
_context->texc->GetFormatAndType( ${arg0}, ${arg1}, &targetFormat, &targetType );
Emu::ConvertedBuffer _buffer( _context->texc->unpackPSS, targetFormat, targetType );
if ( _buffer.ConvertFrom( ${arg4}, ${arg5}, ${arg6}, ${arg7}, ${arg8} ) )
{
if (_context->texc->unpackPSS.alignment != 4)
_context->dispatcher.emulation.glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
_context->dispatcher.emulation.glTexSubImage2D( ${arg0}, ${arg1}, ${arg2}, ${arg3}, ${arg4}, ${arg5}, targetFormat, targetType, _buffer.Get() );
if (_context->texc->unpackPSS.alignment != 4)
_context->dispatcher.emulation.glPixelStorei( GL_UNPACK_ALIGNMENT, _context->texc->unpackPSS.alignment );
}
else
{
_context->dispatcher.emulation.glTexSubImage2D( ${arg0plus} );
}'''
},
}

View file

@ -45534,3 +45534,25 @@ gl.add(A)
gl.add(Y)
gl.add(nbytype)
gl.add(nstarbytype)
# states
MAX_ATTRIB_STACK_DEPTH = State('MAX_ATTRIB_STACK_DEPTH', 'Zplus', 'glGetIntegerv', '16', 'Max depth of the server attribute stack', '21.6', '-')
MAX_CLIENT_ATTRIB_STACK_DEPTH = State('MAX_CLIENT_ATTRIB_STACK_DEPTH', 'Zplus', 'glGetIntegerv', '16', 'Max depth of the client attribute stack', '21.6', '-')
MAX_VERTEX_ATTRIB_BINDINGS = State('MAX_VERTEX_ATTRIB_BINDINGS', 'Zkstar', 'glGetIntegerv', '16', 'Max no. of vertex buffers', '10.3', '-')
MAX_VERTEX_ATTRIBS = State('MAX_VERTEX_ATTRIBS', 'Zplus', 'glGetIntegerv', '16', 'Max no. of active vertex attributes', '10.2', '-')
MAX_TEXTURE_UNITS = State('MAX_TEXTURE_UNITS', 'Zplus', 'glGetIntegerv', '2', 'No. of fixed-function texture units', '10', '-')
MAX_TEXTURE_COORDS = State('MAX_TEXTURE_COORDS', 'Zplus', 'glGetIntegerv', '8', 'No. of texture coordinate sets', '10.2.2', '-')
MAX_COMBINED_TEXTURE_IMAGE_UNITS = State('MAX_COMBINED_TEXTURE_IMAGE_UNITS', 'Zplus', 'glGetIntegerv', '96', 'Total no. of texture units accessible by the GL', '11.1.3.5', '-')
MAX_DRAW_BUFFERS = State('MAX_DRAW_BUFFERS', 'Zplus', 'glGetIntegerv', '8', 'Max no. of active draw buffers', '17.4.1', '-')
MAX_VIEWPORTS = State('MAX_VIEWPORTS', 'Zplus', 'glGetIntegerv', '16', 'Max no. of active viewports', '13.6.1', '-')
gl.add(MAX_ATTRIB_STACK_DEPTH)
gl.add(MAX_CLIENT_ATTRIB_STACK_DEPTH)
gl.add(MAX_VERTEX_ATTRIB_BINDINGS)
gl.add(MAX_VERTEX_ATTRIBS)
gl.add(MAX_TEXTURE_UNITS)
gl.add(MAX_TEXTURE_COORDS)
gl.add(MAX_COMBINED_TEXTURE_IMAGE_UNITS)
gl.add(MAX_DRAW_BUFFERS)
gl.add(MAX_VIEWPORTS)

View file

@ -59,8 +59,10 @@ struct ContextInfo
${VERSION_DECLARE}
GLuint maxVertexAttribs;
GLuint maxVaryings;
// Implementation dependent values
${IMPL_DECLARE}
};
REGAL_NAMESPACE_END
@ -89,7 +91,7 @@ using namespace boost::print;
#include "RegalToken.h"
#include "RegalContext.h"
#include "RegalContextInfo.h"
#include "RegalIff.h" // For REGAL_MAX_VERTEX_ATTRIBS
#include "RegalEmu.h"
REGAL_GLOBAL_END
@ -101,8 +103,7 @@ using namespace ::REGAL_NAMESPACE_INTERNAL::Token;
ContextInfo::ContextInfo()
:
${VERSION_INIT}
maxVertexAttribs(0),
maxVaryings(0)
${IMPL_INIT}
{
Internal("ContextInfo::ContextInfo","()");
}
@ -350,30 +351,21 @@ ${VERSION_DETECT}
${EXT_INIT}
RegalAssert(context.dispatcher.driver.glGetIntegerv);
if (es1)
{
maxVertexAttribs = 8;
maxVaryings = 0;
}
else
{
context.dispatcher.driver.glGetIntegerv( GL_MAX_VERTEX_ATTRIBS, reinterpret_cast<GLint *>(&maxVertexAttribs));
context.dispatcher.driver.glGetIntegerv( es2 ? GL_MAX_VARYING_VECTORS : GL_MAX_VARYING_FLOATS, reinterpret_cast<GLint *>(&maxVaryings));
}
${IMPL_GET}
Info("OpenGL v attribs : ",maxVertexAttribs);
Info("OpenGL varyings : ",maxVaryings);
Info("OpenGL v attribs : ",gl_max_vertex_attribs);
Info("OpenGL varyings : ",gl_max_varying_floats);
if (maxVertexAttribs > REGAL_EMU_IFF_VERTEX_ATTRIBS)
maxVertexAttribs = REGAL_EMU_IFF_VERTEX_ATTRIBS;
if (gl_max_vertex_attribs > REGAL_EMU_MAX_VERTEX_ATTRIBS)
gl_max_vertex_attribs = REGAL_EMU_MAX_VERTEX_ATTRIBS;
// Qualcomm fails with float4 attribs with 256 byte stride, so artificially limit to 8 attribs (n*16 is used
// as the stride in RegalIFF). WebGL (and Pepper) explicitly disallows stride > 255 as well.
if (vendor == "Qualcomm" || vendor == "Chromium" || webgl)
maxVertexAttribs = 8;
gl_max_vertex_attribs = 8;
Info("Regal v attribs : ",maxVertexAttribs);
Info("Regal v attribs : ",gl_max_vertex_attribs);
}
${EXT_CODE}
@ -540,6 +532,94 @@ def versionDetectCode(apis, args):
return code
def implDeclareCode(apis, args):
code = ''
for api in apis:
name = api.name.lower()
if name == 'gl':
code += '\n'
states = []
for state in api.states:
states.append(state.getValue.lower())
for state in sorted(states):
code += ' GLuint gl_%s;\n' % (state)
code += '\n'
code += ' // Max values currently being used\n'
code += '\n'
for state in sorted(states):
code += ' GLuint %s;\n' % (state)
code += '\n'
code += ' GLuint gl_max_varying_floats;\n'
return code
def implInitCode(apis, args):
code = ''
for api in apis:
name = api.name.lower()
if name == 'gl':
states = []
for state in api.states:
states.append(state.getValue.lower())
for state in sorted(states):
code += ' gl_%s(0),\n' % (state)
for state in sorted(states):
code += ' %s(0),\n' % (state)
code += ' gl_max_varying_floats(0)\n'
return code
def implGetCode(apis, args):
code = ''
for api in apis:
name = api.name.lower()
if name == 'gl':
states = []
for state in api.states:
states.append(state.getValue)
code += ' if (es1)\n'
code += ' {\n'
for state in sorted(states):
code += ' gl_%s = 0;\n' % state.lower()
code += '\n'
code += ' gl_max_vertex_attribs = 8;\n'
code += ' }\n'
code += ' else\n'
code += ' {\n'
for state in sorted(states):
code += ' context.dispatcher.driver.glGetIntegerv( GL_%s, reinterpret_cast<GLint *>(&gl_%s));\n' % (state, state.lower())
code += ' context.dispatcher.driver.glGetIntegerv( es2 ? GL_MAX_VARYING_VECTORS : GL_MAX_VARYING_FLOATS, reinterpret_cast<GLint *>(&gl_max_varying_floats));\n'
code += ' }\n'
code += '\n'
for state in sorted(states):
code += ' %s = std::min( gl_%s, static_cast<GLuint>(REGAL_EMU_%s) );\n' % (state.lower(), state.lower(), state)
code += '\n'
return code
def extensionStringCode(apis, args):
code = ''
@ -611,6 +691,7 @@ def generateContextInfoHeader(apis, args):
substitute['COPYRIGHT'] = args.copyright
substitute['HEADER_NAME'] = "REGAL_CONTEXT_INFO"
substitute['VERSION_DECLARE'] = versionDeclareCode(apis,args)
substitute['IMPL_DECLARE'] = implDeclareCode(apis,args)
outputCode( '%s/RegalContextInfo.h' % args.srcdir, contextInfoHeaderTemplate.substitute(substitute))
def generateContextInfoSource(apis, args):
@ -623,4 +704,6 @@ def generateContextInfoSource(apis, args):
substitute['VERSION_DETECT'] = versionDetectCode(apis,args)
substitute['EXT_INIT'] = extensionStringCode(apis,args)
substitute['EXT_CODE'] = getExtensionCode(apis,args)
substitute['IMPL_INIT'] = implInitCode(apis,args)
substitute['IMPL_GET'] = implGetCode(apis,args)
outputCode( '%s/RegalContextInfo.cpp' % args.srcdir, contextInfoSourceTemplate.substitute(substitute))

View file

@ -96,8 +96,7 @@ def apiEmuFuncDefineCode(apis, args):
code += ' _instance.nextDispatchTable = &_context->dispatcher.emulation;\n'
code += ' #endif\n'
for j in e['prefix'] :
code += ' %s\n' % j
code += listToString(indent(e['prefix'],' '))
if l['member'] :
code += ' }\n'
if e!= None and 'impl' in e and l['member']:
@ -146,8 +145,7 @@ def apiEmuFuncDefineCode(apis, args):
code += ' _instance.nextDispatchTable = &_context->dispatcher.emulation;\n'
code += ' #endif\n'
for j in e['impl'] :
code += ' %s\n' % j
code += listToString(indent(e['impl'],' '))
if l['member'] :
if l['member'] != "filt" and typeIsVoid(rType):
code += ' return;\n'

View file

@ -31930,8 +31930,11 @@ extern "C" {
RegalAssert(_next);
EGLBoolean ret = 0;
ret = _next->call(&_next->eglMakeCurrent)(dpy, draw, read, ctx);
#if !REGAL_SYS_PPAPI
if (ret)
Init::makeCurrent(ctx);
Init::makeCurrent(ctx);
#endif
return ret;
}

View file

@ -81,8 +81,10 @@ struct BaseVertex : public ClientState::VertexArray
GLuint currentVBO = ClientState::VertexArray::arrayBufferBinding;
for (GLuint ii=0; ii<ClientState::nNamedArrays; ii++)
size_t num = array_size( ClientState::VertexArray::named );
for (size_t ii=0; ii<num; ii++)
{
RegalAssertArrayIndex( ClientState::VertexArray::named, ii );
ClientState::NamedVertexArray &n = ClientState::VertexArray::named[ii];
if (n.enabled)
{
@ -129,11 +131,14 @@ struct BaseVertex : public ClientState::VertexArray
}
}
for (GLuint ii=0; ii<REGAL_EMU_MAX_VERTEX_ATTRIBS; ii++)
num = array_size( ClientState::VertexArray::generic );
for (size_t ii=0; ii<num; ii++)
{
RegalAssertArrayIndex( ClientState::VertexArray::generic, ii );
ClientState::GenericVertexArray &g = ClientState::VertexArray::generic[ii];
if (g.enabled)
if (g.enabled && g.bindingIndex < array_size( ClientState::VertexArray::bindings ))
{
RegalAssertArrayIndex( ClientState::VertexArray::bindings, g.bindingIndex );
ClientState::VertexBufferBindPoint &b = ClientState::VertexArray::bindings[g.bindingIndex];
GLvoid *p = reinterpret_cast<GLvoid *>(b.offset + (b.stride*basevertex));
@ -143,12 +148,13 @@ struct BaseVertex : public ClientState::VertexArray
dt.call(&dt.glBindBuffer)(GL_ARRAY_BUFFER, currentVBO);
}
GLsizei index = static_cast<GLsizei>(ii);
if (g.isInteger)
dt.call(&dt.glVertexAttribIPointer)(ii, g.size, g.type, b.stride, p);
dt.call(&dt.glVertexAttribIPointer)(index, g.size, g.type, b.stride, p);
else if (g.isLong)
dt.call(&dt.glVertexAttribLPointer)(ii, g.size, g.type, b.stride, p);
dt.call(&dt.glVertexAttribLPointer)(index, g.size, g.type, b.stride, p);
else
dt.call(&dt.glVertexAttribPointer)(ii, g.size, g.type, g.normalized, b.stride, p);
dt.call(&dt.glVertexAttribPointer)(index, g.size, g.type, g.normalized, b.stride, p);
}
}

View file

@ -154,7 +154,7 @@ namespace ClientState
GLuint buffer; // GL_x_ARRAY_BUFFER_BINDING
GLint size; // GL_x_ARRAY_SIZE
GLenum type; // GL_x_ARRAY_TYPE
GLint stride; // GL_x_ARRAY_STRIDE
GLsizei stride; // GL_x_ARRAY_STRIDE
inline NamedVertexArray()
{
@ -672,9 +672,16 @@ namespace ClientState
arrayBufferBinding = 0;
vertexArrayBinding = 0;
for (GLuint ii=0; ii<nNamedArrays; ii++)
size_t n = array_size( named );
for (size_t ii=0; ii<n; ii++)
named[ii].Reset();
RegalAssertArrayIndex( named, NORMAL );
RegalAssertArrayIndex( named, FOG_COORD );
RegalAssertArrayIndex( named, SECONDARY_COLOR );
RegalAssertArrayIndex( named, INDEX );
RegalAssertArrayIndex( named, EDGE_FLAG );
named[NORMAL].size = 3;
named[FOG_COORD].size = 1;
named[SECONDARY_COLOR].size = 3;
@ -682,20 +689,25 @@ namespace ClientState
named[EDGE_FLAG].size = 1;
named[EDGE_FLAG].type = GL_BOOL;
for (GLuint ii=0; ii<REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS; ii++)
n = array_size( bindings );
for (size_t ii=0; ii<n; ii++)
bindings[ii].Reset();
for (GLuint ii=0; ii<REGAL_EMU_MAX_VERTEX_ATTRIBS; ii++)
n = array_size( generic );
for (GLuint ii=0; ii<n; ii++)
generic[ii].Reset(ii);
}
VertexArray &swap(VertexArray &other)
{
for (GLuint ii=0; ii<nNamedArrays; ii++)
size_t n = array_size( named );
for (size_t ii=0; ii<n; ii++)
named[ii].swap(other.named[ii]);
for (GLuint ii=0; ii<REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS; ii++)
n = array_size( bindings );
for (size_t ii=0; ii<n; ii++)
bindings[ii].swap(other.bindings[ii]);
for (GLuint ii=0; ii<REGAL_EMU_MAX_VERTEX_ATTRIBS; ii++)
n = array_size( generic );
for (size_t ii=0; ii<n; ii++)
generic[ii].swap(other.generic[ii]);
std::swap(elementArrayBufferBinding,other.elementArrayBufferBinding);
std::swap(clientActiveTexture,other.clientActiveTexture);
@ -712,12 +724,15 @@ namespace ClientState
dt.call(&dt.glGetIntegerv)(GL_VERTEX_ARRAY_BINDING,reinterpret_cast<GLint*>(&vertexArrayBinding));
if (vertexArrayBinding)
dt.call(&dt.glBindVertexArray)(0);
for (GLuint ii=0; ii<nNamedArrays; ii++)
size_t n = array_size( named );
for (size_t ii=0; ii<n; ii++)
named[ii].get(dt,static_cast<vaName>(ii));
for (GLuint ii=0; ii<REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS; ii++)
bindings[ii].get(dt,ii);
for (GLuint ii=0; ii<REGAL_EMU_MAX_VERTEX_ATTRIBS; ii++)
generic[ii].get(dt,ii);
n = array_size( bindings );
for (size_t ii=0; ii<n; ii++)
bindings[ii].get(dt,static_cast<GLuint>(ii));
n = array_size( generic );
for (size_t ii=0; ii<n; ii++)
generic[ii].get(dt,static_cast<GLuint>(ii));
dt.call(&dt.glGetIntegerv)(GL_ELEMENT_ARRAY_BUFFER_BINDING,reinterpret_cast<GLint*>(&elementArrayBufferBinding));
dt.call(&dt.glGetIntegerv)(GL_CLIENT_ACTIVE_TEXTURE,reinterpret_cast<GLint*>(&clientActiveTexture));
primitiveRestartFixedIndex = dt.call(&dt.glIsEnabled)(GL_PRIMITIVE_RESTART_FIXED_INDEX);
@ -732,12 +747,15 @@ namespace ClientState
const VertexArray &set(DispatchTableGL &dt, bool driverAllowsVertexAttributeArraysWithoutBoundBuffer) const
{
dt.call(&dt.glBindVertexArray)(0);
for (GLint ii=nNamedArrays-1; ii>=0; ii--)
named[ii].set(dt,static_cast<vaName>(ii),driverAllowsVertexAttributeArraysWithoutBoundBuffer);
for (GLuint ii=0; ii<REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS; ii++)
bindings[ii].set(dt,ii);
for (GLint ii=REGAL_EMU_MAX_VERTEX_ATTRIBS-1; ii>=0; ii--)
generic[ii].set(dt,ii);
size_t n = array_size( named );
for (size_t ii=0; ii<n; ii++)
named[n-ii-1].set(dt,static_cast<vaName>(n-ii-1),driverAllowsVertexAttributeArraysWithoutBoundBuffer);
n = array_size( bindings );
for (size_t ii=0; ii<n; ii++)
bindings[ii].set(dt,static_cast<GLuint>(ii));
n = array_size( generic );
for (size_t ii=0; ii<n; ii++)
generic[n-ii-1].set(dt,static_cast<GLuint>(n-ii-1));
dt.call(&dt.glBindBuffer)(GL_ELEMENT_ARRAY_BUFFER,elementArrayBufferBinding);
dt.call(&dt.glClientActiveTexture)(clientActiveTexture);
if (primitiveRestartFixedIndex)
@ -761,12 +779,15 @@ namespace ClientState
vertexArrayBinding = 0;
dt.call(&dt.glBindVertexArray)(vertexArrayBinding);
}
for (GLint ii=nNamedArrays-1; ii>=0; ii--)
named[ii].transition(dt,to.named[ii],static_cast<vaName>(ii),driverAllowsVertexAttributeArraysWithoutBoundBuffer);
for (GLuint ii=0; ii<REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS; ii++)
bindings[ii].transition(dt,to.bindings[ii],ii);
for (GLint ii=REGAL_EMU_MAX_VERTEX_ATTRIBS-1; ii>=0; ii--)
generic[ii].transition(dt,to.generic[ii],ii);
size_t n = array_size( named );
for (size_t ii=0; ii<n; ii++)
named[n-ii-1].transition(dt,to.named[n-ii-1],static_cast<vaName>(n-ii-1),driverAllowsVertexAttributeArraysWithoutBoundBuffer);
n = array_size( bindings );
for (size_t ii=0; ii<n; ii++)
bindings[ii].transition(dt,to.bindings[ii],static_cast<GLuint>(ii));
n = array_size( generic );
for (size_t ii=0; ii<n; ii++)
generic[n-ii-1].transition(dt,to.generic[n-ii-1],static_cast<GLuint>(n-ii-1));
if (elementArrayBufferBinding != to.elementArrayBufferBinding) {
elementArrayBufferBinding = to.elementArrayBufferBinding;
dt.call(&dt.glBindBuffer)(GL_ELEMENT_ARRAY_BUFFER,elementArrayBufferBinding);
@ -806,15 +827,18 @@ namespace ClientState
std::string toString(const char *delim = "\n") const
{
string_list tmp;
for (GLuint ii=0; ii<nNamedArrays; ii++)
size_t n = array_size( named );
for (size_t ii=0; ii<n; ii++)
named[ii].toString(static_cast<vaName>(ii),delim);
for (GLuint ii=0; ii<REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS; ii++)
bindings[ii].toString(ii,delim);
for (GLuint ii=0; ii<REGAL_EMU_MAX_VERTEX_ATTRIBS; ii++)
generic[ii].toString(ii,delim);
n = array_size( bindings );
for (size_t ii=0; ii<n; ii++)
bindings[ii].toString(static_cast<GLuint>(ii),delim);
n = array_size( generic );
for (size_t ii=0; ii<n; ii++)
generic[ii].toString(static_cast<GLuint>(ii),delim);
tmp << print_string("glBindBuffer(GL_ELEMENT_ARRAY_BUFFER",elementArrayBufferBinding,");",delim);
tmp << print_string("glClientActiveTexture(",clientActiveTexture,");",delim);
tmp << print_string("glClientActiveTexture(",Token::GLtextureToString(clientActiveTexture),");",delim);
if (primitiveRestartFixedIndex)
tmp << print_string("glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);",delim);
@ -886,29 +910,39 @@ namespace ClientState
switch (cap)
{
case GL_VERTEX_ARRAY:
RegalAssertArrayIndex( named, VERTEX );
named[VERTEX].enabled = enabled;
break;
case GL_NORMAL_ARRAY:
RegalAssertArrayIndex( named, NORMAL );
named[NORMAL].enabled = enabled;
break;
case GL_FOG_COORD_ARRAY:
RegalAssertArrayIndex( named, FOG_COORD );
named[FOG_COORD].enabled = enabled;
break;
case GL_COLOR_ARRAY:
RegalAssertArrayIndex( named, COLOR );
named[COLOR].enabled = enabled;
break;
case GL_SECONDARY_COLOR_ARRAY:
RegalAssertArrayIndex( named, SECONDARY_COLOR );
named[SECONDARY_COLOR].enabled = enabled;
break;
case GL_INDEX_ARRAY:
RegalAssertArrayIndex( named, INDEX );
named[INDEX].enabled = enabled;
break;
case GL_EDGE_FLAG_ARRAY:
RegalAssertArrayIndex( named, EDGE_FLAG );
named[EDGE_FLAG].enabled = enabled;
break;
case GL_TEXTURE_COORD_ARRAY:
if (index < REGAL_EMU_MAX_TEXTURE_COORDS)
if ( (index+7) < array_size( named ) )
{
RegalAssertArrayIndex( named, index+7 );
named[index+7].enabled = enabled;
}
break;
default:
break;
@ -975,9 +1009,13 @@ namespace ClientState
arrayBufferBinding = 0;
if (buffers[ii] == elementArrayBufferBinding)
elementArrayBufferBinding = 0;
for (GLsizei jj=0; jj<REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS; jj++)
size_t nBindings = array_size( bindings );
for (size_t jj=0; jj<nBindings; jj++)
{
RegalAssertArrayIndex( bindings, jj );
if (buffers[ii] == bindings[jj].buffer)
bindings[jj].buffer = 0;
}
}
}
@ -1079,24 +1117,24 @@ namespace ClientState
inline void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer)
{
if (!vertexArrayBinding &&
index < REGAL_EMU_MAX_VERTEX_ATTRIBS &&
index < REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS)
index < array_size( generic ) &&
index < array_size( bindings ))
glVertexArrayVertexAttribOffsetEXT(vertexArrayBinding, arrayBufferBinding, index, size, type, normalized, stride, ((char *)pointer - (char *)NULL));
}
inline void glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer)
{
if (!vertexArrayBinding &&
index < REGAL_EMU_MAX_VERTEX_ATTRIBS &&
index < REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS)
index < array_size( generic ) &&
index < array_size( bindings ))
glVertexArrayVertexAttribIOffsetEXT(vertexArrayBinding, arrayBufferBinding, index, size, type, stride, ((char *)pointer - (char *)NULL));
}
void glVertexAttribLPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer)
{
if (!vertexArrayBinding &&
index < REGAL_EMU_MAX_VERTEX_ATTRIBS &&
index < REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS)
index < array_size( generic ) &&
index < array_size( bindings ))
{
glVertexAttribLFormat(index, size, type, 0);
glVertexAttribBinding(index, index);
@ -1107,11 +1145,12 @@ namespace ClientState
void glBindVertexBuffers( GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides )
{
if (!vertexArrayBinding && ((first + count) >= first) && (first + count) <= REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS)
if (!vertexArrayBinding && ((first + count) >= first) && (first + count) <= array_size( bindings ))
{
if (buffers)
for (GLsizei ii = 0; ii < count; ii++)
{
RegalAssertArrayIndex( bindings, first );
bindings[first].buffer = buffers[ii];
bindings[first].offset = offsets[ii];
bindings[first].stride = strides[ii];
@ -1120,6 +1159,7 @@ namespace ClientState
else
for (GLsizei ii = 0; ii < count; ii++)
{
RegalAssertArrayIndex( bindings, first );
bindings[first].buffer = 0;
bindings[first].offset = 0;
bindings[first].stride = 16;
@ -1136,9 +1176,11 @@ namespace ClientState
inline void glVertexAttribDivisor(GLuint index, GLuint divisor)
{
if (!vertexArrayBinding &&
index < REGAL_EMU_MAX_VERTEX_ATTRIBS &&
index < REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS)
index < array_size( generic ) &&
index < array_size( bindings ) )
{
RegalAssertArrayIndex( generic, index );
RegalAssertArrayIndex( bindings, index );
generic[index].bindingIndex = index;
bindings[index].divisor = divisor;
}
@ -1146,32 +1188,45 @@ namespace ClientState
inline void glVertexBindingDivisor(GLuint bindingindex, GLuint divisor)
{
if (!vertexArrayBinding && bindingindex < REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS)
if (!vertexArrayBinding && bindingindex < array_size( bindings ))
{
RegalAssertArrayIndex( bindings, bindingindex );
bindings[bindingindex].divisor = divisor;
}
}
inline void glEnableVertexAttribArray(GLuint index)
{
if (!vertexArrayBinding && index < REGAL_EMU_MAX_VERTEX_ATTRIBS)
if (!vertexArrayBinding && index < array_size( generic ))
{
RegalAssertArrayIndex( generic, index );
generic[index].enabled = GL_TRUE;
}
}
inline void glDisableVertexAttribArray(GLuint index)
{
if (!vertexArrayBinding && index < REGAL_EMU_MAX_VERTEX_ATTRIBS)
if (!vertexArrayBinding && index < array_size( generic ))
{
RegalAssertArrayIndex( generic, index );
generic[index].enabled = GL_FALSE;
}
}
inline void glVertexAttribBinding(GLuint attribindex, GLuint bindingindex)
{
if (!vertexArrayBinding && attribindex < REGAL_EMU_MAX_VERTEX_ATTRIBS)
if (!vertexArrayBinding && attribindex < array_size( generic ))
{
RegalAssertArrayIndex( generic, attribindex );
generic[attribindex].bindingIndex = bindingindex;
}
}
inline void glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)
{
if (!vertexArrayBinding && attribindex < REGAL_EMU_MAX_VERTEX_ATTRIBS)
if (!vertexArrayBinding && attribindex < array_size( generic ))
{
RegalAssertArrayIndex( generic, attribindex );
generic[attribindex].size = size;
generic[attribindex].type = type;
generic[attribindex].relativeOffset = relativeoffset;
@ -1183,8 +1238,9 @@ namespace ClientState
inline void glVertexAttribLFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)
{
if (!vertexArrayBinding && attribindex < REGAL_EMU_MAX_VERTEX_ATTRIBS)
if (!vertexArrayBinding && attribindex < array_size( generic ))
{
RegalAssertArrayIndex( generic, attribindex );
generic[attribindex].size = size;
generic[attribindex].type = type;
generic[attribindex].relativeOffset = relativeoffset;
@ -1196,8 +1252,9 @@ namespace ClientState
inline void glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset)
{
if (!vertexArrayBinding && attribindex < REGAL_EMU_MAX_VERTEX_ATTRIBS)
if (!vertexArrayBinding && attribindex < array_size( generic ))
{
RegalAssertArrayIndex( generic, attribindex );
generic[attribindex].size = size;
generic[attribindex].type = type;
generic[attribindex].relativeOffset = relativeoffset;
@ -1209,8 +1266,11 @@ namespace ClientState
inline void glClientActiveTexture(GLenum texture)
{
if ( (texture - GL_TEXTURE0) < REGAL_EMU_MAX_TEXTURE_COORDS)
GLuint index = texture - GL_TEXTURE0;
if ( texture >= GL_TEXTURE0 && index < array_size( generic ))
clientActiveTexture = texture;
else
Warning( "Client active texture out of range: ", Token::GLtextureToString(texture), " > ", Token::GLtextureToString(static_cast<GLenum>(GL_TEXTURE0 + array_size( generic ) - 1)));
}
inline void glPrimitiveRestartIndex(GLuint index)
@ -1254,13 +1314,13 @@ namespace ClientState
inline void glEnableVertexArrayAttribEXT(GLuint vaobj, GLuint index)
{
if (!vaobj && index < REGAL_EMU_MAX_VERTEX_ATTRIBS)
if (!vaobj && index < array_size( generic ))
generic[index].enabled = GL_TRUE;
}
inline void glDisableVertexArrayAttribEXT(GLuint vaobj, GLuint index)
{
if (!vaobj && index < REGAL_EMU_MAX_VERTEX_ATTRIBS)
if (!vaobj && index < array_size( generic ))
generic[index].enabled = GL_FALSE;
}
@ -1268,6 +1328,7 @@ namespace ClientState
{
if (!vaobj)
{
RegalAssertArrayIndex( named, VERTEX );
named[VERTEX].buffer = buffer;
named[VERTEX].size = size;
named[VERTEX].type = type;
@ -1280,6 +1341,7 @@ namespace ClientState
{
if (!vaobj)
{
RegalAssertArrayIndex( named, NORMAL );
named[NORMAL].buffer = buffer;
named[NORMAL].size = 3;
named[NORMAL].type = type;
@ -1292,6 +1354,7 @@ namespace ClientState
{
if (!vaobj)
{
RegalAssertArrayIndex( named, COLOR );
named[COLOR].buffer = buffer;
named[COLOR].size = size;
named[COLOR].type = type;
@ -1304,6 +1367,7 @@ namespace ClientState
{
if (!vaobj)
{
RegalAssertArrayIndex( named, SECONDARY_COLOR );
named[SECONDARY_COLOR].buffer = buffer;
named[SECONDARY_COLOR].size = size;
named[SECONDARY_COLOR].type = type;
@ -1316,6 +1380,7 @@ namespace ClientState
{
if (!vaobj)
{
RegalAssertArrayIndex( named, INDEX );
named[INDEX].buffer = buffer;
named[INDEX].size = 1;
named[INDEX].type = type;
@ -1328,6 +1393,7 @@ namespace ClientState
{
if (!vaobj)
{
RegalAssertArrayIndex( named, EDGE_FLAG );
named[EDGE_FLAG].buffer = buffer;
named[EDGE_FLAG].size = 1;
named[EDGE_FLAG].type = GL_BOOL;
@ -1340,6 +1406,7 @@ namespace ClientState
{
if (!vaobj)
{
RegalAssertArrayIndex( named, FOG_COORD );
named[FOG_COORD].buffer = buffer;
named[FOG_COORD].size = 1;
named[FOG_COORD].type = type;
@ -1350,12 +1417,13 @@ namespace ClientState
void glVertexArrayMultiTexCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLenum texture, GLint size, GLenum type, GLsizei stride, GLintptr offset)
{
if (!vaobj)
if (!vaobj && texture >= GL_TEXTURE0)
{
GLuint index = texture - GL_TEXTURE0;
if (index < REGAL_EMU_MAX_TEXTURE_COORDS && index <= texture)
if ( (index+7) < array_size( named ) )
{
GLuint ii = 7 + index;
RegalAssertArrayIndex( named, ii );
named[ii].buffer = buffer;
named[ii].size = size;
named[ii].type = type;

View file

@ -56,7 +56,7 @@ using namespace boost::print;
#include "RegalToken.h"
#include "RegalContext.h"
#include "RegalContextInfo.h"
#include "RegalIff.h" // For REGAL_MAX_VERTEX_ATTRIBS
#include "RegalEmu.h"
REGAL_GLOBAL_END
@ -794,8 +794,26 @@ ContextInfo::ContextInfo()
egl_nv_system_time(false),
#endif
maxVertexAttribs(0),
maxVaryings(0)
gl_max_attrib_stack_depth(0),
gl_max_client_attrib_stack_depth(0),
gl_max_combined_texture_image_units(0),
gl_max_draw_buffers(0),
gl_max_texture_coords(0),
gl_max_texture_units(0),
gl_max_vertex_attrib_bindings(0),
gl_max_vertex_attribs(0),
gl_max_viewports(0),
max_attrib_stack_depth(0),
max_client_attrib_stack_depth(0),
max_combined_texture_image_units(0),
max_draw_buffers(0),
max_texture_coords(0),
max_texture_units(0),
max_vertex_attrib_bindings(0),
max_vertex_attribs(0),
max_viewports(0),
gl_max_varying_floats(0)
{
Internal("ContextInfo::ContextInfo","()");
}
@ -1743,28 +1761,55 @@ ContextInfo::init(const RegalContext &context)
RegalAssert(context.dispatcher.driver.glGetIntegerv);
if (es1)
{
maxVertexAttribs = 8;
maxVaryings = 0;
gl_max_attrib_stack_depth = 0;
gl_max_client_attrib_stack_depth = 0;
gl_max_combined_texture_image_units = 0;
gl_max_draw_buffers = 0;
gl_max_texture_coords = 0;
gl_max_texture_units = 0;
gl_max_vertex_attribs = 0;
gl_max_vertex_attrib_bindings = 0;
gl_max_viewports = 0;
gl_max_vertex_attribs = 8;
}
else
{
context.dispatcher.driver.glGetIntegerv( GL_MAX_VERTEX_ATTRIBS, reinterpret_cast<GLint *>(&maxVertexAttribs));
context.dispatcher.driver.glGetIntegerv( es2 ? GL_MAX_VARYING_VECTORS : GL_MAX_VARYING_FLOATS, reinterpret_cast<GLint *>(&maxVaryings));
context.dispatcher.driver.glGetIntegerv( GL_MAX_ATTRIB_STACK_DEPTH, reinterpret_cast<GLint *>(&gl_max_attrib_stack_depth));
context.dispatcher.driver.glGetIntegerv( GL_MAX_CLIENT_ATTRIB_STACK_DEPTH, reinterpret_cast<GLint *>(&gl_max_client_attrib_stack_depth));
context.dispatcher.driver.glGetIntegerv( GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, reinterpret_cast<GLint *>(&gl_max_combined_texture_image_units));
context.dispatcher.driver.glGetIntegerv( GL_MAX_DRAW_BUFFERS, reinterpret_cast<GLint *>(&gl_max_draw_buffers));
context.dispatcher.driver.glGetIntegerv( GL_MAX_TEXTURE_COORDS, reinterpret_cast<GLint *>(&gl_max_texture_coords));
context.dispatcher.driver.glGetIntegerv( GL_MAX_TEXTURE_UNITS, reinterpret_cast<GLint *>(&gl_max_texture_units));
context.dispatcher.driver.glGetIntegerv( GL_MAX_VERTEX_ATTRIBS, reinterpret_cast<GLint *>(&gl_max_vertex_attribs));
context.dispatcher.driver.glGetIntegerv( GL_MAX_VERTEX_ATTRIB_BINDINGS, reinterpret_cast<GLint *>(&gl_max_vertex_attrib_bindings));
context.dispatcher.driver.glGetIntegerv( GL_MAX_VIEWPORTS, reinterpret_cast<GLint *>(&gl_max_viewports));
context.dispatcher.driver.glGetIntegerv( es2 ? GL_MAX_VARYING_VECTORS : GL_MAX_VARYING_FLOATS, reinterpret_cast<GLint *>(&gl_max_varying_floats));
}
Info("OpenGL v attribs : ",maxVertexAttribs);
Info("OpenGL varyings : ",maxVaryings);
max_attrib_stack_depth = std::min( gl_max_attrib_stack_depth, static_cast<GLuint>(REGAL_EMU_MAX_ATTRIB_STACK_DEPTH) );
max_client_attrib_stack_depth = std::min( gl_max_client_attrib_stack_depth, static_cast<GLuint>(REGAL_EMU_MAX_CLIENT_ATTRIB_STACK_DEPTH) );
max_combined_texture_image_units = std::min( gl_max_combined_texture_image_units, static_cast<GLuint>(REGAL_EMU_MAX_COMBINED_TEXTURE_IMAGE_UNITS) );
max_draw_buffers = std::min( gl_max_draw_buffers, static_cast<GLuint>(REGAL_EMU_MAX_DRAW_BUFFERS) );
max_texture_coords = std::min( gl_max_texture_coords, static_cast<GLuint>(REGAL_EMU_MAX_TEXTURE_COORDS) );
max_texture_units = std::min( gl_max_texture_units, static_cast<GLuint>(REGAL_EMU_MAX_TEXTURE_UNITS) );
max_vertex_attribs = std::min( gl_max_vertex_attribs, static_cast<GLuint>(REGAL_EMU_MAX_VERTEX_ATTRIBS) );
max_vertex_attrib_bindings = std::min( gl_max_vertex_attrib_bindings, static_cast<GLuint>(REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS) );
max_viewports = std::min( gl_max_viewports, static_cast<GLuint>(REGAL_EMU_MAX_VIEWPORTS) );
if (maxVertexAttribs > REGAL_EMU_IFF_VERTEX_ATTRIBS)
maxVertexAttribs = REGAL_EMU_IFF_VERTEX_ATTRIBS;
Info("OpenGL v attribs : ",gl_max_vertex_attribs);
Info("OpenGL varyings : ",gl_max_varying_floats);
if (gl_max_vertex_attribs > REGAL_EMU_MAX_VERTEX_ATTRIBS)
gl_max_vertex_attribs = REGAL_EMU_MAX_VERTEX_ATTRIBS;
// Qualcomm fails with float4 attribs with 256 byte stride, so artificially limit to 8 attribs (n*16 is used
// as the stride in RegalIFF). WebGL (and Pepper) explicitly disallows stride > 255 as well.
if (vendor == "Qualcomm" || vendor == "Chromium" || webgl)
maxVertexAttribs = 8;
gl_max_vertex_attribs = 8;
Info("Regal v attribs : ",maxVertexAttribs);
Info("Regal v attribs : ",gl_max_vertex_attribs);
}
bool

View file

@ -825,8 +825,32 @@ struct ContextInfo
GLboolean egl_nv_system_time : 1;
#endif
GLuint maxVertexAttribs;
GLuint maxVaryings;
// Implementation dependent values
GLuint gl_max_attrib_stack_depth;
GLuint gl_max_client_attrib_stack_depth;
GLuint gl_max_combined_texture_image_units;
GLuint gl_max_draw_buffers;
GLuint gl_max_texture_coords;
GLuint gl_max_texture_units;
GLuint gl_max_vertex_attrib_bindings;
GLuint gl_max_vertex_attribs;
GLuint gl_max_viewports;
// Max values currently being used
GLuint max_attrib_stack_depth;
GLuint max_client_attrib_stack_depth;
GLuint max_combined_texture_image_units;
GLuint max_draw_buffers;
GLuint max_texture_coords;
GLuint max_texture_units;
GLuint max_vertex_attrib_bindings;
GLuint max_vertex_attribs;
GLuint max_viewports;
GLuint gl_max_varying_floats;
};
REGAL_NAMESPACE_END

View file

@ -10098,7 +10098,12 @@ static void REGAL_CALL emu_glPixelStorei(GLenum pname, GLint param)
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc) break;
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowPixelStore( pname, param );
}
#endif
case 1 :
#if REGAL_EMU_FILTER
@ -10125,16 +10130,6 @@ static void REGAL_CALL emu_glPixelStorei(GLenum pname, GLint param)
case 4 :
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowPixelStore( pname, param );
_context->dispatcher.emulation.glPixelStorei( pname, param );
return;
}
#endif
case 1 :
#if REGAL_EMU_FILTER
if (_context->filt)
@ -16333,7 +16328,9 @@ static void REGAL_CALL emu_glTexGend(GLenum coord, GLenum pname, GLdouble param)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 5;
_context->iff->TexGen( coord, pname, param );
if ( ! _context->iff->TexGen( coord, pname, param ) ) {
_context->dispatcher.emulation.glTexGend( coord, pname, param );
}
return;
}
#endif
@ -16395,7 +16392,9 @@ static void REGAL_CALL emu_glTexGendv(GLenum coord, GLenum pname, const GLdouble
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 5;
_context->iff->TexGen( coord, pname, params );
if ( ! _context->iff->TexGen( coord, pname, params ) ) {
_context->dispatcher.emulation.glTexGendv( coord, pname, params );
}
return;
}
#endif
@ -16467,7 +16466,9 @@ static void REGAL_CALL emu_glTexGenf(GLenum coord, GLenum pname, GLfloat param)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 5;
_context->iff->TexGen( coord, pname, param );
if ( ! _context->iff->TexGen( coord, pname, param ) ) {
_context->dispatcher.emulation.glTexGenf( coord, pname, param );
}
return;
}
#endif
@ -16539,7 +16540,9 @@ static void REGAL_CALL emu_glTexGenfv(GLenum coord, GLenum pname, const GLfloat
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 5;
_context->iff->TexGen( coord, pname, params );
if ( ! _context->iff->TexGen( coord, pname, params ) ) {
_context->dispatcher.emulation.glTexGenfv( coord, pname, params );
}
return;
}
#endif
@ -16611,7 +16614,9 @@ static void REGAL_CALL emu_glTexGeni(GLenum coord, GLenum pname, GLint param)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 5;
_context->iff->TexGen( coord, pname, param );
if ( ! _context->iff->TexGen( coord, pname, param ) ) {
_context->dispatcher.emulation.glTexGeni( coord, pname, param );
}
return;
}
#endif
@ -16683,7 +16688,9 @@ static void REGAL_CALL emu_glTexGeniv(GLenum coord, GLenum pname, const GLint *p
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 5;
_context->iff->TexGen( coord, pname, params );
if ( ! _context->iff->TexGen( coord, pname, params ) ) {
_context->dispatcher.emulation.glTexGeniv( coord, pname, params );
}
return;
}
#endif
@ -16819,7 +16826,12 @@ static void REGAL_CALL emu_glTexImage2D(GLenum target, GLint level, GLint intern
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc) break;
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowTexImage2D( target, level, format, type );
}
#endif
case 1 :
#if REGAL_EMU_FILTER
@ -16855,16 +16867,6 @@ static void REGAL_CALL emu_glTexImage2D(GLenum target, GLint level, GLint intern
case 4 :
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowTexImage2D( target, level, format, type );
_context->dispatcher.emulation.glTexImage2D( target, level, internalformat, width, height, border, format, type, pixels );
return;
}
#endif
case 1 :
#if REGAL_EMU_FILTER
if (_context->filt)
@ -19012,7 +19014,12 @@ static void REGAL_CALL emu_glBindTexture(GLenum target, GLuint texture)
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc) break;
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowBindTexture( target, texture );
}
#endif
case 1 :
#if REGAL_EMU_FILTER
@ -19071,16 +19078,6 @@ static void REGAL_CALL emu_glBindTexture(GLenum target, GLuint texture)
#endif
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowBindTexture( target, texture );
_context->dispatcher.emulation.glBindTexture( target, texture );
return;
}
#endif
case 1 :
#if REGAL_EMU_FILTER
if (_context->filt)
@ -19312,7 +19309,12 @@ static void REGAL_CALL emu_glDeleteTextures(GLsizei n, const GLuint *textures)
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc) break;
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowDeleteTextures( n, textures );
}
#endif
case 1 :
default:
@ -19332,29 +19334,6 @@ static void REGAL_CALL emu_glDeleteTextures(GLsizei n, const GLuint *textures)
return;
}
#endif
case 14 :
case 13 :
case 12 :
case 11 :
case 10 :
case 9 :
case 8 :
case 7 :
case 6 :
case 5 :
case 4 :
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowDeleteTextures( n, textures );
_context->dispatcher.emulation.glDeleteTextures( n, textures );
return;
}
#endif
case 1 :
default:
{
@ -19864,6 +19843,7 @@ static void REGAL_CALL emu_glGenTextures(GLsizei n, GLuint *textures)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->dispatcher.emulation.glGenTextures( n, textures );
_context->texc->ShadowGenTextures( n, textures );
return;
@ -20458,6 +20438,7 @@ static void REGAL_CALL emu_glTexSubImage2D(GLenum target, GLint level, GLint xof
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
GLenum targetFormat;
GLenum targetType;
_context->texc->GetFormatAndType( target, level, &targetFormat, &targetType );
@ -20884,7 +20865,12 @@ static void REGAL_CALL emu_glActiveTexture(GLenum texture)
case 7 :
case 6 :
#if REGAL_EMU_IFF
if (_context->iff) break;
if (_context->iff)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 5;
_context->iff->ShadowActiveTexture( texture );
}
#endif
case 5 :
#if REGAL_EMU_SO
@ -20897,7 +20883,12 @@ static void REGAL_CALL emu_glActiveTexture(GLenum texture)
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc) break;
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowActiveTexture( texture );
}
#endif
case 1 :
default:
@ -20917,17 +20908,6 @@ static void REGAL_CALL emu_glActiveTexture(GLenum texture)
case 8 :
case 7 :
case 6 :
#if REGAL_EMU_IFF
if (_context->iff)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 5;
if( ! _context->iff->ShadowActiveTexture( texture ) ) {
_context->dispatcher.emulation.glActiveTexture( texture );
}
return;
}
#endif
case 5 :
#if REGAL_EMU_SO
if (_context->so)
@ -20953,18 +20933,6 @@ static void REGAL_CALL emu_glActiveTexture(GLenum texture)
return;
}
#endif
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowActiveTexture( texture );
_context->dispatcher.emulation.glActiveTexture( texture );
return;
}
#endif
case 1 :
default:
{
@ -34801,7 +34769,12 @@ static void REGAL_CALL emu_glGenerateMipmap(GLenum target)
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc) break;
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowGenerateMipmap( target );
}
#endif
case 1 :
#if REGAL_EMU_FILTER
@ -34828,16 +34801,6 @@ static void REGAL_CALL emu_glGenerateMipmap(GLenum target)
case 4 :
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowGenerateMipmap( target );
_context->dispatcher.emulation.glGenerateMipmap( target );
return;
}
#endif
case 1 :
#if REGAL_EMU_FILTER
if (_context->filt)
@ -36541,7 +36504,12 @@ static void REGAL_CALL emu_glActiveTextureARB(GLenum texture)
case 7 :
case 6 :
#if REGAL_EMU_IFF
if (_context->iff) break;
if (_context->iff)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 5;
_context->iff->ShadowActiveTexture( texture );
}
#endif
case 5 :
#if REGAL_EMU_SO
@ -36554,7 +36522,12 @@ static void REGAL_CALL emu_glActiveTextureARB(GLenum texture)
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc) break;
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowActiveTexture( texture );
}
#endif
case 1 :
#if REGAL_EMU_FILTER
@ -36577,17 +36550,6 @@ static void REGAL_CALL emu_glActiveTextureARB(GLenum texture)
case 8 :
case 7 :
case 6 :
#if REGAL_EMU_IFF
if (_context->iff)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 5;
if( ! _context->iff->ShadowActiveTexture( texture ) ) {
_context->dispatcher.emulation.glActiveTextureARB( texture );
}
return;
}
#endif
case 5 :
#if REGAL_EMU_SO
if (_context->so)
@ -36615,16 +36577,6 @@ static void REGAL_CALL emu_glActiveTextureARB(GLenum texture)
#endif
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowActiveTexture( texture );
_context->dispatcher.emulation.glActiveTexture( texture );
return;
}
#endif
case 1 :
#if REGAL_EMU_FILTER
if (_context->filt)
@ -64825,7 +64777,12 @@ static void REGAL_CALL emu_glGenerateMipmapEXT(GLenum target)
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc) break;
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowGenerateMipmap( target );
}
#endif
case 1 :
#if REGAL_EMU_FILTER
@ -64852,16 +64809,6 @@ static void REGAL_CALL emu_glGenerateMipmapEXT(GLenum target)
case 4 :
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowGenerateMipmap( target );
_context->dispatcher.emulation.glGenerateMipmap( target );
return;
}
#endif
case 1 :
#if REGAL_EMU_FILTER
if (_context->filt)
@ -67108,7 +67055,12 @@ static void REGAL_CALL emu_glBindTextureEXT(GLenum target, GLuint texture)
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc) break;
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowBindTexture( target, texture );
}
#endif
case 1 :
default:
@ -67141,18 +67093,6 @@ static void REGAL_CALL emu_glBindTextureEXT(GLenum target, GLuint texture)
return;
}
#endif
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowBindTexture( target, texture );
_context->dispatcher.emulation.glBindTexture( target, texture );
return;
}
#endif
case 1 :
default:
{
@ -67196,31 +67136,6 @@ static void REGAL_CALL emu_glDeleteTexturesEXT(GLsizei n, const GLuint *textures
}
#endif
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc) break;
#endif
case 1 :
default:
break;
}
// impl
switch( _context->emuLevel )
{
case 15 :
case 14 :
case 13 :
case 12 :
case 11 :
case 10 :
case 9 :
case 8 :
case 7 :
case 6 :
case 5 :
case 4 :
case 3 :
case 2 :
#if REGAL_EMU_TEXC
if (_context->texc)
@ -67228,21 +67143,16 @@ static void REGAL_CALL emu_glDeleteTexturesEXT(GLsizei n, const GLuint *textures
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->texc->ShadowDeleteTextures( n, textures );
_context->dispatcher.emulation.glDeleteTextures( n, textures );
return;
}
#endif
case 1 :
default:
{
DispatchTableGL *_next = _dispatch.next();
RegalAssert(_next);
_next->call(&_next->glDeleteTexturesEXT)(n, textures);
break;
}
}
DispatchTableGL *_next = _dispatch.next();
RegalAssert(_next);
_next->call(& _next->glDeleteTexturesEXT)(n, textures);
}
static void REGAL_CALL emu_glGenTexturesEXT(GLsizei n, GLuint *textures)
@ -67298,6 +67208,7 @@ static void REGAL_CALL emu_glGenTexturesEXT(GLsizei n, GLuint *textures)
{
Push<int> pushLevel(_context->emuLevel);
_context->emuLevel = 1;
_context->dispatcher.emulation.glGenTextures( n, textures );
_context->texc->ShadowGenTextures( n, textures );
return;

View file

@ -65,7 +65,7 @@ DispatcherGlobal::DispatcherGlobal()
// have to check this early for the global dispatches, otherwise we'd use Config
#if REGAL_TRACE
{
{
getEnv( "REGAL_TRACE", Config::enableTrace);
::memset(&trace, 0, sizeof(trace) );
InitDispatchTableGlobalTrace(trace);

View file

@ -154,6 +154,7 @@ struct Dsa
if( NotMatrixMode( mode ) ) {
dsa.matrixMode = mode;
switch( mode ) {
//<> dsn: wtf? Why are these accepted? And why only up to GL_TEXTURE3?
case GL_TEXTURE0: case GL_TEXTURE1: case GL_TEXTURE2: case GL_TEXTURE3:
DsaActiveTexture( ctx, mode );
dsa.matrixMode = GL_TEXTURE;
@ -175,11 +176,15 @@ struct Dsa
return tex != ( dsa.activeTexture != REGAL_DSA_INVALID ? dsa.activeTexture : drv.activeTexture );
}
bool ShadowActiveTexture( GLenum realActiveTexture ) {
if ( !validTextureEnum(realActiveTexture) )
return false;
drv.activeTexture = realActiveTexture;
bool usingDsa = dsa.activeTexture != REGAL_DSA_INVALID;
return usingDsa;
}
void DsaActiveTexture( RegalContext * ctx, GLenum tex) {
if ( !validTextureEnum(tex) )
return;
if( NotActiveTexture( tex ) ) {
dsa.activeTexture = tex;
ctx->dispatcher.emulation.glActiveTexture( dsa.activeTexture );
@ -545,7 +550,6 @@ struct Dsa
for( int i = maxTextureUnit; i >= 0; i-- ) {
tbl.call(&tbl.glClientActiveTexture)( GL_TEXTURE0 + i );
tbl.call(&tbl.glDisableClientState) ( GL_TEXTURE_COORD_ARRAY );
}
for( int i = 0; i < 16; i++ ) {
tbl.call(&tbl.glDisableVertexAttribArray)( i );

95
src/regal/RegalEmu.cpp Normal file
View file

@ -0,0 +1,95 @@
/*
Copyright (c) 2011-2012 NVIDIA Corporation
Copyright (c) 2011-2012 Cass Everitt
Copyright (c) 2012 Scott Nations
Copyright (c) 2012 Mathias Schott
Copyright (c) 2012 Nigel Stewart
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
Regal Emulation layer helpers
Scott Nations
*/
#include "RegalUtil.h"
#if REGAL_EMULATION
#include "RegalEmu.h"
#include "RegalToken.h"
REGAL_GLOBAL_BEGIN
#include <GL/Regal.h>
#include <cassert>
REGAL_GLOBAL_END
REGAL_NAMESPACE_BEGIN
namespace Emu
{
// From the GL spec for ERRORS associated with glActiveTexture
// An INVALID_ENUM error is generated if an invalid texture is specified.
// texture is a symbolic constant of the form TEXTUREi, indicating that texture
// unit i is to be modified. The constants obey TEXTUREi = TEXTURE0 +i where
// i is in the range 0 to k - 1, and k is the larger of the values of
// MAX_TEXTURE_COORDS and MAX_COMBINED_TEXTURE_IMAGE_UNITS).
// For backwards compatibility, the implementation-dependent constant
// MAX_TEXTURE_UNITS specifies the number of conventional texture units
// supported by the implementation. Its value must be no larger than the
// minimum of MAX_TEXTURE_COORDS and MAX_COMBINED_TEXTURE_IMAGE_UNITS.
bool validTextureEnum(GLenum texture)
{
GLint unit = texture - GL_TEXTURE0;
return validTextureUnit( static_cast<GLuint>(unit) );
}
bool validTextureUnit(GLuint unit)
{
RegalAssert(REGAL_EMU_MAX_COMBINED_TEXTURE_IMAGE_UNITS >= REGAL_EMU_MAX_TEXTURE_COORDS);
if (unit >= REGAL_EMU_MAX_COMBINED_TEXTURE_IMAGE_UNITS)
{
Warning( "Active texture out of range: ",
Token::GLtextureToString(static_cast<GLenum>(GL_TEXTURE0 + unit)),
" > ",
Token::GLtextureToString(static_cast<GLenum>(GL_TEXTURE0 + REGAL_EMU_MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)));
return false;
}
return true;
}
};
REGAL_NAMESPACE_END
#endif // REGAL_EMULATION

View file

@ -30,8 +30,8 @@
/*
Regal Emulation layer base class.
Cass Everitt
Regal Emulation layer constants
Cass Everitt, Scott Nations
*/
@ -44,41 +44,78 @@ REGAL_GLOBAL_BEGIN
#include <GL/Regal.h>
#include <cassert>
REGAL_GLOBAL_END
REGAL_NAMESPACE_BEGIN
namespace Emu
{
// In ES2 mode, 16 texture units only?
// No. of fixed function texture units. 2 minimum.
#ifndef REGAL_EMU_MAX_TEXTURE_UNITS
#define REGAL_EMU_MAX_TEXTURE_UNITS 32
#define REGAL_EMU_MAX_TEXTURE_UNITS 4
#endif
// No. of texture coordinate sets. 8 minimum.
#ifndef REGAL_EMU_MAX_TEXTURE_COORDS
#define REGAL_EMU_MAX_TEXTURE_COORDS 8
#define REGAL_EMU_MAX_TEXTURE_COORDS 16
#endif
// No. of active vertex attributes. 16 minimum.
#ifndef REGAL_EMU_MAX_VERTEX_ATTRIBS
#define REGAL_EMU_MAX_VERTEX_ATTRIBS 16
#endif
// Max no. of vertex buffers. 16 minimum
#ifndef REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS
#define REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS 32
#define REGAL_EMU_MAX_VERTEX_ATTRIB_BINDINGS 16
#endif
// glspec43.compatibility.20130214.withchanges.pdf Table 23.65, p. 709
// lists the minumum value for MAX_CLIENT_ATTRIB_STACK_DEPTH as 16
// Total no. of texture units accessible by the GL. 96 minimum
#ifndef REGAL_EMU_MAX_COMBINED_TEXTURE_IMAGE_UNITS
#define REGAL_EMU_MAX_COMBINED_TEXTURE_IMAGE_UNITS 96
#endif
// Max depth of the server attribute stack. 16 minimum.
#ifndef REGAL_EMU_MAX_ATTRIB_STACK_DEPTH
#define REGAL_EMU_MAX_ATTRIB_STACK_DEPTH 16
#endif
// Max depth of the client attribute stack. 16 minimum.
#ifndef REGAL_EMU_MAX_CLIENT_ATTRIB_STACK_DEPTH
#define REGAL_EMU_MAX_CLIENT_ATTRIB_STACK_DEPTH 16
#endif
// Max no. of active draw buffers. 8 minimum
#ifndef REGAL_EMU_MAX_DRAW_BUFFERS
#define REGAL_EMU_MAX_DRAW_BUFFERS 8
#endif
// Max no. of active viewports. 16 minimum
#ifndef REGAL_EMU_MAX_VIEWPORTS
#define REGAL_EMU_MAX_VIEWPORTS 16
#endif
#if REGAL_EMULATION
extern bool validTextureEnum(GLenum texture);
extern bool validTextureUnit(GLuint unit);
#endif // REGAL_EMULATION
};
REGAL_NAMESPACE_END
#endif // ! __REGAL_EMU_H__

View file

@ -420,8 +420,8 @@ namespace Emu {
case GL_MAX_PIXEL_MAP_TABLE: retVal = 256; break;
case GL_MAX_NAME_STACK_DEPTH: retVal = 128; break;
case GL_MAX_LIST_NESTING: retVal = 64; break;
case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
case GL_MAX_ATTRIB_STACK_DEPTH: retVal = 16; break;
case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: retVal = ctx.info->max_client_attrib_stack_depth; break;
case GL_MAX_ATTRIB_STACK_DEPTH: retVal = ctx.info->max_attrib_stack_depth; break;
case GL_DEPTH_BITS: retVal = 24; break;

View file

@ -192,4 +192,4 @@ REGAL_NAMESPACE_END
#endif // REGAL_EMULATION
#endif // ! __REGAL_BASEVERTEX_H__
#endif // ! __REGAL_HINT_H__

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -627,11 +627,17 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
case GL_MAX_NAME_STACK_DEPTH:
case GL_MAX_LIST_NESTING:
case GL_MAX_EVAL_ORDER:
case GL_MAX_ATTRIB_STACK_DEPTH:
case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
if (params)
params[0] = 0;
break;
case GL_ATTRIB_STACK_DEPTH:
if (params)
params[0] = static_cast<T>(maskStack.size());
break;
case GL_MAX_ATTRIB_STACK_DEPTH:
if (params)
params[0] = static_cast<T>(ctx->info->max_attrib_stack_depth);
break;
default:
return false;
}
@ -720,9 +726,14 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
case GL_DRAW_BUFFER14:
case GL_DRAW_BUFFER15:
{
if (!State::ColorBuffer::fullyDefined())
State::ColorBuffer::getUndefined(ctx->dispatcher.emulation);
params[0] = static_cast<T>(State::ColorBuffer::drawBuffers[pname-GL_DRAW_BUFFER0]);
GLuint index = static_cast<GLuint>(pname - GL_DRAW_BUFFER0);
if ( index < array_size( State::ColorBuffer::drawBuffers ))
{
if (!State::ColorBuffer::fullyDefined())
State::ColorBuffer::getUndefined(ctx->dispatcher.emulation);
RegalAssertArrayIndex( State::ColorBuffer::drawBuffers, index );
params[0] = static_cast<T>(State::ColorBuffer::drawBuffers[index]);
}
}
break;
case GL_FOG_COLOR:
@ -832,6 +843,24 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
case GL_MAP_COLOR:
params[0] = static_cast<T>(State::PixelMode::mapColor);
break;
case GL_ATTRIB_STACK_DEPTH:
params[0] = static_cast<T>(maskStack.size());
break;
case GL_MAX_ATTRIB_STACK_DEPTH:
params[0] = static_cast<T>(ctx->info->max_attrib_stack_depth);
break;
case GL_MAX_VERTEX_ATTRIBS:
*params = static_cast<T>(ctx->info->max_vertex_attribs);
break;
case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
params[0] = static_cast<T>(ctx->info->max_combined_texture_image_units);
break;
case GL_MAX_TEXTURE_COORDS:
params[0] = static_cast<T>(ctx->info->max_texture_coords);
break;
case GL_MAX_TEXTURE_UNITS:
params[0] = static_cast<T>(ctx->info->max_texture_units);
break;
case GL_MAP_STENCIL:
params[0] = static_cast<T>(State::PixelMode::mapStencil);
break;
@ -1017,31 +1046,49 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
switch (pname)
{
case GL_BLEND_DST_ALPHA:
if (index < REGAL_MAX_DRAW_BUFFERS)
if (index < array_size( State::ColorBuffer::blendDstAlpha ))
{
RegalAssertArrayIndex( State::ColorBuffer::blendDstAlpha, index );
params[0] = static_cast<T>(State::ColorBuffer::blendDstAlpha[index]);
}
break;
case GL_BLEND_DST_RGB:
if (index < REGAL_MAX_DRAW_BUFFERS)
if (index < array_size( State::ColorBuffer::blendDstRgb ))
{
RegalAssertArrayIndex( State::ColorBuffer::blendDstRgb, index );
params[0] = static_cast<T>(State::ColorBuffer::blendDstRgb[index]);
}
break;
case GL_BLEND_EQUATION_ALPHA:
if (index < REGAL_MAX_DRAW_BUFFERS)
if (index < array_size( State::ColorBuffer::blendEquationAlpha ))
{
RegalAssertArrayIndex( State::ColorBuffer::blendEquationAlpha, index );
params[0] = static_cast<T>(State::ColorBuffer::blendEquationAlpha[index]);
}
break;
case GL_BLEND_EQUATION_RGB:
if (index < REGAL_MAX_DRAW_BUFFERS)
if (index < array_size( State::ColorBuffer::blendEquationRgb ))
{
RegalAssertArrayIndex( State::ColorBuffer::blendEquationRgb, index );
params[0] = static_cast<T>(State::ColorBuffer::blendEquationRgb[index]);
}
break;
case GL_BLEND_SRC_ALPHA:
if (index < REGAL_MAX_DRAW_BUFFERS)
if (index < array_size( State::ColorBuffer::blendSrcAlpha ))
{
RegalAssertArrayIndex( State::ColorBuffer::blendSrcAlpha, index );
params[0] = static_cast<T>(State::ColorBuffer::blendSrcAlpha[index]);
}
break;
case GL_BLEND_SRC_RGB:
if (index < REGAL_MAX_DRAW_BUFFERS)
if (index < array_size( State::ColorBuffer::blendSrcRgb ))
{
RegalAssertArrayIndex( State::ColorBuffer::blendSrcRgb, index );
params[0] = static_cast<T>(State::ColorBuffer::blendSrcRgb[index]);
}
break;
case GL_COLOR_WRITEMASK:
if (index < REGAL_MAX_DRAW_BUFFERS)
if (index < ctx->info->max_draw_buffers)
{
params[0] = static_cast<T>(State::ColorBuffer::colorWritemask[index][0]);
params[1] = static_cast<T>(State::ColorBuffer::colorWritemask[index][1]);
@ -1050,14 +1097,14 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
}
break;
case GL_DEPTH_RANGE:
if (index < REGAL_MAX_VIEWPORTS)
if (index < ctx->info->max_viewports)
{
params[0] = static_cast<T>(State::Viewport::depthRange[index][0]);
params[1] = static_cast<T>(State::Viewport::depthRange[index][1]);
}
break;
case GL_SCISSOR_BOX:
if (index < REGAL_MAX_VIEWPORTS)
if (index < ctx->info->max_viewports)
{
if (!State::Scissor::fullyDefined())
State::Scissor::getUndefined(ctx->dispatcher.emulation);
@ -1068,7 +1115,7 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
}
break;
case GL_VIEWPORT:
if (index < REGAL_MAX_VIEWPORTS)
if (index < ctx->info->max_viewports)
{
if (!State::Viewport::fullyDefined())
State::Viewport::getUndefined(ctx->dispatcher.emulation);
@ -1195,9 +1242,10 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
UNUSED_PARAMETER(ctx);
GLint ii = light - GL_LIGHT0;
if (ii < 0 || ii >= REGAL_FIXED_FUNCTION_MAX_LIGHTS)
if (ii < 0 || static_cast<size_t>(ii) >= array_size( State::Point::coordReplace ))
return false;
RegalAssertArrayIndex( State::Lighting::lights, ii );
State::LightingLight l = State::Lighting::lights[ii];
GLuint num = 0;
@ -1248,7 +1296,7 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
return false;
}
for (GLuint ii = 0; ii < num; ii++)
for (size_t ii = 0; ii < num; ii++)
params[ii] = static_cast<T>(p[ii]);
return true;
@ -1295,7 +1343,7 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
return false;
}
for (GLuint ii = 0; ii < num; ii++)
for (size_t ii = 0; ii < num; ii++)
params[ii] = static_cast<T>(p[ii]);
return true;
@ -1309,9 +1357,10 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
return false;
GLint ii = texunit - GL_TEXTURE0;
if (ii < 0 || ii >= REGAL_EMU_MAX_TEXTURE_UNITS)
if (ii < 0 || static_cast<size_t>(ii) >= array_size( State::Point::coordReplace ))
return false;
RegalAssertArrayIndex( State::Point::coordReplace, ii );
*params = static_cast<T>(State::Point::coordReplace[ii]);
return true;
@ -1345,6 +1394,7 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
case GL_CLIP_DISTANCE5:
case GL_CLIP_DISTANCE6:
case GL_CLIP_DISTANCE7:
RegalAssertArrayIndex( State::Enable::clipDistance, pname-GL_CLIP_DISTANCE0 );
enabled = State::Enable::clipDistance[pname-GL_CLIP_DISTANCE0];
break;
case GL_COLOR_LOGIC_OP:
@ -1397,6 +1447,7 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
case GL_LIGHT5:
case GL_LIGHT6:
case GL_LIGHT7:
RegalAssertArrayIndex( State::Enable::light, pname-GL_LIGHT0 );
enabled = State::Enable::light[pname-GL_LIGHT0];
break;
case GL_LIGHTING:
@ -1526,27 +1577,39 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
enabled = State::Enable::stencilTest;
break;
case GL_TEXTURE_1D:
RegalAssertArrayIndex( State::Enable::texture1d, activeTextureUnit );
enabled = State::Enable::texture1d[activeTextureUnit];
break;
case GL_TEXTURE_2D:
RegalAssertArrayIndex( State::Enable::texture2d, activeTextureUnit );
enabled = State::Enable::texture2d[activeTextureUnit];
break;
case GL_TEXTURE_3D:
RegalAssertArrayIndex( State::Enable::texture3d, activeTextureUnit );
enabled = State::Enable::texture3d[activeTextureUnit];
break;
case GL_TEXTURE_CUBE_MAP:
RegalAssertArrayIndex( State::Enable::textureCubeMap, activeTextureUnit );
enabled = State::Enable::textureCubeMap[activeTextureUnit];
break;
case GL_TEXTURE_RECTANGLE:
RegalAssertArrayIndex( State::Enable::textureRectangle, activeTextureUnit );
enabled = State::Enable::textureRectangle[activeTextureUnit];
break;
case GL_TEXTURE_GEN_S:
RegalAssertArrayIndex( State::Enable::textureGenS, activeTextureUnit );
enabled = State::Enable::textureGenS[activeTextureUnit];
break;
case GL_TEXTURE_GEN_T:
RegalAssertArrayIndex( State::Enable::textureGenT, activeTextureUnit );
enabled = State::Enable::textureGenT[activeTextureUnit];
break;
case GL_TEXTURE_GEN_R:
RegalAssertArrayIndex( State::Enable::textureGenR, activeTextureUnit );
enabled = State::Enable::textureGenR[activeTextureUnit];
break;
case GL_TEXTURE_GEN_Q:
RegalAssertArrayIndex( State::Enable::textureGenQ, activeTextureUnit );
enabled = State::Enable::textureGenQ[activeTextureUnit];
break;
case GL_VERTEX_PROGRAM_TWO_SIDE:
@ -1566,14 +1629,16 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
switch (pname)
{
case GL_BLEND:
if (index >= REGAL_MAX_DRAW_BUFFERS)
if (index >= array_size( State::Enable::blend ))
return false;
RegalAssertArrayIndex( State::Enable::blend, index );
enabled = State::Enable::blend[index];
break;
case GL_SCISSOR_TEST:
if (index >= REGAL_MAX_VIEWPORTS)
if (index >= array_size( State::Enable::scissorTest ))
return false;
RegalAssertArrayIndex( State::Enable::scissorTest, index );
enabled = State::Enable::scissorTest[index];
break;
@ -1592,8 +1657,14 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
break;
case GL_BLEND:
{
for (GLuint ii=0; ii<REGAL_MAX_DRAW_BUFFERS; ii++)
size_t n = array_size( State::Enable::blend );
RegalAssert( array_size( State::ColorBuffer::blend ) == n );
for (size_t ii=0; ii<n; ii++)
{
RegalAssertArrayIndex( State::Enable::blend, ii );
RegalAssertArrayIndex( State::ColorBuffer::blend, ii );
State::Enable::blend[ii] = State::ColorBuffer::blend[ii] = enabled;
}
}
break;
case GL_AUTO_NORMAL:
@ -1607,6 +1678,8 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
case GL_CLIP_DISTANCE5:
case GL_CLIP_DISTANCE6:
case GL_CLIP_DISTANCE7:
RegalAssertArrayIndex( State::Enable::clipDistance, cap-GL_CLIP_DISTANCE0 );
RegalAssertArrayIndex( State::Transform::clipPlane, cap-GL_CLIP_DISTANCE0 );
State::Enable::clipDistance[cap-GL_CLIP_DISTANCE0] = State::Transform::clipPlane[cap-GL_CLIP_DISTANCE0].enabled = enabled;
break;
case GL_COLOR_LOGIC_OP:
@ -1659,6 +1732,8 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
case GL_LIGHT5:
case GL_LIGHT6:
case GL_LIGHT7:
RegalAssertArrayIndex( State::Enable::light, cap-GL_LIGHT0 );
RegalAssertArrayIndex( State::Lighting::lights, cap-GL_LIGHT0 );
State::Enable::light[cap-GL_LIGHT0] = State::Lighting::lights[cap-GL_LIGHT0].enabled = enabled;
break;
case GL_LIGHTING:
@ -1671,57 +1746,75 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
State::Enable::lineStipple = State::Line::stipple = enabled;
break;
case GL_MAP1_COLOR_4:
RegalAssertArrayIndex( State::Eval::map1dEnables, cap-GL_MAP1_COLOR_4 );
State::Enable::map1Color4 = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled;
break;
case GL_MAP1_INDEX:
RegalAssertArrayIndex( State::Eval::map1dEnables, cap-GL_MAP1_COLOR_4 );
State::Enable::map1Index = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled;
break;
case GL_MAP1_NORMAL:
RegalAssertArrayIndex( State::Eval::map1dEnables, cap-GL_MAP1_COLOR_4 );
State::Enable::map1Normal = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled;
break;
case GL_MAP1_TEXTURE_COORD_1:
RegalAssertArrayIndex( State::Eval::map1dEnables, cap-GL_MAP1_COLOR_4 );
State::Enable::map1TextureCoord1 = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled;
break;
case GL_MAP1_TEXTURE_COORD_2:
RegalAssertArrayIndex( State::Eval::map1dEnables, cap-GL_MAP1_COLOR_4 );
State::Enable::map1TextureCoord2 = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled;
break;
case GL_MAP1_TEXTURE_COORD_3:
RegalAssertArrayIndex( State::Eval::map1dEnables, cap-GL_MAP1_COLOR_4 );
State::Enable::map1TextureCoord3 = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled;
break;
case GL_MAP1_TEXTURE_COORD_4:
RegalAssertArrayIndex( State::Eval::map1dEnables, cap-GL_MAP1_COLOR_4 );
State::Enable::map1TextureCoord4 = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled;
break;
case GL_MAP1_VERTEX_3:
RegalAssertArrayIndex( State::Eval::map1dEnables, cap-GL_MAP1_COLOR_4 );
State::Enable::map1Vertex3 = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled;
break;
case GL_MAP1_VERTEX_4:
RegalAssertArrayIndex( State::Eval::map1dEnables, cap-GL_MAP1_COLOR_4 );
State::Enable::map1Vertex4 = State::Eval::map1dEnables[cap-GL_MAP1_COLOR_4] = enabled;
break;
case GL_MAP2_COLOR_4:
RegalAssertArrayIndex( State::Eval::map2dEnables, cap-GL_MAP2_COLOR_4 );
State::Enable::map2Color4 = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled;
break;
case GL_MAP2_INDEX:
RegalAssertArrayIndex( State::Eval::map2dEnables, cap-GL_MAP2_COLOR_4 );
State::Enable::map2Index = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled;
break;
case GL_MAP2_NORMAL:
RegalAssertArrayIndex( State::Eval::map2dEnables, cap-GL_MAP2_COLOR_4 );
State::Enable::map2Normal = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled;
break;
case GL_MAP2_TEXTURE_COORD_1:
RegalAssertArrayIndex( State::Eval::map2dEnables, cap-GL_MAP2_COLOR_4 );
State::Enable::map2TextureCoord1 = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled;
break;
case GL_MAP2_TEXTURE_COORD_2:
RegalAssertArrayIndex( State::Eval::map2dEnables, cap-GL_MAP2_COLOR_4 );
State::Enable::map2TextureCoord2 = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled;
break;
case GL_MAP2_TEXTURE_COORD_3:
RegalAssertArrayIndex( State::Eval::map2dEnables, cap-GL_MAP2_COLOR_4 );
State::Enable::map2TextureCoord3 = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled;
break;
case GL_MAP2_TEXTURE_COORD_4:
RegalAssertArrayIndex( State::Eval::map2dEnables, cap-GL_MAP2_COLOR_4 );
State::Enable::map2TextureCoord4 = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled;
break;
case GL_MAP2_VERTEX_3:
RegalAssertArrayIndex( State::Eval::map2dEnables, cap-GL_MAP2_COLOR_4 );
State::Enable::map2Vertex3 = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled;
break;
case GL_MAP2_VERTEX_4:
RegalAssertArrayIndex( State::Eval::map2dEnables, cap-GL_MAP2_COLOR_4 );
State::Enable::map2Vertex4 = State::Eval::map2dEnables[cap-GL_MAP2_COLOR_4] = enabled;
break;
case GL_MINMAX:
@ -1780,8 +1873,14 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
break;
case GL_SCISSOR_TEST:
{
for (GLuint ii=0; ii<REGAL_MAX_VIEWPORTS; ii++)
size_t n = array_size( State::Enable::scissorTest );
RegalAssert( array_size( State::Scissor::scissorTest ) == n );
for (size_t ii=0; ii<n; ii++)
{
RegalAssertArrayIndex( State::Enable::scissorTest, ii );
RegalAssertArrayIndex( State::Scissor::scissorTest, ii );
State::Enable::scissorTest[ii] = State::Scissor::scissorTest[ii] = enabled;
}
}
break;
case GL_SEPARABLE_2D:
@ -1791,27 +1890,39 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
State::Enable::stencilTest = State::Stencil::enable = enabled;
break;
case GL_TEXTURE_1D:
RegalAssertArrayIndex( State::Enable::texture1d, activeTextureUnit );
State::Enable::texture1d[activeTextureUnit] = enabled;
break;
case GL_TEXTURE_2D:
RegalAssertArrayIndex( State::Enable::texture2d, activeTextureUnit );
State::Enable::texture2d[activeTextureUnit] = enabled;
break;
case GL_TEXTURE_3D:
RegalAssertArrayIndex( State::Enable::texture3d, activeTextureUnit );
State::Enable::texture3d[activeTextureUnit] = enabled;
break;
case GL_TEXTURE_CUBE_MAP:
RegalAssertArrayIndex( State::Enable::textureCubeMap, activeTextureUnit );
State::Enable::textureCubeMap[activeTextureUnit] = enabled;
break;
case GL_TEXTURE_RECTANGLE:
RegalAssertArrayIndex( State::Enable::textureRectangle, activeTextureUnit );
State::Enable::textureRectangle[activeTextureUnit] = enabled;
break;
case GL_TEXTURE_GEN_S:
RegalAssertArrayIndex( State::Enable::textureGenS, activeTextureUnit );
State::Enable::textureGenS[activeTextureUnit] = enabled;
break;
case GL_TEXTURE_GEN_T:
RegalAssertArrayIndex( State::Enable::textureGenT, activeTextureUnit );
State::Enable::textureGenT[activeTextureUnit] = enabled;
break;
case GL_TEXTURE_GEN_R:
RegalAssertArrayIndex( State::Enable::textureGenR, activeTextureUnit );
State::Enable::textureGenR[activeTextureUnit] = enabled;
break;
case GL_TEXTURE_GEN_Q:
RegalAssertArrayIndex( State::Enable::textureGenQ, activeTextureUnit );
State::Enable::textureGenQ[activeTextureUnit] = enabled;
break;
case GL_VERTEX_PROGRAM_TWO_SIDE:
@ -1843,12 +1954,28 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
switch (cap)
{
case GL_BLEND:
if (index < REGAL_MAX_DRAW_BUFFERS)
State::Enable::blend[index] = State::ColorBuffer::blend[index] = enabled;
{
size_t n = array_size( State::Enable::blend );
RegalAssert( array_size( State::ColorBuffer::blend ) == n );
if (index < n)
{
RegalAssertArrayIndex( State::Enable::blend, index );
RegalAssertArrayIndex( State::ColorBuffer::blend, index );
State::Enable::blend[index] = State::ColorBuffer::blend[index] = enabled;
}
}
break;
case GL_SCISSOR_TEST:
if (index < REGAL_MAX_VIEWPORTS)
State::Enable::scissorTest[index] = State::Scissor::scissorTest[index] = enabled;
{
size_t n = array_size( State::Enable::scissorTest );
RegalAssert( array_size( State::Scissor::scissorTest ) == n );
if (index < n)
{
RegalAssertArrayIndex( State::Enable::scissorTest, index );
RegalAssertArrayIndex( State::Scissor::scissorTest, index );
State::Enable::scissorTest[index] = State::Scissor::scissorTest[index] = enabled;
}
}
break;
default:
@ -1881,16 +2008,12 @@ struct Ppa : public State::Stencil, State::Depth, State::Polygon, State::Transfo
return SetEnablei(ctx, cap, index, GL_FALSE);
}
void glActiveTexture( GLenum tex )
void glActiveTexture( GLenum texture )
{
GLuint unit = tex - GL_TEXTURE0;
if (unit < REGAL_EMU_MAX_TEXTURE_UNITS)
activeTextureUnit = unit;
if ( texture >= GL_TEXTURE0 && texture < static_cast<GLenum>(GL_TEXTURE0 + REGAL_EMU_MAX_TEXTURE_UNITS) )
activeTextureUnit = texture - GL_TEXTURE0;
else
{
Warning( "Active texture out of range: ", Token::GLtextureToString(tex), " > ", Token::GLtextureToString(GL_TEXTURE0 + REGAL_EMU_MAX_TEXTURE_UNITS - 1));
return;
}
Warning( "Active texture out of range: ", Token::GLtextureToString(texture), " > ", Token::GLtextureToString(GL_TEXTURE0 + REGAL_EMU_MAX_TEXTURE_UNITS - 1));
}
inline void glClampColor( GLenum target, GLenum clamp )

View file

@ -107,7 +107,7 @@ struct Ppca : public ClientState::VertexArray, ClientState::PixelStore
//
// TODO: set correct GL error here
if (maskStack.size() >= REGAL_EMU_MAX_CLIENT_ATTRIB_STACK_DEPTH)
if (maskStack.size() >= ctx.info->max_client_attrib_stack_depth)
return;
maskStack.push_back(mask);
@ -241,8 +241,6 @@ struct Ppca : public ClientState::VertexArray, ClientState::PixelStore
bool glGetv(RegalContext &ctx, GLenum pname, GLboolean *params)
{
UNUSED_PARAMETER(ctx);
switch (pname)
{
case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
@ -251,6 +249,15 @@ struct Ppca : public ClientState::VertexArray, ClientState::PixelStore
case GL_CLIENT_ATTRIB_STACK_DEPTH:
params[0] = (maskStack.size() != 0);
break;
case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
params[0] = ctx.info->max_combined_texture_image_units != 0;
break;
case GL_MAX_TEXTURE_COORDS:
params[0] = ctx.info->max_texture_coords != 0;
break;
case GL_MAX_TEXTURE_UNITS:
params[0] = ctx.info->max_texture_units != 0;
break;
default:
return false;
@ -260,16 +267,26 @@ struct Ppca : public ClientState::VertexArray, ClientState::PixelStore
template <typename T> bool glGetv(RegalContext &ctx, GLenum pname, T *params)
{
UNUSED_PARAMETER(ctx);
switch (pname)
{
case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
params[0] = static_cast<T>(REGAL_EMU_MAX_CLIENT_ATTRIB_STACK_DEPTH);
params[0] = static_cast<T>(ctx.info->max_client_attrib_stack_depth);
break;
case GL_CLIENT_ATTRIB_STACK_DEPTH:
params[0] = static_cast<T>(maskStack.size());
break;
case GL_MAX_VERTEX_ATTRIBS:
params[0] = static_cast<T>(ctx.info->max_vertex_attribs);
break;
case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
params[0] = static_cast<T>(ctx.info->max_combined_texture_image_units);
break;
case GL_MAX_TEXTURE_COORDS:
params[0] = static_cast<T>(ctx.info->max_texture_coords);
break;
case GL_MAX_TEXTURE_UNITS:
params[0] = static_cast<T>(ctx.info->max_texture_units);
break;
default:
return false;

View file

@ -135,4 +135,4 @@ REGAL_NAMESPACE_END
#endif // REGAL_EMULATION
#endif // ! __REGAL_BASEVERTEX_H__
#endif // ! __REGAL_RECT_H__

View file

@ -49,7 +49,7 @@ namespace Emu {
using namespace ::REGAL_NAMESPACE_INTERNAL::Logging;
using namespace ::REGAL_NAMESPACE_INTERNAL::Token;
const GLenum So::index2Enum[17] = { GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, REGAL_NUM_TEXTURE_TARGETS };
const GLenum So::index2Enum[REGAL_NUM_TEXTURE_TARGETS] = { GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
void
@ -75,10 +75,12 @@ So::DeleteSamplers(GLsizei count, const GLuint * samplers)
if (s && samplerObjects.count(s) > 0)
{
SamplingState* p = samplerObjects[s];
for (GLsizei unit=0; unit < REGAL_EMU_MAX_TEXTURE_UNITS; unit++)
size_t n = array_size( textureUnits );
for (size_t unit=0; unit < n; unit++)
{
RegalAssertArrayIndex( textureUnits, unit );
if (textureUnits[unit].boundSamplerObject == p)
BindSampler(unit, 0);
BindSampler(static_cast<GLuint>(unit), 0);
}
samplerObjects.erase(s);
delete p;
@ -95,9 +97,9 @@ So::IsSampler(GLuint sampler)
void
So::BindSampler(GLuint unit, GLuint so)
{
if (unit >= REGAL_EMU_MAX_TEXTURE_UNITS)
if (unit >= array_size( textureUnits ))
{
Warning("Texture unit out of range: ", unit, " >= ", REGAL_EMU_MAX_TEXTURE_UNITS);
Warning("Texture unit out of range: ", unit, " >= ", REGAL_EMU_MAX_TEXTURE_COORDS);
return;
}
@ -112,6 +114,7 @@ So::BindSampler(GLuint unit, GLuint so)
SamplingState *pso = so != 0 ? samplerObjects[so] : NULL;
RegalAssertArrayIndex( textureUnits, unit );
textureUnits[unit].boundSamplerObject = pso;
}
@ -141,18 +144,22 @@ So::DeleteTextures(RegalContext &ctx, GLsizei count, const GLuint * textures)
{
TextureState* p = textureObjects[t];
for (GLuint unit=0; unit < REGAL_EMU_MAX_TEXTURE_UNITS; unit++)
size_t n = array_size( textureUnits );
for (size_t unit=0; unit < n; unit++)
{
RegalAssertArrayIndex( textureUnits, unit );
TextureUnit &tu = textureUnits[unit];
for (GLuint jj=0; jj < REGAL_NUM_TEXTURE_TARGETS; jj++)
size_t num = array_size( tu.boundTextureObjects );
for (size_t jj=0; jj<num; jj++)
{
RegalAssertArrayIndex( tu.boundTextureObjects, jj );
if (p == tu.boundTextureObjects[jj])
{
if (activeTextureUnit != unit)
ActiveTexture(ctx, GL_TEXTURE0 + unit );
ActiveTexture(ctx, static_cast<GLenum>(GL_TEXTURE0 + unit));
BindTexture(ctx, unit, TT_Index2Enum(jj), 0);
BindTexture(ctx, static_cast<GLuint>(unit), TT_Index2Enum(jj), 0);
}
}
}
@ -177,9 +184,9 @@ So::BindTexture(RegalContext &ctx, GLuint unit, GLenum target, GLuint to)
{
Internal("Regal::So::BindTexture",&ctx," unit=",unit," target=",target," to=",to);
if (unit >= REGAL_EMU_MAX_TEXTURE_UNITS)
if (unit >= array_size( textureUnits ))
{
Warning("Texture unit out of range: ", unit, " >= ", REGAL_EMU_MAX_TEXTURE_UNITS);
Warning("Texture unit out of range: ", unit, " >= ", REGAL_EMU_MAX_TEXTURE_COORDS);
return false;
}
@ -220,24 +227,21 @@ So::BindTexture(RegalContext &ctx, GLuint unit, GLenum target, GLuint to)
if (activeTextureUnit != originallyActiveUnit)
ActiveTexture(ctx, GL_TEXTURE0 + originallyActiveUnit );
RegalAssertArrayIndex( textureUnits, unit );
textureUnits[unit].boundTextureObjects[tti] = ts;
return true;
}
bool
So::ActiveTexture( RegalContext &ctx, GLenum tex )
So::ActiveTexture( RegalContext &ctx, GLenum texture )
{
GLuint unit = tex - GL_TEXTURE0;
if (unit >= REGAL_EMU_MAX_TEXTURE_UNITS)
{
Warning( "Active texture out of range: ", tex, " >= ",
Token::GLenumToString(GL_TEXTURE0 + REGAL_EMU_MAX_TEXTURE_UNITS));
return false;
}
activeTextureUnit = unit;
ctx.dispatcher.emulation.glActiveTexture( tex );
return true;
if (!validTextureEnum(texture))
return false;
activeTextureUnit = texture - GL_TEXTURE0;
ctx.dispatcher.emulation.glActiveTexture( texture );
return true;
}
void
@ -251,13 +255,17 @@ So::PreDraw( RegalContext &ctx )
GLuint originallyActiveUnit = activeTextureUnit;
// ignoring sampler objects on the last unit... FIXME - cass
for (int unit=REGAL_EMU_MAX_TEXTURE_UNITS-1; unit >= 0; unit--)
const int n = static_cast<GLuint>(array_size( textureUnits ));
for (int unit=n-1; unit >= 0; unit--)
{
RegalAssertArrayIndex( textureUnits, unit );
TextureUnit &tu = textureUnits[unit];
SamplingState *pSS = tu.boundSamplerObject;
for (GLuint tt=0; tt < REGAL_NUM_TEXTURE_TARGETS; tt++)
size_t num = array_size( tu.boundTextureObjects );
for (size_t tt=0; tt < num; tt++)
{
RegalAssertArrayIndex( tu.boundTextureObjects, tt );
TextureState* ts = tu.boundTextureObjects[tt];
GLenum target = TT_Index2Enum( tt );
if( target != GL_TEXTURE_2D )
@ -285,7 +293,7 @@ So::PreDraw( RegalContext &ctx )
SamplingState *newState = pSS ? pSS : &ts->app;
//Internal( "RegalSo", "about to send update samplerVer=", ts->samplerVer, " newState->ver=", newState->ver );
if (SendStateToDriver(ctx, unit, ts->target, *newState, ts->drv)) {
if (SendStateToDriver(ctx, static_cast<GLuint>(unit), ts->target, *newState, ts->drv)) {
//Internal( "RegalSo", "updated unit ", unit, " texture ", ts ? ts->name : 0, " for sampler ", pSS ? pSS->name : 0 );
} else {
//Internal( "RegalSo", "no update occurred" );

View file

@ -91,13 +91,16 @@ struct So
UNUSED_PARAMETER(ctx);
}
static GLenum TT_Index2Enum(GLuint index)
static GLenum TT_Index2Enum(size_t index)
{
if( index > REGAL_NUM_TEXTURE_TARGETS ) {
Warning( "Unhandled texture target index: index = ", index);
index = REGAL_NUM_TEXTURE_TARGETS;
if (index < array_size( index2Enum ))
{
RegalAssertArrayIndex( index2Enum, index );
return index2Enum[index];
}
return index2Enum[index];
Warning( "Unhandled texture target index: index = ", index);
return GL_TEXTURE_2D;
}
static GLuint TT_Enum2Index(GLenum texture)
@ -213,8 +216,10 @@ struct So
TextureUnit()
: boundSamplerObject(NULL)
{
for (int tti = 0; tti< REGAL_NUM_TEXTURE_TARGETS; tti++)
size_t n = array_size( boundTextureObjects );
for (size_t tti = 0; tti < n; tti++)
{
RegalAssertArrayIndex( boundTextureObjects, tti );
boundTextureObjects[tti] = NULL;
}
}
@ -412,8 +417,13 @@ struct So
if (tti >= REGAL_NUM_TEXTURE_TARGETS)
return false;
RegalAssertArrayIndex( textureUnits, activeTextureUnit );
if (activeTextureUnit >= array_size( textureUnits ))
return false;
TextureUnit &tu = textureUnits[activeTextureUnit];
RegalAssertArrayIndex( tu.boundTextureObjects, tti );
TextureState* ts = tu.boundTextureObjects[tti];
SamplingState *as = NULL;
@ -508,8 +518,13 @@ struct So
if (tti >= REGAL_NUM_TEXTURE_TARGETS)
return false;
RegalAssertArrayIndex( textureUnits, activeTextureUnit );
if (activeTextureUnit >= array_size( textureUnits ))
return false;
TextureUnit &tu = textureUnits[activeTextureUnit];
RegalAssertArrayIndex( tu.boundTextureObjects, tti );
TextureState* txs = tu.boundTextureObjects[tti];
if (!txs)
@ -524,6 +539,18 @@ struct So
switch (pname)
{
case GL_MAX_VERTEX_ATTRIBS:
*params = static_cast<T>(ctx.info->max_vertex_attribs);
break;
case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
*params = static_cast<T>(ctx.info->max_combined_texture_image_units);
break;
case GL_MAX_TEXTURE_COORDS:
*params = static_cast<T>(ctx.info->max_texture_coords);
break;
case GL_MAX_TEXTURE_UNITS:
*params = static_cast<T>(ctx.info->max_texture_units);
break;
case GL_TEXTURE_BORDER_COLOR:
params[0] = static_cast<T>(ts->BorderColor[0]);
params[1] = static_cast<T>(ts->BorderColor[1]);
@ -607,6 +634,9 @@ struct So
case GL_SAMPLER_BINDING:
{
RegalAssertArrayIndex( textureUnits, activeTextureUnit );
if (activeTextureUnit >= array_size( textureUnits ))
return false;
SamplingState *pso = textureUnits[activeTextureUnit].boundSamplerObject;
*params = static_cast<T>(pso ? pso->name : 0);
}
@ -659,8 +689,15 @@ struct So
if (tti >= REGAL_NUM_TEXTURE_TARGETS)
return false;
RegalAssertArrayIndex( textureUnits, activeTextureUnit );
if (activeTextureUnit >= array_size( textureUnits ))
return false;
TextureUnit &tu = textureUnits[activeTextureUnit];
RegalAssertArrayIndex( tu.boundTextureObjects, tti );
TextureState* ts = tu.boundTextureObjects[tti];
*params = static_cast<T>(ts ? ts->name : 0);
return true;
@ -685,10 +722,10 @@ struct So
GLuint nextSamplerObjectId;
bool supportSrgb;
bool noSamplersInUse;
TextureUnit textureUnits[REGAL_EMU_MAX_TEXTURE_UNITS];
TextureUnit textureUnits[REGAL_EMU_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
std::map<GLuint, SamplingState*> samplerObjects;
std::map<GLuint, TextureState*> textureObjects;
static const GLenum index2Enum[17];
static const GLenum index2Enum[REGAL_NUM_TEXTURE_TARGETS];
};
}

File diff suppressed because it is too large Load diff

View file

@ -44,6 +44,7 @@ REGAL_GLOBAL_BEGIN
#include "RegalTexC.h"
#include "RegalContext.h"
#include "RegalToken.h"
#include "RegalPixelConversions.h"
REGAL_GLOBAL_END
@ -325,28 +326,35 @@ TexC::Reset_()
{
unpackPSS.Reset();
currentTextureUnit = GL_TEXTURE0;
for ( size_t i = 0; i < REGAL_EMU_MAX_TEXTURE_UNITS; ++i )
currentTextureUnit = 0;
const size_t n = array_size( textureUnitArrayState );
for ( size_t i = 0; i < n; ++i )
{
RegalAssertArrayIndex( textureUnitArrayState, i );
textureUnitArrayState[ i ].UnbindAll();
}
textureZero = TextureState();
}
TextureState *
TexC::GetBoundTexture_( GLenum textureUnit, GLenum target )
TexC::GetBoundTexture_( GLenum texture, GLenum target )
{
size_t i = textureUnit - GL_TEXTURE0;
if ( REGAL_EMU_MAX_TEXTURE_UNITS <= i )
return GetBoundTextureUnit_( static_cast<GLuint>(texture-GL_TEXTURE0), target );
}
TextureState *
TexC::GetBoundTextureUnit_( GLuint textureUnit, GLenum target )
{
size_t i = static_cast<size_t>(textureUnit);
const size_t n = array_size( textureUnitArrayState );
if ( i >= n )
{
RegalAssert( i < REGAL_EMU_MAX_TEXTURE_UNITS );
RegalAssert( i < n );
return NULL;
}
RegalAssertArrayIndex( textureUnitArrayState, i );
TextureState* ts = textureUnitArrayState[ i ].GetBinding( target );
if ( ts != NULL ) {
return ts;
}
return &textureZero;
return ( ts ? ts : &textureZero );
}
TextureState *
@ -369,17 +377,17 @@ TexC::GetTexture_( GLuint texture )
void
TexC::GetFormatAndType( GLenum target, GLint level, GLenum* format, GLenum* type )
{
GetBoundTexture_( currentTextureUnit, target )->GetFormatAndType( level, format, type );
TextureState* p = GetBoundTextureUnit_( currentTextureUnit, target );
if (p)
p->GetFormatAndType( level, format, type );
}
void
TexC::ShadowTexImage2D( GLenum target, GLint level, GLenum format, GLenum type )
{
if ( REGAL_EMU_MAX_TEXTURE_UNITS <= currentTextureUnit - GL_TEXTURE0 ) {
return;
}
GetBoundTexture_( currentTextureUnit, target )->SetFormatAndType( level, format, type );
TextureState* p = GetBoundTextureUnit_( currentTextureUnit, target );
if (p)
p->SetFormatAndType( level, format, type );
}
void
@ -408,15 +416,18 @@ void TexC::ShadowDeleteTextures( GLsizei n, const GLuint* textures )
void TexC::ShadowActiveTexture( GLenum texture )
{
currentTextureUnit = texture;
if (validTextureEnum(texture))
currentTextureUnit = texture - GL_TEXTURE0;
}
void TexC::ShadowBindTexture( GLenum target, GLuint texture )
{
size_t i = currentTextureUnit - GL_TEXTURE0;
if ( REGAL_EMU_MAX_TEXTURE_UNITS <= i ) {
size_t i = currentTextureUnit;
const size_t n = array_size( textureUnitArrayState );
if ( n <= i )
return;
}
RegalAssertArrayIndex( textureUnitArrayState, i );
TextureUnitState& textureUnitState = textureUnitArrayState[ i ];
if ( texture == TEXTURE_ZERO ) {
@ -432,11 +443,9 @@ void TexC::ShadowBindTexture( GLenum target, GLuint texture )
void
TexC::ShadowGenerateMipmap( GLenum target )
{
if ( REGAL_EMU_MAX_TEXTURE_UNITS <= currentTextureUnit - GL_TEXTURE0 ) {
return;
}
GetBoundTexture_( currentTextureUnit, target )->SimulateComputeMipMaps();
TextureState* p = GetBoundTextureUnit_( currentTextureUnit, target );
if (p)
p->SimulateComputeMipMaps();
}
void

View file

@ -187,7 +187,8 @@ struct TexC
void Reset_();
TextureState* GetBoundTexture_( GLenum textureUnit, GLenum target );
TextureState* GetBoundTexture_( GLenum textureEnum, GLenum target );
TextureState* GetBoundTextureUnit_( GLuint textureUnit, GLenum target );
TextureState* GetTexture_( GLuint texture );
void GetFormatAndType( GLenum target, GLint level, GLenum* format, GLenum* type );
@ -217,8 +218,8 @@ struct TexC
PixelStorageStateGLES20 unpackPSS;
GLenum currentTextureUnit;
TextureUnitState textureUnitArrayState[ REGAL_EMU_MAX_TEXTURE_UNITS ];
GLuint currentTextureUnit;
TextureUnitState textureUnitArrayState[ REGAL_EMU_MAX_COMBINED_TEXTURE_IMAGE_UNITS ];
TextureState textureZero;
};

View file

@ -552,6 +552,15 @@ inline bool getEnv(const char * const varname, std::string &var, const bool enab
return false;
}
//
// Array size - the number of elements of a C array
//
// http://stackoverflow.com/questions/437150/can-someone-explain-this-template-code-that-gives-me-the-size-of-an-array
//
template <typename T, size_t N>
inline size_t array_size(const T (&)[N]) { return N; }
//
// RegalCheckGLError
//
@ -586,15 +595,6 @@ inline bool getEnv(const char * const varname, std::string &var, const bool enab
void AssertFunction(const char *file, const std::size_t line, const char *expr);
#endif
//
// Array size - the number of elements of a C array
//
// http://stackoverflow.com/questions/437150/can-someone-explain-this-template-code-that-gives-me-the-size-of-an-array
//
template <typename T, size_t N>
inline size_t array_size(const T (&)[N]) { return N; }
//
//
//

View file

@ -53,8 +53,6 @@ REGAL_GLOBAL_END
REGAL_NAMESPACE_BEGIN
#define REGAL_VAO_NUM_ARRAYS 16
namespace Emu
{
@ -90,7 +88,7 @@ struct Vao
Object() : vertexBuffer( 0 ), indexBuffer( 0 ) {}
GLuint vertexBuffer;
GLuint indexBuffer;
Array a[ REGAL_VAO_NUM_ARRAYS ];
Array a[ REGAL_EMU_MAX_VERTEX_ATTRIBS ];
};
shared_map<GLuint, Object> objects;
@ -105,34 +103,36 @@ struct Vao
GLuint maxName;
// to alias vertex arrays to generic attribs
GLuint ffAttrMap[ REGAL_VAO_NUM_ARRAYS ];
GLuint ffAttrInvMap[ REGAL_VAO_NUM_ARRAYS ];
GLuint ffAttrMap[ REGAL_EMU_MAX_VERTEX_ATTRIBS ];
GLuint ffAttrInvMap[ REGAL_EMU_MAX_VERTEX_ATTRIBS ];
GLuint ffAttrTexBegin;
GLuint ffAttrTexEnd;
GLuint ffAttrNumTex;
GLuint maxVertexAttribs;
GLuint max_vertex_attribs;
void Init( RegalContext &ctx )
{
maxName = 0;
clientActiveTexture = GL_TEXTURE0;
maxVertexAttribs = ctx.info->maxVertexAttribs;
RegalAssert( maxVertexAttribs <= REGAL_VAO_NUM_ARRAYS );
max_vertex_attribs = ctx.info->gl_max_vertex_attribs;
RegalAssert( max_vertex_attribs <= REGAL_EMU_MAX_VERTEX_ATTRIBS );
if (max_vertex_attribs > REGAL_EMU_MAX_VERTEX_ATTRIBS)
max_vertex_attribs = REGAL_EMU_MAX_VERTEX_ATTRIBS;
RegalContext *sharingWith = ctx.groupInitializedContext();
if (sharingWith)
objects = sharingWith->vao->objects;
// we have RFF2A maps for sets of 8 and 16 attributes. if
// REGAL_VAO_NUM_ARRAYS > 16 a new map needs to be added
// REGAL_EMU_MAX_VERTEX_ATTRIBS > 16 a new map needs to be added
RegalAssert( REGAL_VAO_NUM_ARRAYS <= 16 );
RegalAssert( REGAL_EMU_MAX_VERTEX_ATTRIBS <= 16 );
if ( maxVertexAttribs >= 16 )
if ( max_vertex_attribs >= 16 )
{
RegalAssert( REGAL_VAO_NUM_ARRAYS == 16);
//RegalOutput( "Setting up for %d Vertex Attribs\n", maxVertexAttribs );
RegalAssert( REGAL_EMU_MAX_VERTEX_ATTRIBS == 16);
//RegalOutput( "Setting up for %d Vertex Attribs\n", max_vertex_attribs );
for( int i = 0; i < 16; i++ )
{
ffAttrMap[i] = RFF2AMap16[i];
@ -140,23 +140,27 @@ struct Vao
}
ffAttrTexBegin = RFF2ATexBegin16;
ffAttrTexEnd = RFF2ATexEnd16;
if (max_vertex_attribs > 16)
max_vertex_attribs = 16;
}
else
{
RegalAssert( maxVertexAttribs >= 8 );
RegalAssert( max_vertex_attribs >= 8 );
//RegalOutput( "Setting up for 8 Vertex Attribs" );
for( int i = 0; i < 8; i++ )
{
ffAttrMap[i] = RFF2AMap8[i];
ffAttrInvMap[i] = RFF2AInvMap8[i];
}
for( int i = 8; i < REGAL_VAO_NUM_ARRAYS; i++ )
for( int i = 8; i < REGAL_EMU_MAX_VERTEX_ATTRIBS; i++ )
{
ffAttrMap[i] = GLuint(-1);
ffAttrInvMap[i] = GLuint(-1);
}
ffAttrTexBegin = RFF2ATexBegin8;
ffAttrTexEnd = RFF2ATexEnd8;
if (max_vertex_attribs > 8)
max_vertex_attribs = 8;
}
ffAttrNumTex = ffAttrTexEnd - ffAttrTexBegin;
@ -212,15 +216,13 @@ struct Vao
tbl.glBindBuffer( GL_ARRAY_BUFFER, vao.vertexBuffer );
tbl.glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vao.indexBuffer );
GLuint lastBuffer = vao.vertexBuffer;
for( GLuint i = 0; i < maxVertexAttribs; i++ )
RegalAssert( max_vertex_attribs <= REGAL_EMU_MAX_VERTEX_ATTRIBS );
for( GLuint i = 0; i < max_vertex_attribs; i++ )
{
Array &a = vao.a[ i ];
if( a.buffer != lastBuffer )
{
//GLint e = tbl.glGetError();
tbl.glBindBuffer( GL_ARRAY_BUFFER, a.buffer );
//e = tbl.glGetError();
//RegalOutput( "Binding ARRAY_BUFFER %d - %d\n", a.buffer, e );
lastBuffer = a.buffer;
}
@ -281,7 +283,11 @@ struct Vao
void EnableDisableVertexAttribArray( RegalContext *ctx, GLboolean enable, GLuint index )
{
RegalAssert( index < maxVertexAttribs );
RegalAssert( index < REGAL_EMU_MAX_VERTEX_ATTRIBS );
RegalAssert( index < max_vertex_attribs );
if (index >= max_vertex_attribs || index >= REGAL_EMU_MAX_VERTEX_ATTRIBS)
return;
DispatchTableGL &tbl = ctx->dispatcher.emulation;
Array &a = objects[current].a[index];
a.enabled = enable;
@ -314,7 +320,9 @@ struct Vao
if ( ctx->depthBeginEnd )
return;
if (index >= maxVertexAttribs)
RegalAssert( index < REGAL_EMU_MAX_VERTEX_ATTRIBS );
RegalAssert( index < max_vertex_attribs );
if (index >= max_vertex_attribs || index >= REGAL_EMU_MAX_VERTEX_ATTRIBS )
return;
switch (size)
@ -377,17 +385,11 @@ struct Vao
//<> return;
//<> }
if( index == GLuint(~0) )
{
return;
}
if( index >= maxVertexAttribs )
{
return;
}
RegalAssert( index < maxVertexAttribs );
RegalAssert( currObject != NULL );
RegalAssert( index < max_vertex_attribs );
RegalAssert( index < REGAL_EMU_MAX_VERTEX_ATTRIBS );
Array &a = objects[current].a[index];
RegalAssert( currObject != NULL );
a.buffer = currObject->vertexBuffer;
a.size = size;
a.type = type;
@ -404,7 +406,8 @@ struct Vao
{
UNUSED_PARAMETER(ctx);
RegalAssert( currObject != NULL );
for( GLuint i = 0; i < maxVertexAttribs; i++ )
RegalAssert( max_vertex_attribs <= REGAL_EMU_MAX_VERTEX_ATTRIBS );
for( GLuint i = 0; i < max_vertex_attribs; i++ )
{
#if !REGAL_NO_ASSERT
const Array &a = currObject->a[ i ];
@ -415,6 +418,9 @@ struct Vao
template <typename T> void GetAttrib( GLint index, GLenum pname, T *params )
{
if (index >= REGAL_EMU_MAX_VERTEX_ATTRIBS)
return;
Array &a = objects[current].a[index];
switch( pname )
{
@ -425,7 +431,6 @@ struct Vao
*params = static_cast<T>(a.buffer);
break;
case GL_VERTEX_ATTRIB_ARRAY_SIZE:
//if( index == 3 ) RegalOutput( "Returning %d for index 3 from VAO GetAttrib for SIZE\n", a.size );
*params = static_cast<T>(a.size);
break;
case GL_VERTEX_ATTRIB_ARRAY_TYPE:
@ -443,8 +448,12 @@ struct Vao
break;
}
}
template <typename T> void GetAttrib( GLint index, GLenum pname, T **params )
{
if (index >= REGAL_EMU_MAX_VERTEX_ATTRIBS)
return;
Array &a = objects[current].a[index];
switch( pname )
{
@ -481,6 +490,9 @@ struct Vao
bool GetVertexAttribPointerv( GLuint index, GLenum pname, GLvoid **pointer)
{
if (index >= REGAL_EMU_MAX_VERTEX_ATTRIBS)
return false;
if ( pname != GL_VERTEX_ATTRIB_ARRAY_POINTER )
return false;
@ -513,7 +525,7 @@ struct Vao
case GL_TEXTURE_COORD_ARRAY:
{
GLuint index = clientActiveTexture - GL_TEXTURE0;
RegalAssert(index < REGAL_VAO_NUM_ARRAYS);
RegalAssert(index < REGAL_EMU_MAX_VERTEX_ATTRIBS);
if ( index >= ffAttrNumTex )
{
Warning("Texture unit out of range: ", index, " >= ", ffAttrNumTex, ". Clamping to supported maximum.");
@ -721,7 +733,7 @@ struct Vao
GLint index = _texture - GL_TEXTURE0;
if (index >= 0 && index < REGAL_VAO_NUM_ARRAYS)
if (index >= 0 && index < REGAL_EMU_MAX_VERTEX_ATTRIBS)
clientActiveTexture = _texture;
}

View file

@ -96,8 +96,8 @@ extern "C" {
}
static Colormap dummyColormap = 0;
REGAL_DECL Colormap
REGAL_DECL Colormap
XCreateColormap(Display *display, Window w, Visual *visual, int alloc)
{
::REGAL_NAMESPACE_INTERNAL::Init::init();
@ -139,7 +139,7 @@ extern "C" {
return True;
}
} // extern "C"
} // extern "C"
REGAL_GLOBAL_END

View file

@ -47,6 +47,7 @@ REGAL_GLOBAL_BEGIN
#include "RegalEmu.h"
#include "RegalPrivate.h"
#include "RegalContext.h"
#include "RegalToken.h"
#include "RegalContextInfo.h"
#include <map>
@ -78,20 +79,20 @@ struct Xfer
}
void PixelStore( RegalContext * ctx, GLenum pname, GLint param );
void PixelStore( RegalContext * ctx, GLenum pname, GLfloat param ) {
void PixelStore( RegalContext * ctx, GLenum pname, GLfloat param )
{
PixelStore( ctx, pname, GLint( param ) );
}
void ShadowActiveTexture( GLenum tex ) {
int r = tex - GL_TEXTURE0;
if( r < 0 || r > REGAL_EMU_MAX_TEXTURE_UNITS ) {
Warning("Regal can't share initialized context groups.");
return;
}
activeTextureIndex = tex - GL_TEXTURE0;
void ShadowActiveTexture( GLenum texture )
{
if (validTextureEnum(texture))
activeTextureIndex = texture - GL_TEXTURE0;
}
void ShadowBindTexture( GLenum target, GLuint name ) {
void ShadowBindTexture( GLenum target, GLuint name )
{
UNUSED_PARAMETER(target);
textureBinding2D[ activeTextureIndex ] = name;
}
@ -109,7 +110,7 @@ struct Xfer
GLint unpackSkipPixels;
int activeTextureIndex;
GLuint textureBinding2D[REGAL_EMU_MAX_TEXTURE_UNITS];
GLuint textureBinding2D[REGAL_EMU_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
std::map< GLuint, GLuint > name2ifmt;
};

View file

@ -159,6 +159,7 @@ TEST ( RegalPpca, Ppca_Defaults )
ctx.info->core = false;
ctx.info->es1 = false;
ctx.info->es2 = false;
ctx.info->max_client_attrib_stack_depth = 16;
InitDispatchTableGMock( ctx.dispatcher.emulation );
Ppca ppca;
@ -428,6 +429,7 @@ TEST ( RegalPpca, PixelStore_PushPop )
RegalContext ctx;
ctx.info = new ContextInfo();
ctx.info->max_client_attrib_stack_depth = 16;
InitDispatchTableGMock( ctx.dispatcher.emulation );
Ppca ppca;
@ -651,7 +653,7 @@ TEST ( RegalPpca, VertexArray_PushPop )
RegalContext ctx;
ctx.info = new ContextInfo();
ctx.info = new ContextInfo();
ctx.info->max_client_attrib_stack_depth = 16;
InitDispatchTableGMock( ctx.dispatcher.emulation );
Ppca ppca;
@ -835,6 +837,7 @@ TEST ( RegalPpca, ClientAttrib_PushPop )
ctx.info->core = false;
ctx.info->es1 = false;
ctx.info->es2 = false;
ctx.info->max_client_attrib_stack_depth = 16;
InitDispatchTableGMock( ctx.dispatcher.emulation );
Ppca ppca;
@ -2814,6 +2817,7 @@ TEST ( RegalPpca, glGet_Shadowing )
{
RegalContext ctx;
ctx.info = new ContextInfo();
ctx.info->max_client_attrib_stack_depth = 16;
Ppca ppca;
ppca.Init(ctx);

View file

@ -580,13 +580,13 @@ TEST ( RegalTexC, GetBoundTexture ) {
// Setup
texc.textureUnitArrayState[ 0 ].Bind( GL_TEXTURE_CUBE_MAP, &boundToCubemapUnit0 );
texc.textureUnitArrayState[ REGAL_EMU_MAX_TEXTURE_UNITS - 1 ].Bind( GL_TEXTURE_CUBE_MAP, &boundToCubemapUnitMax );
texc.textureUnitArrayState[ REGAL_EMU_MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1 ].Bind( GL_TEXTURE_CUBE_MAP, &boundToCubemapUnitMax );
// Test expectations.
EXPECT_EQ( &texc.textureZero, texc.GetBoundTexture_( GL_TEXTURE0, GL_TEXTURE_2D ) );
EXPECT_EQ( &boundToCubemapUnit0, texc.GetBoundTexture_( GL_TEXTURE0, GL_TEXTURE_CUBE_MAP ) );
EXPECT_EQ( &boundToCubemapUnitMax, texc.GetBoundTexture_( GL_TEXTURE0 + REGAL_EMU_MAX_TEXTURE_UNITS - 1, GL_TEXTURE_CUBE_MAP ) );
EXPECT_EQ( NULL, texc.GetBoundTexture_( GL_TEXTURE0 + REGAL_EMU_MAX_TEXTURE_UNITS, GL_TEXTURE_2D ) );
EXPECT_EQ( &boundToCubemapUnitMax, texc.GetBoundTexture_( GL_TEXTURE0 + REGAL_EMU_MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1, GL_TEXTURE_CUBE_MAP ) );
EXPECT_EQ( NULL, texc.GetBoundTexture_( GL_TEXTURE0 + REGAL_EMU_MAX_COMBINED_TEXTURE_IMAGE_UNITS, GL_TEXTURE_2D ) );
EXPECT_EQ( NULL, texc.GetBoundTexture_( GL_TEXTURE0 - 1, GL_TEXTURE_2D ) );
}
@ -671,7 +671,7 @@ TEST ( RegalTexC, ShadowTexImage2D ) {
GLenum type;
// Set the current texture unit away from default.
texc.currentTextureUnit = GL_TEXTURE1;
texc.currentTextureUnit = 1;
// Test the first overload, affecting textureZero.
// Setting the format/type and then getting it should match.
@ -691,7 +691,7 @@ TEST ( RegalTexC, ShadowTexImage2D ) {
EXPECT_EQ( 31u, type );
// If the texture unit is out of range, the call silently is ignored.
texc.currentTextureUnit = GL_TEXTURE0 - 1;
texc.currentTextureUnit = -1;
texc.ShadowTexImage2D( GL_TEXTURE_2D, 15, 0, 0 );
}
@ -779,15 +779,21 @@ TEST ( RegalTexC, ShadowActiveTexture ) {
TexC texc;
// Verify initial state
EXPECT_EQ( static_cast<GLenum>( GL_TEXTURE0 ), texc.currentTextureUnit );
EXPECT_EQ( static_cast<GLenum>( 0 ), texc.currentTextureUnit );
// Each call should just simply change currentTextureUnit.
texc.ShadowActiveTexture( GL_TEXTURE1 );
EXPECT_EQ( static_cast<GLenum>( GL_TEXTURE1 ), texc.currentTextureUnit );
EXPECT_EQ( static_cast<GLenum>( 1 ), texc.currentTextureUnit );
// No range checking is done.
// invalid enums should be ignored
texc.ShadowActiveTexture( GL_TEXTURE0 - 1 );
EXPECT_EQ( static_cast<GLenum>( GL_TEXTURE0 - 1 ), texc.currentTextureUnit );
EXPECT_EQ( static_cast<GLenum>( 1 ), texc.currentTextureUnit );
texc.ShadowActiveTexture( GL_TEXTURE0 + REGAL_EMU_MAX_COMBINED_TEXTURE_IMAGE_UNITS );
EXPECT_EQ( static_cast<GLenum>( 1 ), texc.currentTextureUnit );
texc.ShadowActiveTexture( GLenum(~0) );
EXPECT_EQ( static_cast<GLenum>( 1 ), texc.currentTextureUnit );
}
TEST ( RegalTexC, ShadowBindTexture ) {
@ -800,7 +806,7 @@ TEST ( RegalTexC, ShadowBindTexture ) {
EXPECT_EQ( NULL, texc.textureUnitArrayState[ 1 ].GetBinding( GL_TEXTURE_2D ) );
// Set the current texture unit to non-default
texc.currentTextureUnit = GL_TEXTURE1;
texc.currentTextureUnit = 1;
// Binding texture 123 ...
texc.ShadowBindTexture( GL_TEXTURE_2D, 123 );
@ -819,7 +825,7 @@ TEST ( RegalTexC, ShadowBindTexture ) {
EXPECT_EQ( NULL, texc.textureUnitArrayState[ 1 ].GetBinding( GL_TEXTURE_2D ) );
// If the texture unit is out of the valid range ...
texc.currentTextureUnit = GL_TEXTURE0 - 1;
texc.currentTextureUnit = -1;
// The call should silently do nothing.
texc.ShadowBindTexture( GL_TEXTURE_2D, 123 );
@ -838,7 +844,7 @@ TEST ( RegalTexC, ShadowGenerateMipmap ) {
texc.textureUnitArrayState[ 1 ].Bind( GL_TEXTURE_2D, &boundToUnit1 );
// Invoke the function under test to emulate mipmap generation.
texc.currentTextureUnit = GL_TEXTURE1;
texc.currentTextureUnit = 1;
texc.ShadowGenerateMipmap( GL_TEXTURE_2D );
// We expect the texture state to indicate a single default format.