Initial support for integer format textures.

They can't be rendered to and ImageData can't use the formats, for now.
This commit is contained in:
Alex Szpakowski
2021-08-12 16:38:54 -03:00
parent 4caeb27047
commit 48b3a4e860
11 changed files with 502 additions and 252 deletions
+6
View File
@@ -693,6 +693,9 @@ void Graphics::setRenderTargets(const RenderTargets &rts)
if (!firsttex->isValidSlice(firsttarget.slice))
throw love::Exception("Invalid slice index: %d.", firsttarget.slice + 1);
if (isPixelFormatInteger(firstcolorformat))
throw love::Exception("Textures with integer pixel formats cannot be rendered to, currently.");
bool hasSRGBtexture = firstcolorformat == PIXELFORMAT_sRGBA8_UNORM;
int pixelw = firsttex->getPixelWidth(firsttarget.mipmap);
int pixelh = firsttex->getPixelHeight(firsttarget.mipmap);
@@ -726,6 +729,9 @@ void Graphics::setRenderTargets(const RenderTargets &rts)
if (isPixelFormatDepthStencil(format))
throw love::Exception("Depth/stencil format textures must be used with the 'depthstencil' field of the table passed into setRenderTargets.");
if (isPixelFormatInteger(format))
throw love::Exception("Textures with integer pixel formats cannot be rendered to, currently.");
if (format == PIXELFORMAT_sRGBA8_UNORM)
hasSRGBtexture = true;
}
+2 -3
View File
@@ -635,10 +635,9 @@ bool Shader::isDefaultActive()
return false;
}
TextureType Shader::getMainTextureType() const
const Shader::UniformInfo *Shader::getMainTextureInfo() const
{
const UniformInfo *info = getUniformInfo(BUILTIN_TEXTURE_MAIN);
return info != nullptr ? info->textureType : TEXTURE_MAX_ENUM;
return getUniformInfo(BUILTIN_TEXTURE_MAIN);
}
void Shader::validateDrawState(PrimitiveType primtype, Texture *maintex) const
+3 -3
View File
@@ -131,9 +131,9 @@ public:
};
UniformType baseType;
Access access;
DataBaseType dataBaseType;
TextureType textureType;
DataBaseType texelBufferType;
Access access;
bool isDepthSampler;
size_t bufferStride;
size_t bufferMemberCount;
@@ -221,7 +221,7 @@ public:
**/
virtual void setVideoTextures(Texture *ytexture, Texture *cbtexture, Texture *crtexture) = 0;
TextureType getMainTextureType() const;
const UniformInfo *getMainTextureInfo() const;
void validateDrawState(PrimitiveType primtype, Texture *maintexture) const;
void getLocalThreadgroupSize(int *x, int *y, int *z);
+3
View File
@@ -504,6 +504,9 @@ void Texture::generateMipmaps()
if (isPixelFormatDepthStencil(format))
throw love::Exception("generateMipmaps cannot be called on a depth/stencil Texture.");
if (isPixelFormatInteger(format))
throw love::Exception("generateMipmaps cannot be called on an integer Texture.");
generateMipmapsInternal();
}
+2 -1
View File
@@ -341,6 +341,7 @@ bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, b
batchedDrawState.indexBuffer = CreateStreamBuffer(BUFFERUSAGE_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
}
// TODO: one buffer each for float, int, uint
if (capabilities.features[FEATURE_TEXEL_BUFFER] && defaultBuffers[BUFFERUSAGE_TEXEL].get() == nullptr)
{
Buffer::Settings settings(BUFFERUSAGEFLAG_TEXEL, BUFFERDATAUSAGE_STATIC);
@@ -1723,7 +1724,7 @@ bool Graphics::isPixelFormatSupported(PixelFormat format, bool rendertarget, boo
// Make sure at least something is bound to a color attachment. I believe
// this is required on ES2 but I'm not positive.
if (isPixelFormatDepthStencil(format))
gl.framebufferTexture(GL_COLOR_ATTACHMENT0, TEXTURE_2D, gl.getDefaultTexture(TEXTURE_2D), 0, 0, 0);
gl.framebufferTexture(GL_COLOR_ATTACHMENT0, TEXTURE_2D, gl.getDefaultTexture(TEXTURE_2D, DATA_BASETYPE_FLOAT), 0, 0, 0);
if (readable)
{
+177 -40
View File
@@ -304,10 +304,13 @@ void OpenGL::deInitContext()
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
{
if (state.defaultTexture[i] != 0)
for (int datatype = DATA_BASETYPE_FLOAT; datatype <= DATA_BASETYPE_UINT; datatype++)
{
gl.deleteTexture(state.defaultTexture[i]);
state.defaultTexture[i] = 0;
if (state.defaultTexture[i][datatype] != 0)
{
gl.deleteTexture(state.defaultTexture[i][datatype]);
state.defaultTexture[i][datatype] = 0;
}
}
}
@@ -569,6 +572,7 @@ void OpenGL::createDefaultTexture()
// which would create the need to use different "passthrough" shaders for
// untextured primitives vs images.
const GLubyte pix[] = {255, 255, 255, 255};
const GLubyte intpix[] = {1, 1, 1, 1};
SamplerState s;
s.minFilter = s.magFilter = SamplerState::FILTER_NEAREST;
@@ -576,41 +580,55 @@ void OpenGL::createDefaultTexture()
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
{
state.defaultTexture[i] = 0;
TextureType type = (TextureType) i;
if (!isTextureTypeSupported(type))
continue;
GLuint curtexture = state.boundTextures[type][0];
glGenTextures(1, &state.defaultTexture[type]);
bindTextureToUnit(type, state.defaultTexture[type], 0, false);
setSamplerState(type, s);
bool isSRGB = false;
rawTexStorage(type, 1, PIXELFORMAT_RGBA8_UNORM, isSRGB, 1, 1);
TextureFormat fmt = convertPixelFormat(PIXELFORMAT_RGBA8_UNORM, false, isSRGB);
int slices = type == TEXTURE_CUBE ? 6 : 1;
for (int slice = 0; slice < slices; slice++)
for (int datatype = (int)DATA_BASETYPE_FLOAT; datatype <= (int)DATA_BASETYPE_UINT; datatype++)
{
GLenum gltarget = getGLTextureType(type);
state.defaultTexture[i][datatype] = 0;
if (type == TEXTURE_CUBE)
gltarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice;
TextureType type = (TextureType) i;
if (type == TEXTURE_2D || type == TEXTURE_CUBE)
glTexSubImage2D(gltarget, 0, 0, 0, 1, 1, fmt.externalformat, fmt.type, pix);
else if (type == TEXTURE_2D_ARRAY || type == TEXTURE_VOLUME)
glTexSubImage3D(gltarget, 0, 0, 0, slice, 1, 1, 1, fmt.externalformat, fmt.type, pix);
if (!isTextureTypeSupported(type))
continue;
if (datatype != DATA_BASETYPE_FLOAT && !(GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0))
continue;
GLuint curtexture = state.boundTextures[type][0];
glGenTextures(1, &state.defaultTexture[type][datatype]);
bindTextureToUnit(type, state.defaultTexture[type][datatype], 0, false);
setSamplerState(type, s);
PixelFormat format = PIXELFORMAT_RGBA8_UNORM;
if (datatype == DATA_BASETYPE_INT)
format = PIXELFORMAT_RGBA8_INT;
else if (datatype == DATA_BASETYPE_UINT)
format = PIXELFORMAT_RGBA8_UINT;
const GLubyte *p = datatype == DATA_BASETYPE_FLOAT ? pix : intpix;
bool isSRGB = false;
rawTexStorage(type, 1, format, isSRGB, 1, 1);
TextureFormat fmt = convertPixelFormat(format, false, isSRGB);
int slices = type == TEXTURE_CUBE ? 6 : 1;
for (int slice = 0; slice < slices; slice++)
{
GLenum gltarget = getGLTextureType(type);
if (type == TEXTURE_CUBE)
gltarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice;
if (type == TEXTURE_2D || type == TEXTURE_CUBE)
glTexSubImage2D(gltarget, 0, 0, 0, 1, 1, fmt.externalformat, fmt.type, p);
else if (type == TEXTURE_2D_ARRAY || type == TEXTURE_VOLUME)
glTexSubImage3D(gltarget, 0, 0, 0, slice, 1, 1, 1, fmt.externalformat, fmt.type, p);
}
bindTextureToUnit(type, curtexture, 0, false);
}
bindTextureToUnit(type, curtexture, 0, false);
}
}
@@ -1113,9 +1131,9 @@ GLuint OpenGL::getDefaultFBO() const
#endif
}
GLuint OpenGL::getDefaultTexture(TextureType type) const
GLuint OpenGL::getDefaultTexture(TextureType type, DataBaseType datatype) const
{
return state.defaultTexture[type];
return state.defaultTexture[type][datatype];
}
void OpenGL::setTextureUnit(int textureunit)
@@ -1166,14 +1184,19 @@ void OpenGL::bindTextureToUnit(Texture *texture, int textureunit, bool restorepr
}
else
{
DataBaseType datatype = DATA_BASETYPE_FLOAT;
if (textureunit == 0 && Shader::current != nullptr)
{
TextureType shadertex = Shader::current->getMainTextureType();
if (shadertex != TEXTURE_MAX_ENUM)
textype = shadertex;
const Shader::UniformInfo *info = Shader::current->getMainTextureInfo();
if (info != nullptr)
{
textype = info->textureType;
datatype = info->dataBaseType;
}
}
handle = getDefaultTexture(textype);
handle = getDefaultTexture(textype, datatype);
}
bindTextureToUnit(textype, handle, textureunit, restoreprev, bindforedit);
@@ -1662,6 +1685,7 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
f.externalformat = GL_RGBA;
f.type = GL_UNSIGNED_SHORT;
break;
case PIXELFORMAT_R16_FLOAT:
f.internalformat = GL_R16F;
f.externalformat = GL_RED;
@@ -1702,6 +1726,97 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
f.type = GL_FLOAT;
break;
case PIXELFORMAT_R8_INT:
f.internalformat = GL_R8I;
f.externalformat = GL_RED_INTEGER;
f.type = GL_BYTE;
break;
case PIXELFORMAT_R8_UINT:
f.internalformat = GL_R8UI;
f.externalformat = GL_RED_INTEGER;
f.type = GL_UNSIGNED_BYTE;
break;
case PIXELFORMAT_RG8_INT:
f.internalformat = GL_RG8I;
f.externalformat = GL_RG_INTEGER;
f.type = GL_BYTE;
break;
case PIXELFORMAT_RG8_UINT:
f.internalformat = GL_RG8UI;
f.externalformat = GL_RG_INTEGER;
f.type = GL_UNSIGNED_BYTE;
break;
case PIXELFORMAT_RGBA8_INT:
f.internalformat = GL_RGBA8I;
f.externalformat = GL_RGBA_INTEGER;
f.type = GL_BYTE;
break;
case PIXELFORMAT_RGBA8_UINT:
f.internalformat = GL_RGBA8UI;
f.externalformat = GL_RGBA_INTEGER;
f.type = GL_UNSIGNED_BYTE;
break;
case PIXELFORMAT_R16_INT:
f.internalformat = GL_R16I;
f.externalformat = GL_RED_INTEGER;
f.type = GL_SHORT;
break;
case PIXELFORMAT_R16_UINT:
f.internalformat = GL_R16UI;
f.externalformat = GL_RED_INTEGER;
f.type = GL_UNSIGNED_SHORT;
break;
case PIXELFORMAT_RG16_INT:
f.internalformat = GL_RG16I;
f.externalformat = GL_RG_INTEGER;
f.type = GL_SHORT;
break;
case PIXELFORMAT_RG16_UINT:
f.internalformat = GL_RG16UI;
f.externalformat = GL_RG_INTEGER;
f.type = GL_UNSIGNED_SHORT;
break;
case PIXELFORMAT_RGBA16_INT:
f.internalformat = GL_RGBA16I;
f.externalformat = GL_RGBA_INTEGER;
f.type = GL_SHORT;
break;
case PIXELFORMAT_RGBA16_UINT:
f.internalformat = GL_RGBA16UI;
f.externalformat = GL_RGBA_INTEGER;
f.type = GL_UNSIGNED_SHORT;
break;
case PIXELFORMAT_R32_INT:
f.internalformat = GL_R32I;
f.externalformat = GL_RED_INTEGER;
f.type = GL_INT;
break;
case PIXELFORMAT_R32_UINT:
f.internalformat = GL_R32UI;
f.externalformat = GL_RED_INTEGER;
f.type = GL_UNSIGNED_INT;
break;
case PIXELFORMAT_RG32_INT:
f.internalformat = GL_RG32I;
f.externalformat = GL_RG_INTEGER;
f.type = GL_INT;
break;
case PIXELFORMAT_RG32_UINT:
f.internalformat = GL_RG32UI;
f.externalformat = GL_RG_INTEGER;
f.type = GL_UNSIGNED_INT;
break;
case PIXELFORMAT_RGBA32_INT:
f.internalformat = GL_RGBA32I;
f.externalformat = GL_RGBA_INTEGER;
f.type = GL_INT;
break;
case PIXELFORMAT_RGBA32_UINT:
f.internalformat = GL_RGBA32UI;
f.externalformat = GL_RGBA_INTEGER;
f.type = GL_UNSIGNED_INT;
break;
case PIXELFORMAT_LA8_UNORM:
if (gl.isCoreProfile() || GLAD_ES_VERSION_3_0)
{
@@ -2046,6 +2161,28 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
flags &= ~PIXELFORMATUSAGEFLAGS_LINEAR;
break;
case PIXELFORMAT_R8_INT:
case PIXELFORMAT_R8_UINT:
case PIXELFORMAT_RG8_INT:
case PIXELFORMAT_RG8_UINT:
case PIXELFORMAT_RGBA8_INT:
case PIXELFORMAT_RGBA8_UINT:
case PIXELFORMAT_R16_INT:
case PIXELFORMAT_R16_UINT:
case PIXELFORMAT_RG16_INT:
case PIXELFORMAT_RG16_UINT:
case PIXELFORMAT_RGBA16_INT:
case PIXELFORMAT_RGBA16_UINT:
case PIXELFORMAT_R32_INT:
case PIXELFORMAT_R32_UINT:
case PIXELFORMAT_RG32_INT:
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;
break;
case PIXELFORMAT_LA8_UNORM:
flags |= commonsample;
break;
+2 -2
View File
@@ -312,7 +312,7 @@ public:
/**
* Gets the ID for love's default texture (used for "untextured" primitives.)
**/
GLuint getDefaultTexture(TextureType type) const;
GLuint getDefaultTexture(TextureType type, DataBaseType datatype) const;
/**
* Gets the texture ID for love's default texel buffer.
@@ -523,7 +523,7 @@ private:
GLuint boundFramebuffers[2];
GLuint defaultTexture[TEXTURE_MAX_ENUM];
GLuint defaultTexture[TEXTURE_MAX_ENUM][DATA_BASETYPE_MAX_ENUM];
GLuint defaultTexelBuffer;
GLuint defaultStorageBuffer;
+150 -120
View File
@@ -119,16 +119,8 @@ void Shader::mapActiveUniforms()
u.name = std::string(cname, (size_t) namelen);
u.location = glGetUniformLocation(program, u.name.c_str());
u.baseType = getUniformBaseType(gltype);
u.access = ACCESS_READ;
u.textureType = getUniformTextureType(gltype);
u.texelBufferType = getUniformTexelBufferType(gltype);
u.isDepthSampler = isDepthTextureType(gltype);
if (u.baseType == UNIFORM_MATRIX)
u.matrix = getMatrixSize(gltype);
else
u.components = getUniformTypeComponents(gltype);
computeUniformTypeInfo(gltype, u);
// glGetActiveUniform appends "[0]" to the end of array uniform names...
if (u.name.length() > 3)
@@ -160,7 +152,7 @@ void Shader::mapActiveUniforms()
else
{
unit.isTexelBuffer = false;
unit.texture = gl.getDefaultTexture(u.textureType);
unit.texture = gl.getDefaultTexture(u.textureType, u.dataBaseType);
}
for (int i = 0; i < u.count; i++)
@@ -718,6 +710,40 @@ void Shader::updateUniform(const UniformInfo *info, int count, bool internalupda
}
}
static bool isResourceBaseTypeCompatible(DataBaseType a, DataBaseType b)
{
if (a == DATA_BASETYPE_FLOAT || a == DATA_BASETYPE_UNORM || a == DATA_BASETYPE_SNORM)
return b == DATA_BASETYPE_FLOAT || b == DATA_BASETYPE_UNORM || b == DATA_BASETYPE_SNORM;
if (a == DATA_BASETYPE_INT && b == DATA_BASETYPE_INT)
return true;
if (a == DATA_BASETYPE_UINT && b == DATA_BASETYPE_UINT)
return true;
return false;
}
static DataBaseType getDataBaseType(PixelFormat format)
{
switch (getPixelFormatInfo(format).dataType)
{
case PIXELFORMATTYPE_UNORM:
return DATA_BASETYPE_UNORM;
case PIXELFORMATTYPE_SNORM:
return DATA_BASETYPE_SNORM;
case PIXELFORMATTYPE_UFLOAT:
case PIXELFORMATTYPE_SFLOAT:
return DATA_BASETYPE_FLOAT;
case PIXELFORMATTYPE_SINT:
return DATA_BASETYPE_INT;
case PIXELFORMATTYPE_UINT:
return DATA_BASETYPE_UINT;
default:
return DATA_BASETYPE_FLOAT;
}
}
void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **textures, int count)
{
Shader::sendTextures(info, textures, count, false);
@@ -742,7 +768,6 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex
if (tex != nullptr)
{
const SamplerState &sampler = tex->getSamplerState();
if (!tex->isReadable())
{
if (internalUpdate)
@@ -750,7 +775,7 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex
else
throw love::Exception("Textures with non-readable formats cannot be sampled from in a shader.");
}
else if (info->isDepthSampler != sampler.depthSampleMode.hasValue)
else if (info->isDepthSampler != tex->getSamplerState().depthSampleMode.hasValue)
{
if (internalUpdate)
continue;
@@ -772,6 +797,13 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex
throw love::Exception("Texture's type (%s) must match the type of %s (%s).", textypestr, info->name.c_str(), shadertextypestr);
}
}
else if (!isResourceBaseTypeCompatible(info->dataBaseType, getDataBaseType(tex->getPixelFormat())))
{
if (internalUpdate)
continue;
else
throw love::Exception("Texture's data format base type must match the uniform variable declared in the shader (float, int, or uint).");
}
tex->retain();
}
@@ -785,7 +817,7 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex
if (textures[i] != nullptr)
gltex = (GLuint) tex->getHandle();
else
gltex = gl.getDefaultTexture(info->textureType);
gltex = gl.getDefaultTexture(info->textureType, info->dataBaseType);
int texunit = info->ints[i];
@@ -802,20 +834,6 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe
Shader::sendBuffers(info, buffers, count, false);
}
static bool isTexelBufferTypeCompatible(DataBaseType a, DataBaseType b)
{
if (a == DATA_BASETYPE_FLOAT || a == DATA_BASETYPE_UNORM || a == DATA_BASETYPE_SNORM)
return b == DATA_BASETYPE_FLOAT || b == DATA_BASETYPE_UNORM || b == DATA_BASETYPE_SNORM;
if (a == DATA_BASETYPE_INT && b == DATA_BASETYPE_INT)
return true;
if (a == DATA_BASETYPE_UINT && b == DATA_BASETYPE_UINT)
return true;
return false;
}
void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count, bool internalUpdate)
{
uint32 requiredtypeflags = 0;
@@ -860,7 +878,7 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe
if (texelbinding)
{
DataBaseType basetype = buffer->getDataMember(0).info.baseType;
if (!isTexelBufferTypeCompatible(basetype, info->texelBufferType))
if (!isResourceBaseTypeCompatible(basetype, info->dataBaseType))
{
if (internalUpdate)
continue;
@@ -1043,11 +1061,6 @@ void Shader::updateBuiltinUniforms(love::graphics::Graphics *gfx, int viewportW,
int Shader::getUniformTypeComponents(GLenum type) const
{
UniformType basetype = getUniformBaseType(type);
if (basetype == UNIFORM_SAMPLER || basetype == UNIFORM_TEXELBUFFER)
return 1;
switch (type)
{
case GL_INT:
@@ -1122,25 +1135,35 @@ Shader::MatrixSize Shader::getMatrixSize(GLenum type) const
return m;
}
Shader::UniformType Shader::getUniformBaseType(GLenum type) const
void Shader::computeUniformTypeInfo(GLenum type, UniformInfo &u)
{
u.isDepthSampler = false;
u.components = getUniformTypeComponents(type);
u.baseType = UNIFORM_UNKNOWN;
switch (type)
{
case GL_INT:
case GL_INT_VEC2:
case GL_INT_VEC3:
case GL_INT_VEC4:
return UNIFORM_INT;
u.baseType = UNIFORM_INT;
u.dataBaseType = DATA_BASETYPE_INT;
break;
case GL_UNSIGNED_INT:
case GL_UNSIGNED_INT_VEC2:
case GL_UNSIGNED_INT_VEC3:
case GL_UNSIGNED_INT_VEC4:
return UNIFORM_UINT;
u.baseType = UNIFORM_UINT;
u.dataBaseType = DATA_BASETYPE_UINT;
break;
case GL_FLOAT:
case GL_FLOAT_VEC2:
case GL_FLOAT_VEC3:
case GL_FLOAT_VEC4:
return UNIFORM_FLOAT;
u.baseType = UNIFORM_FLOAT;
u.dataBaseType = DATA_BASETYPE_FLOAT;
break;
case GL_FLOAT_MAT2:
case GL_FLOAT_MAT3:
case GL_FLOAT_MAT4:
@@ -1150,105 +1173,112 @@ Shader::UniformType Shader::getUniformBaseType(GLenum type) const
case GL_FLOAT_MAT3x4:
case GL_FLOAT_MAT4x2:
case GL_FLOAT_MAT4x3:
return UNIFORM_MATRIX;
u.baseType = UNIFORM_MATRIX;
u.dataBaseType = DATA_BASETYPE_FLOAT;
u.matrix = getMatrixSize(type);
break;
case GL_BOOL:
case GL_BOOL_VEC2:
case GL_BOOL_VEC3:
case GL_BOOL_VEC4:
return UNIFORM_BOOL;
case GL_SAMPLER_1D:
case GL_SAMPLER_1D_SHADOW:
case GL_SAMPLER_1D_ARRAY:
case GL_SAMPLER_1D_ARRAY_SHADOW:
u.baseType = UNIFORM_BOOL;
u.dataBaseType = DATA_BASETYPE_BOOL;
break;
case GL_SAMPLER_2D:
case GL_SAMPLER_2D_MULTISAMPLE:
case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
case GL_SAMPLER_2D_RECT:
case GL_SAMPLER_2D_RECT_SHADOW:
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_FLOAT;
u.textureType = TEXTURE_2D;
break;
case GL_SAMPLER_2D_SHADOW:
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_FLOAT;
u.textureType = TEXTURE_2D;
u.isDepthSampler = true;
break;
case GL_INT_SAMPLER_2D:
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_INT;
u.textureType = TEXTURE_2D;
break;
case GL_UNSIGNED_INT_SAMPLER_2D:
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_UINT;
u.textureType = TEXTURE_2D;
break;
case GL_SAMPLER_2D_ARRAY:
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_FLOAT;
u.textureType = TEXTURE_2D_ARRAY;
break;
case GL_SAMPLER_2D_ARRAY_SHADOW:
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_FLOAT;
u.textureType = TEXTURE_2D_ARRAY;
u.isDepthSampler = true;
break;
case GL_INT_SAMPLER_2D_ARRAY:
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_INT;
u.textureType = TEXTURE_2D_ARRAY;
break;
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_UINT;
u.textureType = TEXTURE_2D_ARRAY;
break;
case GL_SAMPLER_3D:
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_FLOAT;
u.textureType = TEXTURE_VOLUME;
break;
case GL_INT_SAMPLER_3D:
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_INT;
u.textureType = TEXTURE_VOLUME;
break;
case GL_UNSIGNED_INT_SAMPLER_3D:
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_UINT;
u.textureType = TEXTURE_VOLUME;
break;
case GL_SAMPLER_CUBE:
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_FLOAT;
u.textureType = TEXTURE_CUBE;
break;
case GL_SAMPLER_CUBE_SHADOW:
case GL_SAMPLER_CUBE_MAP_ARRAY:
case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
return UNIFORM_SAMPLER;
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_FLOAT;
u.textureType = TEXTURE_CUBE;
u.isDepthSampler = true;
break;
case GL_INT_SAMPLER_CUBE:
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_INT;
u.textureType = TEXTURE_CUBE;
break;
case GL_UNSIGNED_INT_SAMPLER_CUBE:
u.baseType = UNIFORM_SAMPLER;
u.dataBaseType = DATA_BASETYPE_UINT;
u.textureType = TEXTURE_CUBE;
break;
case GL_SAMPLER_BUFFER:
u.baseType = UNIFORM_TEXELBUFFER;
u.dataBaseType = DATA_BASETYPE_FLOAT;
break;
case GL_INT_SAMPLER_BUFFER:
u.baseType = UNIFORM_TEXELBUFFER;
u.dataBaseType = DATA_BASETYPE_INT;
break;
case GL_UNSIGNED_INT_SAMPLER_BUFFER:
return UNIFORM_TEXELBUFFER;
default:
return UNIFORM_UNKNOWN;
}
}
u.baseType = UNIFORM_TEXELBUFFER;
u.dataBaseType = DATA_BASETYPE_UINT;
break;
TextureType Shader::getUniformTextureType(GLenum type) const
{
switch (type)
{
case GL_SAMPLER_1D:
case GL_SAMPLER_1D_SHADOW:
case GL_SAMPLER_1D_ARRAY:
case GL_SAMPLER_1D_ARRAY_SHADOW:
// 1D-typed textures are not supported.
return TEXTURE_MAX_ENUM;
case GL_SAMPLER_2D:
case GL_SAMPLER_2D_SHADOW:
return TEXTURE_2D;
case GL_SAMPLER_2D_MULTISAMPLE:
case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
// Multisample textures are not supported.
return TEXTURE_MAX_ENUM;
case GL_SAMPLER_2D_RECT:
case GL_SAMPLER_2D_RECT_SHADOW:
// Rectangle textures are not supported.
return TEXTURE_MAX_ENUM;
case GL_SAMPLER_2D_ARRAY:
case GL_SAMPLER_2D_ARRAY_SHADOW:
return TEXTURE_2D_ARRAY;
case GL_SAMPLER_3D:
return TEXTURE_VOLUME;
case GL_SAMPLER_CUBE:
case GL_SAMPLER_CUBE_SHADOW:
return TEXTURE_CUBE;
case GL_SAMPLER_CUBE_MAP_ARRAY:
case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
// Cubemap array textures are not supported.
return TEXTURE_MAX_ENUM;
default:
return TEXTURE_MAX_ENUM;
}
}
DataBaseType Shader::getUniformTexelBufferType(GLenum type) const
{
switch (type)
{
case GL_SAMPLER_BUFFER:
return DATA_BASETYPE_FLOAT;
case GL_INT_SAMPLER_BUFFER:
return DATA_BASETYPE_INT;
case GL_UNSIGNED_INT_SAMPLER_BUFFER:
return DATA_BASETYPE_UINT;
default:
return DATA_BASETYPE_MAX_ENUM;
}
}
bool Shader::isDepthTextureType(GLenum type) const
{
switch (type)
{
case GL_SAMPLER_1D_SHADOW:
case GL_SAMPLER_1D_ARRAY_SHADOW:
case GL_SAMPLER_2D_SHADOW:
case GL_SAMPLER_2D_ARRAY_SHADOW:
case GL_SAMPLER_CUBE_SHADOW:
case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
return true;
default:
return false;
break;
}
}
+1 -4
View File
@@ -92,11 +92,8 @@ private:
void sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count, bool internalupdate);
int getUniformTypeComponents(GLenum type) const;
void computeUniformTypeInfo(GLenum type, UniformInfo &u);
MatrixSize getMatrixSize(GLenum type) const;
UniformType getUniformBaseType(GLenum type) const;
TextureType getUniformTextureType(GLenum type) const;
DataBaseType getUniformTexelBufferType(GLenum type) const;
bool isDepthTextureType(GLenum type) const;
void flushBatchedDraws() const;