Skip to content

Commit

Permalink
Merge branch 'master' of github.com:gwaldron/osgearth
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonbeverage committed Jan 12, 2024
2 parents b5652de + 5e01b51 commit 3e88404
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/osgEarth/Chonk
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ namespace osgEarth
float visibility[2]; // per LOD
float radius; // per chonk
float alphaCutoff;
GLuint first_lod_cmd_index;
GLint first_lod_cmd_index = -1; // invalid instance
};
using Instances = std::vector<Instance>;
using Batches = std::unordered_map<Chonk::Ptr, Instances>;
Expand Down
6 changes: 5 additions & 1 deletion src/osgEarth/Chonk.Culling.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#pragma import_defines(OE_GPUCULL_DEBUG)
#pragma import_defines(OE_IS_SHADOW_CAMERA)

layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;

struct DrawElementsIndirectCommand
{
Expand Down Expand Up @@ -98,6 +98,10 @@ void cull()
const uint i = gl_GlobalInvocationID.x; // instance
const uint lod = gl_GlobalInvocationID.y; // lod

// skip instances that exist only to pad the instance array to the workgroup size:
if (input_instances[i].first_lod_cmd_index < 0)
return;

// initialize by clearing the visibility for this LOD:
input_instances[i].visibility[lod] = 0.0;

Expand Down
18 changes: 15 additions & 3 deletions src/osgEarth/Chonk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ using namespace osgEarth;

#define MAX_NEAR_PIXEL_SCALE FLT_MAX

// note: this MUST match the local_size product in Chonk.Culling.glsl
#define GPU_CULLING_LOCAL_WG_SIZE 32

namespace
{
struct SendIndices
Expand Down Expand Up @@ -1176,14 +1179,22 @@ ChonkDrawable::GLObjects::update(
}

// append the instance data (transforms) and set
// the index of the first variant command, which the compute
// the index of the first lod command, which the compute
// shader will need.
for (auto& instance : instances)
{
_all_instances.push_back(instance);
_all_instances.back().first_lod_cmd_index = first_lod_cmd_index;
}

// pad out the size of the instances array so it's a multiple of the
// GPU culling workgroup size. Add "padding" instances will have the
// first_lod_cmd_index member equal to -1, indicating an invalid instance.
// The CS will check for this and discard them.
unsigned workgroups = (_all_instances.size() + GPU_CULLING_LOCAL_WG_SIZE - 1) / GPU_CULLING_LOCAL_WG_SIZE;
unsigned paddedSize = workgroups * GPU_CULLING_LOCAL_WG_SIZE;
_all_instances.resize(paddedSize);

max_lod_count = std::max(max_lod_count, lod_commands.size());
}

Expand Down Expand Up @@ -1261,15 +1272,16 @@ ChonkDrawable::GLObjects::cull(osg::State& state)
// calls for each tile.
// Also, removing the memory barrier seems to make no difference,
// but it's the right thing to do
unsigned workgroups = (_numInstances + (GPU_CULLING_LOCAL_WG_SIZE-1)) / GPU_CULLING_LOCAL_WG_SIZE;

// cull:
ext->glUniform1i(ps._passUL, 0);
ext->glDispatchCompute(_numInstances, _maxNumLODs, 1);
ext->glDispatchCompute(workgroups, _maxNumLODs, 1);

// compact:
ext->glUniform1i(ps._passUL, 1);
ext->glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
ext->glDispatchCompute(_numInstances, _maxNumLODs, 1);
ext->glDispatchCompute(workgroups, _maxNumLODs, 1);
}

void
Expand Down
16 changes: 8 additions & 8 deletions src/osgEarth/Version.in
Original file line number Diff line number Diff line change
Expand Up @@ -34,32 +34,32 @@ namespace osgEarth
(major == rhs.major && minor < rhs.minor) ||
(major == rhs.major && minor == rhs.minor && patch < rhs.patch);
}
inline bool lessThan(int major, int minor, int patch) const {
return this->lessThan(Version{ major, minor, patch });
inline bool lessThan(int in_major, int in_minor, int in_patch) const {
return lessThan(Version{ in_major, in_minor, in_patch });
}
inline bool lessThanOrEqualTo(const Version& rhs) const {
return major < rhs.major ||
(major == rhs.major && minor < rhs.minor) ||
(major == rhs.major && minor == rhs.minor && patch <= rhs.patch);
}
inline bool lessThanOrEqualTo(int major, int minor, int patch) const {
return this->lessThanOrEqualTo(Version{ major, minor, patch });
inline bool lessThanOrEqualTo(int in_major, int in_minor, int in_patch) const {
return lessThanOrEqualTo(Version{ in_major, in_minor, in_patch });
}
inline bool greaterThan(const Version& rhs) const {
return major > rhs.major ||
(major == rhs.major && minor > rhs.minor) ||
(major == rhs.major && minor == rhs.minor && patch > rhs.patch);
}
inline bool greaterThan(int major, int minor, int patch) const {
return this->greaterThan(Version{ major, minor, patch });
inline bool greaterThan(int in_major, int in_minor, int in_patch) const {
return greaterThan(Version{ in_major, in_minor, in_patch });
}
inline bool greaterThanOrEqualTo(const Version& rhs) const {
return major > rhs.major ||
(major == rhs.major && minor > rhs.minor) ||
(major == rhs.major && minor == rhs.minor && patch >= rhs.patch);
}
inline bool greaterThanOrEqualTo(int major, int minor, int patch) const {
return this->greaterThanOrEqualTo(Version{ major, minor, patch });
inline bool greaterThanOrEqualTo(int in_major, int in_minor, int in_patch) const {
return greaterThanOrEqualTo(Version{ in_major, in_minor, in_patch });
}
};

Expand Down

0 comments on commit 3e88404

Please sign in to comment.