more cleanup: remove unused code, hardcoded types...

- don't use a separate array for "reversedWindingOrder"
  it's just one bit of data and we had 7 bits left in the Visibility structure.

- use Culler::result_type instead of hardcoded value everywhere

- other minor cleanups
This commit is contained in:
Mathias Agopian
2021-08-17 12:18:42 -07:00
committed by Mathias Agopian
parent e2c5bb025b
commit 7ed073ec3f
9 changed files with 42 additions and 40 deletions

View File

@@ -22,8 +22,17 @@
using namespace filament::math;
// We use a vectorize width of 8 because, on ARMv8 it allows the compiler to write eight
// 8-bits results in one go. Without this it has to do 4 separate byte writes, which
// ends-up being slower.
#define FILAMENT_CULLER_VECTORIZE_HINT 8
namespace filament {
static_assert(Culler::MODULO % FILAMENT_CULLER_VECTORIZE_HINT == 0,
"MODULO m=must be a multiple of FILAMENT_CULLER_VECTORIZE_HINT");
void Culler::intersects(
result_type* UTILS_RESTRICT results,
Frustum const& UTILS_RESTRICT frustum,
@@ -32,11 +41,8 @@ void Culler::intersects(
float4 const * const UTILS_RESTRICT planes = frustum.mPlanes;
// we use a vectorize width of 8 because, on ARMv8 it allow the compiler to write 8
// 8-bits results in one go. Without this it has to do 4 separate byte writes, which
// ends-up being slower.
count = round(count); // capacity guaranteed to be multiple of 8
#pragma clang loop vectorize_width(8)
count = round(count);
#pragma clang loop vectorize_width(FILAMENT_CULLER_VECTORIZE_HINT)
for (size_t i = 0; i < count; i++) {
int visible = ~0;
float4 const sphere(b[i]);
@@ -64,11 +70,8 @@ void Culler::intersects(
float4 const * UTILS_RESTRICT const planes = frustum.mPlanes;
// we use a vectorize width of 8 because, on ARMv8 it allows the compiler to write eight
// 8-bits results in one go. Without this it has to do 4 separate byte writes, which
// ends-up being slower.
count = round(count); // capacity guaranteed to be multiple of 8
#pragma clang loop vectorize_width(8)
count = round(count);
#pragma clang loop vectorize_width(FILAMENT_CULLER_VECTORIZE_HINT)
for (size_t i = 0; i < count; i++) {
int visible = ~0;

View File

@@ -37,14 +37,11 @@ namespace filament {
class Culler {
public:
// Culler can only process buffers with a size multiple of MODULO
static constexpr size_t MODULO = 8;
static constexpr size_t MODULO = 8u;
static inline size_t round(size_t count) noexcept {
return (count + (MODULO - 1)) & ~(MODULO - 1);
}
// A good loop value to use to amortize the loop overhead
static constexpr size_t MIN_LOOP_COUNT_HINT = 8;
using result_type = uint8_t;
/*

View File

@@ -275,7 +275,6 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags,
const bool depthFilterAlphaMaskedObjects = bool(extraFlags & CommandTypeFlags::DEPTH_FILTER_ALPHA_MASKED_OBJECTS);
auto const* const UTILS_RESTRICT soaWorldAABBCenter = soa.data<FScene::WORLD_AABB_CENTER>();
auto const* const UTILS_RESTRICT soaReversedWinding = soa.data<FScene::REVERSED_WINDING_ORDER>();
auto const* const UTILS_RESTRICT soaVisibility = soa.data<FScene::VISIBILITY_STATE>();
auto const* const UTILS_RESTRICT soaPrimitives = soa.data<FScene::PRIMITIVES>();
auto const* const UTILS_RESTRICT soaVisibilityMask = soa.data<FScene::VISIBLE_MASK>();
@@ -347,7 +346,7 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags,
const uint32_t distanceBits = reinterpret_cast<uint32_t&>(distance);
// calculate the per-primitive face winding order inversion
const bool inverseFrontFaces = viewInverseFrontFaces ^ soaReversedWinding[i];
const bool inverseFrontFaces = viewInverseFrontFaces ^ soaVisibility[i].reversedWindingOrder;
cmdColor.key = makeField(soaVisibility[i].priority, PRIORITY_MASK, PRIORITY_SHIFT);
cmdColor.primitive.index = (uint16_t)i;

View File

@@ -121,6 +121,7 @@ void FScene::prepare(const mat4& worldOriginTransform, bool shadowReceiversAreCa
const Box worldAABB = rigidTransform(rcm.getAABB(ri), worldTransform);
auto visibility = rcm.getVisibility(ri);
visibility.reversedWindingOrder = reversedWindingOrder;
if (shadowReceiversAreCasters && visibility.receiveShadows) {
visibility.castShadows = true;
}
@@ -135,7 +136,6 @@ void FScene::prepare(const mat4& worldOriginTransform, bool shadowReceiversAreCa
sceneData.push_back_unsafe(
ri, // RENDERABLE_INSTANCE
worldTransform, // WORLD_TRANSFORM
reversedWindingOrder, // REVERSED_WINDING_ORDER
visibility, // VISIBILITY_STATE
rcm.getSkinningBufferInfo(ri), // SKINNING_BUFFER
worldAABB.center, // WORLD_AABB_CENTER
@@ -207,6 +207,7 @@ void FScene::updateUBOs(utils::Range<uint32_t> visibleRenderables, backend::Hand
auto& sceneData = mRenderableData;
for (uint32_t i : visibleRenderables) {
mat4f const& model = sceneData.elementAt<WORLD_TRANSFORM>(i);
FRenderableManager::Visibility visibility = sceneData.elementAt<VISIBILITY_STATE>(i);
const size_t offset = i * sizeof(PerRenderableUib);
UniformBuffer::setUniform(buffer,
@@ -229,7 +230,7 @@ void FScene::updateUBOs(utils::Range<uint32_t> visibleRenderables, backend::Hand
// The shading normal must be flipped for mirror transformations.
// Basically we're shading the other side of the polygon and therefore need to negate the
// normal, similar to what we already do to support double-sided lighting.
if (sceneData.elementAt<REVERSED_WINDING_ORDER>(i)) {
if (visibility.reversedWindingOrder) {
m = -m;
}
@@ -239,7 +240,6 @@ void FScene::updateUBOs(utils::Range<uint32_t> visibleRenderables, backend::Hand
// Note that we cast bool to uint32_t. Booleans are byte-sized in C++, but we need to
// initialize all 32 bits in the UBO field.
FRenderableManager::Visibility visibility = sceneData.elementAt<VISIBILITY_STATE>(i);
hasContactShadows = hasContactShadows || visibility.screenSpaceContactShadows;
UniformBuffer::setUniform(buffer,

View File

@@ -196,7 +196,7 @@ bool FView::isSkyboxVisible() const noexcept {
return skybox != nullptr && (skybox->getLayerMask() & mVisibleLayers);
}
void FView::prepareShadowing(FEngine& engine, backend::DriverApi& driver,
void FView::prepareShadowing(FEngine& engine, DriverApi& driver,
FScene::RenderableSoa& renderableData, FScene::LightSoa& lightData) noexcept {
SYSTRACE_CALL();
@@ -320,7 +320,7 @@ void FView::prepareLighting(FEngine& engine, FEngine::DriverApi& driver, ArenaSc
mHasDirectionalLight = directionalLight.isValid();
}
void FView::prepare(FEngine& engine, backend::DriverApi& driver, ArenaScope& arena,
void FView::prepare(FEngine& engine, DriverApi& driver, ArenaScope& arena,
filament::Viewport const& viewport, float4 const& userTime) noexcept {
JobSystem& js = engine.getJobSystem();
@@ -436,7 +436,7 @@ void FView::prepare(FEngine& engine, backend::DriverApi& driver, ArenaScope& are
uint8_t const* layers = renderableData.data<FScene::LAYERS>();
auto const* visibility = renderableData.data<FScene::VISIBILITY_STATE>();
computeVisibilityMasks(getVisibleLayers(), layers, visibility, cullingMask.begin(),
renderableData.size(), hasVsm());
renderableData.size());
auto const beginRenderables = renderableData.begin();
auto beginCasters = partition(beginRenderables, renderableData.end(), VISIBLE_RENDERABLE);
@@ -466,7 +466,7 @@ void FView::prepare(FEngine& engine, backend::DriverApi& driver, ArenaScope& are
mRenderableUBOSize = uint32_t(count * sizeof(PerRenderableUib));
driver.destroyBufferObject(mRenderableUbh);
mRenderableUbh = driver.createBufferObject(mRenderableUBOSize,
BufferObjectBinding::UNIFORM, backend::BufferUsage::STREAM);
BufferObjectBinding::UNIFORM, BufferUsage::STREAM);
} else {
// TODO: should we shrink the underlying UBO at some point?
}
@@ -498,7 +498,7 @@ void FView::computeVisibilityMasks(
uint8_t visibleLayers,
uint8_t const* UTILS_RESTRICT layers,
FRenderableManager::Visibility const* UTILS_RESTRICT visibility,
uint8_t* UTILS_RESTRICT visibleMask, size_t count, bool hasVsm) {
Culler::result_type* UTILS_RESTRICT visibleMask, size_t count) {
// __restrict__ seems to only be taken into account as function parameters. This is very
// important here, otherwise, this loop doesn't get vectorized.
// This is vectorized 16x.
@@ -565,16 +565,16 @@ void FView::prepareSSAO(Handle<HwTexture> ssao) const noexcept {
mPerViewUniforms.prepareSSAO(ssao, mAmbientOcclusionOptions);
}
void FView::prepareSSR(backend::Handle<backend::HwTexture> ssr, float refractionLodOffset) const noexcept {
void FView::prepareSSR(Handle<HwTexture> ssr, float refractionLodOffset) const noexcept {
mPerViewUniforms.prepareSSR(ssr, refractionLodOffset);
}
void FView::prepareStructure(backend::Handle<backend::HwTexture> structure) const noexcept {
void FView::prepareStructure(Handle<HwTexture> structure) const noexcept {
// sampler must be NEAREST
mPerViewUniforms.prepareStructure(structure);
}
void FView::prepareShadow(backend::Handle<backend::HwTexture> texture) const noexcept {
void FView::prepareShadow(Handle<HwTexture> texture) const noexcept {
if (hasVsm()) {
mPerViewUniforms.prepareShadowVSM(texture, mVsmShadowOptions);
} else {
@@ -597,14 +597,14 @@ void FView::froxelize(FEngine& engine) const noexcept {
mFroxelizer.froxelizeLights(engine, mViewingCameraInfo, mScene->getLightData());
}
void FView::commitUniforms(backend::DriverApi& driver) const noexcept {
void FView::commitUniforms(DriverApi& driver) const noexcept {
mPerViewUniforms.commit(driver);
if (mShadowUb.isDirty()) {
driver.updateBufferObject(mShadowUbh, mShadowUb.toBufferDescriptor(driver), 0);
}
}
void FView::commitFroxels(backend::DriverApi& driverApi) const noexcept {
void FView::commitFroxels(DriverApi& driverApi) const noexcept {
if (mHasDynamicLighting) {
mFroxelizer.commit(driverApi);
}

View File

@@ -57,6 +57,7 @@ public:
bool skinning : 1;
bool morphing : 1;
bool screenSpaceContactShadows : 1;
bool reversedWindingOrder : 1;
};
static_assert(sizeof(Visibility) == sizeof(uint16_t), "Visibility should be 16 bits");

View File

@@ -103,7 +103,6 @@ public:
enum {
RENDERABLE_INSTANCE, // 4 | instance of the Renderable component
WORLD_TRANSFORM, // 16 | instance of the Transform component
REVERSED_WINDING_ORDER, // 1 | det(WORLD_TRANSFORM)<0
VISIBILITY_STATE, // 1 | visibility data of the component
SKINNING_BUFFER, // 8 | bones uniform buffer handle, count, offset
WORLD_AABB_CENTER, // 12 | world-space bounding box center of the renderable
@@ -126,7 +125,6 @@ public:
using RenderableSoa = utils::StructureOfArrays<
utils::EntityInstance<RenderableManager>, // RENDERABLE_INSTANCE
math::mat4f, // WORLD_TRANSFORM
bool, // REVERSED_WINDING_ORDER
FRenderableManager::Visibility, // VISIBILITY_STATE
FRenderableManager::SkinningBindingInfo, // SKINNING_BUFFER
math::float3, // WORLD_AABB_CENTER

View File

@@ -88,19 +88,19 @@ static constexpr size_t VISIBLE_RENDERABLE_BIT = 0u;
static constexpr size_t VISIBLE_DIR_SHADOW_RENDERABLE_BIT = 1u;
static constexpr size_t VISIBLE_SPOT_SHADOW_RENDERABLE_N_BIT(size_t n) { return n + 2; }
static constexpr uint8_t VISIBLE_RENDERABLE = 1u << VISIBLE_RENDERABLE_BIT;
static constexpr uint8_t VISIBLE_DIR_SHADOW_RENDERABLE = 1u << VISIBLE_DIR_SHADOW_RENDERABLE_BIT;
static constexpr uint8_t VISIBLE_SPOT_SHADOW_RENDERABLE_N(size_t n) {
static constexpr Culler::result_type VISIBLE_RENDERABLE = 1u << VISIBLE_RENDERABLE_BIT;
static constexpr Culler::result_type VISIBLE_DIR_SHADOW_RENDERABLE = 1u << VISIBLE_DIR_SHADOW_RENDERABLE_BIT;
static constexpr Culler::result_type VISIBLE_SPOT_SHADOW_RENDERABLE_N(size_t n) {
return 1u << VISIBLE_SPOT_SHADOW_RENDERABLE_N_BIT(n);
}
// ORing of all the VISIBLE_SPOT_SHADOW_RENDERABLE bits
static constexpr uint8_t VISIBLE_SPOT_SHADOW_RENDERABLE =
(0xFFu >> (sizeof(uint8_t) * 8u - CONFIG_MAX_SHADOW_CASTING_SPOTS)) << 2u;
static constexpr Culler::result_type VISIBLE_SPOT_SHADOW_RENDERABLE =
(0xFFu >> (sizeof(Culler::result_type) * 8u - CONFIG_MAX_SHADOW_CASTING_SPOTS)) << 2u;
// Because we're using a uint8_t for the visibility mask, we're limited to 6 spot light shadows.
// (2 of the bits are used for visible renderables + directional light shadow casters).
static_assert(CONFIG_MAX_SHADOW_CASTING_SPOTS <= 6,
static_assert(CONFIG_MAX_SHADOW_CASTING_SPOTS <= sizeof(Culler::result_type) * 8 - 2,
"CONFIG_MAX_SHADOW_CASTING_SPOTS cannot be higher than 6.");
// ------------------------------------------------------------------------------------------------
@@ -441,8 +441,9 @@ private:
static void computeVisibilityMasks(
uint8_t visibleLayers, uint8_t const* layers,
FRenderableManager::Visibility const* visibility, uint8_t* visibleMask,
size_t count, bool hasVsm);
FRenderableManager::Visibility const* visibility,
Culler::result_type* visibleMask,
size_t count);
void bindPerViewUniformsAndSamplers(FEngine::DriverApi& driver) const noexcept {
mPerViewUniforms.bind(driver);

View File

@@ -19,6 +19,7 @@
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/memalign.h>
#include <utils/Mutex.h>
#include <utils/SpinLock.h>
@@ -793,7 +794,9 @@ public:
explicit STLAllocator(STLAllocator<U, ARENA> const& rhs) : mArena(rhs.mArena) { }
TYPE* allocate(std::size_t n) {
return static_cast<TYPE *>(mArena.alloc(n * sizeof(TYPE), alignof(TYPE)));
auto p = static_cast<TYPE *>(mArena.alloc(n * sizeof(TYPE), alignof(TYPE)));
assert_invariant(p);
return p;
}
void deallocate(TYPE* p, std::size_t n) {