A morphing buffer must be bound when skinning is active

This is because we're using the same program variant for skinning
and morphing, in the skinning-only case, the buffer won't be accessed
in the shader, but it must be present.

fixes #5085
This commit is contained in:
Mathias Agopian
2022-01-25 12:18:50 -08:00
parent a8006acd33
commit e829d90c4a
8 changed files with 83 additions and 28 deletions

View File

@@ -261,6 +261,20 @@ void FEngine::init() {
.package(MATERIALS_DEFAULTMATERIAL_DATA, MATERIALS_DEFAULTMATERIAL_SIZE)
.build(*const_cast<FEngine*>(this)));
// create dummy textures we need throughout the engine
mDummyOneTexture = driverApi.createTexture(SamplerType::SAMPLER_2D, 1,
TextureFormat::RGBA8, 1, 1, 1, 1, TextureUsage::DEFAULT);
mDummyOneTextureArray = driverApi.createTexture(SamplerType::SAMPLER_2D_ARRAY, 1,
TextureFormat::RGBA8, 1, 1, 1, 1, TextureUsage::DEFAULT);
mDummyZeroTexture = driverApi.createTexture(SamplerType::SAMPLER_2D, 1,
TextureFormat::RGBA8, 1, 1, 1, 1, TextureUsage::DEFAULT);
// dummy textures must be initialized before this call
mDummyMorphingSamplerGroup = FMorphTargetBuffer::createDummySampleGroup(*this);
mPostProcessManager.init();
mLightManager.init(*this);
mDFG = std::make_unique<DFG>(*this);
@@ -344,6 +358,11 @@ void FEngine::shutdown() {
}
cleanupResourceList(mFences);
driver.destroySamplerGroup(mDummyMorphingSamplerGroup);
driver.destroyTexture(mDummyOneTexture);
driver.destroyTexture(mDummyOneTextureArray);
driver.destroyTexture(mDummyZeroTexture);
/*
* Shutdown the backend...
*/

View File

