metal: fix Shader:send with matrices and arrays.

This commit is contained in:
Alex Szpakowski
2022-01-05 20:33:08 -04:00
parent 5864d83c31
commit 674143175f
+41 -9
View File
@@ -430,14 +430,14 @@ void Shader::buildLocalUniforms(const spirv_cross::CompilerMSL &msl, const spirv
u.matrix.rows = membertype.vecsize;
u.matrix.columns = membertype.columns;
}
if (validationReflection.localUniforms.find(u.name) != validationReflection.localUniforms.end())
const auto &reflectionit = validationReflection.localUniforms.find(u.name);
if (reflectionit != validationReflection.localUniforms.end())
{
const auto &ru = validationReflection.localUniforms.find(u.name);
const auto &values = ru->second.initializerValues;
const auto &localuniform = reflectionit->second;
const auto &values = localuniform.initializerValues;
if (!values.empty())
{
memcpy(u.data, values.data(), std::min(u.dataSize, values.size() * sizeof(LocalUniformValue)));
}
}
uniforms[u.name] = u;
@@ -894,15 +894,47 @@ const Shader::UniformInfo *Shader::getUniformInfo(BuiltinUniform builtin) const
return builtinUniformInfo[(int)builtin];
}
void Shader::updateUniform(const UniformInfo *info, int /*count*/)
void Shader::updateUniform(const UniformInfo *info, int count)
{
if (current == this)
Graphics::flushBatchedDrawsGlobal();
// Staging -> uniform buffer data copy needed for batch flushing to work.
// TODO: account for padding with 3x3 matrices etc.
count = std::min(count, info->count);
// TODO: store some of this in UniformInfo.
size_t elementsize = info->components * 4;
if (info->baseType == UNIFORM_MATRIX)
elementsize = info->matrix.columns * info->matrix.rows * 4;
size_t offset = (const uint8 *)info->data - localUniformStagingData;
memcpy(localUniformBufferData + offset, info->data, info->dataSize);
// Assuming std140 packing rules, the source data can only be direct-copied
// to the uniform buffer in certain cases because it's tightly packed whereas
// the buffer's data isn't.
if (elementsize * info->count == info->dataSize || (count == 1 && info->baseType != UNIFORM_MATRIX))
{
memcpy(localUniformBufferData + offset, info->data, elementsize * count);
}
else
{
int veccount = count;
int comp = info->components;
if (info->baseType == UNIFORM_MATRIX)
{
veccount *= info->matrix.rows;
comp = info->matrix.columns;
}
const int *src = info->ints;
int *dst = (int *) (localUniformBufferData + offset);
for (int i = 0; i < veccount; i++)
{
for (int c = 0; c < comp; c++)
dst[i * 4 + c] = src[i * comp + c];
}
}
}
void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **textures, int count)