From 0837e7451a84f95c29dbdb9bd6b8b931fee1635d Mon Sep 17 00:00:00 2001 From: Julian Sikorski Date: Sun, 13 Oct 2019 13:50:38 +0200 Subject: WIP: sync bgfx, bx and bimg with latest upstream (#5723) * Sync with bgfx upstream revision b91d0b6 * Sync with bx upstream revision d60912b * Sync with bimg upstream revision bd81f60 * Add astc-codec decoder * Rename VertexDecl to VertexLayout * Rename UniformType enum Int1 to Sampler. * Add NVN stub * Fix unused-const-variable error on macOS * Drop redundant explicit language parameters buildoptions_cpp are only applied to c++ files and buildoptions_objcpp are only applied to objective c++ files. As such, hardcoding -x offers no benefit while preventing overrides (such as one needed by 3rdparty/bgfx/src/renderer_vk.cpp on macOS) from working. * Re-introduce -x c++ in places where C code is compiled as C++ to prevent clang from throwing a warning * Build bgfx as Objective-C++ on macOS It is needed due to included headers * Enable Direct3D12 and Vulkan bgfx rendering backends * Enable building of spirv shaders * Properly escape /c in cmd call * Comment out dx12 bgfx renderer * Honor VERBOSE setting during shaders build * Only invert hlsl shader XYZ_TO_sRGB matrix for opengl * Add spirv shaders * OpenGL ES needs transposed matrix too * Metal needs transposed matrix as well --- .../37-gpudrivenrendering/gpudrivenrendering.cpp | 275 ++++++++------------- 1 file changed, 101 insertions(+), 174 deletions(-) (limited to '3rdparty/bgfx/examples/37-gpudrivenrendering/gpudrivenrendering.cpp') 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" + ); -- cgit v1.2.3-70-g09d2