|
@@ -722,37 +722,8 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex
|
|
|
|
|
|
if (tex != nullptr)
|
|
if (tex != nullptr)
|
|
{
|
|
{
|
|
- const SamplerState &sampler = tex->getSamplerState();
|
|
|
|
- if (!tex->isReadable())
|
|
|
|
- {
|
|
|
|
- if (internalUpdate)
|
|
|
|
- continue;
|
|
|
|
- else
|
|
|
|
- throw love::Exception("Textures with non-readable formats cannot be sampled from in a shader.");
|
|
|
|
- }
|
|
|
|
- else if (info->isDepthSampler != sampler.depthSampleMode.hasValue)
|
|
|
|
- {
|
|
|
|
- if (internalUpdate)
|
|
|
|
- continue;
|
|
|
|
- else if (info->isDepthSampler)
|
|
|
|
- throw love::Exception("Depth comparison samplers in shaders can only be used with depth textures which have depth comparison set.");
|
|
|
|
- else
|
|
|
|
- throw love::Exception("Depth textures which have depth comparison set can only be used with depth/shadow samplers in shaders.");
|
|
|
|
- }
|
|
|
|
- else if (tex->getTextureType() != info->textureType)
|
|
|
|
- {
|
|
|
|
- if (internalUpdate)
|
|
|
|
- continue;
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- const char *textypestr = "unknown";
|
|
|
|
- const char *shadertextypestr = "unknown";
|
|
|
|
- Texture::getConstant(tex->getTextureType(), textypestr);
|
|
|
|
- Texture::getConstant(info->textureType, shadertextypestr);
|
|
|
|
- throw love::Exception("Texture's type (%s) must match the type of %s (%s).", textypestr, info->name.c_str(), shadertextypestr);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ if (!validateTexture(info, tex, internalUpdate))
|
|
|
|
+ continue;
|
|
tex->retain();
|
|
tex->retain();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -782,33 +753,12 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe
|
|
Shader::sendBuffers(info, buffers, count, false);
|
|
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)
|
|
void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count, bool internalUpdate)
|
|
{
|
|
{
|
|
- uint32 requiredtypeflags = 0;
|
|
|
|
-
|
|
|
|
bool texelbinding = info->baseType == UNIFORM_TEXELBUFFER;
|
|
bool texelbinding = info->baseType == UNIFORM_TEXELBUFFER;
|
|
bool storagebinding = info->baseType == UNIFORM_STORAGEBUFFER;
|
|
bool storagebinding = info->baseType == UNIFORM_STORAGEBUFFER;
|
|
|
|
|
|
- if (texelbinding)
|
|
|
|
- requiredtypeflags = BUFFERUSAGEFLAG_TEXEL;
|
|
|
|
- else if (storagebinding)
|
|
|
|
- requiredtypeflags = BUFFERUSAGEFLAG_SHADER_STORAGE;
|
|
|
|
-
|
|
|
|
- if (requiredtypeflags == 0)
|
|
|
|
|
|
+ if (!texelbinding && !storagebinding)
|
|
return;
|
|
return;
|
|
|
|
|
|
bool shaderactive = current == this;
|
|
bool shaderactive = current == this;
|
|
@@ -825,49 +775,8 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe
|
|
|
|
|
|
if (buffer != nullptr)
|
|
if (buffer != nullptr)
|
|
{
|
|
{
|
|
- if ((buffer->getUsageFlags() & requiredtypeflags) == 0)
|
|
|
|
- {
|
|
|
|
- if (internalUpdate)
|
|
|
|
- continue;
|
|
|
|
- else if (texelbinding)
|
|
|
|
- throw love::Exception("Shader uniform '%s' is a texel buffer, but the given Buffer was not created with texel buffer capabilities.", info->name.c_str());
|
|
|
|
- else if (storagebinding)
|
|
|
|
- throw love::Exception("Shader uniform '%s' is a shader storage buffer block, but the given Buffer was not created with shader storage buffer capabilities.", info->name.c_str());
|
|
|
|
- else
|
|
|
|
- throw love::Exception("Shader uniform '%s' does not match the types supported by the given Buffer.", info->name.c_str());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (texelbinding)
|
|
|
|
- {
|
|
|
|
- DataBaseType basetype = buffer->getDataMember(0).info.baseType;
|
|
|
|
- if (!isTexelBufferTypeCompatible(basetype, info->texelBufferType))
|
|
|
|
- {
|
|
|
|
- if (internalUpdate)
|
|
|
|
- continue;
|
|
|
|
- else
|
|
|
|
- throw love::Exception("Texel buffer's data format base type must match the variable declared in the shader.");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else if (storagebinding)
|
|
|
|
- {
|
|
|
|
- if (info->bufferStride != buffer->getArrayStride())
|
|
|
|
- {
|
|
|
|
- if (internalUpdate)
|
|
|
|
- continue;
|
|
|
|
- else
|
|
|
|
- throw love::Exception("Shader storage block '%s' has an array stride of %d bytes, but the given Buffer has an array stride of %d bytes.",
|
|
|
|
- info->name.c_str(), info->bufferStride, buffer->getArrayStride());
|
|
|
|
- }
|
|
|
|
- else if (info->bufferMemberCount != buffer->getDataMembers().size())
|
|
|
|
- {
|
|
|
|
- if (internalUpdate)
|
|
|
|
- continue;
|
|
|
|
- else
|
|
|
|
- throw love::Exception("Shader storage block '%s' has a struct with %d fields, but the given Buffer has a format with %d members.",
|
|
|
|
- info->name.c_str(), info->bufferMemberCount, buffer->getDataMembers().size());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ if (!validateBuffer(info, buffer, internalUpdate))
|
|
|
|
+ continue;
|
|
buffer->retain();
|
|
buffer->retain();
|
|
}
|
|
}
|
|
|
|
|