graphics: handle default textures in high level code.

Previously each backend had to set up default textures with its own code, which needs some care for it to be robust.
This commit is contained in:
Sasha Szpakowski
2023-12-27 21:28:02 +01:00
parent e42019c59e
commit 8872497561
15 changed files with 167 additions and 189 deletions
+93 -6
View File
@@ -195,6 +195,7 @@ Graphics::Graphics()
, quadIndexBuffer(nullptr)
, fanIndexBuffer(nullptr)
, capabilities()
, defaultTextures()
, cachedShaderStages()
{
transformStack.reserve(16);
@@ -217,6 +218,8 @@ Graphics::~Graphics()
if (fanIndexBuffer != nullptr)
fanIndexBuffer->release();
releaseDefaultResources();
// Clean up standard shaders before the active shader. If we do it after,
// the active shader may try to activate a standard shader when deactivating
// itself, which will cause problems since it calls Graphics methods in the
@@ -530,6 +533,90 @@ bool Graphics::validateShader(bool gles, const std::vector<std::string> &stagess
return Shader::validate(stages, err);
}
Texture *Graphics::getDefaultTexture(TextureType type, DataBaseType dataType)
{
Texture *tex = defaultTextures[type][dataType];
if (tex != nullptr)
return tex;
Texture::Settings settings;
settings.type = type;
switch (dataType)
{
case DATA_BASETYPE_INT:
settings.format = PIXELFORMAT_RGBA8_INT;
break;
case DATA_BASETYPE_UINT:
settings.format = PIXELFORMAT_RGBA8_UINT;
break;
case DATA_BASETYPE_FLOAT:
default:
settings.format = PIXELFORMAT_RGBA8_UNORM;
break;
}
std::string name = "default_";
const char *tname = "unknown";
Texture::getConstant(type, tname);
name += tname;
const char *formatname = "unknown";
love::getConstant(settings.format, formatname);
name += std::string("_") + formatname;
settings.debugName = name;
tex = newTexture(settings);
SamplerState s;
s.minFilter = s.magFilter = SamplerState::FILTER_NEAREST;
s.wrapU = s.wrapV = s.wrapW = SamplerState::WRAP_CLAMP;
tex->setSamplerState(s);
uint8 pixel[] = {255, 255, 255, 255};
if (isPixelFormatInteger(settings.format))
pixel[0] = pixel[1] = pixel[2] = pixel[3] = 1;
for (int slice = 0; slice < (type == TEXTURE_CUBE ? 6 : 1); slice++)
tex->replacePixels(pixel, sizeof(pixel), slice, 0, {0, 0, 1, 1}, false);
defaultTextures[type][dataType] = tex;
return tex;
}
void Graphics::releaseDefaultResources()
{
for (int type = 0; type < TEXTURE_MAX_ENUM; type++)
{
for (int dataType = 0; dataType < DATA_BASETYPE_MAX_ENUM; dataType++)
{
if (defaultTextures[type][dataType])
defaultTextures[type][dataType]->release();
defaultTextures[type][dataType] = nullptr;
}
}
}
Texture *Graphics::getTextureOrDefaultForActiveShader(Texture *tex)
{
if (tex != nullptr)
return tex;
Shader *shader = Shader::current;
if (shader != nullptr)
{
auto texinfo = shader->getMainTextureInfo();
if (texinfo != nullptr && texinfo->textureType != TEXTURE_MAX_ENUM)
return getDefaultTexture(texinfo->textureType, texinfo->dataBaseType);
}
return getDefaultTexture(TEXTURE_2D, DATA_BASETYPE_FLOAT);
}
int Graphics::getWidth() const
{
return width;
@@ -1825,7 +1912,7 @@ void Graphics::flushBatchedDraws()
cmd.indexCount = sbstate.indexCount;
cmd.indexType = INDEX_UINT16;
cmd.indexBufferOffset = sbstate.indexBuffer->unmap(usedsizes[2]);
cmd.texture = sbstate.texture;
cmd.texture = getTextureOrDefaultForActiveShader(sbstate.texture);
draw(cmd);
sbstate.indexBufferMap = StreamBuffer::MapInfo();
@@ -1836,7 +1923,7 @@ void Graphics::flushBatchedDraws()
cmd.primitiveType = sbstate.primitiveMode;
cmd.vertexStart = 0;
cmd.vertexCount = sbstate.vertexCount;
cmd.texture = sbstate.texture;
cmd.texture = getTextureOrDefaultForActiveShader(sbstate.texture);
draw(cmd);
}
@@ -1933,7 +2020,7 @@ void Graphics::drawFromShader(PrimitiveType primtype, int vertexcount, int insta
cmd.primitiveType = primtype;
cmd.vertexCount = vertexcount;
cmd.instanceCount = std::max(1, instancecount);
cmd.texture = maintexture;
cmd.texture = getTextureOrDefaultForActiveShader(maintexture);
draw(cmd);
}
@@ -1974,7 +2061,7 @@ void Graphics::drawFromShader(Buffer *indexbuffer, int indexcount, int instancec
cmd.indexType = getIndexDataType(indexbuffer->getDataMember(0).decl.format);
cmd.indexBufferOffset = startindex * getIndexDataSize(cmd.indexType);
cmd.texture = maintexture;
cmd.texture = getTextureOrDefaultForActiveShader(maintexture);
draw(cmd);
}
@@ -2001,7 +2088,7 @@ void Graphics::drawFromShaderIndirect(PrimitiveType primtype, Buffer *indirectar
cmd.primitiveType = primtype;
cmd.indirectBuffer = indirectargs;
cmd.indirectBufferOffset = argsindex * indirectargs->getArrayStride();
cmd.texture = maintexture;
cmd.texture = getTextureOrDefaultForActiveShader(maintexture);
draw(cmd);
}
@@ -2029,7 +2116,7 @@ void Graphics::drawFromShaderIndirect(Buffer *indexbuffer, Buffer *indirectargs,
cmd.indexType = getIndexDataType(indexbuffer->getDataMember(0).decl.format);
cmd.indirectBuffer = indirectargs;
cmd.indexBufferOffset = argsindex * indirectargs->getArrayStride();
cmd.texture = maintexture;
cmd.texture = getTextureOrDefaultForActiveShader(maintexture);
draw(cmd);
}
+7
View File
@@ -487,6 +487,9 @@ public:
bool validateShader(bool gles, const std::vector<std::string> &stages, const Shader::CompileOptions &options, std::string &err);
Texture *getDefaultTexture(TextureType type, DataBaseType dataType);
Texture *getTextureOrDefaultForActiveShader(Texture *tex);
/**
* Resets the current color, background color, line style, and so forth.
**/
@@ -1039,6 +1042,8 @@ protected:
void updatePendingReadbacks();
void releaseDefaultResources();
void restoreState(const DisplayState &s);
void restoreStateChecked(const DisplayState &s);
@@ -1094,6 +1099,8 @@ private:
void checkSetDefaultFont();
int calculateEllipsePoints(float rx, float ry) const;
Texture *defaultTextures[TEXTURE_MAX_ENUM][DATA_BASETYPE_MAX_ENUM];
std::vector<uint8> scratchBuffer;
std::unordered_map<std::string, ShaderStage *> cachedShaderStages[SHADERSTAGE_MAX_ENUM];
+2 -2
View File
@@ -667,7 +667,7 @@ void Mesh::drawInternal(Graphics *gfx, const Matrix4 &m, int instancecount, Buff
cmd.primitiveType = primitiveType;
cmd.indexType = indexDataType;
cmd.instanceCount = instancecount;
cmd.texture = texture;
cmd.texture = gfx->getTextureOrDefaultForActiveShader(texture);
cmd.cullMode = gfx->getMeshCullMode();
cmd.indexBufferOffset = r.getOffset() * indexbuffer->getArrayStride();
@@ -691,7 +691,7 @@ void Mesh::drawInternal(Graphics *gfx, const Matrix4 &m, int instancecount, Buff
cmd.vertexStart = (int) r.getOffset();
cmd.vertexCount = (int) r.getSize();
cmd.instanceCount = instancecount;
cmd.texture = texture;
cmd.texture = gfx->getTextureOrDefaultForActiveShader(texture);
cmd.cullMode = gfx->getMeshCullMode();
cmd.indirectBuffer = indirectargs;
+2 -1
View File
@@ -1086,7 +1086,8 @@ void ParticleSystem::draw(Graphics *gfx, const Matrix4 &m)
BufferBindings vertexbuffers;
vertexbuffers.set(0, buffer, 0);
gfx->drawQuads(0, pCount, vertexAttributes, vertexbuffers, texture);
Texture *tex = gfx->getTextureOrDefaultForActiveShader(texture);
gfx->drawQuads(0, pCount, vertexAttributes, vertexbuffers, tex);
}
bool ParticleSystem::getConstant(const char *in, AreaSpreadDistribution &out)
+4 -1
View File
@@ -395,7 +395,10 @@ void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m)
count = std::min(count, next - start);
if (count > 0)
gfx->drawQuads(start, count, attributes, buffers, texture);
{
Texture *tex = gfx->getTextureOrDefaultForActiveShader(texture);
gfx->drawQuads(start, count, attributes, buffers, tex);
}
}
} // graphics
+4 -1
View File
@@ -290,7 +290,10 @@ void TextBatch::draw(Graphics *gfx, const Matrix4 &m)
Graphics::TempTransform transform(gfx, m);
for (const Font::DrawCommand &cmd : drawCommands)
gfx->drawQuads(cmd.startvertex / 4, cmd.vertexcount / 4, vertexAttributes, vertexBuffers, cmd.texture);
{
Texture *tex = gfx->getTextureOrDefaultForActiveShader(cmd.texture);
gfx->drawQuads(cmd.startvertex / 4, cmd.vertexcount / 4, vertexAttributes, vertexBuffers, tex);
}
}
} // graphics
-3
View File
@@ -139,7 +139,6 @@ public:
StreamBuffer *getUniformBuffer() const { return uniformBuffer; }
Buffer *getDefaultAttributesBuffer() const { return defaultAttributesBuffer; }
Texture *getDefaultTexture(TextureType textype) const { return defaultTextures[textype]; }
int getClosestMSAASamples(int requestedsamples);
@@ -247,8 +246,6 @@ private:
Buffer *defaultAttributesBuffer;
Texture *defaultTextures[TEXTURE_MAX_ENUM];
std::map<uint64, void *> cachedSamplers;
std::unordered_map<uint64, void *> cachedDepthStencilStates;
-22
View File
@@ -281,7 +281,6 @@ Graphics::Graphics()
, renderBindings()
, uniformBufferOffset(0)
, defaultAttributesBuffer(nullptr)
, defaultTextures()
, families()
{ @autoreleasepool {
if (@available(macOS 10.15, iOS 13.0, *))
@@ -346,17 +345,6 @@ Graphics::Graphics()
defaultAttributesBuffer = newBuffer(attribsettings, dataformat, &defaults, sizeof(DefaultVertexAttributes), 0);
}
uint8 defaultpixel[] = {255, 255, 255, 255};
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
{
Texture::Settings settings;
settings.type = (TextureType) i;
settings.format = PIXELFORMAT_RGBA8_UNORM;
defaultTextures[i] = newTexture(settings);
Rect r = {0, 0, 1, 1};
defaultTextures[i]->replacePixels(defaultpixel, sizeof(defaultpixel), 0, 0, r, false);
}
if (batchedDrawState.vb[0] == nullptr)
{
// Initial sizes that should be good enough for most cases. It will
@@ -426,9 +414,6 @@ Graphics::~Graphics()
commandQueue = nil;
device = nil;
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
defaultTextures[i]->release();
for (auto &kvp : cachedSamplers)
CFBridgingRelease(kvp.second);
@@ -1144,13 +1129,6 @@ void Graphics::applyShaderUniforms(id<MTLRenderCommandEncoder> renderEncoder, lo
if (b.isMainTexture)
{
if (maintex == nullptr)
{
auto texinfo = shader->getMainTextureInfo();
if (texinfo != nullptr && texinfo->textureType != TEXTURE_MAX_ENUM)
maintex = defaultTextures[texinfo->textureType];
}
texture = getMTLTexture(maintex);
samplertex = maintex;
}
+10 -3
View File
@@ -524,7 +524,7 @@ void Shader::addImage(const spirv_cross::CompilerMSL &msl, const spirv_cross::Re
if (u.baseType == UNIFORM_SAMPLER)
{
auto tex = Graphics::getInstance()->getDefaultTexture(u.textureType);
auto tex = Graphics::getInstance()->getDefaultTexture(u.textureType, u.dataBaseType);
for (int i = 0; i < u.count; i++)
{
tex->retain();
@@ -538,8 +538,15 @@ void Shader::addImage(const spirv_cross::CompilerMSL &msl, const spirv_cross::Re
}
else if (u.baseType == UNIFORM_STORAGETEXTURE)
{
Texture *tex = nullptr;
if ((u.access & ACCESS_WRITE) == 0)
tex = Graphics::getInstance()->getDefaultTexture(u.textureType, u.dataBaseType);
for (int i = 0; i < u.count; i++)
u.textures[i] = nullptr;
{
if (tex)
tex->retain();
u.textures[i] = tex;
}
}
uniforms[u.name] = u;
@@ -983,7 +990,7 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex
else
{
auto gfx = Graphics::getInstance();
tex = gfx->getDefaultTexture(info->textureType);
tex = gfx->getDefaultTexture(info->textureType, info->dataBaseType);
}
tex->retain();
+4 -1
View File
@@ -1765,7 +1765,10 @@ uint32 Graphics::computePixelFormatUsage(PixelFormat format, bool readable)
// 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, DATA_BASETYPE_FLOAT), 0, 0, 0);
{
love::graphics::Texture *tex = getDefaultTexture(TEXTURE_2D, DATA_BASETYPE_FLOAT);
gl.framebufferTexture(GL_COLOR_ATTACHMENT0, TEXTURE_2D, (GLuint) tex->getHandle(), 0, 0, 0);
}
if (readable)
{
+5 -109
View File
@@ -323,8 +323,6 @@ void OpenGL::setupContext()
setStencilWriteMask(state.stencilWriteMask);
setColorWriteMask(state.colorWriteMask);
createDefaultTexture();
contextInitialized = true;
#ifdef LOVE_ANDROID
@@ -341,18 +339,6 @@ void OpenGL::deInitContext()
if (!contextInitialized)
return;
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
{
for (int datatype = DATA_BASETYPE_FLOAT; datatype <= DATA_BASETYPE_UINT; datatype++)
{
if (state.defaultTexture[i][datatype] != 0)
{
gl.deleteTexture(state.defaultTexture[i][datatype]);
state.defaultTexture[i][datatype] = 0;
}
}
}
contextInitialized = false;
}
@@ -604,71 +590,6 @@ void OpenGL::initMaxValues()
maxLODBias = 0.0f;
}
void OpenGL::createDefaultTexture()
{
// Set the 'default' texture as a repeating white pixel. Otherwise, texture
// calls inside a shader would return black when drawing graphics primitives
// 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;
s.wrapU = s.wrapV = s.wrapW = SamplerState::WRAP_CLAMP;
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
{
for (int datatype = (int)DATA_BASETYPE_FLOAT; datatype <= (int)DATA_BASETYPE_UINT; datatype++)
{
state.defaultTexture[i][datatype] = 0;
TextureType type = (TextureType) i;
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;
rawTexStorage(type, 1, format, 1, 1);
TextureFormat fmt = convertPixelFormat(format, false);
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);
}
}
}
void OpenGL::prepareDraw(love::graphics::Graphics *gfx)
{
TempDebugGroup debuggroup("Prepare OpenGL draw");
@@ -702,6 +623,7 @@ GLenum OpenGL::getGLBufferType(BufferUsage usage)
case BUFFERUSAGE_VERTEX: return GL_ARRAY_BUFFER;
case BUFFERUSAGE_INDEX: return GL_ELEMENT_ARRAY_BUFFER;
case BUFFERUSAGE_TEXEL: return GL_TEXTURE_BUFFER;
case BUFFERUSAGE_UNIFORM: return GL_UNIFORM_BUFFER;
case BUFFERUSAGE_SHADER_STORAGE: return GL_SHADER_STORAGE_BUFFER;
case BUFFERUSAGE_INDIRECT_ARGUMENTS: return GL_DRAW_INDIRECT_BUFFER;
case BUFFERUSAGE_MAX_ENUM: return GL_ZERO;
@@ -1191,11 +1113,6 @@ GLuint OpenGL::getDefaultFBO() const
#endif
}
GLuint OpenGL::getDefaultTexture(TextureType type, DataBaseType datatype) const
{
return state.defaultTexture[type][datatype];
}
void OpenGL::setTextureUnit(int textureunit)
{
if (textureunit != state.curTextureUnit)
@@ -1234,31 +1151,8 @@ void OpenGL::bindBufferTextureToUnit(GLuint texture, int textureunit, bool resto
void OpenGL::bindTextureToUnit(Texture *texture, int textureunit, bool restoreprev, bool bindforedit)
{
TextureType textype = TEXTURE_2D;
GLuint handle = 0;
if (texture != nullptr)
{
textype = texture->getTextureType();
handle = (GLuint) texture->getHandle();
}
else
{
DataBaseType datatype = DATA_BASETYPE_FLOAT;
if (textureunit == 0 && Shader::current != nullptr)
{
const Shader::UniformInfo *info = Shader::current->getMainTextureInfo();
if (info != nullptr)
{
textype = info->textureType;
datatype = info->dataBaseType;
}
}
handle = getDefaultTexture(textype, datatype);
}
TextureType textype = texture->getTextureType();
GLuint handle = (GLuint) texture->getHandle();
bindTextureToUnit(textype, handle, textureunit, restoreprev, bindforedit);
}
@@ -1537,6 +1431,8 @@ bool OpenGL::isBufferUsageSupported(BufferUsage usage) const
return true;
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;
case BUFFERUSAGE_SHADER_STORAGE:
return (GLAD_VERSION_4_3 && isCoreProfile()) || GLAD_ES_VERSION_3_1;
case BUFFERUSAGE_INDIRECT_ARGUMENTS:
-7
View File
@@ -330,11 +330,6 @@ public:
**/
GLuint getDefaultFBO() const;
/**
* Gets the ID for love's default texture (used for "untextured" primitives.)
**/
GLuint getDefaultTexture(TextureType type, DataBaseType datatype) const;
/**
* Gets the texture ID for love's default texel buffer.
**/
@@ -492,7 +487,6 @@ private:
void initVendor();
void initOpenGLFunctions();
void initMaxValues();
void createDefaultTexture();
bool contextInitialized;
@@ -550,7 +544,6 @@ private:
GLuint boundFramebuffers[2];
GLuint defaultTexture[TEXTURE_MAX_ENUM][DATA_BASETYPE_MAX_ENUM];
GLuint defaultTexelBuffer;
GLuint defaultStorageBuffer;
+35 -16
View File
@@ -110,6 +110,8 @@ void Shader::mapActiveUniforms()
std::map<std::string, UniformInfo> olduniforms = uniforms;
uniforms.clear();
auto gfx = Module::getInstance<love::graphics::Graphics>(Module::M_GRAPHICS);
for (int uindex = 0; uindex < numuniforms; uindex++)
{
GLsizei namelen = 0;
@@ -140,7 +142,7 @@ void Shader::mapActiveUniforms()
continue;
if (!fillUniformReflectionData(u))
continue;;
continue;
if ((u.baseType == UNIFORM_SAMPLER && builtin != BUILTIN_TEXTURE_MAIN) || u.baseType == UNIFORM_TEXELBUFFER)
{
@@ -156,7 +158,7 @@ void Shader::mapActiveUniforms()
else
{
unit.isTexelBuffer = false;
unit.texture = gl.getDefaultTexture(u.textureType, u.dataBaseType);
unit.texture = 0; // Handled below.
}
for (int i = 0; i < u.count; i++)
@@ -165,7 +167,7 @@ void Shader::mapActiveUniforms()
else if (u.baseType == UNIFORM_STORAGETEXTURE)
{
StorageTextureBinding binding = {};
binding.gltexture = gl.getDefaultTexture(u.textureType, u.dataBaseType);
binding.gltexture = 0; // Handled below.
binding.type = u.textureType;
if ((u.access & (ACCESS_READ | ACCESS_WRITE)) != 0)
@@ -247,7 +249,13 @@ void Shader::mapActiveUniforms()
else
{
u.textures = new love::graphics::Texture*[u.count];
memset(u.textures, 0, sizeof(Texture *) * u.count);
auto *tex = gfx->getDefaultTexture(u.textureType, u.dataBaseType);
for (int i = 0; i < u.count; i++)
{
tex->retain();
u.textures[i] = tex;
}
}
}
else if (u.baseType == UNIFORM_STORAGETEXTURE)
@@ -259,7 +267,20 @@ void Shader::mapActiveUniforms()
glUniform1iv(u.location, u.count, u.ints);
u.textures = new love::graphics::Texture*[u.count];
memset(u.textures, 0, sizeof(Texture *) * u.count);
if ((u.access & ACCESS_WRITE) != 0)
{
memset(u.textures, 0, sizeof(Texture *) * u.count);
}
else
{
auto *tex = gfx->getDefaultTexture(u.textureType, u.dataBaseType);
for (int i = 0; i < u.count; i++)
{
tex->retain();
u.textures[i] = tex;
}
}
}
}
@@ -777,8 +798,14 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex
{
if (!validateTexture(info, tex, internalUpdate))
continue;
tex->retain();
}
else
{
auto gfx = Module::getInstance<love::graphics::Graphics>(Module::M_GRAPHICS);
tex = gfx->getDefaultTexture(info->textureType, info->dataBaseType);
}
tex->retain();
if (info->textures[i] != nullptr)
info->textures[i]->release();
@@ -787,11 +814,7 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex
if (isstoragetex)
{
GLuint gltex = 0;
if (tex != nullptr)
gltex = (GLuint) tex->getHandle();
else
gltex = gl.getDefaultTexture(info->textureType, info->dataBaseType);
GLuint gltex = (GLuint) tex->getHandle();
int bindingindex = info->ints[i];
auto &binding = storageTextureBindings[bindingindex];
@@ -804,11 +827,7 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex
}
else
{
GLuint gltex = 0;
if (textures[i] != nullptr)
gltex = (GLuint) tex->getHandle();
else
gltex = gl.getDefaultTexture(info->textureType, info->dataBaseType);
GLuint gltex = (GLuint) tex->getHandle();
int texunit = info->ints[i];
+1 -15
View File
@@ -157,7 +157,6 @@ Graphics::~Graphics()
{
defaultConstantTexCoord.set(nullptr);
defaultConstantColor.set(nullptr);
defaultTexture.set(nullptr);
Volatile::unloadAll();
cleanup();
@@ -676,7 +675,6 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
defaultConstantColor = newBuffer(settings, { format }, whiteColor, sizeof(whiteColor), 1);
}
createDefaultTexture();
createDefaultShaders();
Shader::current = Shader::standardShaders[Shader::StandardShader::STANDARD_DEFAULT];
createQuadIndexBuffer();
@@ -2384,10 +2382,7 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi
offsets.push_back((VkDeviceSize)0);
}
if (texture == nullptr)
configuration.shader->setMainTex(defaultTexture);
else
configuration.shader->setMainTex(texture);
configuration.shader->setMainTex(texture);
ensureGraphicsPipelineConfiguration(configuration);
@@ -3035,15 +3030,6 @@ void Graphics::createSyncObjects()
throw love::Exception("failed to create synchronization objects for a frame!");
}
void Graphics::createDefaultTexture()
{
Texture::Settings settings;
defaultTexture.set(newTexture(settings, nullptr), Acquire::NORETAIN);
uint8_t whitePixels[] = {255, 255, 255, 255};
defaultTexture->replacePixels(whitePixels, sizeof(whitePixels), 0, 0, { 0, 0, 1, 1 }, false);
}
void Graphics::cleanup()
{
for (auto &cleanUpFns : cleanUpFunctions)
-2
View File
@@ -367,7 +367,6 @@ private:
void createCommandPool();
void createCommandBuffers();
void createSyncObjects();
void createDefaultTexture();
void cleanup();
void cleanupSwapChain();
void recreateSwapChain();
@@ -442,7 +441,6 @@ private:
bool swapChainRecreationRequested = false;
bool transitionColorDepthLayouts = false;
VmaAllocator vmaAllocator = VK_NULL_HANDLE;
StrongRef<love::graphics::Texture> defaultTexture;
StrongRef<love::graphics::Buffer> defaultConstantColor;
StrongRef<love::graphics::Buffer> defaultConstantTexCoord;
// functions that need to be called to cleanup objects that were needed for rendering a frame.