Skip to content

Commit

Permalink
Factor out common computations from IsTooSmall into BoxTestSetup
Browse files Browse the repository at this point in the history
  • Loading branch information
rygorous committed Feb 24, 2013
1 parent 5334623 commit 2411249
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 40 deletions.
5 changes: 4 additions & 1 deletion SoftwareOcclusionCulling/AABBoxRasterizerSSE.cpp
Expand Up @@ -186,6 +186,9 @@ void AABBoxRasterizerSSE::Render(CPUTAssetSet **pAssetSet,
{
int count = 0;

BoxTestSetup setup;
setup.Init(mViewMatrix, mProjMatrix, mpCamera, mOccludeeSizeThreshold);

for(UINT assetId = 0, modelId = 0; assetId < numAssetSets; assetId++)
{
for(UINT nodeId = 0; nodeId < pAssetSet[assetId]->GetAssetCount(); nodeId++)
Expand All @@ -195,7 +198,7 @@ void AABBoxRasterizerSSE::Render(CPUTAssetSet **pAssetSet,
ASSERT((CPUT_SUCCESS == result), _L ("Failed getting asset by index"));
if(pRenderNode->IsModel())
{
if(!mpTransformedAABBox[modelId].IsTooSmall(mViewMatrix, mProjMatrix, mpCamera))
if(!mpTransformedAABBox[modelId].IsTooSmall(setup))
{
CPUTModelDX11* model = (CPUTModelDX11*)pRenderNode;
model = (CPUTModelDX11*)pRenderNode;
Expand Down
8 changes: 1 addition & 7 deletions SoftwareOcclusionCulling/AABBoxRasterizerSSE.h
Expand Up @@ -47,13 +47,7 @@ class AABBoxRasterizerSSE : public AABBoxRasterizer
void SetViewProjMatrix(float4x4 *viewMatrix, float4x4 *projMatrix);
inline void SetCPURenderTargetPixels(UINT *pRenderTargetPixels){mpRenderTargetPixels = pRenderTargetPixels;}
inline void SetDepthTestTasks(UINT numTasks) {mNumDepthTestTasks = numTasks;}
inline void SetOccludeeSizeThreshold(float occludeeSizeThreshold)
{
for(UINT i = 0; i < mNumModels; i++)
{
mpTransformedAABBox[i].SetOccludeeSizeThreshold(occludeeSizeThreshold);
}
}
inline void SetOccludeeSizeThreshold(float occludeeSizeThreshold) {mOccludeeSizeThreshold = occludeeSizeThreshold;}
inline void SetCamera(CPUTCamera *pCamera) {mpCamera = pCamera;}

inline UINT GetNumOccludees() {return mNumModels;}
Expand Down
5 changes: 4 additions & 1 deletion SoftwareOcclusionCulling/AABBoxRasterizerSSEMT.cpp
Expand Up @@ -90,6 +90,9 @@ void AABBoxRasterizerSSEMT::TransformAABBoxAndDepthTest()
//--------------------------------------------------------------------------------
void AABBoxRasterizerSSEMT::TransformAABBoxAndDepthTest(UINT taskId)
{
BoxTestSetup setup;
setup.Init(mViewMatrix, mProjMatrix, mpCamera, mOccludeeSizeThreshold);

static const UINT kChunkSize = 64;
for(UINT base = taskId*kChunkSize; base < mNumModels; base += mNumDepthTestTasks * kChunkSize)
{
Expand All @@ -98,7 +101,7 @@ void AABBoxRasterizerSSEMT::TransformAABBoxAndDepthTest(UINT taskId)
{
mpVisible[i] = false;

if(mpBBoxVisible[i] && !mpTransformedAABBox[i].IsTooSmall(mViewMatrix, mProjMatrix, mpCamera))
if(mpBBoxVisible[i] && !mpTransformedAABBox[i].IsTooSmall(setup))
{
if(mpTransformedAABBox[i].TransformAABBox())
mpVisible[i] = mpTransformedAABBox[i].RasterizeAndDepthTestAABBox(mpRenderTargetPixels);
Expand Down
5 changes: 4 additions & 1 deletion SoftwareOcclusionCulling/AABBoxRasterizerSSEST.cpp
Expand Up @@ -47,11 +47,14 @@ void AABBoxRasterizerSSEST::TransformAABBoxAndDepthTest()
{
mDepthTestTimer.StartTimer();

BoxTestSetup setup;
setup.Init(mViewMatrix, mProjMatrix, mpCamera, mOccludeeSizeThreshold);

for(UINT i = 0; i < mNumModels; i++)
{
mpVisible[i] = false;

if(mpBBoxVisible[i] && !mpTransformedAABBox[i].IsTooSmall(mViewMatrix, mProjMatrix, mpCamera))
if(mpBBoxVisible[i] && !mpTransformedAABBox[i].IsTooSmall(setup))
{
if(mpTransformedAABBox[i].TransformAABBox())
mpVisible[i] = mpTransformedAABBox[i].RasterizeAndDepthTestAABBox(mpRenderTargetPixels);
Expand Down
49 changes: 25 additions & 24 deletions SoftwareOcclusionCulling/TransformedAABBoxSSE.cpp
Expand Up @@ -44,28 +44,36 @@ static const UINT sBBIndexList[AABB_INDICES] =
1, 6, 0,
};

void BoxTestSetup::Init(const __m128 viewMatrix[4], const __m128 projMatrix[4], CPUTCamera *pCamera, float occludeeSizeThreshold)
{
__m128 viewPortMatrix[4];
viewPortMatrix[0] = _mm_loadu_ps((float*)&viewportMatrix.r0);
viewPortMatrix[1] = _mm_loadu_ps((float*)&viewportMatrix.r1);
viewPortMatrix[2] = _mm_loadu_ps((float*)&viewportMatrix.r2);
viewPortMatrix[3] = _mm_loadu_ps((float*)&viewportMatrix.r3);

MatrixMultiply(viewMatrix, projMatrix, mViewProjViewport);
MatrixMultiply(mViewProjViewport, viewPortMatrix, mViewProjViewport);

float fov = pCamera->GetFov();
float tanOfHalfFov = tanf(fov * 0.5f);
radiusThreshold = occludeeSizeThreshold * occludeeSizeThreshold * tanOfHalfFov;
}

TransformedAABBoxSSE::TransformedAABBoxSSE()
: mpCPUTModel(NULL),
mOccludeeSizeThreshold(0.0f)
: mpCPUTModel(NULL)
{
mWorldMatrix = (__m128*)_aligned_malloc(sizeof(float) * 4 * 4, 16);
mpBBVertexList = (__m128*)_aligned_malloc(sizeof(float) * 4 * AABB_VERTICES, 16);
mpXformedPos = (__m128*)_aligned_malloc(sizeof(float) * 4 * AABB_VERTICES, 16);
mViewPortMatrix = (__m128*)_aligned_malloc(sizeof(float) * 4 * 4, 16);
mCumulativeMatrix = (__m128*)_aligned_malloc(sizeof(float) * 4 * 4, 16);

mViewPortMatrix[0] = _mm_loadu_ps((float*)&viewportMatrix.r0);
mViewPortMatrix[1] = _mm_loadu_ps((float*)&viewportMatrix.r1);
mViewPortMatrix[2] = _mm_loadu_ps((float*)&viewportMatrix.r2);
mViewPortMatrix[3] = _mm_loadu_ps((float*)&viewportMatrix.r3);
}

TransformedAABBoxSSE::~TransformedAABBoxSSE()
{
_aligned_free(mWorldMatrix);
_aligned_free(mpBBVertexList);
_aligned_free(mpXformedPos);
_aligned_free(mViewPortMatrix);
_aligned_free(mCumulativeMatrix);
}

Expand All @@ -83,10 +91,12 @@ void TransformedAABBoxSSE::CreateAABBVertexIndexList(CPUTModelDX11 *pModel)
mWorldMatrix[2] = _mm_loadu_ps(world + 8);
mWorldMatrix[3] = _mm_loadu_ps(world + 12);

pModel->GetBoundsObjectSpace(&mBBCenter, &mBBHalf);
float3 bbHalf;
pModel->GetBoundsObjectSpace(&mBBCenter, &bbHalf);
mRadiusSq = bbHalf.lengthSq();

float3 min = mBBCenter - mBBHalf;
float3 max = mBBCenter + mBBHalf;
float3 min = mBBCenter - bbHalf;
float3 max = mBBCenter + bbHalf;

//Top 4 vertices in BB
mpBBVertexList[0] = _mm_set_ps(1.0f, max.z, max.y, max.x);
Expand All @@ -103,25 +113,16 @@ void TransformedAABBoxSSE::CreateAABBVertexIndexList(CPUTModelDX11 *pModel)
//----------------------------------------------------------------------------
// Determine if the occluddee size is too small and if so avoid drawing it
//----------------------------------------------------------------------------
bool TransformedAABBoxSSE::IsTooSmall(__m128 *pViewMatrix, __m128 *pProjMatrix, CPUTCamera *pCamera)
bool TransformedAABBoxSSE::IsTooSmall(const BoxTestSetup &setup)
{
float radius = mBBHalf.lengthSq(); // Use length-squared to avoid sqrt(). Relative comparissons hold.
float fov = pCamera->GetFov();
float tanOfHalfFov = tanf(fov * 0.5f);

MatrixMultiply(mWorldMatrix, pViewMatrix, mCumulativeMatrix);
MatrixMultiply(mCumulativeMatrix, pProjMatrix, mCumulativeMatrix);
MatrixMultiply(mCumulativeMatrix, mViewPortMatrix, mCumulativeMatrix);
MatrixMultiply(mWorldMatrix, setup.mViewProjViewport, mCumulativeMatrix);

__m128 center = _mm_set_ps(1.0f, mBBCenter.z, mBBCenter.y, mBBCenter.x);
__m128 mBBCenterOSxForm = TransformCoords(&center, mCumulativeMatrix);
float w = mBBCenterOSxForm.m128_f32[3];
if( w > 1.0f )
{
float radiusDivW = radius / w;
float r2DivW2DivTanFov = radiusDivW / tanOfHalfFov;

return r2DivW2DivTanFov < (mOccludeeSizeThreshold * mOccludeeSizeThreshold) ? true : false;
return mRadiusSq < w * setup.radiusThreshold;
}

return false;
Expand Down
16 changes: 10 additions & 6 deletions SoftwareOcclusionCulling/TransformedAABBoxSSE.h
Expand Up @@ -23,6 +23,14 @@
#include "Constants.h"
#include "HelperSSE.h"

struct BoxTestSetup : public HelperSSE
{
__m128 mViewProjViewport[4];
float radiusThreshold;

void Init(const __m128 viewMatrix[4], const __m128 projMatrix[4], CPUTCamera *pCamera, float occludeeSizeThreshold);
};

class TransformedAABBoxSSE : public HelperSSE
{
public:
Expand All @@ -31,25 +39,21 @@ class TransformedAABBoxSSE : public HelperSSE
void CreateAABBVertexIndexList(CPUTModelDX11 *pModel);
void TransformAABBoxAndDepthTest();

bool IsTooSmall(__m128 *pViewMatrix, __m128 *pProjMatrix, CPUTCamera *pCamera);
bool IsTooSmall(const BoxTestSetup &setup);

bool TransformAABBox();

bool RasterizeAndDepthTestAABBox(UINT *pRenderTargetPixels);

inline void SetOccludeeSizeThreshold(float occludeeSizeThreshold){mOccludeeSizeThreshold = occludeeSizeThreshold;}

private:
CPUTModelDX11 *mpCPUTModel;
__m128 *mWorldMatrix;
__m128 *mpBBVertexList;
__m128 *mpXformedPos;
__m128 *mCumulativeMatrix;
float mOccludeeSizeThreshold;
__m128 *mViewPortMatrix;

float3 mBBCenter;
float3 mBBHalf;
float mRadiusSq;

void Gather(vFloat4 pOut[3], UINT triId);
};
Expand Down

0 comments on commit 2411249

Please sign in to comment.