mirror of
https://github.com/love2d/love.git
synced 2026-08-12 00:20:52 +02:00
Minimum required opengl version is now OpenGL 3.3 / OpenGL ES 3.0.
This commit is contained in:
@@ -86,9 +86,6 @@ Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector<DataDe
|
||||
|
||||
if (indexbuffer)
|
||||
{
|
||||
if (!caps.features[Graphics::FEATURE_INDEX_BUFFER_32BIT] && format == DATAFORMAT_UINT32)
|
||||
throw love::Exception("32 bit index buffer formats are not supported on this system.");
|
||||
|
||||
if (format != DATAFORMAT_UINT16 && format != DATAFORMAT_UINT32)
|
||||
throw love::Exception("Index buffers only support uint16 and uint32 data types.");
|
||||
|
||||
|
||||
@@ -1604,9 +1604,6 @@ void Graphics::captureScreenshot(const ScreenshotInfo &info)
|
||||
|
||||
void Graphics::copyBuffer(Buffer *source, Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size)
|
||||
{
|
||||
if (!capabilities.features[FEATURE_COPY_BUFFER])
|
||||
throw love::Exception("Buffer copying is not supported on this system.");
|
||||
|
||||
Range sourcerange(sourceoffset, size);
|
||||
Range destrange(destoffset, size);
|
||||
|
||||
@@ -1640,9 +1637,6 @@ void Graphics::copyTextureToBuffer(Texture *source, Buffer *dest, int slice, int
|
||||
{
|
||||
if (!source->isRenderTarget())
|
||||
throw love::Exception("Copying a non-render target Texture to a Buffer is not supported on this system.");
|
||||
|
||||
if (!capabilities.features[FEATURE_COPY_RENDER_TARGET_TO_BUFFER])
|
||||
throw love::Exception("Copying a render target Texture to a Buffer is not supported on this system.");
|
||||
}
|
||||
|
||||
PixelFormat format = source->getPixelFormat();
|
||||
@@ -1728,9 +1722,6 @@ void Graphics::copyTextureToBuffer(Texture *source, Buffer *dest, int slice, int
|
||||
|
||||
void Graphics::copyBufferToTexture(Buffer *source, Texture *dest, size_t sourceoffset, int sourcewidth, int slice, int mipmap, const Rect &rect)
|
||||
{
|
||||
if (!capabilities.features[FEATURE_COPY_BUFFER_TO_TEXTURE])
|
||||
throw love::Exception("Copying a Buffer to a Texture is not supported on this system.");
|
||||
|
||||
if (source->getDataUsage() == BUFFERDATAUSAGE_READBACK)
|
||||
throw love::Exception("Buffers created with 'readback' data usage cannot be used as a copy source.");
|
||||
|
||||
@@ -2914,7 +2905,6 @@ STRINGMAP_CLASS_BEGIN(Graphics, Graphics::Feature, Graphics::FEATURE_MAX_ENUM, f
|
||||
{ "multirendertargetformats", Graphics::FEATURE_MULTI_RENDER_TARGET_FORMATS },
|
||||
{ "clampzero", Graphics::FEATURE_CLAMP_ZERO },
|
||||
{ "clampone", Graphics::FEATURE_CLAMP_ONE },
|
||||
{ "blendminmax", Graphics::FEATURE_BLEND_MINMAX },
|
||||
{ "lighten", Graphics::FEATURE_LIGHTEN },
|
||||
{ "fullnpot", Graphics::FEATURE_FULL_NPOT },
|
||||
{ "pixelshaderhighp", Graphics::FEATURE_PIXEL_SHADER_HIGHP },
|
||||
@@ -2923,12 +2913,7 @@ STRINGMAP_CLASS_BEGIN(Graphics, Graphics::Feature, Graphics::FEATURE_MAX_ENUM, f
|
||||
{ "glsl4", Graphics::FEATURE_GLSL4 },
|
||||
{ "instancing", Graphics::FEATURE_INSTANCING },
|
||||
{ "texelbuffer", Graphics::FEATURE_TEXEL_BUFFER },
|
||||
{ "indexbuffer32bit", Graphics::FEATURE_INDEX_BUFFER_32BIT },
|
||||
{ "copybuffer", Graphics::FEATURE_COPY_BUFFER },
|
||||
{ "copybuffertotexture", Graphics::FEATURE_COPY_BUFFER_TO_TEXTURE },
|
||||
{ "copytexturetobuffer", Graphics::FEATURE_COPY_TEXTURE_TO_BUFFER },
|
||||
{ "copyrendertargettobuffer", Graphics::FEATURE_COPY_RENDER_TARGET_TO_BUFFER },
|
||||
{ "mipmaprange", Graphics::FEATURE_MIPMAP_RANGE },
|
||||
{ "indirectdraw", Graphics::FEATURE_INDIRECT_DRAW },
|
||||
}
|
||||
STRINGMAP_CLASS_END(Graphics, Graphics::Feature, Graphics::FEATURE_MAX_ENUM, feature)
|
||||
|
||||
@@ -147,24 +147,18 @@ public:
|
||||
|
||||
enum Feature
|
||||
{
|
||||
FEATURE_MULTI_RENDER_TARGET_FORMATS,
|
||||
FEATURE_MULTI_RENDER_TARGET_FORMATS, // Deprecated
|
||||
FEATURE_CLAMP_ZERO,
|
||||
FEATURE_CLAMP_ONE,
|
||||
FEATURE_BLEND_MINMAX,
|
||||
FEATURE_LIGHTEN, // Deprecated
|
||||
FEATURE_FULL_NPOT,
|
||||
FEATURE_PIXEL_SHADER_HIGHP,
|
||||
FEATURE_SHADER_DERIVATIVES,
|
||||
FEATURE_GLSL3,
|
||||
FEATURE_FULL_NPOT, // Deprecated
|
||||
FEATURE_PIXEL_SHADER_HIGHP, // Deprecated
|
||||
FEATURE_SHADER_DERIVATIVES, // Deprecated
|
||||
FEATURE_GLSL3, // Deprecated
|
||||
FEATURE_GLSL4,
|
||||
FEATURE_INSTANCING,
|
||||
FEATURE_INSTANCING, // Deprecated
|
||||
FEATURE_TEXEL_BUFFER,
|
||||
FEATURE_INDEX_BUFFER_32BIT,
|
||||
FEATURE_COPY_BUFFER,
|
||||
FEATURE_COPY_BUFFER_TO_TEXTURE,
|
||||
FEATURE_COPY_TEXTURE_TO_BUFFER,
|
||||
FEATURE_COPY_RENDER_TARGET_TO_BUFFER,
|
||||
FEATURE_MIPMAP_RANGE,
|
||||
FEATURE_INDIRECT_DRAW,
|
||||
FEATURE_MAX_ENUM
|
||||
};
|
||||
|
||||
@@ -40,9 +40,6 @@ GraphicsReadback::GraphicsReadback(Graphics *gfx, ReadbackMethod method, Buffer
|
||||
{
|
||||
const auto &caps = gfx->getCapabilities();
|
||||
|
||||
if (!caps.features[Graphics::FEATURE_COPY_BUFFER])
|
||||
throw love::Exception("readbackBuffer is not supported on this system (buffer copy support is required).");
|
||||
|
||||
if (offset + size > buffer->getSize())
|
||||
throw love::Exception("Invalid offset or size for the given Buffer.");
|
||||
|
||||
@@ -94,9 +91,7 @@ GraphicsReadback::GraphicsReadback(Graphics *gfx, ReadbackMethod method, Texture
|
||||
|
||||
if (method == READBACK_ASYNC)
|
||||
{
|
||||
if (isRT && !caps.features[Graphics::FEATURE_COPY_RENDER_TARGET_TO_BUFFER])
|
||||
throw love::Exception("readbackTextureAsync is not supported on this system.");
|
||||
else if (!isRT && !caps.features[Graphics::FEATURE_COPY_TEXTURE_TO_BUFFER])
|
||||
if (!isRT && !caps.features[Graphics::FEATURE_COPY_TEXTURE_TO_BUFFER])
|
||||
throw love::Exception("readbackTextureAsync with a non-render-target texture is not supported on this system.");
|
||||
}
|
||||
else
|
||||
|
||||
@@ -51,11 +51,7 @@ static const char global_syntax[] = R"(
|
||||
#define mediump
|
||||
#define highp
|
||||
#endif
|
||||
#if defined(VERTEX) || __VERSION__ > 100 || defined(GL_FRAGMENT_PRECISION_HIGH)
|
||||
#define LOVE_HIGHP_OR_MEDIUMP highp
|
||||
#else
|
||||
#define LOVE_HIGHP_OR_MEDIUMP mediump
|
||||
#endif
|
||||
#define LOVE_HIGHP_OR_MEDIUMP highp
|
||||
#if __VERSION__ >= 300
|
||||
#define LOVE_IO_LOCATION(x) layout (location = x)
|
||||
#else
|
||||
@@ -88,15 +84,7 @@ static const char global_syntax[] = R"(
|
||||
)";
|
||||
|
||||
static const char render_uniforms[] = R"(
|
||||
// According to the GLSL ES 1.0 spec, uniform precision must match between stages,
|
||||
// but we can't guarantee that highp is always supported in fragment shaders...
|
||||
// We *really* don't want to use mediump for these in vertex shaders though.
|
||||
#ifdef LOVE_SPLIT_UNIFORMS_PER_DRAW
|
||||
uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw[11];
|
||||
uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw2[1];
|
||||
#else
|
||||
uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw[12];
|
||||
#endif
|
||||
uniform highp vec4 love_UniformsPerDraw[12];
|
||||
|
||||
// Older GLSL doesn't support preprocessor line continuations...
|
||||
#define TransformMatrix mat4(love_UniformsPerDraw[0], love_UniformsPerDraw[1], love_UniformsPerDraw[2], love_UniformsPerDraw[3])
|
||||
@@ -105,16 +93,9 @@ uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw[12];
|
||||
|
||||
#define CurrentDPIScale (love_UniformsPerDraw[8].x)
|
||||
#define ConstantPointSize (love_UniformsPerDraw[8].y)
|
||||
|
||||
#define love_ClipSpaceParams (love_UniformsPerDraw[9])
|
||||
|
||||
#define ConstantColor (love_UniformsPerDraw[10])
|
||||
|
||||
#ifdef LOVE_SPLIT_UNIFORMS_PER_DRAW
|
||||
#define love_ScreenSize (love_UniformsPerDraw2[0])
|
||||
#else
|
||||
#define love_ScreenSize (love_UniformsPerDraw[11])
|
||||
#endif
|
||||
|
||||
// Alternate names
|
||||
#define ViewSpaceFromLocal TransformMatrix
|
||||
@@ -667,11 +648,6 @@ std::string Shader::createShaderStageCode(Graphics *gfx, ShaderStageType stage,
|
||||
if (info.usesMRT)
|
||||
ss << "#define LOVE_MULTI_RENDER_TARGETS 1\n";
|
||||
|
||||
// Note: backends are expected to handle this situation if highp is ever
|
||||
// conditional in that backend.
|
||||
if (!gfx->getCapabilities().features[Graphics::FEATURE_PIXEL_SHADER_HIGHP])
|
||||
ss << "#define LOVE_SPLIT_UNIFORMS_PER_DRAW 1\n";
|
||||
|
||||
for (const auto &def : options.defines)
|
||||
ss << "#define " + def.first + " " + def.second + "\n";
|
||||
|
||||
|
||||
@@ -253,9 +253,6 @@ Texture::Texture(Graphics *gfx, const Settings &settings, const Slices *slices)
|
||||
mipmapCount = std::min(totalMipmapCount, requestedMipmapCount);
|
||||
else
|
||||
mipmapCount = totalMipmapCount;
|
||||
|
||||
if (mipmapCount != totalMipmapCount && !caps.features[Graphics::FEATURE_MIPMAP_RANGE])
|
||||
throw love::Exception("Custom mipmap ranges for a texture are not supported on this system (%d mipmap levels are required but only %d levels were provided.)", totalMipmapCount, mipmapCount);
|
||||
}
|
||||
|
||||
const char *miperr = nullptr;
|
||||
|
||||
@@ -2227,7 +2227,6 @@ void Graphics::initCapabilities()
|
||||
if (families.mac[1] || families.macCatalyst[1] || families.apple[7])
|
||||
capabilities.features[FEATURE_CLAMP_ONE] = true;
|
||||
}
|
||||
capabilities.features[FEATURE_BLEND_MINMAX] = true;
|
||||
capabilities.features[FEATURE_LIGHTEN] = true;
|
||||
capabilities.features[FEATURE_FULL_NPOT] = true;
|
||||
capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = true;
|
||||
@@ -2236,19 +2235,14 @@ void Graphics::initCapabilities()
|
||||
capabilities.features[FEATURE_GLSL4] = true;
|
||||
capabilities.features[FEATURE_INSTANCING] = true;
|
||||
capabilities.features[FEATURE_TEXEL_BUFFER] = true;
|
||||
capabilities.features[FEATURE_INDEX_BUFFER_32BIT] = true;
|
||||
capabilities.features[FEATURE_COPY_BUFFER] = true;
|
||||
capabilities.features[FEATURE_COPY_BUFFER_TO_TEXTURE] = true;
|
||||
capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = true;
|
||||
capabilities.features[FEATURE_COPY_RENDER_TARGET_TO_BUFFER] = true;
|
||||
capabilities.features[FEATURE_MIPMAP_RANGE] = true;
|
||||
|
||||
if (families.mac[1] || families.macCatalyst[1] || families.apple[3])
|
||||
capabilities.features[FEATURE_INDIRECT_DRAW] = true;
|
||||
else
|
||||
capabilities.features[FEATURE_INDIRECT_DRAW] = false;
|
||||
|
||||
static_assert(FEATURE_MAX_ENUM == 19, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
static_assert(FEATURE_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
|
||||
// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
|
||||
capabilities.limits[LIMIT_POINT_SIZE] = 511;
|
||||
|
||||
@@ -196,11 +196,7 @@ void *Buffer::map(MapType map, size_t offset, size_t size)
|
||||
if (map == MAP_READ_ONLY)
|
||||
{
|
||||
gl.bindBuffer(mapUsage, buffer);
|
||||
|
||||
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0)
|
||||
data = (char *) glMapBufferRange(target, offset, size, GL_MAP_READ_BIT);
|
||||
else if (GLAD_VERSION_1_1)
|
||||
data = (char *) glMapBuffer(target, GL_READ_ONLY) + offset;
|
||||
data = (char *) glMapBufferRange(target, offset, size, GL_MAP_READ_BIT);
|
||||
}
|
||||
else if (ownsMemoryMap)
|
||||
{
|
||||
|
||||
@@ -225,14 +225,6 @@ void Graphics::backbufferChanged(int width, int height, int pixelwidth, int pixe
|
||||
if (msaa > 1)
|
||||
useinternalbackbuffer = true;
|
||||
|
||||
// Our internal backbuffer code needs glBlitFramebuffer.
|
||||
if (!(GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object || GLAD_ES_VERSION_3_0
|
||||
|| GLAD_EXT_framebuffer_blit || GLAD_ANGLE_framebuffer_blit || GLAD_NV_framebuffer_blit))
|
||||
{
|
||||
if (!(msaa > 1 && GLAD_APPLE_framebuffer_multisample))
|
||||
useinternalbackbuffer = false;
|
||||
}
|
||||
|
||||
GLuint prevFBO = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
|
||||
bool restoreFBO = prevFBO != getInternalBackbufferFBO();
|
||||
|
||||
@@ -350,8 +342,7 @@ bool Graphics::setMode(void */*context*/, int width, int height, int pixelwidth,
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
|
||||
// Set whether drawing converts input from linear -> sRGB colorspace.
|
||||
if (!gl.bugs.brokenSRGB && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB
|
||||
|| GLAD_EXT_framebuffer_sRGB || GLAD_ES_VERSION_3_0))
|
||||
if (!gl.bugs.brokenSRGB)
|
||||
{
|
||||
if (GLAD_VERSION_1_0 || GLAD_EXT_sRGB_write_control)
|
||||
gl.setEnableState(OpenGL::ENABLE_FRAMEBUFFER_SRGB, isGammaCorrect());
|
||||
@@ -947,7 +938,6 @@ void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt sten
|
||||
|
||||
flushBatchedDraws();
|
||||
|
||||
bool drawbuffersmodified = false;
|
||||
ncolors = std::min(ncolors, ncolorRTs);
|
||||
|
||||
for (int i = 0; i < ncolors; i++)
|
||||
@@ -961,51 +951,25 @@ void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt sten
|
||||
|
||||
ColorD c = colors[i].value;
|
||||
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0)
|
||||
if (datatype == PIXELFORMATTYPE_SINT)
|
||||
{
|
||||
if (datatype == PIXELFORMATTYPE_SINT)
|
||||
{
|
||||
const GLint carray[] = {(GLint)c.r, (GLint)c.g, (GLint)c.b, (GLint)c.a};
|
||||
glClearBufferiv(GL_COLOR, i, carray);
|
||||
}
|
||||
else if (datatype == PIXELFORMATTYPE_UINT)
|
||||
{
|
||||
const GLuint carray[] = {(GLuint)c.r, (GLuint)c.g, (GLuint)c.b, (GLuint)c.a};
|
||||
glClearBufferuiv(GL_COLOR, i, carray);
|
||||
}
|
||||
else
|
||||
{
|
||||
Colorf cf((float)c.r, (float)c.g, (float)c.b, (float)c.a);
|
||||
gammaCorrectColor(cf);
|
||||
const GLfloat carray[] = {cf.r, cf.g, cf.b, cf.a};
|
||||
glClearBufferfv(GL_COLOR, i, carray);
|
||||
}
|
||||
const GLint carray[] = {(GLint)c.r, (GLint)c.g, (GLint)c.b, (GLint)c.a};
|
||||
glClearBufferiv(GL_COLOR, i, carray);
|
||||
}
|
||||
else if (datatype == PIXELFORMATTYPE_UINT)
|
||||
{
|
||||
const GLuint carray[] = {(GLuint)c.r, (GLuint)c.g, (GLuint)c.b, (GLuint)c.a};
|
||||
glClearBufferuiv(GL_COLOR, i, carray);
|
||||
}
|
||||
else
|
||||
{
|
||||
Colorf cf((float)c.r, (float)c.g, (float)c.b, (float)c.a);
|
||||
gammaCorrectColor(cf);
|
||||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0 + i);
|
||||
glClearColor(cf.r, cf.g, cf.b, cf.a);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
drawbuffersmodified = true;
|
||||
const GLfloat carray[] = {cf.r, cf.g, cf.b, cf.a};
|
||||
glClearBufferfv(GL_COLOR, i, carray);
|
||||
}
|
||||
}
|
||||
|
||||
// Revert to the expected draw buffers once we're done, if glClearBuffer
|
||||
// wasn't supported.
|
||||
if (drawbuffersmodified)
|
||||
{
|
||||
GLenum bufs[MAX_COLOR_RENDER_TARGETS];
|
||||
|
||||
for (int i = 0; i < ncolorRTs; i++)
|
||||
bufs[i] = GL_COLOR_ATTACHMENT0 + i;
|
||||
|
||||
glDrawBuffers(ncolorRTs, bufs);
|
||||
}
|
||||
|
||||
GLbitfield flags = 0;
|
||||
|
||||
if (stencil.hasValue)
|
||||
@@ -1145,7 +1109,7 @@ GLuint Graphics::bindCachedFBO(const RenderTargets &targets)
|
||||
auto attachRT = [&](const RenderTarget &rt)
|
||||
{
|
||||
bool renderbuffer = msaa > 1 || !rt.texture->isReadable();
|
||||
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(rt.texture->getPixelFormat(), renderbuffer);
|
||||
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(rt.texture->getPixelFormat());
|
||||
|
||||
if (fmt.framebufferAttachments[0] == GL_COLOR_ATTACHMENT0)
|
||||
{
|
||||
@@ -1183,14 +1147,10 @@ GLuint Graphics::bindCachedFBO(const RenderTargets &targets)
|
||||
|
||||
if (ncolortargets > 1)
|
||||
glDrawBuffers(ncolortargets, drawbuffers);
|
||||
else if (ncolortargets == 0 && hasDS && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0))
|
||||
else if (ncolortargets == 0 && hasDS)
|
||||
{
|
||||
// glDrawBuffers is an ext in GL2. glDrawBuffer doesn't exist in ES3.
|
||||
GLenum none = GL_NONE;
|
||||
if (GLAD_ES_VERSION_3_0)
|
||||
glDrawBuffers(1, &none);
|
||||
else
|
||||
glDrawBuffer(GL_NONE);
|
||||
glDrawBuffers(1, &none);
|
||||
glReadBuffer(GL_NONE);
|
||||
}
|
||||
|
||||
@@ -1521,13 +1481,6 @@ void Graphics::setBlendState(const BlendState &blend)
|
||||
if (!(blend == states.back().blend))
|
||||
flushBatchedDraws();
|
||||
|
||||
if (blend.operationRGB == BLENDOP_MAX || blend.operationA == BLENDOP_MAX
|
||||
|| blend.operationRGB == BLENDOP_MIN || blend.operationA == BLENDOP_MIN)
|
||||
{
|
||||
if (!capabilities.features[FEATURE_BLEND_MINMAX])
|
||||
throw love::Exception("The 'min' and 'max' blend operations are not supported on this system.");
|
||||
}
|
||||
|
||||
if (blend.enable != gl.isStateEnabled(OpenGL::ENABLE_BLEND))
|
||||
gl.setEnableState(OpenGL::ENABLE_BLEND, blend.enable);
|
||||
|
||||
@@ -1629,26 +1582,20 @@ void Graphics::getAPIStats(int &shaderswitches) const
|
||||
|
||||
void Graphics::initCapabilities()
|
||||
{
|
||||
capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = gl.isMultiFormatMRTSupported();
|
||||
capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = true;
|
||||
capabilities.features[FEATURE_CLAMP_ZERO] = gl.isClampZeroOneTextureWrapSupported();
|
||||
capabilities.features[FEATURE_CLAMP_ONE] = gl.isClampZeroOneTextureWrapSupported();
|
||||
capabilities.features[FEATURE_BLEND_MINMAX] = GLAD_VERSION_1_4 || GLAD_ES_VERSION_3_0 || GLAD_EXT_blend_minmax;
|
||||
capabilities.features[FEATURE_LIGHTEN] = capabilities.features[FEATURE_BLEND_MINMAX];
|
||||
capabilities.features[FEATURE_FULL_NPOT] = GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_npot;
|
||||
capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = gl.isPixelShaderHighpSupported();
|
||||
capabilities.features[FEATURE_SHADER_DERIVATIVES] = GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_standard_derivatives;
|
||||
capabilities.features[FEATURE_GLSL3] = GLAD_ES_VERSION_3_0 || gl.isCoreProfile();
|
||||
capabilities.features[FEATURE_LIGHTEN] = true;
|
||||
capabilities.features[FEATURE_FULL_NPOT] = true;
|
||||
capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = true;
|
||||
capabilities.features[FEATURE_SHADER_DERIVATIVES] = true;
|
||||
capabilities.features[FEATURE_GLSL3] = true;
|
||||
capabilities.features[FEATURE_GLSL4] = GLAD_ES_VERSION_3_1 || (gl.isCoreProfile() && GLAD_VERSION_4_3);
|
||||
capabilities.features[FEATURE_INSTANCING] = gl.isInstancingSupported();
|
||||
capabilities.features[FEATURE_INSTANCING] = true;
|
||||
capabilities.features[FEATURE_TEXEL_BUFFER] = gl.isBufferUsageSupported(BUFFERUSAGE_TEXEL);
|
||||
capabilities.features[FEATURE_INDEX_BUFFER_32BIT] = GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_element_index_uint;
|
||||
capabilities.features[FEATURE_COPY_BUFFER] = gl.isCopyBufferSupported();
|
||||
capabilities.features[FEATURE_COPY_BUFFER_TO_TEXTURE] = gl.isCopyBufferToTextureSupported();
|
||||
capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = gl.isCopyTextureToBufferSupported();
|
||||
capabilities.features[FEATURE_COPY_RENDER_TARGET_TO_BUFFER] = gl.isCopyRenderTargetToBufferSupported();
|
||||
capabilities.features[FEATURE_MIPMAP_RANGE] = GLAD_VERSION_1_2 || GLAD_ES_VERSION_3_0;
|
||||
capabilities.features[FEATURE_INDIRECT_DRAW] = capabilities.features[FEATURE_GLSL4];
|
||||
static_assert(FEATURE_MAX_ENUM == 19, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
static_assert(FEATURE_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
|
||||
capabilities.limits[LIMIT_POINT_SIZE] = gl.getMaxPointSize();
|
||||
capabilities.limits[LIMIT_TEXTURE_SIZE] = gl.getMax2DTextureSize();
|
||||
@@ -1666,7 +1613,7 @@ void Graphics::initCapabilities()
|
||||
static_assert(LIMIT_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new system limit!");
|
||||
|
||||
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
|
||||
capabilities.textureTypes[i] = gl.isTextureTypeSupported((TextureType) i);
|
||||
capabilities.textureTypes[i] = true;
|
||||
|
||||
for (int i = 0; i < PIXELFORMAT_MAX_ENUM; i++)
|
||||
{
|
||||
@@ -1708,7 +1655,7 @@ uint32 Graphics::computePixelFormatUsage(PixelFormat format, bool readable)
|
||||
GLuint texture = 0;
|
||||
GLuint renderbuffer = 0;
|
||||
|
||||
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, !readable);
|
||||
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format);
|
||||
|
||||
GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
|
||||
|
||||
|
||||
@@ -130,7 +130,6 @@ OpenGL::OpenGL()
|
||||
: stats()
|
||||
, bugs()
|
||||
, contextInitialized(false)
|
||||
, pixelShaderHighpSupported(false)
|
||||
, baseVertexSupported(false)
|
||||
, maxAnisotropy(1.0f)
|
||||
, maxLODBias(0.0f)
|
||||
@@ -166,16 +165,6 @@ bool OpenGL::initContext()
|
||||
|
||||
bugs = {};
|
||||
|
||||
if (GLAD_ES_VERSION_3_0 && !GLAD_ES_VERSION_3_1)
|
||||
{
|
||||
const char *device = (const char *) glGetString(GL_RENDERER);
|
||||
if (getVendor() == VENDOR_VIVANTE && strstr(device, "Vivante GC7000UL"))
|
||||
bugs.brokenGLES3 = true;
|
||||
}
|
||||
|
||||
if (bugs.brokenGLES3)
|
||||
GLAD_ES_VERSION_3_0 = false;
|
||||
|
||||
if (GLAD_VERSION_3_2)
|
||||
{
|
||||
GLint profileMask = 0;
|
||||
@@ -274,11 +263,8 @@ void OpenGL::setupContext()
|
||||
setEnableState(ENABLE_SCISSOR_TEST, state.enableState[ENABLE_SCISSOR_TEST]);
|
||||
setEnableState(ENABLE_FACE_CULL, state.enableState[ENABLE_FACE_CULL]);
|
||||
|
||||
if (!bugs.brokenSRGB && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB
|
||||
|| GLAD_EXT_framebuffer_sRGB || GLAD_EXT_sRGB_write_control))
|
||||
{
|
||||
if (!bugs.brokenSRGB)
|
||||
setEnableState(ENABLE_FRAMEBUFFER_SRGB, state.enableState[ENABLE_FRAMEBUFFER_SRGB]);
|
||||
}
|
||||
else
|
||||
state.enableState[ENABLE_FRAMEBUFFER_SRGB] = false;
|
||||
|
||||
@@ -310,9 +296,7 @@ void OpenGL::setupContext()
|
||||
for (int j = 0; j < TEXTURE_MAX_ENUM; j++)
|
||||
{
|
||||
TextureType textype = (TextureType) j;
|
||||
|
||||
if (isTextureTypeSupported(textype))
|
||||
glBindTexture(getGLTextureType(textype), 0);
|
||||
glBindTexture(getGLTextureType(textype), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,89 +358,6 @@ void OpenGL::initVendor()
|
||||
|
||||
void OpenGL::initOpenGLFunctions()
|
||||
{
|
||||
// Alias extension-suffixed framebuffer functions to core versions since
|
||||
// there are so many different-named extensions that do the same things...
|
||||
if (!(GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object))
|
||||
{
|
||||
if (GLAD_VERSION_1_0 && GLAD_EXT_framebuffer_object)
|
||||
{
|
||||
fp_glBindRenderbuffer = fp_glBindRenderbufferEXT;
|
||||
fp_glDeleteRenderbuffers = fp_glDeleteRenderbuffersEXT;
|
||||
fp_glGenRenderbuffers = fp_glGenRenderbuffersEXT;
|
||||
fp_glRenderbufferStorage = fp_glRenderbufferStorageEXT;
|
||||
fp_glGetRenderbufferParameteriv = fp_glGetRenderbufferParameterivEXT;
|
||||
fp_glBindFramebuffer = fp_glBindFramebufferEXT;
|
||||
fp_glDeleteFramebuffers = fp_glDeleteFramebuffersEXT;
|
||||
fp_glGenFramebuffers = fp_glGenFramebuffersEXT;
|
||||
fp_glCheckFramebufferStatus = fp_glCheckFramebufferStatusEXT;
|
||||
fp_glFramebufferTexture2D = fp_glFramebufferTexture2DEXT;
|
||||
fp_glFramebufferTexture3D = fp_glFramebufferTexture3DEXT;
|
||||
fp_glFramebufferRenderbuffer = fp_glFramebufferRenderbufferEXT;
|
||||
fp_glGetFramebufferAttachmentParameteriv = fp_glGetFramebufferAttachmentParameterivEXT;
|
||||
fp_glGenerateMipmap = fp_glGenerateMipmapEXT;
|
||||
}
|
||||
|
||||
if (GLAD_VERSION_1_0 && GLAD_EXT_texture_array)
|
||||
fp_glFramebufferTextureLayer = fp_glFramebufferTextureLayerEXT;
|
||||
|
||||
if (GLAD_EXT_framebuffer_blit)
|
||||
fp_glBlitFramebuffer = fp_glBlitFramebufferEXT;
|
||||
else if (GLAD_ANGLE_framebuffer_blit)
|
||||
fp_glBlitFramebuffer = fp_glBlitFramebufferANGLE;
|
||||
else if (GLAD_NV_framebuffer_blit)
|
||||
fp_glBlitFramebuffer = fp_glBlitFramebufferNV;
|
||||
|
||||
if (GLAD_EXT_framebuffer_multisample)
|
||||
fp_glRenderbufferStorageMultisample = fp_glRenderbufferStorageMultisampleEXT;
|
||||
else if (GLAD_APPLE_framebuffer_multisample)
|
||||
fp_glRenderbufferStorageMultisample = fp_glRenderbufferStorageMultisampleAPPLE;
|
||||
else if (GLAD_ANGLE_framebuffer_multisample)
|
||||
fp_glRenderbufferStorageMultisample = fp_glRenderbufferStorageMultisampleANGLE;
|
||||
else if (GLAD_NV_framebuffer_multisample)
|
||||
fp_glRenderbufferStorageMultisample = fp_glRenderbufferStorageMultisampleNV;
|
||||
}
|
||||
|
||||
if (isInstancingSupported() && !(GLAD_VERSION_3_3 || GLAD_ES_VERSION_3_0))
|
||||
{
|
||||
if (GLAD_ARB_instanced_arrays)
|
||||
{
|
||||
fp_glDrawArraysInstanced = fp_glDrawArraysInstancedARB;
|
||||
fp_glDrawElementsInstanced = fp_glDrawElementsInstancedARB;
|
||||
fp_glVertexAttribDivisor = fp_glVertexAttribDivisorARB;
|
||||
}
|
||||
else if (GLAD_EXT_instanced_arrays)
|
||||
{
|
||||
fp_glDrawArraysInstanced = fp_glDrawArraysInstancedEXT;
|
||||
fp_glDrawElementsInstanced = fp_glDrawElementsInstancedEXT;
|
||||
fp_glVertexAttribDivisor = fp_glVertexAttribDivisorEXT;
|
||||
}
|
||||
else if (GLAD_ANGLE_instanced_arrays)
|
||||
{
|
||||
fp_glDrawArraysInstanced = fp_glDrawArraysInstancedANGLE;
|
||||
fp_glDrawElementsInstanced = fp_glDrawElementsInstancedANGLE;
|
||||
fp_glVertexAttribDivisor = fp_glVertexAttribDivisorANGLE;
|
||||
}
|
||||
}
|
||||
|
||||
if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0)
|
||||
{
|
||||
// The Nvidia Tegra 3 driver (used by Ouya) claims to support GL_EXT_texture_array but
|
||||
// segfaults if you actually try to use it. OpenGL ES 2.0 devices should use OES_texture_3D.
|
||||
// GL_EXT_texture_array is for desktops.
|
||||
GLAD_EXT_texture_array = false;
|
||||
|
||||
if (GLAD_OES_texture_3D)
|
||||
{
|
||||
// Function signatures don't match, we'll have to conditionally call it
|
||||
//fp_glTexImage3D = fp_glTexImage3DOES;
|
||||
fp_glTexSubImage3D = fp_glTexSubImage3DOES;
|
||||
fp_glCopyTexSubImage3D = fp_glCopyTexSubImage3DOES;
|
||||
fp_glCompressedTexImage3D = fp_glCompressedTexImage3DOES;
|
||||
fp_glCompressedTexSubImage3D = fp_glCompressedTexSubImage3DOES;
|
||||
fp_glFramebufferTexture3D = fp_glFramebufferTexture3DOES;
|
||||
}
|
||||
}
|
||||
|
||||
if (!GLAD_VERSION_3_2 && !GLAD_ES_VERSION_3_2 && !GLAD_ARB_draw_elements_base_vertex)
|
||||
{
|
||||
if (GLAD_OES_draw_elements_base_vertex)
|
||||
@@ -486,16 +387,6 @@ void OpenGL::initOpenGLFunctions()
|
||||
|
||||
void OpenGL::initMaxValues()
|
||||
{
|
||||
if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0)
|
||||
{
|
||||
GLint range = 0;
|
||||
GLint precision = 0;
|
||||
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, &range, &precision);
|
||||
pixelShaderHighpSupported = range > 0;
|
||||
}
|
||||
else
|
||||
pixelShaderHighpSupported = true;
|
||||
|
||||
baseVertexSupported = GLAD_VERSION_3_2 || GLAD_ES_VERSION_3_2 || GLAD_ARB_draw_elements_base_vertex
|
||||
|| GLAD_OES_draw_elements_base_vertex || GLAD_EXT_draw_elements_base_vertex;
|
||||
|
||||
@@ -507,16 +398,8 @@ void OpenGL::initMaxValues()
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DTextureSize);
|
||||
glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeTextureSize);
|
||||
|
||||
if (isTextureTypeSupported(TEXTURE_VOLUME))
|
||||
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
|
||||
else
|
||||
max3DTextureSize = 0;
|
||||
|
||||
if (isTextureTypeSupported(TEXTURE_2D_ARRAY))
|
||||
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureArrayLayers);
|
||||
else
|
||||
maxTextureArrayLayers = 0;
|
||||
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
|
||||
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureArrayLayers);
|
||||
|
||||
if (isBufferUsageSupported(BUFFERUSAGE_TEXEL))
|
||||
glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &maxTexelBufferSize);
|
||||
@@ -549,23 +432,12 @@ void OpenGL::initMaxValues()
|
||||
|
||||
int maxattachments = 1;
|
||||
int maxdrawbuffers = 1;
|
||||
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_2_0)
|
||||
{
|
||||
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxattachments);
|
||||
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxdrawbuffers);
|
||||
}
|
||||
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxattachments);
|
||||
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxdrawbuffers);
|
||||
|
||||
maxRenderTargets = std::max(std::min(maxattachments, maxdrawbuffers), 1);
|
||||
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object
|
||||
|| GLAD_EXT_framebuffer_multisample || GLAD_APPLE_framebuffer_multisample
|
||||
|| GLAD_ANGLE_framebuffer_multisample)
|
||||
{
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
|
||||
}
|
||||
else
|
||||
maxSamples = 1;
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
|
||||
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
|
||||
|
||||
@@ -794,8 +666,7 @@ GLenum OpenGL::getGLBufferDataUsage(BufferDataUsage usage)
|
||||
case BUFFERDATAUSAGE_STREAM: return GL_STREAM_DRAW;
|
||||
case BUFFERDATAUSAGE_DYNAMIC: return GL_DYNAMIC_DRAW;
|
||||
case BUFFERDATAUSAGE_STATIC: return GL_STATIC_DRAW;
|
||||
case BUFFERDATAUSAGE_READBACK:
|
||||
return (GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0) ? GL_STREAM_READ : GL_STREAM_DRAW;
|
||||
case BUFFERDATAUSAGE_READBACK: return GL_STREAM_READ;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
@@ -1285,42 +1156,27 @@ void OpenGL::setSamplerState(TextureType target, SamplerState &s)
|
||||
s.maxAnisotropy = 1;
|
||||
}
|
||||
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_1_0)
|
||||
glTexParameterf(gltarget, GL_TEXTURE_MIN_LOD, (float)s.minLod);
|
||||
glTexParameterf(gltarget, GL_TEXTURE_MAX_LOD, (float)s.maxLod);
|
||||
|
||||
if (s.depthSampleMode.hasValue)
|
||||
{
|
||||
glTexParameterf(gltarget, GL_TEXTURE_MIN_LOD, (float)s.minLod);
|
||||
glTexParameterf(gltarget, GL_TEXTURE_MAX_LOD, (float)s.maxLod);
|
||||
// See the comment in renderstate.h
|
||||
GLenum glmode = getGLCompareMode(getReversedCompareMode(s.depthSampleMode.value));
|
||||
|
||||
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_FUNC, glmode);
|
||||
}
|
||||
else
|
||||
{
|
||||
s.minLod = 0;
|
||||
s.maxLod = LOVE_UINT8_MAX;
|
||||
}
|
||||
|
||||
if (isDepthCompareSampleSupported())
|
||||
{
|
||||
if (s.depthSampleMode.hasValue)
|
||||
{
|
||||
// See the comment in renderstate.h
|
||||
GLenum glmode = getGLCompareMode(getReversedCompareMode(s.depthSampleMode.value));
|
||||
|
||||
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_FUNC, glmode);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s.depthSampleMode.hasValue = false;
|
||||
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenGL::rawTexStorage(TextureType target, int levels, PixelFormat pixelformat, int width, int height, int depth)
|
||||
{
|
||||
GLenum gltarget = getGLTextureType(target);
|
||||
TextureFormat fmt = convertPixelFormat(pixelformat, false);
|
||||
TextureFormat fmt = convertPixelFormat(pixelformat);
|
||||
|
||||
// This shouldn't be needed for glTexStorage, but some drivers don't follow
|
||||
// the spec apparently.
|
||||
@@ -1375,16 +1231,8 @@ bool OpenGL::rawTexStorage(TextureType target, int levels, PixelFormat pixelform
|
||||
}
|
||||
else if (target == TEXTURE_2D_ARRAY || target == TEXTURE_VOLUME)
|
||||
{
|
||||
if (target == TEXTURE_VOLUME && GLAD_ES_VERSION_2_0 && GLAD_OES_texture_3D && !GLAD_ES_VERSION_3_0)
|
||||
{
|
||||
glTexImage3DOES(gltarget, level, fmt.internalformat, w, h,
|
||||
d, 0, fmt.externalformat, fmt.type, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexImage3D(gltarget, level, fmt.internalformat, w, h, d,
|
||||
0, fmt.externalformat, fmt.type, nullptr);
|
||||
}
|
||||
glTexImage3D(gltarget, level, fmt.internalformat, w, h, d,
|
||||
0, fmt.externalformat, fmt.type, nullptr);
|
||||
}
|
||||
|
||||
w = std::max(w / 2, 1);
|
||||
@@ -1406,24 +1254,6 @@ bool OpenGL::isTexStorageSupported()
|
||||
return GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_2 || GLAD_ARB_texture_storage;
|
||||
}
|
||||
|
||||
bool OpenGL::isTextureTypeSupported(TextureType type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TEXTURE_2D:
|
||||
return true;
|
||||
case TEXTURE_VOLUME:
|
||||
return GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_3D;
|
||||
case TEXTURE_2D_ARRAY:
|
||||
return GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_texture_array;
|
||||
case TEXTURE_CUBE:
|
||||
return GLAD_VERSION_1_3 || GLAD_ES_VERSION_2_0;
|
||||
case TEXTURE_MAX_ENUM:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OpenGL::isBufferUsageSupported(BufferUsage usage) const
|
||||
{
|
||||
switch (usage)
|
||||
@@ -1434,7 +1264,7 @@ bool OpenGL::isBufferUsageSupported(BufferUsage usage) const
|
||||
case BUFFERUSAGE_TEXEL:
|
||||
return GLAD_VERSION_3_1 || GLAD_ES_VERSION_3_2;
|
||||
case BUFFERUSAGE_UNIFORM:
|
||||
return GLAD_VERSION_3_1 || GLAD_ES_VERSION_3_0;
|
||||
return true;
|
||||
case BUFFERUSAGE_SHADER_STORAGE:
|
||||
return (GLAD_VERSION_4_3 && isCoreProfile()) || GLAD_ES_VERSION_3_1;
|
||||
case BUFFERUSAGE_INDIRECT_ARGUMENTS:
|
||||
@@ -1450,24 +1280,6 @@ bool OpenGL::isClampZeroOneTextureWrapSupported() const
|
||||
return GLAD_VERSION_1_3 || GLAD_EXT_texture_border_clamp || GLAD_NV_texture_border_clamp;
|
||||
}
|
||||
|
||||
bool OpenGL::isPixelShaderHighpSupported() const
|
||||
{
|
||||
return pixelShaderHighpSupported;
|
||||
}
|
||||
|
||||
bool OpenGL::isInstancingSupported() const
|
||||
{
|
||||
return GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_3
|
||||
|| GLAD_ARB_instanced_arrays || GLAD_EXT_instanced_arrays || GLAD_ANGLE_instanced_arrays;
|
||||
}
|
||||
|
||||
bool OpenGL::isDepthCompareSampleSupported() const
|
||||
{
|
||||
// Our official API only supports this in GLSL3 shaders, but unofficially
|
||||
// the requirements are more lax.
|
||||
return GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_shadow_samplers;
|
||||
}
|
||||
|
||||
bool OpenGL::isSamplerLODBiasSupported() const
|
||||
{
|
||||
return GLAD_VERSION_1_4;
|
||||
@@ -1478,34 +1290,12 @@ bool OpenGL::isBaseVertexSupported() const
|
||||
return baseVertexSupported;
|
||||
}
|
||||
|
||||
bool OpenGL::isMultiFormatMRTSupported() const
|
||||
{
|
||||
return getMaxRenderTargets() > 1 && (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object);
|
||||
}
|
||||
|
||||
bool OpenGL::isCopyBufferSupported() const
|
||||
{
|
||||
return GLAD_VERSION_3_1 || GLAD_ES_VERSION_3_0;
|
||||
}
|
||||
|
||||
bool OpenGL::isCopyBufferToTextureSupported() const
|
||||
{
|
||||
// Requires pixel unpack buffer binding support.
|
||||
return GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0;
|
||||
}
|
||||
|
||||
bool OpenGL::isCopyTextureToBufferSupported() const
|
||||
{
|
||||
// Requires glGetTextureSubImage support.
|
||||
return GLAD_VERSION_4_5 || GLAD_ARB_get_texture_sub_image;
|
||||
}
|
||||
|
||||
bool OpenGL::isCopyRenderTargetToBufferSupported() const
|
||||
{
|
||||
// Requires pixel pack buffer binding support.
|
||||
return GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0;
|
||||
}
|
||||
|
||||
int OpenGL::getMax2DTextureSize() const
|
||||
{
|
||||
return std::max(max2DTextureSize, 1);
|
||||
@@ -1596,7 +1386,7 @@ OpenGL::Vendor OpenGL::getVendor() const
|
||||
return vendor;
|
||||
}
|
||||
|
||||
OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool renderbuffer)
|
||||
OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat)
|
||||
{
|
||||
TextureFormat f;
|
||||
|
||||
@@ -1613,8 +1403,7 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
|
||||
switch (pixelformat)
|
||||
{
|
||||
case PIXELFORMAT_R8_UNORM:
|
||||
if ((GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_texture_rg || GLAD_EXT_texture_rg)
|
||||
&& !gl.bugs.brokenR8PixelFormat)
|
||||
if (!gl.bugs.brokenR8PixelFormat)
|
||||
{
|
||||
f.internalformat = GL_R8;
|
||||
f.externalformat = GL_RED;
|
||||
@@ -1639,10 +1428,7 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
|
||||
case PIXELFORMAT_RGBA8_sRGB:
|
||||
f.internalformat = GL_SRGB8_ALPHA8;
|
||||
f.type = GL_UNSIGNED_BYTE;
|
||||
if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0)
|
||||
f.externalformat = GL_SRGB_ALPHA;
|
||||
else
|
||||
f.externalformat = GL_RGBA;
|
||||
f.externalformat = GL_RGBA;
|
||||
break;
|
||||
case PIXELFORMAT_BGRA8_UNORM:
|
||||
case PIXELFORMAT_BGRA8_sRGB:
|
||||
@@ -1841,28 +1627,10 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
|
||||
|
||||
case PIXELFORMAT_STENCIL8:
|
||||
// Prefer a combined depth/stencil buffer due to driver issues.
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object)
|
||||
{
|
||||
f.internalformat = GL_DEPTH24_STENCIL8;
|
||||
f.externalformat = GL_DEPTH_STENCIL;
|
||||
f.type = GL_UNSIGNED_INT_24_8;
|
||||
f.framebufferAttachments[0] = GL_DEPTH_STENCIL_ATTACHMENT;
|
||||
}
|
||||
else if (GLAD_EXT_packed_depth_stencil || GLAD_OES_packed_depth_stencil)
|
||||
{
|
||||
f.internalformat = GL_DEPTH24_STENCIL8;
|
||||
f.externalformat = GL_DEPTH_STENCIL;
|
||||
f.type = GL_UNSIGNED_INT_24_8;
|
||||
f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
|
||||
f.framebufferAttachments[1] = GL_STENCIL_ATTACHMENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
f.internalformat = GL_STENCIL_INDEX8;
|
||||
f.externalformat = GL_STENCIL;
|
||||
f.type = GL_UNSIGNED_BYTE;
|
||||
f.framebufferAttachments[0] = GL_STENCIL_ATTACHMENT;
|
||||
}
|
||||
f.internalformat = GL_DEPTH24_STENCIL8;
|
||||
f.externalformat = GL_DEPTH_STENCIL;
|
||||
f.type = GL_UNSIGNED_INT_24_8;
|
||||
f.framebufferAttachments[0] = GL_DEPTH_STENCIL_ATTACHMENT;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_DEPTH16_UNORM:
|
||||
@@ -1873,21 +1641,10 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_DEPTH24_UNORM:
|
||||
if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0 && !GLAD_OES_depth24 && GLAD_OES_packed_depth_stencil)
|
||||
{
|
||||
f.internalformat = GL_DEPTH24_STENCIL8;
|
||||
f.externalformat = GL_DEPTH_STENCIL;
|
||||
f.type = GL_UNSIGNED_INT_24_8;
|
||||
f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
|
||||
f.framebufferAttachments[1] = GL_STENCIL_ATTACHMENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
f.internalformat = GL_DEPTH_COMPONENT24;
|
||||
f.externalformat = GL_DEPTH_COMPONENT;
|
||||
f.type = GL_UNSIGNED_INT;
|
||||
f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
|
||||
}
|
||||
f.internalformat = GL_DEPTH_COMPONENT24;
|
||||
f.externalformat = GL_DEPTH_COMPONENT;
|
||||
f.type = GL_UNSIGNED_INT;
|
||||
f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_DEPTH32_FLOAT:
|
||||
@@ -1901,15 +1658,7 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
|
||||
f.internalformat = GL_DEPTH24_STENCIL8;
|
||||
f.externalformat = GL_DEPTH_STENCIL;
|
||||
f.type = GL_UNSIGNED_INT_24_8;
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object)
|
||||
{
|
||||
f.framebufferAttachments[0] = GL_DEPTH_STENCIL_ATTACHMENT;
|
||||
}
|
||||
else if (GLAD_EXT_packed_depth_stencil || GLAD_OES_packed_depth_stencil)
|
||||
{
|
||||
f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
|
||||
f.framebufferAttachments[1] = GL_STENCIL_ATTACHMENT;
|
||||
}
|
||||
f.framebufferAttachments[0] = GL_DEPTH_STENCIL_ATTACHMENT;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_DEPTH32_FLOAT_STENCIL8:
|
||||
@@ -2111,22 +1860,6 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isPixelFormatCompressed(pixelformat))
|
||||
{
|
||||
// glTexImage in OpenGL ES 2 only accepts internal format enums that
|
||||
// match the external format. GLES3 doesn't have that restriction -
|
||||
// except for GL_LUMINANCE_ALPHA which doesn't have a sized version in
|
||||
// ES3. However we always use RG8 for PIXELFORMAT_LA8 on GLES3 so it
|
||||
// doesn't matter there.
|
||||
// Also note that GLES2+extension sRGB format enums are different from
|
||||
// desktop GL and GLES3+ (this is handled above).
|
||||
if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0
|
||||
&& !renderbuffer && !isTexStorageSupported())
|
||||
{
|
||||
f.internalformat = f.externalformat;
|
||||
}
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
@@ -2142,28 +1875,19 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
|
||||
{
|
||||
case PIXELFORMAT_R8_UNORM:
|
||||
case PIXELFORMAT_RG8_UNORM:
|
||||
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_texture_rg || GLAD_EXT_texture_rg)
|
||||
flags |= commonsample | commonrender;
|
||||
else if (pixelformat == PIXELFORMAT_R8_UNORM && (GLAD_ES_VERSION_2_0 || GLAD_VERSION_1_1))
|
||||
flags |= commonsample; // We'll use OpenGL's luminance format internally.
|
||||
flags |= commonsample | commonrender;
|
||||
if (GLAD_VERSION_4_3)
|
||||
flags |= computewrite;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA8_UNORM:
|
||||
flags |= commonsample;
|
||||
if (GLAD_VERSION_1_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_rgb8_rgba8 || GLAD_ARM_rgba8)
|
||||
flags |= commonrender;
|
||||
flags |= commonsample | commonrender;
|
||||
if (GLAD_VERSION_4_3 || GLAD_ES_VERSION_3_1)
|
||||
flags |= computewrite;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA8_sRGB:
|
||||
if (gl.bugs.brokenSRGB)
|
||||
break;
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_2_1 || GLAD_EXT_texture_sRGB)
|
||||
flags |= commonsample;
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0
|
||||
|| ((GLAD_ARB_framebuffer_sRGB || GLAD_EXT_framebuffer_sRGB) && (GLAD_VERSION_2_1 || GLAD_EXT_texture_sRGB)))
|
||||
flags |= commonrender;
|
||||
flags |= commonsample | commonrender;
|
||||
break;
|
||||
case PIXELFORMAT_BGRA8_UNORM:
|
||||
case PIXELFORMAT_BGRA8_sRGB:
|
||||
@@ -2171,9 +1895,7 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
|
||||
break;
|
||||
case PIXELFORMAT_R16_UNORM:
|
||||
case PIXELFORMAT_RG16_UNORM:
|
||||
if (GLAD_VERSION_3_0
|
||||
|| (GLAD_VERSION_1_1 && GLAD_ARB_texture_rg)
|
||||
|| (GLAD_EXT_texture_norm16 && (GLAD_ES_VERSION_3_0 || GLAD_EXT_texture_rg)))
|
||||
if (GLAD_VERSION_3_0 || (GLAD_EXT_texture_norm16 && GLAD_ES_VERSION_3_0))
|
||||
flags |= commonsample | commonrender;
|
||||
if (GLAD_VERSION_4_3)
|
||||
flags |= computewrite;
|
||||
@@ -2186,26 +1908,20 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
|
||||
break;
|
||||
case PIXELFORMAT_R16_FLOAT:
|
||||
case PIXELFORMAT_RG16_FLOAT:
|
||||
if (GLAD_VERSION_1_0 && (GLAD_VERSION_3_0 || (GLAD_ARB_texture_float && GLAD_ARB_half_float_pixel && GLAD_ARB_texture_rg)))
|
||||
flags |= commonsample | commonrender;
|
||||
if (GLAD_ES_VERSION_3_0 || (GLAD_OES_texture_half_float && GLAD_EXT_texture_rg))
|
||||
flags |= commonsample;
|
||||
if ((GLAD_EXT_color_buffer_half_float || GLAD_EXT_color_buffer_float) && (GLAD_ES_VERSION_3_0 || GLAD_EXT_texture_rg))
|
||||
flags |= commonsample;
|
||||
if (GLAD_VERSION_3_0)
|
||||
flags |= commonrender;
|
||||
if ((GLAD_EXT_color_buffer_half_float || GLAD_EXT_color_buffer_float) && GLAD_ES_VERSION_3_0)
|
||||
flags |= commonrender;
|
||||
if (!(GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float_linear))
|
||||
flags &= ~PIXELFORMATUSAGEFLAGS_LINEAR;
|
||||
if (GLAD_VERSION_4_3)
|
||||
flags |= computewrite;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA16_FLOAT:
|
||||
if (GLAD_VERSION_3_0 || (GLAD_VERSION_1_0 && GLAD_ARB_texture_float && GLAD_ARB_half_float_pixel))
|
||||
flags |= commonsample | commonrender;
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float)
|
||||
flags |= commonsample;
|
||||
flags |= commonsample;
|
||||
if (GLAD_VERSION_3_0)
|
||||
flags |= commonrender;
|
||||
if (GLAD_EXT_color_buffer_half_float || GLAD_EXT_color_buffer_float)
|
||||
flags |= commonrender;
|
||||
if (!(GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float_linear))
|
||||
flags &= ~PIXELFORMATUSAGEFLAGS_LINEAR;
|
||||
if (GLAD_VERSION_4_3 || GLAD_ES_VERSION_3_1)
|
||||
flags |= computewrite;
|
||||
break;
|
||||
@@ -2214,22 +1930,20 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
|
||||
flags |= computewrite;
|
||||
// Fallthrough.
|
||||
case PIXELFORMAT_RG32_FLOAT:
|
||||
if (GLAD_VERSION_3_0 || (GLAD_VERSION_1_0 && GLAD_ARB_texture_float && GLAD_ARB_texture_rg))
|
||||
flags |= commonsample | commonrender;
|
||||
if (GLAD_ES_VERSION_3_0 || (GLAD_OES_texture_float && GLAD_EXT_texture_rg))
|
||||
flags |= commonsample;
|
||||
flags |= commonsample;
|
||||
if (GLAD_VERSION_3_0)
|
||||
flags |= commonrender;
|
||||
if (GLAD_EXT_color_buffer_float)
|
||||
flags |= commonrender;
|
||||
if (!(GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float_linear))
|
||||
if (!(GLAD_VERSION_1_1 || GLAD_OES_texture_float_linear))
|
||||
flags &= ~PIXELFORMATUSAGEFLAGS_LINEAR;
|
||||
if (GLAD_VERSION_4_3)
|
||||
flags |= computewrite;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA32_FLOAT:
|
||||
if (GLAD_VERSION_3_0 || (GLAD_VERSION_1_0 && GLAD_ARB_texture_float))
|
||||
flags |= commonsample | commonrender;
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_OES_texture_float)
|
||||
flags |= commonsample;
|
||||
flags |= commonsample;
|
||||
if (GLAD_VERSION_3_0)
|
||||
flags |= commonrender;
|
||||
if (GLAD_EXT_color_buffer_float)
|
||||
flags |= commonrender;
|
||||
if (!(GLAD_VERSION_1_1 || GLAD_OES_texture_float_linear))
|
||||
@@ -2256,8 +1970,7 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
|
||||
case PIXELFORMAT_RG32_UINT:
|
||||
case PIXELFORMAT_RGBA32_INT:
|
||||
case PIXELFORMAT_RGBA32_UINT:
|
||||
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0)
|
||||
flags |= PIXELFORMATUSAGEFLAGS_SAMPLE | PIXELFORMATUSAGEFLAGS_RENDERTARGET;
|
||||
flags |= PIXELFORMATUSAGEFLAGS_SAMPLE | PIXELFORMATUSAGEFLAGS_RENDERTARGET;
|
||||
if (GLAD_VERSION_4_3)
|
||||
flags |= computewrite;
|
||||
if (GLAD_ES_VERSION_3_1)
|
||||
@@ -2293,8 +2006,7 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
|
||||
flags |= commonsample | commonrender;
|
||||
break;
|
||||
case PIXELFORMAT_RGB10A2_UNORM:
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_1_0)
|
||||
flags |= commonsample | commonrender;
|
||||
flags |= commonsample | commonrender;
|
||||
if (GLAD_VERSION_4_3)
|
||||
flags |= computewrite;
|
||||
break;
|
||||
@@ -2314,31 +2026,20 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_DEPTH16_UNORM:
|
||||
flags |= PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
|
||||
if (GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_depth_texture)
|
||||
flags |= commonsample;
|
||||
flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_DEPTH24_UNORM:
|
||||
if (GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_depth24 || GLAD_OES_depth_texture)
|
||||
flags |= PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
|
||||
|
||||
if (GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || (GLAD_OES_depth_texture && (GLAD_OES_depth24 || GLAD_OES_depth_texture)))
|
||||
flags |= commonsample;
|
||||
flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_DEPTH24_UNORM_STENCIL8:
|
||||
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_packed_depth_stencil || GLAD_OES_packed_depth_stencil)
|
||||
flags |= PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
|
||||
|
||||
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_packed_depth_stencil || (GLAD_OES_depth_texture && GLAD_OES_packed_depth_stencil))
|
||||
flags |= commonsample;
|
||||
flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_DEPTH32_FLOAT:
|
||||
case PIXELFORMAT_DEPTH32_FLOAT_STENCIL8:
|
||||
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_depth_buffer_float)
|
||||
flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
|
||||
flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_DXT1_UNORM:
|
||||
@@ -2386,7 +2087,7 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
|
||||
break;
|
||||
case PIXELFORMAT_ETC1_UNORM:
|
||||
// ETC2 support guarantees ETC1 support as well.
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility || GLAD_OES_compressed_ETC1_RGB8_texture)
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility)
|
||||
flags |= commonsample;
|
||||
break;
|
||||
case PIXELFORMAT_ETC2_RGB_UNORM:
|
||||
|
||||
@@ -200,13 +200,6 @@ public:
|
||||
**/
|
||||
bool brokenSRGB;
|
||||
|
||||
/**
|
||||
* Some Android graphics drivers claim to support GLES3.0 but have bugs
|
||||
* with certain aspects that users expect to work. For example:
|
||||
* https://github.com/love2d/love-android/issues/204
|
||||
**/
|
||||
bool brokenGLES3;
|
||||
|
||||
/**
|
||||
* Other bugs which have workarounds that don't use conditional code at
|
||||
* the moment:
|
||||
@@ -369,19 +362,11 @@ public:
|
||||
**/
|
||||
bool rawTexStorage(TextureType target, int levels, PixelFormat pixelformat, int width, int height, int depth = 1);
|
||||
|
||||
bool isTextureTypeSupported(TextureType type) const;
|
||||
bool isBufferUsageSupported(BufferUsage usage) const;
|
||||
bool isClampZeroOneTextureWrapSupported() const;
|
||||
bool isPixelShaderHighpSupported() const;
|
||||
bool isInstancingSupported() const;
|
||||
bool isDepthCompareSampleSupported() const;
|
||||
bool isSamplerLODBiasSupported() const;
|
||||
bool isBaseVertexSupported() const;
|
||||
bool isMultiFormatMRTSupported() const;
|
||||
bool isCopyBufferSupported() const;
|
||||
bool isCopyBufferToTextureSupported() const;
|
||||
bool isCopyTextureToBufferSupported() const;
|
||||
bool isCopyRenderTargetToBufferSupported() const;
|
||||
|
||||
/**
|
||||
* Returns the maximum supported width or height of a texture.
|
||||
@@ -461,7 +446,7 @@ public:
|
||||
static GLint getGLWrapMode(SamplerState::WrapMode wmode);
|
||||
static GLint getGLCompareMode(CompareMode mode);
|
||||
|
||||
static TextureFormat convertPixelFormat(PixelFormat pixelformat, bool renderbuffer);
|
||||
static TextureFormat convertPixelFormat(PixelFormat pixelformat);
|
||||
static bool isTexStorageSupported();
|
||||
static uint32 getPixelFormatUsageFlags(PixelFormat pixelformat);
|
||||
|
||||
@@ -481,7 +466,6 @@ private:
|
||||
|
||||
bool contextInitialized;
|
||||
|
||||
bool pixelShaderHighpSupported;
|
||||
bool baseVertexSupported;
|
||||
|
||||
float maxAnisotropy;
|
||||
|
||||
@@ -41,7 +41,6 @@ namespace opengl
|
||||
Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const CompileOptions &options)
|
||||
: love::graphics::Shader(stages, options)
|
||||
, program(0)
|
||||
, splitUniformsPerDraw(false)
|
||||
, builtinUniforms()
|
||||
, builtinUniformInfo()
|
||||
{
|
||||
@@ -158,7 +157,7 @@ void Shader::mapActiveUniforms()
|
||||
else if ((u.access & ACCESS_READ) != 0)
|
||||
binding.access = GL_READ_ONLY;
|
||||
|
||||
auto fmt = OpenGL::convertPixelFormat(u.storageTextureFormat, false);
|
||||
auto fmt = OpenGL::convertPixelFormat(u.storageTextureFormat);
|
||||
binding.internalFormat = fmt.internalformat;
|
||||
|
||||
for (int i = 0; i < u.count; i++)
|
||||
@@ -283,11 +282,6 @@ bool Shader::loadVolatile()
|
||||
{
|
||||
OpenGL::TempDebugGroup debuggroup("Shader load");
|
||||
|
||||
// love::graphics::Shader sets up the shader code-side of this.
|
||||
auto gfx = Module::getInstance<love::graphics::Graphics>(Module::M_GRAPHICS);
|
||||
if (gfx != nullptr)
|
||||
splitUniformsPerDraw = !gfx->getCapabilities().features[Graphics::FEATURE_PIXEL_SHADER_HIGHP];
|
||||
|
||||
// zero out active texture list
|
||||
textureUnits.clear();
|
||||
textureUnits.push_back(TextureUnit());
|
||||
@@ -813,27 +807,9 @@ void Shader::updateBuiltinUniforms(love::graphics::Graphics *gfx, int viewportW,
|
||||
data.constantColor = gfx->getColor();
|
||||
gammaCorrectColor(data.constantColor);
|
||||
|
||||
// This branch is to avoid always declaring the whole array as highp in the
|
||||
// vertex shader and mediump in the pixel shader for love's default shaders,
|
||||
// on systems that don't support highp in pixel shaders. The default shaders
|
||||
// use the transform matrices in vertex shaders and screen size params in
|
||||
// pixel shaders. If there's a single array containing both and each shader
|
||||
// stage declares a different precision, that's a compile error.
|
||||
if (splitUniformsPerDraw)
|
||||
{
|
||||
GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
|
||||
if (location >= 0)
|
||||
glUniform4fv(location, 11, (const GLfloat *) &data);
|
||||
GLint location2 = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW_2];
|
||||
if (location2 >= 0)
|
||||
glUniform4fv(location2, 1, (const GLfloat *) &data.screenSizeParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
|
||||
if (location >= 0)
|
||||
glUniform4fv(location, 12, (const GLfloat *) &data);
|
||||
}
|
||||
GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
|
||||
if (location >= 0)
|
||||
glUniform4fv(location, 12, (const GLfloat *) &data);
|
||||
}
|
||||
|
||||
} // opengl
|
||||
|
||||
@@ -106,8 +106,6 @@ private:
|
||||
// volatile
|
||||
GLuint program;
|
||||
|
||||
bool splitUniformsPerDraw;
|
||||
|
||||
// Location values for any built-in uniform variables.
|
||||
GLint builtinUniforms[BUILTIN_MAX_ENUM];
|
||||
UniformInfo *builtinUniformInfo[BUILTIN_MAX_ENUM];
|
||||
|
||||
@@ -45,18 +45,14 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
|
||||
|
||||
if (texture != 0)
|
||||
{
|
||||
if (isPixelFormatDepthStencil(format) && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0))
|
||||
if (isPixelFormatDepthStencil(format))
|
||||
{
|
||||
// glDrawBuffers is an ext in GL2. glDrawBuffer doesn't exist in ES3.
|
||||
GLenum none = GL_NONE;
|
||||
if (GLAD_ES_VERSION_3_0)
|
||||
glDrawBuffers(1, &none);
|
||||
else
|
||||
glDrawBuffer(GL_NONE);
|
||||
glDrawBuffers(1, &none);
|
||||
glReadBuffer(GL_NONE);
|
||||
}
|
||||
|
||||
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false);
|
||||
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format);
|
||||
|
||||
int faces = texType == TEXTURE_CUBE ? 6 : 1;
|
||||
|
||||
@@ -124,7 +120,7 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
|
||||
|
||||
static GLenum newRenderbuffer(int width, int height, int &samples, PixelFormat pixelformat, GLuint &buffer)
|
||||
{
|
||||
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(pixelformat, true);
|
||||
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(pixelformat);
|
||||
|
||||
GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
|
||||
|
||||
@@ -133,14 +129,10 @@ static GLenum newRenderbuffer(int width, int height, int &samples, PixelFormat p
|
||||
glGenFramebuffers(1, &fbo);
|
||||
gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, fbo);
|
||||
|
||||
if (isPixelFormatDepthStencil(pixelformat) && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0))
|
||||
if (isPixelFormatDepthStencil(pixelformat))
|
||||
{
|
||||
// glDrawBuffers is an ext in GL2. glDrawBuffer doesn't exist in ES3.
|
||||
GLenum none = GL_NONE;
|
||||
if (GLAD_ES_VERSION_3_0)
|
||||
glDrawBuffers(1, &none);
|
||||
else
|
||||
glDrawBuffer(GL_NONE);
|
||||
glDrawBuffers(1, &none);
|
||||
glReadBuffer(GL_NONE);
|
||||
}
|
||||
|
||||
@@ -278,7 +270,7 @@ void Texture::createTexture()
|
||||
|
||||
if (parentView.texture != this)
|
||||
{
|
||||
OpenGL::TextureFormat fmt = gl.convertPixelFormat(format, false);
|
||||
OpenGL::TextureFormat fmt = gl.convertPixelFormat(format);
|
||||
Texture *basetex = (Texture *) parentView.texture;
|
||||
int layers = texType == TEXTURE_CUBE ? 6 : getLayerCount();
|
||||
|
||||
@@ -317,14 +309,14 @@ void Texture::createTexture()
|
||||
gl.rawTexStorage(texType, mipcount, format, pixelWidth, pixelHeight, texType == TEXTURE_VOLUME ? depth : layers);
|
||||
|
||||
// rawTexStorage handles this for uncompressed textures.
|
||||
if (isCompressed() && (GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0))
|
||||
if (isCompressed())
|
||||
glTexParameteri(gltype, GL_TEXTURE_MAX_LEVEL, mipcount - 1);
|
||||
|
||||
int w = pixelWidth;
|
||||
int h = pixelHeight;
|
||||
int d = depth;
|
||||
|
||||
OpenGL::TextureFormat fmt = gl.convertPixelFormat(format, false);
|
||||
OpenGL::TextureFormat fmt = gl.convertPixelFormat(format);
|
||||
|
||||
for (int mip = 0; mip < mipcount; mip++)
|
||||
{
|
||||
@@ -413,14 +405,6 @@ bool Texture::loadVolatile()
|
||||
|
||||
OpenGL::TempDebugGroup debuggroup("Texture load");
|
||||
|
||||
// NPOT textures don't support mipmapping without full NPOT support.
|
||||
if ((GLAD_ES_VERSION_2_0 && !(GLAD_ES_VERSION_3_0 || GLAD_OES_texture_npot))
|
||||
&& (pixelWidth != nextP2(pixelWidth) || pixelHeight != nextP2(pixelHeight)))
|
||||
{
|
||||
mipmapCount = 1;
|
||||
samplerState.mipmapFilter = SamplerState::MIPMAP_FILTER_NONE;
|
||||
}
|
||||
|
||||
actualSamples = std::max(1, std::min(getRequestedMSAA(), gl.getMaxSamples()));
|
||||
|
||||
while (glGetError() != GL_NO_ERROR); // Clear errors.
|
||||
@@ -512,7 +496,7 @@ void Texture::uploadByteData(const void *data, size_t size, int level, int slice
|
||||
|
||||
gl.bindTextureToUnit(this, 0, false);
|
||||
|
||||
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false);
|
||||
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format);
|
||||
GLenum gltarget = OpenGL::getGLTextureType(texType);
|
||||
|
||||
if (texType == TEXTURE_CUBE)
|
||||
@@ -555,12 +539,12 @@ void Texture::generateMipmapsInternal()
|
||||
void Texture::readbackInternal(int slice, int mipmap, const Rect &rect, int destwidth, size_t size, void *dest)
|
||||
{
|
||||
// Not supported in GL with compressed textures...
|
||||
if ((GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0) && !isCompressed())
|
||||
if (!isCompressed())
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, destwidth);
|
||||
|
||||
gl.bindTextureToUnit(this, 0, false);
|
||||
|
||||
OpenGL::TextureFormat fmt = gl.convertPixelFormat(format, false);
|
||||
OpenGL::TextureFormat fmt = gl.convertPixelFormat(format);
|
||||
|
||||
if (gl.isCopyTextureToBufferSupported())
|
||||
{
|
||||
@@ -589,7 +573,7 @@ void Texture::readbackInternal(int slice, int mipmap, const Rect &rect, int dest
|
||||
gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, current_fbo);
|
||||
}
|
||||
|
||||
if ((GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0) && !isCompressed())
|
||||
if (!isCompressed())
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||
}
|
||||
|
||||
@@ -630,18 +614,8 @@ void Texture::copyToBuffer(love::graphics::Buffer *dest, int slice, int mipmap,
|
||||
|
||||
void Texture::setSamplerState(const SamplerState &s)
|
||||
{
|
||||
if (s.depthSampleMode.hasValue && !gl.isDepthCompareSampleSupported())
|
||||
throw love::Exception("Depth comparison sampling in shaders is not supported on this system.");
|
||||
|
||||
samplerState = validateSamplerState(s);
|
||||
|
||||
// If we only have limited NPOT support then the wrap mode must be CLAMP.
|
||||
if ((GLAD_ES_VERSION_2_0 && !(GLAD_ES_VERSION_3_0 || GLAD_OES_texture_npot))
|
||||
&& (pixelWidth != nextP2(pixelWidth) || pixelHeight != nextP2(pixelHeight) || depth != nextP2(depth)))
|
||||
{
|
||||
samplerState.wrapU = samplerState.wrapV = samplerState.wrapW = SamplerState::WRAP_CLAMP;
|
||||
}
|
||||
|
||||
gl.bindTextureToUnit(this, 0, false);
|
||||
gl.setSamplerState(texType, samplerState);
|
||||
}
|
||||
|
||||
@@ -739,7 +739,6 @@ void Graphics::initCapabilities()
|
||||
capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = true;
|
||||
capabilities.features[FEATURE_CLAMP_ZERO] = true;
|
||||
capabilities.features[FEATURE_CLAMP_ONE] = true;
|
||||
capabilities.features[FEATURE_BLEND_MINMAX] = true;
|
||||
capabilities.features[FEATURE_LIGHTEN] = true;
|
||||
capabilities.features[FEATURE_FULL_NPOT] = true;
|
||||
capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = true;
|
||||
@@ -748,14 +747,9 @@ void Graphics::initCapabilities()
|
||||
capabilities.features[FEATURE_GLSL4] = true;
|
||||
capabilities.features[FEATURE_INSTANCING] = true;
|
||||
capabilities.features[FEATURE_TEXEL_BUFFER] = true;
|
||||
capabilities.features[FEATURE_INDEX_BUFFER_32BIT] = true;
|
||||
capabilities.features[FEATURE_COPY_BUFFER] = true;
|
||||
capabilities.features[FEATURE_COPY_BUFFER_TO_TEXTURE] = true;
|
||||
capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = true;
|
||||
capabilities.features[FEATURE_COPY_RENDER_TARGET_TO_BUFFER] = true;
|
||||
capabilities.features[FEATURE_MIPMAP_RANGE] = true;
|
||||
capabilities.features[FEATURE_INDIRECT_DRAW] = true;
|
||||
static_assert(FEATURE_MAX_ENUM == 19, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
static_assert(FEATURE_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
|
||||
VkPhysicalDeviceProperties properties;
|
||||
vkGetPhysicalDeviceProperties(physicalDevice, &properties);
|
||||
@@ -1410,7 +1404,7 @@ graphics::Shader::BuiltinUniformData Graphics::getCurrentBuiltinUniformData()
|
||||
data.projectionMatrix = getDeviceProjection();
|
||||
|
||||
data.scaleParams.x = (float) getCurrentDPIScale();
|
||||
data.scaleParams.y = getPointSize();;
|
||||
data.scaleParams.y = getPointSize();
|
||||
|
||||
// Flip y to convert input y-up [-1, 1] to vulkan's y-down [-1, 1].
|
||||
// Convert input z [-1, 1] to vulkan [0, 1].
|
||||
@@ -2809,7 +2803,8 @@ VkPipeline Graphics::createGraphicsPipeline(GraphicsPipelineConfiguration &confi
|
||||
return graphicsPipeline;
|
||||
}
|
||||
|
||||
void Graphics::ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration &configuration) {
|
||||
void Graphics::ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration &configuration)
|
||||
{
|
||||
auto it = graphicsPipelines.find(configuration);
|
||||
if (it != graphicsPipelines.end())
|
||||
{
|
||||
|
||||
@@ -259,9 +259,6 @@ std::vector<Window::ContextAttribs> Window::getContextAttribsList() const
|
||||
// Do we want a debug context?
|
||||
bool debug = love::graphics::isDebugEnabled();
|
||||
|
||||
const char *preferGL2hint = SDL_GetHint("LOVE_GRAPHICS_USE_GL2");
|
||||
bool preferGL2 = (preferGL2hint != nullptr && preferGL2hint[0] != '0');
|
||||
|
||||
const char *preferGL3hint = SDL_GetHint("LOVE_GRAPHICS_USE_GL3");
|
||||
bool preferGL3 = (preferGL3hint != nullptr && preferGL3hint[0] != '0');
|
||||
|
||||
@@ -269,22 +266,15 @@ std::vector<Window::ContextAttribs> Window::getContextAttribsList() const
|
||||
{
|
||||
{4, 3, false, debug},
|
||||
{3, 3, false, debug},
|
||||
{2, 1, false, debug},
|
||||
};
|
||||
|
||||
std::vector<ContextAttribs> glescontexts =
|
||||
{
|
||||
{3, 2, true, debug},
|
||||
{3, 0, true, debug},
|
||||
{2, 0, true, debug}
|
||||
};
|
||||
|
||||
if (preferGL2)
|
||||
{
|
||||
std::swap(glcontexts[0], glcontexts[2]);
|
||||
std::swap(glescontexts[0], glescontexts[2]);
|
||||
}
|
||||
else if (preferGL3)
|
||||
if (preferGL3)
|
||||
{
|
||||
std::swap(glcontexts[0], glcontexts[1]);
|
||||
std::swap(glescontexts[0], glescontexts[1]);
|
||||
@@ -458,7 +448,7 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
|
||||
if (failed)
|
||||
{
|
||||
std::string title = "Unable to create renderer";
|
||||
std::string message = "This program requires a graphics card and video drivers which support OpenGL 2.1 or OpenGL ES 2.";
|
||||
std::string message = "This program requires a graphics card and video drivers which support OpenGL 3.3 or OpenGL ES 3.0.";
|
||||
|
||||
if (!glversion.empty())
|
||||
message += "\n\nDetected OpenGL version:\n" + glversion;
|
||||
|
||||
@@ -2805,10 +2805,9 @@ love.test.graphics.getSupported = function(test)
|
||||
-- table match what the documentation lists
|
||||
local gfs = {
|
||||
'clampzero', 'lighten', 'glsl3', 'instancing', 'fullnpot',
|
||||
'pixelshaderhighp', 'shaderderivatives', 'indirectdraw', 'mipmaprange',
|
||||
'copyrendertargettobuffer', 'copytexturetobuffer', 'copybuffer',
|
||||
'copybuffertotexture', 'indexbuffer32bit', 'multirendertargetformats',
|
||||
'clampone', 'blendminmax', 'glsl4'
|
||||
'pixelshaderhighp', 'shaderderivatives', 'indirectdraw',
|
||||
'copytexturetobuffer', 'multirendertargetformats',
|
||||
'clampone', 'glsl4'
|
||||
}
|
||||
local features = love.graphics.getSupported()
|
||||
for g=1,#gfs do
|
||||
|
||||
Reference in New Issue
Block a user