Skip to content

Commit

Permalink
Merge branch 'main' into fix/test-gltfio-cmake-duplicate-libs
Browse files Browse the repository at this point in the history
  • Loading branch information
poweifeng authored Sep 25, 2023
2 parents 9ba0ea7 + 04c8845 commit 3faf5ca
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 57 deletions.
3 changes: 2 additions & 1 deletion filament/backend/src/opengl/OpenGLProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ void OpenGLProgram::updateSamplers(OpenGLDriver* const gld) const noexcept {
auto const& UTILS_RESTRICT usedBindingPoints = mUsedSamplerBindingPoints;

for (uint8_t i = 0, tmu = 0, n = mUsedBindingsCount; i < n; i++) {
auto const binding = usedBindingPoints[i];
size_t const binding = usedBindingPoints[i];
assert_invariant(binding < Program::SAMPLER_BINDING_COUNT);
auto const * const sb = samplerBindings[binding];
assert_invariant(sb);
for (uint8_t j = 0, m = sb->textureUnitEntries.size(); j < m; ++j, ++tmu) { // "<=" on purpose here
Expand Down
11 changes: 6 additions & 5 deletions filament/src/RenderPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -875,14 +875,12 @@ void RenderPass::Executor::execute(backend::DriverApi& driver,
info.skinningHandle,
info.skinningOffset * sizeof(PerRenderableBoneUib::BoneData),
sizeof(PerRenderableBoneUib));
// note: always bind the skinningTexture because the shader needs it.
driver.bindSamplers(+SamplerBindingPoints::PER_RENDERABLE_SKINNING,
info.skinningTexture);
// note: even if only skinning is enabled, binding morphTargetBuffer is needed.
driver.bindSamplers(+SamplerBindingPoints::PER_RENDERABLE_MORPHING,
info.morphTargetBuffer);

if (UTILS_UNLIKELY(info.skinningTexture)) {
driver.bindSamplers(+SamplerBindingPoints::PER_RENDERABLE_SKINNING,
info.skinningTexture);
}
}

if (UTILS_UNLIKELY(info.morphWeightBuffer)) {
Expand All @@ -892,6 +890,9 @@ void RenderPass::Executor::execute(backend::DriverApi& driver,
info.morphWeightBuffer);
driver.bindSamplers(+SamplerBindingPoints::PER_RENDERABLE_MORPHING,
info.morphTargetBuffer);
// note: even if only morphing is enabled, binding skinningTexture is needed.
driver.bindSamplers(+SamplerBindingPoints::PER_RENDERABLE_SKINNING,
info.skinningTexture);
}

driver.draw(pipeline, info.primitiveHandle, instanceCount);
Expand Down
40 changes: 20 additions & 20 deletions filament/src/components/RenderableManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,30 +596,30 @@ void FRenderableManager::create(
}
}

if (UTILS_UNLIKELY(boneCount > 0) && (builder->mBoneIndicesAndWeightsCount > 0)){
// create and set texture for bone indices and weights
Bones& bones = manager[ci].bones;
FSkinningBuffer::HandleIndicesAndWeights handle = downcast(builder->mSkinningBuffer)->
createIndicesAndWeightsHandle(downcast(engine), builder->mBoneIndicesAndWeightsCount);
bones.handleSamplerGroup = handle.sampler;
bones.handleTexture = handle.texture;
downcast(builder->mSkinningBuffer)->
setIndicesAndWeightsData(downcast(engine), handle.texture,
builder->mBoneIndicesAndWeights, builder->mBoneIndicesAndWeightsCount);
}

// Create and initialize all needed MorphTargets.
// It's required to avoid branches in hot loops.
MorphTargets* morphTargets = new MorphTargets[entryCount];
for (size_t i = 0; i < entryCount; ++i) {
morphTargets[i] = { mEngine.getDummyMorphTargetBuffer(), 0, 0 };
}
MorphTargets* const morphTargets = new MorphTargets[entryCount];
std::generate_n(morphTargets, entryCount,
[dummy = mEngine.getDummyMorphTargetBuffer()]() -> MorphTargets {
return { dummy, 0, 0 };
});

mManager[ci].morphTargets = { morphTargets, size_type(entryCount) };

// Even morphing isn't enabled, we should create morphig resources.
// Because morphing shader code is generated when skinning is enabled.
// You can see more detail at Variant::SKINNING_OR_MORPHING.
// Always create skinning and morphing resources if one of them is enabled because
// the shader always handles both. See Variant::SKINNING_OR_MORPHING.
if (UTILS_UNLIKELY(boneCount > 0 || targetCount > 0)) {

auto [sampler, texture] = FSkinningBuffer::createIndicesAndWeightsHandle(
downcast(engine), builder->mBoneIndicesAndWeightsCount);
if (builder->mBoneIndicesAndWeightsCount > 0) {
FSkinningBuffer::setIndicesAndWeightsData(downcast(engine), texture,
builder->mBoneIndicesAndWeights, builder->mBoneIndicesAndWeightsCount);
}
Bones& bones = manager[ci].bones;
bones.handleSamplerGroup = sampler;
bones.handleTexture = texture;

// Instead of using a UBO per primitive, we could also have a single UBO for all primitives
// and use bindUniformBufferRange which might be more efficient.
MorphWeights& morphWeights = manager[ci].morphWeights;
Expand All @@ -643,7 +643,7 @@ void FRenderableManager::create(
// morphWeights uniform array to avoid crash on adreno gpu.
if (UTILS_UNLIKELY(targetCount == 0 &&
driver.isWorkaroundNeeded(Workaround::ADRENO_UNIFORM_ARRAY_CRASH))) {
float initWeights[1] = {0};
float initWeights[1] = { 0 };
setMorphWeights(ci, initWeights, 1, 0);
}
}
Expand Down
60 changes: 31 additions & 29 deletions filament/src/details/SkinningBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,12 @@ void FSkinningBuffer::setBones(FEngine& engine, Handle<backend::HwBufferObject>
constexpr size_t MAX_SKINNING_BUFFER_WIDTH = 2048;

static inline size_t getSkinningBufferWidth(size_t pairCount) noexcept {
return std::min(pairCount, MAX_SKINNING_BUFFER_WIDTH);
return std::clamp(pairCount, size_t(1), MAX_SKINNING_BUFFER_WIDTH);
}

static inline size_t getSkinningBufferHeight(size_t pairCount) noexcept {
return (pairCount + MAX_SKINNING_BUFFER_WIDTH - 1) / MAX_SKINNING_BUFFER_WIDTH;
return std::max(size_t(1),
(pairCount + MAX_SKINNING_BUFFER_WIDTH - 1) / MAX_SKINNING_BUFFER_WIDTH);
}

inline size_t getSkinningBufferSize(size_t pairCount) noexcept {
Expand All @@ -191,62 +192,63 @@ void updateDataAt(backend::DriverApi& driver,
const utils::FixedCapacityVector<math::float2>& pairs,
size_t count) {

size_t elementSize = sizeof(float2);
size_t size = getSkinningBufferSize(count);
auto* out = (float2*) malloc(size);
size_t const elementSize = sizeof(float2);
size_t const size = getSkinningBufferSize(count);
auto* out = (float2*)malloc(size);
std::memcpy(out, pairs.begin(), size);

size_t const textureWidth = getSkinningBufferWidth( count);
size_t const lineCount = count / textureWidth;
size_t const lastLineCount = count % textureWidth;
size_t const textureWidth = getSkinningBufferWidth(count);
size_t const lineCount = count / textureWidth;
size_t const lastLineCount = count % textureWidth;

// 'out' buffer is going to be used up to 2 times, so for simplicity we use a shared_buffer
// to manage its lifetime. One side effect of this is that the callbacks below will allocate
// a small object on the heap. (inspired by MorphTargetBuffered)
std::shared_ptr<void> allocation((void*)out, ::free);
std::shared_ptr<void> const allocation((void*)out, ::free);

if (lineCount) {
// update the full-width lines if any
driver.update3DImage(handle, 0, 0, 0, 0,
textureWidth, lineCount, 1,
PixelBufferDescriptor::make(
out, textureWidth * lineCount * elementSize,
format, type, [allocation](void const*, size_t) {}
));
textureWidth, lineCount, 1,
PixelBufferDescriptor::make(
out, textureWidth * lineCount * elementSize,
format, type, [allocation](void const*, size_t) {}
));
out += lineCount * textureWidth;
}

if (lastLineCount) {
// update the last partial line if any
driver.update3DImage(handle, 0, 0, lineCount, 0,
lastLineCount, 1, 1,
PixelBufferDescriptor::make(
out, lastLineCount * elementSize,
format, type, [allocation](void const*, size_t) {}
));
lastLineCount, 1, 1,
PixelBufferDescriptor::make(
out, lastLineCount * elementSize,
format, type, [allocation](void const*, size_t) {}
));
}
}

FSkinningBuffer::HandleIndicesAndWeights FSkinningBuffer::createIndicesAndWeightsHandle(FEngine& engine, size_t count) {
FSkinningBuffer::HandleIndicesAndWeights FSkinningBuffer::createIndicesAndWeightsHandle(
FEngine& engine, size_t count) {
backend::Handle<backend::HwSamplerGroup> samplerHandle;
backend::Handle<backend::HwTexture> textureHandle;

FEngine::DriverApi& driver = engine.getDriverApi();
// create a texture for skinning pairs data (bone index and weight)
textureHandle = driver.createTexture(SamplerType::SAMPLER_2D, 1,
TextureFormat::RG32F, 1,
getSkinningBufferWidth(count),
getSkinningBufferHeight(count), 1,
TextureUsage::DEFAULT);
TextureFormat::RG32F, 1,
getSkinningBufferWidth(count),
getSkinningBufferHeight(count), 1,
TextureUsage::DEFAULT);
samplerHandle = driver.createSamplerGroup(PerRenderPrimitiveSkinningSib::SAMPLER_COUNT);
SamplerGroup samplerGroup(PerRenderPrimitiveSkinningSib::SAMPLER_COUNT);
samplerGroup.setSampler(PerRenderPrimitiveSkinningSib::BONE_INDICES_AND_WEIGHTS,
{textureHandle, {}});
{ textureHandle, {}});
driver.updateSamplerGroup(samplerHandle,
samplerGroup.toBufferDescriptor(driver));
samplerGroup.toBufferDescriptor(driver));
return {
.sampler = samplerHandle,
.texture = textureHandle
.sampler = samplerHandle,
.texture = textureHandle
};
}

Expand All @@ -257,7 +259,7 @@ void FSkinningBuffer::setIndicesAndWeightsData(FEngine& engine,
FEngine::DriverApi& driver = engine.getDriverApi();
updateDataAt(driver, textureHandle,
Texture::Format::RG, Texture::Type::FLOAT,
pairs, count);
pairs, count);
}

} // namespace filament
Expand Down
4 changes: 2 additions & 2 deletions filament/src/details/SkinningBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ class FSkinningBuffer : public SkinningBuffer {
backend::Handle<backend::HwSamplerGroup> sampler;
backend::Handle<backend::HwTexture> texture;
};
HandleIndicesAndWeights createIndicesAndWeightsHandle(FEngine& engine,
static HandleIndicesAndWeights createIndicesAndWeightsHandle(FEngine& engine,
size_t count);
void setIndicesAndWeightsData(FEngine& engine,
static void setIndicesAndWeightsData(FEngine& engine,
backend::Handle<backend::HwTexture> textureHandle,
const utils::FixedCapacityVector<math::float2>& pairs,
size_t count);
Expand Down

0 comments on commit 3faf5ca

Please sign in to comment.