Skip to content

Commit 3e88404

Browse files
committed
Merge branch 'master' of github.com:gwaldron/osgearth
2 parents b5652de + 5e01b51 commit 3e88404

File tree

4 files changed

+29
-13
lines changed

4 files changed

+29
-13
lines changed

src/osgEarth/Chonk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ namespace osgEarth
303303
float visibility[2]; // per LOD
304304
float radius; // per chonk
305305
float alphaCutoff;
306-
GLuint first_lod_cmd_index;
306+
GLint first_lod_cmd_index = -1; // invalid instance
307307
};
308308
using Instances = std::vector<Instance>;
309309
using Batches = std::unordered_map<Chonk::Ptr, Instances>;

src/osgEarth/Chonk.Culling.glsl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#pragma import_defines(OE_GPUCULL_DEBUG)
55
#pragma import_defines(OE_IS_SHADOW_CAMERA)
66

7-
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
7+
layout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;
88

99
struct DrawElementsIndirectCommand
1010
{
@@ -98,6 +98,10 @@ void cull()
9898
const uint i = gl_GlobalInvocationID.x; // instance
9999
const uint lod = gl_GlobalInvocationID.y; // lod
100100

101+
// skip instances that exist only to pad the instance array to the workgroup size:
102+
if (input_instances[i].first_lod_cmd_index < 0)
103+
return;
104+
101105
// initialize by clearing the visibility for this LOD:
102106
input_instances[i].visibility[lod] = 0.0;
103107

src/osgEarth/Chonk.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ using namespace osgEarth;
4242

4343
#define MAX_NEAR_PIXEL_SCALE FLT_MAX
4444

45+
// note: this MUST match the local_size product in Chonk.Culling.glsl
46+
#define GPU_CULLING_LOCAL_WG_SIZE 32
47+
4548
namespace
4649
{
4750
struct SendIndices
@@ -1176,14 +1179,22 @@ ChonkDrawable::GLObjects::update(
11761179
}
11771180

11781181
// append the instance data (transforms) and set
1179-
// the index of the first variant command, which the compute
1182+
// the index of the first lod command, which the compute
11801183
// shader will need.
11811184
for (auto& instance : instances)
11821185
{
11831186
_all_instances.push_back(instance);
11841187
_all_instances.back().first_lod_cmd_index = first_lod_cmd_index;
11851188
}
11861189

1190+
// pad out the size of the instances array so it's a multiple of the
1191+
// GPU culling workgroup size. Add "padding" instances will have the
1192+
// first_lod_cmd_index member equal to -1, indicating an invalid instance.
1193+
// The CS will check for this and discard them.
1194+
unsigned workgroups = (_all_instances.size() + GPU_CULLING_LOCAL_WG_SIZE - 1) / GPU_CULLING_LOCAL_WG_SIZE;
1195+
unsigned paddedSize = workgroups * GPU_CULLING_LOCAL_WG_SIZE;
1196+
_all_instances.resize(paddedSize);
1197+
11871198
max_lod_count = std::max(max_lod_count, lod_commands.size());
11881199
}
11891200

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

12651277
// cull:
12661278
ext->glUniform1i(ps._passUL, 0);
1267-
ext->glDispatchCompute(_numInstances, _maxNumLODs, 1);
1279+
ext->glDispatchCompute(workgroups, _maxNumLODs, 1);
12681280

12691281
// compact:
12701282
ext->glUniform1i(ps._passUL, 1);
12711283
ext->glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
1272-
ext->glDispatchCompute(_numInstances, _maxNumLODs, 1);
1284+
ext->glDispatchCompute(workgroups, _maxNumLODs, 1);
12731285
}
12741286

12751287
void

src/osgEarth/Version.in

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,32 +34,32 @@ namespace osgEarth
3434
(major == rhs.major && minor < rhs.minor) ||
3535
(major == rhs.major && minor == rhs.minor && patch < rhs.patch);
3636
}
37-
inline bool lessThan(int major, int minor, int patch) const {
38-
return this->lessThan(Version{ major, minor, patch });
37+
inline bool lessThan(int in_major, int in_minor, int in_patch) const {
38+
return lessThan(Version{ in_major, in_minor, in_patch });
3939
}
4040
inline bool lessThanOrEqualTo(const Version& rhs) const {
4141
return major < rhs.major ||
4242
(major == rhs.major && minor < rhs.minor) ||
4343
(major == rhs.major && minor == rhs.minor && patch <= rhs.patch);
4444
}
45-
inline bool lessThanOrEqualTo(int major, int minor, int patch) const {
46-
return this->lessThanOrEqualTo(Version{ major, minor, patch });
45+
inline bool lessThanOrEqualTo(int in_major, int in_minor, int in_patch) const {
46+
return lessThanOrEqualTo(Version{ in_major, in_minor, in_patch });
4747
}
4848
inline bool greaterThan(const Version& rhs) const {
4949
return major > rhs.major ||
5050
(major == rhs.major && minor > rhs.minor) ||
5151
(major == rhs.major && minor == rhs.minor && patch > rhs.patch);
5252
}
53-
inline bool greaterThan(int major, int minor, int patch) const {
54-
return this->greaterThan(Version{ major, minor, patch });
53+
inline bool greaterThan(int in_major, int in_minor, int in_patch) const {
54+
return greaterThan(Version{ in_major, in_minor, in_patch });
5555
}
5656
inline bool greaterThanOrEqualTo(const Version& rhs) const {
5757
return major > rhs.major ||
5858
(major == rhs.major && minor > rhs.minor) ||
5959
(major == rhs.major && minor == rhs.minor && patch >= rhs.patch);
6060
}
61-
inline bool greaterThanOrEqualTo(int major, int minor, int patch) const {
62-
return this->greaterThanOrEqualTo(Version{ major, minor, patch });
61+
inline bool greaterThanOrEqualTo(int in_major, int in_minor, int in_patch) const {
62+
return greaterThanOrEqualTo(Version{ in_major, in_minor, in_patch });
6363
}
6464
};
6565

0 commit comments

Comments
 (0)