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:
committed by
Mathias Agopian
parent
e2c5bb025b
commit
7ed073ec3f
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user