@@ -118,10 +118,19 @@ void FMorphTargetBuffer::terminate(FEngine& engine) {
driver.destroyTexture(mTbHandle);
}
Handle<HwSamplerGroup> FMorphTargetBuffer::createDummySampleGroup(FEngine& engine) noexcept {
DriverApi& driver = engine.getDriverApi();
Handle<HwSamplerGroup> sgh = driver.createSamplerGroup(PerRenderPrimitiveMorphingSib::SAMPLER_COUNT);
backend::SamplerGroup group(PerRenderPrimitiveMorphingSib::SAMPLER_COUNT);
group.setSampler(PerRenderPrimitiveMorphingSib::TARGETS, engine.getOneTextureArray(), {});
driver.updateSamplerGroup(sgh, std::move(group.toCommandStream()));
return sgh;
}
void FMorphTargetBuffer::setPositionsAt(FEngine& engine, size_t targetIndex, math::float3 const* positions, size_t count) {
ASSERT_PRECONDITION(targetIndex < mCount, "targetIndex must be < count");
auto size = getSize(mVertexCount);
const size_t size = getSize(mVertexCount);
ASSERT_PRECONDITION((int)sizeof(math::float3) * count <= size,
"MorphTargetBuffer (size=%lu) overflow (size=%lu)",

View File

@@ -253,15 +253,6 @@ void PostProcessManager::init() noexcept {
registerPostProcessMaterial(info.name, info.data, info.size);
}
mDummyOneTexture = driver.createTexture(SamplerType::SAMPLER_2D, 1,
TextureFormat::RGBA8, 1, 1, 1, 1, TextureUsage::DEFAULT);
mDummyOneTextureArray = driver.createTexture(SamplerType::SAMPLER_2D_ARRAY, 1,
TextureFormat::RGBA8, 1, 1, 1, 1, TextureUsage::DEFAULT);
mDummyZeroTexture = driver.createTexture(SamplerType::SAMPLER_2D, 1,
TextureFormat::RGBA8, 1, 1, 1, 1, TextureUsage::DEFAULT);
mStarburstTexture = driver.createTexture(SamplerType::SAMPLER_2D, 1,
TextureFormat::R8, 1, 256, 1, 1, TextureUsage::DEFAULT);
@@ -277,17 +268,26 @@ void PostProcessManager::init() noexcept {
float r = 0.5f + 0.5f * dist(gen);
return uint8_t(r * 255.0f);
});
driver.update2DImage(mDummyOneTexture, 0, 0, 0, 1, 1, std::move(dataOne));
driver.update3DImage(mDummyOneTextureArray, 0, 0, 0, 0, 1, 1, 1, std::move(dataOneArray));
driver.update2DImage(mDummyZeroTexture, 0, 0, 0, 1, 1, std::move(dataZero));
driver.update2DImage(mStarburstTexture, 0, 0, 0, 256, 1, std::move(dataStarburst));
driver.update2DImage(engine.getOneTexture(),
0, 0, 0, 1, 1,
std::move(dataOne));
driver.update3DImage(engine.getOneTextureArray(),
0, 0, 0, 0, 1, 1, 1,
std::move(dataOneArray));
driver.update2DImage(engine.getZeroTexture(),
0, 0, 0, 1, 1,
std::move(dataZero));
driver.update2DImage(mStarburstTexture,
0, 0, 0, 256, 1,
std::move(dataStarburst));
}
void PostProcessManager::terminate(DriverApi& driver) noexcept {
FEngine& engine = mEngine;
driver.destroyTexture(mDummyOneTexture);
driver.destroyTexture(mDummyOneTextureArray);
driver.destroyTexture(mDummyZeroTexture);
driver.destroyTexture(mStarburstTexture);
auto first = mMaterialRegistry.begin();
auto last = mMaterialRegistry.end();
@@ -297,6 +297,18 @@ void PostProcessManager::terminate(DriverApi& driver) noexcept {
}
}
backend::Handle<backend::HwTexture> PostProcessManager::getOneTexture() const {
return mEngine.getOneTexture();
}
backend::Handle<backend::HwTexture> PostProcessManager::getZeroTexture() const {
return mEngine.getZeroTexture();
}
backend::Handle<backend::HwTexture> PostProcessManager::getOneTextureArray() const {
return mEngine.getOneTextureArray();
}
UTILS_NOINLINE
void PostProcessManager::commitAndRender(FrameGraphResources::RenderPassInfo const& out,
PostProcessMaterial const& material, uint8_t variant, DriverApi& driver) const noexcept {

View File

@@ -156,9 +156,9 @@ public:
FrameGraphId<FrameGraphTexture> output, uint8_t dstLevel, uint8_t layer,
bool reinhard, size_t kernelWidth, float sigma = 6.0f) noexcept;
backend::Handle<backend::HwTexture> getOneTexture() const { return mDummyOneTexture; }
backend::Handle<backend::HwTexture> getZeroTexture() const { return mDummyZeroTexture; }
backend::Handle<backend::HwTexture> getOneTextureArray() const { return mDummyOneTextureArray; }
backend::Handle<backend::HwTexture> getOneTexture() const;
backend::Handle<backend::HwTexture> getZeroTexture() const;
backend::Handle<backend::HwTexture> getOneTextureArray() const;
math::float2 halton(size_t index) const noexcept {
return mHaltonSamples[index & 0xFu];
@@ -234,9 +234,6 @@ private:
void registerPostProcessMaterial(utils::StaticString name, uint8_t const* data, int size);
PostProcessMaterial& getPostProcessMaterial(utils::StaticString name) noexcept;
backend::Handle<backend::HwTexture> mDummyOneTexture;
backend::Handle<backend::HwTexture> mDummyOneTextureArray;
backend::Handle<backend::HwTexture> mDummyZeroTexture;
backend::Handle<backend::HwTexture> mStarburstTexture;
std::uniform_real_distribution<float> mUniformDistribution{0.0f, 1.0f};

View File

@@ -528,12 +528,13 @@ void RenderPass::Executor::execute(const char* name,
engine.flush();
driver.beginRenderPass(renderTarget, params);
recordDriverCommands(driver, mBegin, mEnd, mRenderableSoa);
recordDriverCommands(engine, driver, mBegin, mEnd, mRenderableSoa);
driver.endRenderPass();
}
UTILS_NOINLINE // no need to be inlined
void RenderPass::Executor::recordDriverCommands(backend::DriverApi& driver,
void RenderPass::Executor::recordDriverCommands(FEngine& engine,
backend::DriverApi& driver,
const Command* first, const Command* last,
FScene::RenderableSoa const& soa) const noexcept {
SYSTRACE_CALL();
@@ -589,6 +590,11 @@ void RenderPass::Executor::recordDriverCommands(backend::DriverApi& driver,
skinning.handle,
skinning.offset * sizeof(PerRenderableUibBone),
CONFIG_MAX_BONE_COUNT * sizeof(PerRenderableUibBone));
if (!info.morphTargetBuffer) {
driver.bindSamplers(BindingPoints::PER_RENDERABLE_MORPHING,
engine.getDummyMorphingSamplerGroup());
}
}
if (UTILS_UNLIKELY(info.morphWeightBuffer)) {
@@ -598,7 +604,7 @@ void RenderPass::Executor::recordDriverCommands(backend::DriverApi& driver,
info.morphWeightBuffer);
// When only skinning is enabled, morphTargetBuffer isn't created.
if (UTILS_UNLIKELY(info.morphTargetBuffer)) {
if (info.morphTargetBuffer) {
driver.bindSamplers(BindingPoints::PER_RENDERABLE_MORPHING,
info.morphTargetBuffer);
}

View File

@@ -333,7 +333,7 @@ public:
assert_invariant(e <= pass->end());
}
void recordDriverCommands(backend::DriverApi& driver,
void recordDriverCommands(FEngine& engine, backend::DriverApi& driver,
const Command* first, const Command* last,
FScene::RenderableSoa const& soa) const noexcept;

View File

@@ -332,10 +332,15 @@ public:
return mRandomEngine;
}
void pumpMessageQueues() {
void pumpMessageQueues() const {
getDriver().purge();
}
backend::Handle<backend::HwTexture> getOneTexture() const { return mDummyOneTexture; }
backend::Handle<backend::HwTexture> getZeroTexture() const { return mDummyZeroTexture; }
backend::Handle<backend::HwTexture> getOneTextureArray() const { return mDummyOneTextureArray; }
backend::Handle<backend::HwSamplerGroup> getDummyMorphingSamplerGroup() const { return mDummyMorphingSamplerGroup; }
private:
FEngine(Backend backend, Platform* platform, void* sharedGLContext);
void init();
@@ -424,6 +429,11 @@ private:
mutable filaflat::ShaderBuilder mFragmentShaderBuilder;
FDebugRegistry mDebugRegistry;
backend::Handle<backend::HwTexture> mDummyOneTexture;
backend::Handle<backend::HwTexture> mDummyOneTextureArray;
backend::Handle<backend::HwTexture> mDummyZeroTexture;
backend::Handle<backend::HwSamplerGroup> mDummyMorphingSamplerGroup;
std::thread::id mMainThreadId{};
public:

View File

@@ -48,6 +48,8 @@ public:
inline size_t getVertexCount() const noexcept { return mVertexCount; }
inline size_t getCount() const noexcept { return mCount; }
static backend::Handle<backend::HwSamplerGroup> createDummySampleGroup(FEngine& engine) noexcept;
private:
friend class FView;
friend class RenderPass;