blob: 7ce143bb392eeb1b6b0c959735da274e8996067e [file] [log] [blame]
/*
Copyright (c) 2011-2013 NVIDIA Corporation
Copyright (c) 2011-2013 Cass Everitt
Copyright (c) 2012-2013 Scott Nations
Copyright (c) 2012-2013 Mathias Schott
Copyright (c) 2012-2013 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.
*/
#include "pch.h" /* For MS precompiled header support */
#include "RegalUtil.h"
#if REGAL_EMULATION
REGAL_GLOBAL_BEGIN
#include "RegalLog.h"
#include "RegalFilt.h"
#include "RegalToken.h"
REGAL_GLOBAL_END
REGAL_NAMESPACE_BEGIN
namespace Emu {
using namespace ::REGAL_NAMESPACE_INTERNAL::Logging;
using namespace ::REGAL_NAMESPACE_INTERNAL::Token;
bool Filt::BindTexture(const RegalContext &ctx, GLenum target, GLuint name)
{
UNUSED_PARAMETER(ctx);
UNUSED_PARAMETER(target);
UNUSED_PARAMETER(name);
if (ctx.isES2())
{
switch( target )
{
case GL_TEXTURE_1D:
case GL_TEXTURE_3D:
Warning( "Regal does not support ", GLenumToString( target ), " as target for glBindTexture for ES 2.0 profile - skipping." );
return true;
default:
break;
}
}
return false;
}
bool Filt::BindFramebuffer(const RegalContext &ctx, GLenum target, GLuint framebuffer)
{
UNUSED_PARAMETER(ctx);
UNUSED_PARAMETER(target);
UNUSED_PARAMETER(framebuffer);
fboID = framebuffer;
return false;
}
bool Filt::DrawBuffers(const RegalContext &ctx, GLsizei n, const GLenum *bufs)
{
UNUSED_PARAMETER(ctx);
if (!ctx.isES2())
return false;
for (GLsizei i = 0; i < n; ++i)
{
if (bufs[i] == GL_NONE || (bufs[i] >= GL_COLOR_ATTACHMENT0 && bufs[i] <= GL_COLOR_ATTACHMENT15))
continue;
Warning( "Regal does not support ", GLenumToString( bufs[i] ), " as target for glDrawBuffers for ES 2.0 profile - skipping." );
return true;
}
return false;
}
bool Filt::FilterTexParameter(const RegalContext &ctx, GLenum target, GLenum pname, GLfloat param, GLfloat &newParam)
{
UNUSED_PARAMETER(ctx);
UNUSED_PARAMETER(target);
if (!ctx.isES2() && !ctx.isCore())
return false;
switch(pname)
{
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
case GL_TEXTURE_WRAP_R:
switch(int(param))
{
case GL_CLAMP:
Warning("Regal does not support GL_CLAMP wrap mode for core or ES 2.0 profiles - remapping to equivalent GL_CLAMP_TO_EDGE");
newParam = GL_CLAMP_TO_EDGE;
return true;
default: break;
}
default: break;
}
return false;
}
bool Filt::FramebufferTexture2D(const RegalContext &ctx, GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level)
{
UNUSED_PARAMETER(ctx);
UNUSED_PARAMETER(target);
UNUSED_PARAMETER(attachment);
UNUSED_PARAMETER(textarget);
UNUSED_PARAMETER(texture);
UNUSED_PARAMETER(level);
if (!FramebufferAttachmentSupported(ctx, attachment))
{
return true;
}
if (!ctx.isES2())
return false;
if ((level > 0) && !ctx.info->gl_oes_fbo_render_mipmap)
{
Warning("glFramebufferTexture2D with level > 0 not supported for ES 2.0 without OES_fbo_render_mipmap.");
return true;
}
if (texture > 0)
{
switch (textarget)
{
case GL_TEXTURE_2D:
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
break;
default:
Warning("glFramebufferTexture2D with ", GLenumToString(target), ") not supported for ES 2.0.");
return true;
}
}
return false;
}
bool Filt::GenerateMipmap(const RegalContext &ctx, GLenum target)
{
UNUSED_PARAMETER(ctx);
UNUSED_PARAMETER(target);
if (!ctx.isES2())
return false;
switch(target)
{
case GL_TEXTURE_2D:
case GL_TEXTURE_CUBE_MAP:
break;
case GL_TEXTURE_2D_ARRAY:
if (!ctx.info->gl_nv_texture_array)
{
Warning("glGenerateMipmap(GL_TEXTURE_2D_ARRAY) not supported for ES 2.0 without NV_texture_array.");
return true;
}
break;
default:
Warning("glGenerateMipmap(", GLenumToString(target), ") not supported for ES 2.0.");
return true;
}
return false;
}
bool Filt::ReadBuffer(const RegalContext &ctx, GLenum src)
{
UNUSED_PARAMETER(ctx);
UNUSED_PARAMETER(src);
if (!ctx.isES2() || !ctx.info->gl_nv_read_buffer)
return false;
switch(src)
{
// These two should always be supported w/o additional extensions
case GL_COLOR_ATTACHMENT0:
case GL_BACK:
break;
// GL_FRONT may require NV_read_buffer_front, depending whether the context is
// double buffered. Let's output a warning but still pass it through
case GL_FRONT:
if (!ctx.info->gl_nv_read_buffer_front)
Warning("glReadBuffer(GL_FRONT) may not work on ES 2 without NV_read_buffer_front, depending on context buffering.");
break;
case GL_COLOR_ATTACHMENT1:
case GL_COLOR_ATTACHMENT2:
case GL_COLOR_ATTACHMENT3:
case GL_COLOR_ATTACHMENT4:
case GL_COLOR_ATTACHMENT5:
case GL_COLOR_ATTACHMENT6:
case GL_COLOR_ATTACHMENT7:
case GL_COLOR_ATTACHMENT8:
case GL_COLOR_ATTACHMENT9:
case GL_COLOR_ATTACHMENT10:
case GL_COLOR_ATTACHMENT11:
case GL_COLOR_ATTACHMENT12:
case GL_COLOR_ATTACHMENT13:
case GL_COLOR_ATTACHMENT14:
case GL_COLOR_ATTACHMENT15:
if (!ctx.info->gl_nv_draw_buffers)
{
Warning("glReadBuffer(GL_COLOR_ATTACHMENT1+) not supported for ES 2 without NV_draw_buffers.");
return true;
}
break;
default:
Warning("glReadBuffer(", GLenumToString(src), ") not supported for ES 2.\n");
return true;
}
return false;
}
bool Filt::RenderMode(const RegalContext &ctx, GLenum mode)
{
UNUSED_PARAMETER(ctx);
UNUSED_PARAMETER(mode);
if (ctx.isCore() || ctx.isES2())
if (mode!=GL_RENDER)
{
Warning("Regal does not support ", GLenumToString(mode), " render mode for core or ES 2.0 profiles, only GL_RENDER is supported in those profiles - skipping.");
return true;
}
return false;
}
bool Filt::FramebufferAttachmentSupported(const RegalContext &ctx, GLenum attachment)
{
UNUSED_PARAMETER(ctx);
UNUSED_PARAMETER(attachment);
// If we're running on a non-ES context, then all attachments from EXT_framebuffer_object
// are supported
if (!ctx.isES2())
return true;
// COLOR_ATTACHMENT1 and up not supported in base ES 2.0. Need either
// NV_fbo_color_attachments, or EXT_draw_buffers (not yet checked by Regal)
if ((attachment > GL_COLOR_ATTACHMENT0) &&
(attachment <= GL_COLOR_ATTACHMENT15) &&
!(ctx.info->gl_nv_fbo_color_attachments /*|| ctx.info->gl_ext_draw_buffers*/))
{
Warning("GL_COLOR_ATTACHMENT1+ not supported for ES 2.0 without NV_fbo_color_attachments or EXT_draw_buffers.");
return false;
}
return true;
}
bool Filt::PixelStorei(const RegalContext &ctx, GLenum pname, GLint param)
{
UNUSED_PARAMETER(ctx);
UNUSED_PARAMETER(pname);
UNUSED_PARAMETER(param);
if (ctx.isES2())
{
switch(pname)
{
case GL_PACK_ALIGNMENT:
case GL_UNPACK_ALIGNMENT:
break;
case GL_UNPACK_ROW_LENGTH_EXT:
case GL_UNPACK_SKIP_ROWS_EXT:
case GL_UNPACK_SKIP_PIXELS_EXT:
if (!ctx.info->gl_ext_unpack_subimage)
{
Warning("glPixelStorei ", GLenumToString(pname),
" not supported for ES 2.0 without EXT_unpack_subimage.");
return true;
}
break;
case GL_UNPACK_SKIP_IMAGES_NV:
case GL_UNPACK_IMAGE_HEIGHT_NV:
if (!ctx.info->gl_ext_unpack_subimage || !ctx.info->gl_nv_texture_array)
{
Warning("glPixelStorei ", GLenumToString(pname),
" not supported for ES 2.0 without EXT_unpack_subimage and NV_texture_array.");
return true;
}
break;
case GL_PACK_ROW_LENGTH_NV:
case GL_PACK_SKIP_ROWS_NV:
case GL_PACK_SKIP_PIXELS_NV:
if (!ctx.info->gl_nv_pack_subimage)
{
Warning("glPixelStorei ", GLenumToString(pname),
" not supported for ES 2.0 without NV_pack_subimage.");
return true;
}
break;
case GL_PACK_IMAGE_HEIGHT:
case GL_PACK_SKIP_IMAGES:
if (!ctx.info->gl_nv_pack_subimage || !ctx.info->gl_nv_texture_array)
{
Warning("glPixelStorei ", GLenumToString(pname),
" not supported for ES 2.0 without NV_pack_subimage and NV_texture_array.");
return true;
}
break;
default:
Warning("glPixelStorei ", GLenumToString(pname), " not supported for ES 2.0.");
return true;
}
}
return false;
}
bool Filt::PolygonMode(const RegalContext &ctx, GLenum face, GLenum mode)
{
UNUSED_PARAMETER(ctx);
UNUSED_PARAMETER(face);
UNUSED_PARAMETER(mode);
if (ctx.isCore())
{
if (face!=GL_FRONT_AND_BACK)
{
Warning("Regal does not support ", GLenumToString(face), " in glPolygonMode for core profile, only GL_FRONT_AND_BACK is supported - skipping.");
return true;
}
}
if (ctx.isES2())
{
Warning("Regal does not support glPolygonMode for ES 2.0 - skipping.");
return true;
}
return false;
}
bool Filt::FilterGet(const RegalContext &ctx, GLenum pname, int &retVal)
{
UNUSED_PARAMETER(ctx);
UNUSED_PARAMETER(pname);
bool filtered = false;
if (ctx.isCore() || ctx.isES2())
{
filtered = true;
switch (pname )
{
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_DEPTH_BITS: retVal = 24; break;
case GL_RED_BITS:
case GL_GREEN_BITS:
case GL_BLUE_BITS:
case GL_ALPHA_BITS:
case GL_STENCIL_BITS:
retVal = 8;
break;
case GL_INDEX_MODE:
case GL_UNPACK_LSB_FIRST:
case GL_UNPACK_SWAP_BYTES:
case GL_PACK_LSB_FIRST:
case GL_PACK_SWAP_BYTES:
retVal = 0;
break;
default:
filtered = false;
break;
}
if (filtered)
{
Warning( "Regal does not support ", GLenumToString(pname), " as pname for glGet for core or ES 2.0 profiles - skipping." );
return true;
}
}
if (ctx.isCore())
{
filtered = true;
#if 0
switch (pname )
{
/* just a test
case GL_UNPACK_ALIGNMENT:
retVal = 0;
break;
*/
default:
filtered = false;
break;
}
#else
filtered = false;
#endif
if (filtered)
{
Warning( "Regal does not support ", GLenumToString(pname), " as pname for glGet for core profile - skipping." );
return true;
}
}
if (ctx.isES2())
{
filtered = true;
switch (pname) {
case GL_MAX_COLOR_ATTACHMENTS:
if (ctx.info->gl_nv_fbo_color_attachments)
filtered = false;
else
retVal = 1;
break;
case GL_PACK_ROW_LENGTH_NV:
case GL_PACK_SKIP_ROWS_NV:
case GL_PACK_SKIP_PIXELS_NV:
if (ctx.info->gl_nv_pack_subimage)
filtered = false;
else
retVal = 0;
break;
case GL_PACK_IMAGE_HEIGHT:
case GL_PACK_SKIP_IMAGES:
if (ctx.info->gl_nv_pack_subimage && ctx.info->gl_nv_texture_array)
filtered = false;
else
retVal = 0;
break;
case GL_UNPACK_ROW_LENGTH_EXT:
case GL_UNPACK_SKIP_ROWS_EXT:
case GL_UNPACK_SKIP_PIXELS_EXT:
if (ctx.info->gl_ext_unpack_subimage)
filtered = false;
else
retVal = 0;
break;
case GL_UNPACK_IMAGE_HEIGHT_NV:
case GL_UNPACK_SKIP_IMAGES_NV:
if (ctx.info->gl_ext_unpack_subimage && ctx.info->gl_nv_texture_array)
filtered = false;
else
retVal = 0;
break;
// need to filter on ES2.0 since this query returns an
// INVALID_ENUM if no FBO is currently active
case GL_DRAW_BUFFER0:
case GL_DRAW_BUFFER1:
case GL_DRAW_BUFFER2:
case GL_DRAW_BUFFER3:
case GL_DRAW_BUFFER4:
case GL_DRAW_BUFFER5:
case GL_DRAW_BUFFER6:
case GL_DRAW_BUFFER7:
case GL_DRAW_BUFFER8:
case GL_DRAW_BUFFER9:
case GL_DRAW_BUFFER10:
case GL_DRAW_BUFFER11:
case GL_DRAW_BUFFER12:
case GL_DRAW_BUFFER13:
case GL_DRAW_BUFFER14:
case GL_DRAW_BUFFER15:
if (ctx.info->gl_nv_draw_buffers)
{
if (fboID == 0)
retVal = GL_NONE;
else
filtered = false;
}
else
retVal = GL_NONE;
break;
default:
filtered = false;
break;
}
if (filtered)
{
Warning( "Regal does not support ", GLenumToString(pname), " as pname for glGet for ES 2.0 profile - skipping." );
return true;
}
}
return false;
}
}
REGAL_NAMESPACE_END
#endif // REGAL_EMULATION