diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 44b196a44..0cf3eb139 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -589,6 +589,55 @@ Texture *Graphics::getDefaultTexture(TextureType type, DataBaseType dataType) return tex; } +Buffer *Graphics::getDefaultTexelBuffer(DataBaseType dataType) +{ + Buffer *buffer = defaultTexelBuffers[dataType]; + if (buffer != nullptr) + return buffer; + + Buffer::Settings settings(BUFFERUSAGEFLAG_TEXEL, BUFFERDATAUSAGE_STATIC); + settings.zeroInitialize = true; + settings.debugName = "default_texelbuffer_"; + + DataFormat format = DATAFORMAT_FLOAT; + switch (dataType) + { + case DATA_BASETYPE_FLOAT: + default: + format = DATAFORMAT_FLOAT; + settings.debugName += "float"; + break; + case DATA_BASETYPE_INT: + format = DATAFORMAT_INT32; + settings.debugName += "int"; + break; + case DATA_BASETYPE_UINT: + format = DATAFORMAT_UINT32; + settings.debugName += "uint"; + break; + } + + buffer = newBuffer(settings, format, nullptr, sizeof(float), 1); + + defaultTexelBuffers[dataType] = buffer; + + return buffer; +} + +Buffer *Graphics::getDefaultStorageBuffer() +{ + if (defaultStorageBuffer != nullptr) + return defaultStorageBuffer; + + Buffer::Settings settings(BUFFERUSAGEFLAG_SHADER_STORAGE, BUFFERDATAUSAGE_STATIC); + settings.zeroInitialize = true; + settings.debugName = "default_storagebuffer"; + + defaultStorageBuffer = newBuffer(settings, DATAFORMAT_FLOAT, nullptr, Buffer::SHADER_STORAGE_BUFFER_MAX_STRIDE, 0); + + return defaultStorageBuffer; +} + void Graphics::releaseDefaultResources() { for (int type = 0; type < TEXTURE_MAX_ENUM; type++) @@ -600,6 +649,17 @@ void Graphics::releaseDefaultResources() defaultTextures[type][dataType] = nullptr; } } + + for (int dataType = 0; dataType < DATA_BASETYPE_MAX_ENUM; dataType++) + { + if (defaultTexelBuffers[dataType]) + defaultTexelBuffers[dataType]->release(); + defaultTexelBuffers[dataType] = nullptr; + } + + if (defaultStorageBuffer) + defaultStorageBuffer->release(); + defaultStorageBuffer = nullptr; } Texture *Graphics::getTextureOrDefaultForActiveShader(Texture *tex) diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 4a2c92b9c..1968da453 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -488,6 +488,8 @@ public: bool validateShader(bool gles, const std::vector &stages, const Shader::CompileOptions &options, std::string &err); Texture *getDefaultTexture(TextureType type, DataBaseType dataType); + Buffer *getDefaultTexelBuffer(DataBaseType dataType); + Buffer *getDefaultStorageBuffer(); Texture *getTextureOrDefaultForActiveShader(Texture *tex); /** @@ -1111,6 +1113,8 @@ private: int calculateEllipsePoints(float rx, float ry) const; Texture *defaultTextures[TEXTURE_MAX_ENUM][DATA_BASETYPE_MAX_ENUM]; + Buffer *defaultTexelBuffers[DATA_BASETYPE_MAX_ENUM]; + Buffer *defaultStorageBuffer; std::vector scratchBuffer; diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index f6ff52205..9013ee808 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -112,7 +112,6 @@ Graphics::Graphics() , requestedBackbufferMSAA(0) , bufferMapMemory(nullptr) , bufferMapMemorySize(2 * 1024 * 1024) - , defaultBuffers() , pixelFormatUsage() { gl = OpenGL(); @@ -384,43 +383,6 @@ bool Graphics::setMode(void */*context*/, int width, int height, int pixelwidth, 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); - std::vector format = {{"", DATAFORMAT_FLOAT_VEC4, 0}}; - - const float texel[] = {0.0f, 0.0f, 0.0f, 1.0f}; - - auto buffer = newBuffer(settings, format, texel, sizeof(texel), 1); - defaultBuffers[BUFFERUSAGE_TEXEL].set(buffer, Acquire::NORETAIN); - } - - if (capabilities.features[FEATURE_GLSL4] && defaultBuffers[BUFFERUSAGE_SHADER_STORAGE].get() == nullptr) - { - Buffer::Settings settings(BUFFERUSAGEFLAG_SHADER_STORAGE, BUFFERDATAUSAGE_STATIC); - std::vector format = {{"", DATAFORMAT_FLOAT, 0}}; - - std::vector data; - data.resize(Buffer::SHADER_STORAGE_BUFFER_MAX_STRIDE / 4); - - auto buffer = newBuffer(settings, format, data.data(), data.size() * sizeof(float), data.size()); - defaultBuffers[BUFFERUSAGE_SHADER_STORAGE].set(buffer, Acquire::NORETAIN); - } - - // Load default resources before other Volatile. - for (int i = 0; i < BUFFERUSAGE_MAX_ENUM; i++) - { - if (defaultBuffers[i].get()) - ((Buffer *) defaultBuffers[i].get())->loadVolatile(); - } - - if (defaultBuffers[BUFFERUSAGE_TEXEL].get()) - gl.setDefaultTexelBuffer((GLuint) defaultBuffers[BUFFERUSAGE_TEXEL]->getTexelBufferHandle()); - - if (defaultBuffers[BUFFERUSAGE_SHADER_STORAGE].get()) - gl.setDefaultStorageBuffer((GLuint) defaultBuffers[BUFFERUSAGE_SHADER_STORAGE]->getHandle()); - // Reload all volatile objects. if (!Volatile::loadAll()) ::printf("Could not reload all volatile objects.\n"); diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 7e064420e..cb39c1e81 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -173,9 +173,6 @@ private: char *bufferMapMemory; size_t bufferMapMemorySize; - // Only needed for buffer types that can be bound to shaders. - StrongRef defaultBuffers[BUFFERUSAGE_MAX_ENUM]; - // [non-readable, readable] uint32 pixelFormatUsage[PIXELFORMAT_MAX_ENUM][2]; diff --git a/src/modules/graphics/opengl/OpenGL.h b/src/modules/graphics/opengl/OpenGL.h index 32f2bf8c1..6aa6a5337 100644 --- a/src/modules/graphics/opengl/OpenGL.h +++ b/src/modules/graphics/opengl/OpenGL.h @@ -330,15 +330,6 @@ public: **/ GLuint getDefaultFBO() const; - /** - * Gets the texture ID for love's default texel buffer. - **/ - GLuint getDefaultTexelBuffer() const { return state.defaultTexelBuffer; } - void setDefaultTexelBuffer(GLuint tex) { state.defaultTexelBuffer = tex; } - - GLuint getDefaultStorageBuffer() const { return state.defaultStorageBuffer; } - void setDefaultStorageBuffer(GLuint buf) { state.defaultStorageBuffer = buf; } - /** * Helper for setting the active texture unit. * @@ -544,9 +535,6 @@ private: GLuint boundFramebuffers[2]; - GLuint defaultTexelBuffer; - GLuint defaultStorageBuffer; - } state; }; // OpenGL diff --git a/src/modules/graphics/opengl/Shader.cpp b/src/modules/graphics/opengl/Shader.cpp index e99642d99..d1fd38209 100644 --- a/src/modules/graphics/opengl/Shader.cpp +++ b/src/modules/graphics/opengl/Shader.cpp @@ -149,17 +149,8 @@ void Shader::mapActiveUniforms() TextureUnit unit; unit.type = u.textureType; unit.active = true; - - if (u.baseType == UNIFORM_TEXELBUFFER) - { - unit.isTexelBuffer = true; - unit.texture = gl.getDefaultTexelBuffer(); - } - else - { - unit.isTexelBuffer = false; - unit.texture = 0; // Handled below. - } + unit.texture = 0; // Handled below. + unit.isTexelBuffer = u.baseType == UNIFORM_TEXELBUFFER; for (int i = 0; i < u.count; i++) textureUnits.push_back(unit); @@ -414,7 +405,7 @@ void Shader::mapActiveUniforms() BufferBinding binding; binding.bindingindex = u.ints[0]; - binding.buffer = gl.getDefaultStorageBuffer(); + binding.buffer = 0; if (binding.bindingindex >= 0) { @@ -867,13 +858,23 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe for (int i = 0; i < count; i++) { love::graphics::Buffer *buffer = buffers[i]; + bool isdefault = buffer != nullptr; if (buffer != nullptr) { if (!validateBuffer(info, buffer, internalUpdate)) continue; - buffer->retain(); } + else + { + auto gfx = Module::getInstance(Module::M_GRAPHICS); + if (texelbinding) + buffer = gfx->getDefaultTexelBuffer(info->dataBaseType); + else + buffer = gfx->getDefaultStorageBuffer(); + } + + buffer->retain(); if (info->buffers[i] != nullptr) info->buffers[i]->release(); @@ -882,12 +883,7 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe if (texelbinding) { - GLuint gltex = 0; - if (buffer != nullptr) - gltex = (GLuint) buffer->getTexelBufferHandle(); - else - gltex = gl.getDefaultTexelBuffer(); - + GLuint gltex = (GLuint) buffer->getTexelBufferHandle(); int texunit = info->ints[i]; if (shaderactive) @@ -898,14 +894,9 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe } else if (storagebinding) { + GLuint glbuffer = (GLuint)buffer->getHandle(); int bindingindex = info->ints[i]; - GLuint glbuffer = 0; - if (buffer != nullptr) - glbuffer = (GLuint) buffer->getHandle(); - else - glbuffer = gl.getDefaultStorageBuffer(); - if (shaderactive) gl.bindIndexedBuffer(glbuffer, BUFFERUSAGE_SHADER_STORAGE, bindingindex); @@ -915,7 +906,7 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe activeStorageBufferBindings[activeindex.first].buffer = glbuffer; if (activeindex.second >= 0) - activeWritableStorageBuffers[activeindex.second] = buffer; + activeWritableStorageBuffers[activeindex.second] = isdefault ? nullptr : buffer; } } }