|
@@ -553,172 +553,78 @@ void Shader::updateUniform(const UniformInfo *info, int count, bool internalupda
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **textures, int count)
|
|
|
|
|
|
+void Shader::applyTexture(const UniformInfo *info, int i, love::graphics::Texture *texture, UniformType basetype, bool isdefault)
|
|
{
|
|
{
|
|
- Shader::sendTextures(info, textures, count, false);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **textures, int count, bool internalUpdate)
|
|
|
|
-{
|
|
|
|
- bool issampler = info->baseType == UNIFORM_SAMPLER;
|
|
|
|
- bool isstoragetex = info->baseType == UNIFORM_STORAGETEXTURE;
|
|
|
|
-
|
|
|
|
- if (!issampler && !isstoragetex)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
bool shaderactive = current == this;
|
|
bool shaderactive = current == this;
|
|
|
|
|
|
- if (!internalUpdate && shaderactive)
|
|
|
|
- flushBatchedDraws();
|
|
|
|
-
|
|
|
|
- count = std::min(count, info->count);
|
|
|
|
-
|
|
|
|
- // Bind the textures to the texture units.
|
|
|
|
- for (int i = 0; i < count; i++)
|
|
|
|
|
|
+ if (basetype == UNIFORM_STORAGETEXTURE)
|
|
{
|
|
{
|
|
- love::graphics::Texture *tex = textures[i];
|
|
|
|
- bool isdefault = tex == nullptr;
|
|
|
|
-
|
|
|
|
- if (tex != nullptr)
|
|
|
|
- {
|
|
|
|
- if (!validateTexture(info, tex, internalUpdate))
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- auto gfx = Module::getInstance<love::graphics::Graphics>(Module::M_GRAPHICS);
|
|
|
|
- tex = gfx->getDefaultTexture(info->textureType, info->dataBaseType, info->isDepthSampler);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- tex->retain();
|
|
|
|
-
|
|
|
|
- int resourceindex = info->resourceIndex + i;
|
|
|
|
-
|
|
|
|
- if (activeTextures[resourceindex] != nullptr)
|
|
|
|
- activeTextures[resourceindex]->release();
|
|
|
|
|
|
+ GLuint gltex = (GLuint) texture->getHandle();
|
|
|
|
|
|
- activeTextures[resourceindex] = tex;
|
|
|
|
|
|
+ int bindingindex = info->ints[i];
|
|
|
|
+ auto &binding = storageTextureBindings[bindingindex];
|
|
|
|
|
|
- if (isstoragetex)
|
|
|
|
|
|
+ if (isdefault && (info->access & ACCESS_WRITE) != 0)
|
|
{
|
|
{
|
|
- GLuint gltex = (GLuint) tex->getHandle();
|
|
|
|
-
|
|
|
|
- int bindingindex = info->ints[i];
|
|
|
|
- auto &binding = storageTextureBindings[bindingindex];
|
|
|
|
-
|
|
|
|
- if (isdefault && (info->access & ACCESS_WRITE) != 0)
|
|
|
|
- {
|
|
|
|
- binding.texture = nullptr;
|
|
|
|
- binding.gltexture = 0;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- binding.texture = tex;
|
|
|
|
- binding.gltexture = gltex;
|
|
|
|
-
|
|
|
|
- if (shaderactive)
|
|
|
|
- glBindImageTexture(bindingindex, binding.gltexture, 0, GL_TRUE, 0, binding.access, binding.internalFormat);
|
|
|
|
- }
|
|
|
|
|
|
+ binding.texture = nullptr;
|
|
|
|
+ binding.gltexture = 0;
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- GLuint gltex = (GLuint) tex->getHandle();
|
|
|
|
-
|
|
|
|
- int texunit = info->ints[i];
|
|
|
|
|
|
+ binding.texture = texture;
|
|
|
|
+ binding.gltexture = gltex;
|
|
|
|
|
|
if (shaderactive)
|
|
if (shaderactive)
|
|
- gl.bindTextureToUnit(info->textureType, gltex, texunit, false, false);
|
|
|
|
-
|
|
|
|
- // Store texture id so it can be re-bound to the texture unit later.
|
|
|
|
- textureUnits[texunit].texture = gltex;
|
|
|
|
|
|
+ glBindImageTexture(bindingindex, binding.gltexture, 0, GL_TRUE, 0, binding.access, binding.internalFormat);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ GLuint gltex = (GLuint) texture->getHandle();
|
|
|
|
|
|
-void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count)
|
|
|
|
-{
|
|
|
|
- Shader::sendBuffers(info, buffers, count, false);
|
|
|
|
-}
|
|
|
|
|
|
+ int texunit = info->ints[i];
|
|
|
|
|
|
-void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count, bool internalUpdate)
|
|
|
|
-{
|
|
|
|
- bool texelbinding = info->baseType == UNIFORM_TEXELBUFFER;
|
|
|
|
- bool storagebinding = info->baseType == UNIFORM_STORAGEBUFFER;
|
|
|
|
|
|
+ if (shaderactive)
|
|
|
|
+ gl.bindTextureToUnit(info->textureType, gltex, texunit, false, false);
|
|
|
|
|
|
- if (!texelbinding && !storagebinding)
|
|
|
|
- return;
|
|
|
|
|
|
+ // Store texture id so it can be re-bound to the texture unit later.
|
|
|
|
+ textureUnits[texunit].texture = gltex;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
|
|
+void Shader::applyBuffer(const UniformInfo *info, int i, love::graphics::Buffer *buffer, UniformType basetype, bool isdefault)
|
|
|
|
+{
|
|
bool shaderactive = current == this;
|
|
bool shaderactive = current == this;
|
|
|
|
|
|
- if (!internalUpdate && shaderactive)
|
|
|
|
- flushBatchedDraws();
|
|
|
|
-
|
|
|
|
- count = std::min(count, info->count);
|
|
|
|
-
|
|
|
|
- for (int i = 0; i < count; i++)
|
|
|
|
|
|
+ if (basetype == UNIFORM_TEXELBUFFER)
|
|
{
|
|
{
|
|
- love::graphics::Buffer *buffer = buffers[i];
|
|
|
|
- bool isdefault = buffer == nullptr;
|
|
|
|
|
|
+ GLuint gltex = (GLuint) buffer->getTexelBufferHandle();
|
|
|
|
+ int texunit = info->ints[i];
|
|
|
|
|
|
- if (buffer != nullptr)
|
|
|
|
- {
|
|
|
|
- if (!validateBuffer(info, buffer, internalUpdate))
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- auto gfx = Module::getInstance<love::graphics::Graphics>(Module::M_GRAPHICS);
|
|
|
|
- if (texelbinding)
|
|
|
|
- buffer = gfx->getDefaultTexelBuffer(info->dataBaseType);
|
|
|
|
- else
|
|
|
|
- buffer = gfx->getDefaultStorageBuffer();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- buffer->retain();
|
|
|
|
-
|
|
|
|
- int resourceindex = info->resourceIndex + i;
|
|
|
|
-
|
|
|
|
- if (activeBuffers[resourceindex] != nullptr)
|
|
|
|
- activeBuffers[resourceindex]->release();
|
|
|
|
-
|
|
|
|
- activeBuffers[resourceindex] = buffer;
|
|
|
|
-
|
|
|
|
- if (texelbinding)
|
|
|
|
- {
|
|
|
|
- GLuint gltex = (GLuint) buffer->getTexelBufferHandle();
|
|
|
|
- int texunit = info->ints[i];
|
|
|
|
-
|
|
|
|
- if (shaderactive)
|
|
|
|
- gl.bindBufferTextureToUnit(gltex, texunit, false, false);
|
|
|
|
|
|
+ if (shaderactive)
|
|
|
|
+ gl.bindBufferTextureToUnit(gltex, texunit, false, false);
|
|
|
|
|
|
- // Store texture id so it can be re-bound to the texture unit later.
|
|
|
|
- textureUnits[texunit].texture = gltex;
|
|
|
|
- }
|
|
|
|
- else if (storagebinding)
|
|
|
|
- {
|
|
|
|
- GLuint glbuffer = (GLuint)buffer->getHandle();
|
|
|
|
- int bindingindex = info->ints[i];
|
|
|
|
|
|
+ // Store texture id so it can be re-bound to the texture unit later.
|
|
|
|
+ textureUnits[texunit].texture = gltex;
|
|
|
|
+ }
|
|
|
|
+ else if (basetype == UNIFORM_STORAGEBUFFER)
|
|
|
|
+ {
|
|
|
|
+ GLuint glbuffer = (GLuint)buffer->getHandle();
|
|
|
|
+ int bindingindex = info->ints[i];
|
|
|
|
|
|
- if (shaderactive)
|
|
|
|
- gl.bindIndexedBuffer(glbuffer, BUFFERUSAGE_SHADER_STORAGE, bindingindex);
|
|
|
|
|
|
+ if (shaderactive)
|
|
|
|
+ gl.bindIndexedBuffer(glbuffer, BUFFERUSAGE_SHADER_STORAGE, bindingindex);
|
|
|
|
|
|
- auto activeindex = storageBufferBindingIndexToActiveBinding[bindingindex];
|
|
|
|
|
|
+ auto activeindex = storageBufferBindingIndexToActiveBinding[bindingindex];
|
|
|
|
|
|
- if (activeindex.first >= 0)
|
|
|
|
- activeStorageBufferBindings[activeindex.first].buffer = glbuffer;
|
|
|
|
|
|
+ if (activeindex.first >= 0)
|
|
|
|
+ activeStorageBufferBindings[activeindex.first].buffer = glbuffer;
|
|
|
|
|
|
- if (activeindex.second >= 0)
|
|
|
|
- activeWritableStorageBuffers[activeindex.second] = isdefault ? nullptr : buffer;
|
|
|
|
- }
|
|
|
|
|
|
+ if (activeindex.second >= 0)
|
|
|
|
+ activeWritableStorageBuffers[activeindex.second] = isdefault ? nullptr : buffer;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void Shader::flushBatchedDraws() const
|
|
|
|
-{
|
|
|
|
- if (current == this)
|
|
|
|
- Graphics::flushBatchedDrawsGlobal();
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
ptrdiff_t Shader::getHandle() const
|
|
ptrdiff_t Shader::getHandle() const
|
|
{
|
|
{
|
|
return program;
|
|
return program;
|
|
@@ -736,25 +642,6 @@ int Shader::getVertexAttributeIndex(const std::string &name)
|
|
return location;
|
|
return location;
|
|
}
|
|
}
|
|
|
|
|
|
-void Shader::setVideoTextures(love::graphics::Texture *ytexture, love::graphics::Texture *cbtexture, love::graphics::Texture *crtexture)
|
|
|
|
-{
|
|
|
|
- const BuiltinUniform builtins[3] = {
|
|
|
|
- BUILTIN_TEXTURE_VIDEO_Y,
|
|
|
|
- BUILTIN_TEXTURE_VIDEO_CB,
|
|
|
|
- BUILTIN_TEXTURE_VIDEO_CR,
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- love::graphics::Texture *textures[3] = {ytexture, cbtexture, crtexture};
|
|
|
|
-
|
|
|
|
- for (int i = 0; i < 3; i++)
|
|
|
|
- {
|
|
|
|
- const UniformInfo *info = builtinUniformInfo[builtins[i]];
|
|
|
|
-
|
|
|
|
- if (info != nullptr)
|
|
|
|
- sendTextures(info, &textures[i], 1, true);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
void Shader::updateBuiltinUniforms(love::graphics::Graphics *gfx, int viewportW, int viewportH)
|
|
void Shader::updateBuiltinUniforms(love::graphics::Graphics *gfx, int viewportW, int viewportH)
|
|
{
|
|
{
|
|
if (current != this)
|
|
if (current != this)
|