summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/examples/37-gpudrivenrendering/gpudrivenrendering.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/examples/37-gpudrivenrendering/gpudrivenrendering.cpp')
-rw-r--r--3rdparty/bgfx/examples/37-gpudrivenrendering/gpudrivenrendering.cpp275
1 files changed, 101 insertions, 174 deletions
diff --git a/3rdparty/bgfx/examples/37-gpudrivenrendering/gpudrivenrendering.cpp b/3rdparty/bgfx/examples/37-gpudrivenrendering/gpudrivenrendering.cpp
index 9a3bb3a6b6a..e647a6b8af8 100644
--- a/3rdparty/bgfx/examples/37-gpudrivenrendering/gpudrivenrendering.cpp
+++ b/3rdparty/bgfx/examples/37-gpudrivenrendering/gpudrivenrendering.cpp
@@ -33,19 +33,11 @@ struct Camera
void reset()
{
- m_target.curr[0] = 0.0f;
- m_target.curr[1] = 0.0f;
- m_target.curr[2] = 0.0f;
- m_target.dest[0] = 0.0f;
- m_target.dest[1] = 0.0f;
- m_target.dest[2] = 0.0f;
-
- m_pos.curr[0] = 55.0f;
- m_pos.curr[1] = 20.0f;
- m_pos.curr[2] = 65.0f;
- m_pos.dest[0] = 55.0f;
- m_pos.dest[1] = 20.0f;
- m_pos.dest[2] = 65.0f;
+ m_target.curr = { 0.0f, 0.0f, 0.0f };
+ m_target.dest = { 0.0f, 0.0f, 0.0f };
+
+ m_pos.curr = { 55.0f, 20.0f, 65.0f };
+ m_pos.dest = { 55.0f, 20.0f, 65.0f };
m_orbit[0] = 0.0f;
m_orbit[1] = 0.0f;
@@ -53,7 +45,7 @@ struct Camera
void mtxLookAt(float* _outViewMtx)
{
- bx::mtxLookAt(_outViewMtx, bx::load(m_pos.curr), bx::load(m_target.curr) );
+ bx::mtxLookAt(_outViewMtx, m_pos.curr, m_target.curr);
}
void orbit(float _dx, float _dy)
@@ -65,31 +57,19 @@ struct Camera
void dolly(float _dz)
{
const float cnear = 1.0f;
- const float cfar = 100.0f;
+ const float cfar = 100.0f;
- const float toTarget[3] =
- {
- m_target.dest[0] - m_pos.dest[0],
- m_target.dest[1] - m_pos.dest[1],
- m_target.dest[2] - m_pos.dest[2],
- };
- const float toTargetLen = bx::vec3Length(toTarget);
- const float invToTargetLen = 1.0f / (toTargetLen + FLT_MIN);
- const float toTargetNorm[3] =
- {
- toTarget[0] * invToTargetLen,
- toTarget[1] * invToTargetLen,
- toTarget[2] * invToTargetLen,
- };
+ const bx::Vec3 toTarget = bx::sub(m_target.dest, m_pos.dest);
+ const float toTargetLen = bx::length(toTarget);
+ const float invToTargetLen = 1.0f / (toTargetLen + bx::kFloatMin);
+ const bx::Vec3 toTargetNorm = bx::mul(toTarget, invToTargetLen);
- float delta = toTargetLen*_dz;
+ float delta = toTargetLen * _dz;
float newLen = toTargetLen + delta;
- if ((cnear < newLen || _dz < 0.0f)
- && (newLen < cfar || _dz > 0.0f))
+ if ( (cnear < newLen || _dz < 0.0f)
+ && (newLen < cfar || _dz > 0.0f) )
{
- m_pos.dest[0] += toTargetNorm[0] * delta;
- m_pos.dest[1] += toTargetNorm[1] * delta;
- m_pos.dest[2] += toTargetNorm[2] * delta;
+ m_pos.dest = bx::mad(toTargetNorm, delta, m_pos.dest);
}
}
@@ -101,41 +81,22 @@ struct Camera
m_orbit[0] -= consume[0];
m_orbit[1] -= consume[1];
- const float toPos[3] =
- {
- m_pos.curr[0] - m_target.curr[0],
- m_pos.curr[1] - m_target.curr[1],
- m_pos.curr[2] - m_target.curr[2],
- };
- const float toPosLen = bx::vec3Length(toPos);
- const float invToPosLen = 1.0f / (toPosLen + FLT_MIN);
- const float toPosNorm[3] =
- {
- toPos[0] * invToPosLen,
- toPos[1] * invToPosLen,
- toPos[2] * invToPosLen,
- };
+ const bx::Vec3 toPos = bx::sub(m_pos.curr, m_target.curr);
+ const float toPosLen = bx::length(toPos);
+ const float invToPosLen = 1.0f / (toPosLen + bx::kFloatMin);
+ const bx::Vec3 toPosNorm = bx::mul(toPos, invToPosLen);
float ll[2];
- latLongFromVec(ll[0], ll[1], toPosNorm);
+ bx::toLatLong(&ll[0], &ll[1], toPosNorm);
ll[0] += consume[0];
ll[1] -= consume[1];
- ll[1] = bx::clamp(ll[1], 0.02f, 0.98f);
-
- float tmp[3];
- vecFromLatLong(tmp, ll[0], ll[1]);
-
- float diff[3];
- diff[0] = (tmp[0] - toPosNorm[0])*toPosLen;
- diff[1] = (tmp[1] - toPosNorm[1])*toPosLen;
- diff[2] = (tmp[2] - toPosNorm[2])*toPosLen;
-
- m_pos.curr[0] += diff[0];
- m_pos.curr[1] += diff[1];
- m_pos.curr[2] += diff[2];
- m_pos.dest[0] += diff[0];
- m_pos.dest[1] += diff[1];
- m_pos.dest[2] += diff[2];
+ ll[1] = bx::clamp(ll[1], 0.02f, 0.98f);
+
+ const bx::Vec3 tmp = bx::fromLatLong(ll[0], ll[1]);
+ const bx::Vec3 diff = bx::mul(bx::sub(tmp, toPosNorm), toPosLen);
+
+ m_pos.curr = bx::add(m_pos.curr, diff);
+ m_pos.dest = bx::add(m_pos.dest, diff);
}
void update(float _dt)
@@ -144,54 +105,31 @@ struct Camera
consumeOrbit(amount);
- m_target.curr[0] = bx::lerp(m_target.curr[0], m_target.dest[0], amount);
- m_target.curr[1] = bx::lerp(m_target.curr[1], m_target.dest[1], amount);
- m_target.curr[2] = bx::lerp(m_target.curr[2], m_target.dest[2], amount);
- m_pos.curr[0] = bx::lerp(m_pos.curr[0], m_pos.dest[0], amount);
- m_pos.curr[1] = bx::lerp(m_pos.curr[1], m_pos.dest[1], amount);
- m_pos.curr[2] = bx::lerp(m_pos.curr[2], m_pos.dest[2], amount);
+ m_target.curr = bx::lerp(m_target.curr, m_target.dest, amount);
+ m_pos.curr = bx::lerp(m_pos.curr, m_pos.dest, amount);
}
void envViewMtx(float* _mtx)
{
- const float toTarget[3] =
- {
- m_target.curr[0] - m_pos.curr[0],
- m_target.curr[1] - m_pos.curr[1],
- m_target.curr[2] - m_pos.curr[2],
- };
-
- const float toTargetLen = bx::vec3Length(toTarget);
- const float invToTargetLen = 1.0f / (toTargetLen + FLT_MIN);
- const float toTargetNorm[3] =
- {
- toTarget[0] * invToTargetLen,
- toTarget[1] * invToTargetLen,
- toTarget[2] * invToTargetLen,
- };
-
- float tmp[3];
- const float fakeUp[3] = { 0.0f, 1.0f, 0.0f };
-
- float right[3];
- bx::vec3Cross(tmp, fakeUp, toTargetNorm);
- bx::vec3Norm(right, tmp);
-
- float up[3];
- bx::vec3Cross(tmp, toTargetNorm, right);
- bx::vec3Norm(up, tmp);
-
- _mtx[0] = right[0];
- _mtx[1] = right[1];
- _mtx[2] = right[2];
- _mtx[3] = 0.0f;
- _mtx[4] = up[0];
- _mtx[5] = up[1];
- _mtx[6] = up[2];
- _mtx[7] = 0.0f;
- _mtx[8] = toTargetNorm[0];
- _mtx[9] = toTargetNorm[1];
- _mtx[10] = toTargetNorm[2];
+ const bx::Vec3 toTarget = bx::sub(m_target.curr, m_pos.curr);
+ const float toTargetLen = bx::length(toTarget);
+ const float invToTargetLen = 1.0f / (toTargetLen + bx::kFloatMin);
+ const bx::Vec3 toTargetNorm = bx::mul(toTarget, invToTargetLen);
+
+ const bx::Vec3 right = bx::normalize(bx::cross({ 0.0f, 1.0f, 0.0f }, toTargetNorm) );
+ const bx::Vec3 up = bx::normalize(bx::cross(toTargetNorm, right) );
+
+ _mtx[ 0] = right.x;
+ _mtx[ 1] = right.y;
+ _mtx[ 2] = right.z;
+ _mtx[ 3] = 0.0f;
+ _mtx[ 4] = up.x;
+ _mtx[ 5] = up.y;
+ _mtx[ 6] = up.z;
+ _mtx[ 7] = 0.0f;
+ _mtx[ 8] = toTargetNorm.x;
+ _mtx[ 9] = toTargetNorm.y;
+ _mtx[10] = toTargetNorm.z;
_mtx[11] = 0.0f;
_mtx[12] = 0.0f;
_mtx[13] = 0.0f;
@@ -199,34 +137,10 @@ struct Camera
_mtx[15] = 1.0f;
}
- static inline void vecFromLatLong(float _vec[3], float _u, float _v)
- {
- const float phi = _u * 2.0f*bx::kPi;
- const float theta = _v * bx::kPi;
-
- const float st = bx::sin(theta);
- const float sp = bx::sin(phi);
- const float ct = bx::cos(theta);
- const float cp = bx::cos(phi);
-
- _vec[0] = -st*sp;
- _vec[1] = ct;
- _vec[2] = -st*cp;
- }
-
- static inline void latLongFromVec(float& _u, float& _v, const float _vec[3])
- {
- const float phi = bx::atan2(_vec[0], _vec[2]);
- const float theta = bx::acos(_vec[1]);
-
- _u = (bx::kPi + phi)*bx::kInvPi*0.5f;
- _v = theta*bx::kInvPi;
- }
-
struct Interp3f
{
- float curr[3];
- float dest[3];
+ bx::Vec3 curr;
+ bx::Vec3 dest;
};
Interp3f m_target;
@@ -279,16 +193,16 @@ struct PosVertex
static void init()
{
- ms_decl
+ ms_layout
.begin()
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
.end();
};
- static bgfx::VertexDecl ms_decl;
+ static bgfx::VertexLayout ms_layout;
};
-bgfx::VertexDecl PosVertex::ms_decl;
+bgfx::VertexLayout PosVertex::ms_layout;
static PosVertex s_cubeVertices[8] =
{
@@ -373,12 +287,12 @@ void createCubeMesh(Prop& prop)
prop.m_vertices = new PosVertex[prop.m_noofVertices];
prop.m_indices = new uint16_t[prop.m_noofIndices];
- bx::memCopy(prop.m_vertices, s_cubeVertices, prop.m_noofVertices * PosVertex::ms_decl.getStride());
+ bx::memCopy(prop.m_vertices, s_cubeVertices, prop.m_noofVertices * PosVertex::ms_layout.getStride());
bx::memCopy(prop.m_indices, s_cubeIndices, prop.m_noofIndices * sizeof(uint16_t));
prop.m_vertexbufferHandle = bgfx::createVertexBuffer(
- bgfx::makeRef(prop.m_vertices, prop.m_noofVertices * PosVertex::ms_decl.getStride()),
- PosVertex::ms_decl);
+ bgfx::makeRef(prop.m_vertices, prop.m_noofVertices * PosVertex::ms_layout.getStride()),
+ PosVertex::ms_layout);
prop.m_indexbufferHandle = bgfx::createIndexBuffer(bgfx::makeRef(prop.m_indices, prop.m_noofIndices * sizeof(uint16_t)));
}
@@ -392,8 +306,8 @@ float rand01()
class GPUDrivenRendering : public entry::AppI
{
public:
- GPUDrivenRendering(const char* _name, const char* _description)
- : entry::AppI(_name, _description)
+ GPUDrivenRendering(const char* _name, const char* _description, const char* _url)
+ : entry::AppI(_name, _description, _url)
{
}
@@ -426,7 +340,7 @@ public:
u_inputRTSize = bgfx::createUniform("u_inputRTSize", bgfx::UniformType::Vec4);
u_cullingConfig = bgfx::createUniform("u_cullingConfig", bgfx::UniformType::Vec4);
u_color = bgfx::createUniform("u_color", bgfx::UniformType::Vec4, 32);
- s_texOcclusionDepth = bgfx::createUniform("s_texOcclusionDepth", bgfx::UniformType::Int1);
+ s_texOcclusionDepth = bgfx::createUniform("s_texOcclusionDepth", bgfx::UniformType::Sampler);
//create props
{
@@ -614,8 +528,8 @@ public:
//bounding box for each instance, will be fed to the compute shader to calculate occlusion
{
- bgfx::VertexDecl computeVertexDecl;
- computeVertexDecl.begin()
+ bgfx::VertexLayout computeVertexLayout;
+ computeVertexLayout.begin()
.add(bgfx::Attrib::TexCoord0, 4, bgfx::AttribType::Float)
.end();
@@ -643,13 +557,13 @@ public:
const bgfx::Memory* mem = bgfx::makeRef(boundingBoxes, sizeof(float) * sizeOfBuffer);
- m_instanceBoundingBoxes = bgfx::createDynamicVertexBuffer(mem, computeVertexDecl, BGFX_BUFFER_COMPUTE_READ);
+ m_instanceBoundingBoxes = bgfx::createDynamicVertexBuffer(mem, computeVertexLayout, BGFX_BUFFER_COMPUTE_READ);
}
//pre and post occlusion culling instance data buffers
{
- bgfx::VertexDecl instanceBufferVertexDecl;
- instanceBufferVertexDecl.begin()
+ bgfx::VertexLayout instanceBufferVertexLayout;
+ instanceBufferVertexLayout.begin()
.add(bgfx::Attrib::TexCoord0, 4, bgfx::AttribType::Float)
.add(bgfx::Attrib::TexCoord1, 4, bgfx::AttribType::Float)
.add(bgfx::Attrib::TexCoord2, 4, bgfx::AttribType::Float)
@@ -679,10 +593,10 @@ public:
const bgfx::Memory* mem = bgfx::makeRef(instanceData, sizeof(float) * sizeOfBuffer);
//pre occlusion buffer
- m_instanceBuffer = bgfx::createVertexBuffer(mem, instanceBufferVertexDecl, BGFX_BUFFER_COMPUTE_READ);
+ m_instanceBuffer = bgfx::createVertexBuffer(mem, instanceBufferVertexLayout, BGFX_BUFFER_COMPUTE_READ);
//post occlusion buffer
- m_culledInstanceBuffer = bgfx::createDynamicVertexBuffer(4 * m_totalInstancesCount, instanceBufferVertexDecl, BGFX_BUFFER_COMPUTE_WRITE);
+ m_culledInstanceBuffer = bgfx::createDynamicVertexBuffer(4 * m_totalInstancesCount, instanceBufferVertexLayout, BGFX_BUFFER_COMPUTE_WRITE);
}
//we use one "drawcall" per prop to render all its instances
@@ -690,6 +604,7 @@ public:
// Create programs from shaders for occlusion pass.
m_programOcclusionPass = loadProgram("vs_gdr_render_occlusion", NULL);
+ m_programCopyZ = loadProgram("cs_gdr_copy_z", NULL);
m_programDownscaleHiZ = loadProgram("cs_gdr_downscale_hi_z", NULL);
m_programOccludeProps = loadProgram("cs_gdr_occlude_props", NULL);
m_programStreamCompaction = loadProgram("cs_gdr_stream_compaction", NULL);
@@ -762,8 +677,8 @@ public:
// Create master vertex buffer
m_allPropsVertexbufferHandle = bgfx::createVertexBuffer(
- bgfx::makeRef(m_allPropVerticesDataCPU, totalNoofVertices * PosVertex::ms_decl.getStride())
- , PosVertex::ms_decl
+ bgfx::makeRef(m_allPropVerticesDataCPU, totalNoofVertices * PosVertex::ms_layout.getStride())
+ , PosVertex::ms_layout
);
// Create master index buffer.
@@ -780,6 +695,7 @@ public:
m_timeOffset = bx::getHPCounter();
m_useIndirect = true;
+ m_firstFrame = true;
imguiCreate();
}
@@ -792,6 +708,7 @@ public:
bgfx::destroy(m_programMainPass);
bgfx::destroy(m_programOcclusionPass);
+ bgfx::destroy(m_programCopyZ);
bgfx::destroy(m_programDownscaleHiZ);
bgfx::destroy(m_programOccludeProps);
bgfx::destroy(m_programStreamCompaction);
@@ -899,29 +816,29 @@ public:
uint32_t width = m_hiZwidth;
uint32_t height = m_hiZheight;
- for (uint8_t lod = 0; lod < m_noofHiZMips; ++lod)
+ // copy mip zero over to the hi Z buffer.
+ // We can't currently use blit as it requires same format and CopyResource is not exposed.
{
- float coordinateScale = lod > 0 ? 2.0f : 1.0f;
+ float inputRendertargetSize[4] = { (float)width, (float)height, 0.0f, 0.0f };
+ bgfx::setUniform(u_inputRTSize, inputRendertargetSize);
- float inputRendertargetSize[4] = { (float)width, (float)height, coordinateScale, coordinateScale };
+ bgfx::setTexture(0, s_texOcclusionDepth, getTexture(m_hiZDepthBuffer, 0));
+ bgfx::setImage(1, getTexture(m_hiZBuffer, 0), 0, bgfx::Access::Write);
+
+ bgfx::dispatch(RENDER_PASS_HIZ_DOWNSCALE_ID, m_programCopyZ, width/16, height/16);
+ }
+
+ for (uint8_t lod = 1; lod < m_noofHiZMips; ++lod)
+ {
+ float inputRendertargetSize[4] = { (float)width, (float)height, 2.0f, 2.0f };
bgfx::setUniform(u_inputRTSize, inputRendertargetSize);
- if (lod > 0)
- {
- // down scale mip 1 onwards
- width /= 2;
- height /= 2;
+ // down scale mip 1 onwards
+ width /= 2;
+ height /= 2;
- bgfx::setImage(0, getTexture(m_hiZBuffer, 0), lod - 1, bgfx::Access::Read);
- bgfx::setImage(1, getTexture(m_hiZBuffer, 0), lod, bgfx::Access::Write);
- }
- else
- {
- // copy mip zero over to the hi Z buffer.
- // We can't currently use blit as it requires same format and CopyResource is not exposed.
- bgfx::setImage(0, getTexture(m_hiZDepthBuffer, 0), 0, bgfx::Access::Read);
- bgfx::setImage(1, getTexture(m_hiZBuffer, 0), 0, bgfx::Access::Write);
- }
+ bgfx::setImage(0, getTexture(m_hiZBuffer, 0), lod - 1, bgfx::Access::Read);
+ bgfx::setImage(1, getTexture(m_hiZBuffer, 0), lod, bgfx::Access::Write);
bgfx::dispatch(RENDER_PASS_HIZ_DOWNSCALE_ID, m_programDownscaleHiZ, width/16, height/16);
}
@@ -1000,7 +917,9 @@ public:
// Set "material" data (currently a color only)
bgfx::setUniform(u_color, &m_materials[0].m_color, m_noofMaterials);
- if (m_useIndirect)
+ // We can't use indirect drawing for the first frame because the content of m_drawcallInstanceCounts
+ // is initially undefined.
+ if (m_useIndirect && !m_firstFrame)
{
// Set vertex and index buffer.
bgfx::setVertexBuffer(0, m_allPropsVertexbufferHandle);
@@ -1051,6 +970,7 @@ public:
}
}
}
+ m_firstFrame = false;
}
bool update() override
@@ -1172,6 +1092,7 @@ public:
bgfx::ProgramHandle m_programMainPass;
bgfx::ProgramHandle m_programOcclusionPass;
+ bgfx::ProgramHandle m_programCopyZ;
bgfx::ProgramHandle m_programDownscaleHiZ;
bgfx::ProgramHandle m_programOccludeProps;
bgfx::ProgramHandle m_programStreamCompaction;
@@ -1214,6 +1135,7 @@ public:
uint8_t m_noofHiZMips;
bool m_useIndirect;
+ bool m_firstFrame;
Camera m_camera;
Mouse m_mouse;
@@ -1221,4 +1143,9 @@ public:
} // namespace
-ENTRY_IMPLEMENT_MAIN(GPUDrivenRendering, "37-gpudrivenrendering", "GPU-Driven Rendering.");
+ENTRY_IMPLEMENT_MAIN(
+ GPUDrivenRendering
+ , "37-gpudrivenrendering"
+ , "GPU-Driven Rendering."
+ , "https://bkaradzic.github.io/bgfx/examples.html#gpudrivenrendering"
+ );