Browse Source

Move default texel and shader storage buffers to high level code.

Sasha Szpakowski 1 year ago
parent
commit
3e8345280f

+ 60 - 0
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)

+ 4 - 0
src/modules/graphics/Graphics.h

@@ -488,6 +488,8 @@ public:
 	bool validateShader(bool gles, const std::vector<std::string> &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<uint8> scratchBuffer;
 

+ 0 - 38
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<Buffer::DataDeclaration> 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<Buffer::DataDeclaration> format = {{"", DATAFORMAT_FLOAT, 0}};
-
-		std::vector<float> 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");

+ 0 - 3
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<love::graphics::Buffer> defaultBuffers[BUFFERUSAGE_MAX_ENUM];
-
 	// [non-readable, readable]
 	uint32 pixelFormatUsage[PIXELFORMAT_MAX_ENUM][2];
 

+ 0 - 12
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

+ 17 - 26
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<love::graphics::Graphics>(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;
 		}
 	}
 }