gpu: small refactor of compute shaders
split get_face into get_face + add_face_prio_distance, as the ssbo reading did not need to be behind the first barrier used to initialize the shared variables. The rest of this is just code style cleanups
This commit is contained in:
@@ -67,7 +67,7 @@ int face_distance(ivec4 vA, ivec4 vB, ivec4 vC, int cameraYaw, int cameraPitch)
|
||||
/*
|
||||
* Test if a face is visible (not backward facing)
|
||||
*/
|
||||
bool face_visible(ivec4 vA, ivec4 vB, ivec4 vC, ivec4 position, int cameraYaw, int cameraPitch, int centerX, int centerY, int zoom) {
|
||||
bool face_visible(ivec4 vA, ivec4 vB, ivec4 vC, ivec4 position) {
|
||||
// Move model to scene location, and account for camera offset
|
||||
ivec4 cameraPos = ivec4(cameraX, cameraY, cameraZ, 0);
|
||||
vA += position - cameraPos;
|
||||
|
||||
@@ -44,7 +44,7 @@ void main() {
|
||||
uint groupId = gl_WorkGroupID.x;
|
||||
uint localId = gl_LocalInvocationID.x * 4;
|
||||
modelinfo minfo = ol[groupId];
|
||||
int length = minfo.size;
|
||||
ivec4 pos = ivec4(minfo.x, minfo.y, minfo.z, 0);
|
||||
|
||||
if (localId == 0) {
|
||||
min10 = 1600;
|
||||
@@ -57,29 +57,35 @@ void main() {
|
||||
}
|
||||
}
|
||||
|
||||
memoryBarrierShared();
|
||||
barrier();
|
||||
|
||||
int prio1, dis1, prio1Adj;
|
||||
int prio1, dis1;
|
||||
ivec4 vA1, vA2, vA3;
|
||||
|
||||
int prio2, dis2, prio2Adj;
|
||||
int prio2, dis2;
|
||||
ivec4 vB1, vB2, vB3;
|
||||
|
||||
int prio3, dis3, prio3Adj;
|
||||
int prio3, dis3;
|
||||
ivec4 vC1, vC2, vC3;
|
||||
|
||||
int prio4, dis4, prio4Adj;
|
||||
int prio4, dis4;
|
||||
ivec4 vD1, vD2, vD3;
|
||||
|
||||
get_face(localId, minfo, cameraYaw, cameraPitch, centerX, centerY, zoom, prio1, dis1, vA1, vA2, vA3);
|
||||
get_face(localId + 1, minfo, cameraYaw, cameraPitch, centerX, centerY, zoom, prio2, dis2, vB1, vB2, vB3);
|
||||
get_face(localId + 2, minfo, cameraYaw, cameraPitch, centerX, centerY, zoom, prio3, dis3, vC1, vC2, vC3);
|
||||
get_face(localId + 3, minfo, cameraYaw, cameraPitch, centerX, centerY, zoom, prio4, dis4, vD1, vD2, vD3);
|
||||
get_face(localId, minfo, cameraYaw, cameraPitch, prio1, dis1, vA1, vA2, vA3);
|
||||
get_face(localId + 1, minfo, cameraYaw, cameraPitch, prio2, dis2, vB1, vB2, vB3);
|
||||
get_face(localId + 2, minfo, cameraYaw, cameraPitch, prio3, dis3, vC1, vC2, vC3);
|
||||
get_face(localId + 3, minfo, cameraYaw, cameraPitch, prio4, dis4, vD1, vD2, vD3);
|
||||
|
||||
memoryBarrierShared();
|
||||
barrier();
|
||||
|
||||
add_face_prio_distance(localId , minfo, vA1, vA2, vA3, prio1, dis1, pos);
|
||||
add_face_prio_distance(localId + 1, minfo, vB1, vB2, vB3, prio2, dis2, pos);
|
||||
add_face_prio_distance(localId + 2, minfo, vC1, vC2, vC3, prio3, dis3, pos);
|
||||
add_face_prio_distance(localId + 3, minfo, vD1, vD2, vD3, prio4, dis4, pos);
|
||||
|
||||
memoryBarrierShared();
|
||||
barrier();
|
||||
|
||||
int prio1Adj, prio2Adj, prio3Adj, prio4Adj;
|
||||
int idx1 = map_face_priority(localId, minfo, prio1, dis1, prio1Adj);
|
||||
int idx2 = map_face_priority(localId + 1, minfo, prio2, dis2, prio2Adj);
|
||||
int idx3 = map_face_priority(localId + 2, minfo, prio3, dis3, prio3Adj);
|
||||
|
||||
@@ -44,6 +44,7 @@ void main() {
|
||||
uint groupId = gl_WorkGroupID.x;
|
||||
uint localId = gl_LocalInvocationID.x;
|
||||
modelinfo minfo = ol[groupId];
|
||||
ivec4 pos = ivec4(minfo.x, minfo.y, minfo.z, 0);
|
||||
|
||||
if (localId == 0) {
|
||||
min10 = 1600;
|
||||
@@ -56,17 +57,20 @@ void main() {
|
||||
}
|
||||
}
|
||||
|
||||
memoryBarrierShared();
|
||||
barrier();
|
||||
|
||||
int prio1, dis1, prio1Adj;
|
||||
int prio1, dis1;
|
||||
ivec4 vA1, vA2, vA3;
|
||||
|
||||
get_face(localId, minfo, cameraYaw, cameraPitch, centerX, centerY, zoom, prio1, dis1, vA1, vA2, vA3);
|
||||
get_face(localId, minfo, cameraYaw, cameraPitch, prio1, dis1, vA1, vA2, vA3);
|
||||
|
||||
memoryBarrierShared();
|
||||
barrier();
|
||||
|
||||
add_face_prio_distance(localId, minfo, vA1, vA2, vA3, prio1, dis1, pos);
|
||||
|
||||
memoryBarrierShared();
|
||||
barrier();
|
||||
|
||||
int prio1Adj;
|
||||
int idx1 = map_face_priority(localId, minfo, prio1, dis1, prio1Adj);
|
||||
|
||||
memoryBarrierShared();
|
||||
|
||||
@@ -110,69 +110,45 @@ int count_prio_offset(int priority) {
|
||||
}
|
||||
}
|
||||
|
||||
void get_face(uint localId, modelinfo minfo, int cameraYaw, int cameraPitch, int centerX, int centerY, int zoom,
|
||||
void get_face(uint localId, modelinfo minfo, int cameraYaw, int cameraPitch,
|
||||
out int prio, out int dis, out ivec4 o1, out ivec4 o2, out ivec4 o3) {
|
||||
int offset = minfo.offset;
|
||||
int size = minfo.size;
|
||||
int flags = minfo.flags;
|
||||
int radius = (flags & 0x7fffffff) >> 12;
|
||||
int orientation = flags & 0x7ff;
|
||||
ivec4 pos = ivec4(minfo.x, minfo.y, minfo.z, 0);
|
||||
|
||||
uint ssboOffset;
|
||||
|
||||
if (localId < size) {
|
||||
ssboOffset = localId;
|
||||
} else {
|
||||
ssboOffset = 0;
|
||||
}
|
||||
int offset = minfo.offset;
|
||||
int flags = minfo.flags;
|
||||
int radius = (flags & 0x7fffffff) >> 12;
|
||||
int orientation = flags & 0x7ff;
|
||||
|
||||
ivec4 thisA;
|
||||
ivec4 thisB;
|
||||
ivec4 thisC;
|
||||
ivec4 thisA;
|
||||
ivec4 thisB;
|
||||
ivec4 thisC;
|
||||
|
||||
// Grab triangle vertices from the correct buffer
|
||||
if (flags < 0) {
|
||||
thisA = vb[offset + ssboOffset * 3 ];
|
||||
thisB = vb[offset + ssboOffset * 3 + 1];
|
||||
thisC = vb[offset + ssboOffset * 3 + 2];
|
||||
} else {
|
||||
thisA = tempvb[offset + ssboOffset * 3 ];
|
||||
thisB = tempvb[offset + ssboOffset * 3 + 1];
|
||||
thisC = tempvb[offset + ssboOffset * 3 + 2];
|
||||
}
|
||||
// Grab triangle vertices from the correct buffer
|
||||
if (flags < 0) {
|
||||
thisA = vb[offset + localId * 3];
|
||||
thisB = vb[offset + localId * 3 + 1];
|
||||
thisC = vb[offset + localId * 3 + 2];
|
||||
} else {
|
||||
thisA = tempvb[offset + localId * 3];
|
||||
thisB = tempvb[offset + localId * 3 + 1];
|
||||
thisC = tempvb[offset + localId * 3 + 2];
|
||||
}
|
||||
|
||||
ivec4 thisrvA;
|
||||
ivec4 thisrvB;
|
||||
ivec4 thisrvC;
|
||||
|
||||
int thisPriority, thisDistance;
|
||||
|
||||
if (localId < size) {
|
||||
// rotate for model orientation
|
||||
thisrvA = rotate(thisA, orientation);
|
||||
thisrvB = rotate(thisB, orientation);
|
||||
thisrvC = rotate(thisC, orientation);
|
||||
ivec4 thisrvA = rotate(thisA, orientation);
|
||||
ivec4 thisrvB = rotate(thisB, orientation);
|
||||
ivec4 thisrvC = rotate(thisC, orientation);
|
||||
|
||||
// calculate distance to face
|
||||
thisPriority = (thisA.w >> 16) & 0xff; // all vertices on the face have the same priority
|
||||
int thisPriority = (thisA.w >> 16) & 0xff;// all vertices on the face have the same priority
|
||||
int thisDistance;
|
||||
if (radius == 0) {
|
||||
thisDistance = 0;
|
||||
} else {
|
||||
thisDistance = face_distance(thisrvA, thisrvB, thisrvC, cameraYaw, cameraPitch) + radius;
|
||||
}
|
||||
|
||||
// if the face is not culled, it is calculated into priority distance averages
|
||||
if (face_visible(thisrvA, thisrvB, thisrvC, pos, cameraYaw, cameraPitch, centerX, centerY, zoom)) {
|
||||
atomicAdd(totalNum[thisPriority], 1);
|
||||
atomicAdd(totalDistance[thisPriority], thisDistance);
|
||||
|
||||
// calculate minimum distance to any face of priority 10 for positioning the 11 faces later
|
||||
if (thisPriority == 10) {
|
||||
atomicMin(min10, thisDistance);
|
||||
}
|
||||
}
|
||||
|
||||
o1 = thisrvA;
|
||||
o2 = thisrvB;
|
||||
o3 = thisrvC;
|
||||
@@ -180,19 +156,34 @@ void get_face(uint localId, modelinfo minfo, int cameraYaw, int cameraPitch, int
|
||||
prio = thisPriority;
|
||||
dis = thisDistance;
|
||||
} else {
|
||||
o1 = ivec4(0);
|
||||
o2 = ivec4(0);
|
||||
o3 = ivec4(0);
|
||||
prio = 0;
|
||||
dis = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void add_face_prio_distance(uint localId, modelinfo minfo, ivec4 thisrvA, ivec4 thisrvB, ivec4 thisrvC, int thisPriority, int thisDistance, ivec4 pos) {
|
||||
if (localId < minfo.size) {
|
||||
// if the face is not culled, it is calculated into priority distance averages
|
||||
if (face_visible(thisrvA, thisrvB, thisrvC, pos)) {
|
||||
atomicAdd(totalNum[thisPriority], 1);
|
||||
atomicAdd(totalDistance[thisPriority], thisDistance);
|
||||
|
||||
// calculate minimum distance to any face of priority 10 for positioning the 11 faces later
|
||||
if (thisPriority == 10) {
|
||||
atomicMin(min10, thisDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int map_face_priority(uint localId, modelinfo minfo, int thisPriority, int thisDistance, out int prio) {
|
||||
int size = minfo.size;
|
||||
|
||||
// Compute average distances for 0/2, 3/4, and 6/8
|
||||
|
||||
int adjPrio;
|
||||
int prioIdx;
|
||||
|
||||
if (localId < size) {
|
||||
int avg1 = 0;
|
||||
int avg2 = 0;
|
||||
@@ -210,16 +201,14 @@ int map_face_priority(uint localId, modelinfo minfo, int thisPriority, int thisD
|
||||
avg3 = (totalDistance[6] + totalDistance[8]) / (totalNum[6] + totalNum[8]);
|
||||
}
|
||||
|
||||
int _min10 = min10;
|
||||
adjPrio = priority_map(thisPriority, thisDistance, _min10, avg1, avg2, avg3);
|
||||
|
||||
int adjPrio = priority_map(thisPriority, thisDistance, min10, avg1, avg2, avg3);
|
||||
int prioIdx = atomicAdd(totalMappedNum[adjPrio], 1);
|
||||
|
||||
prio = adjPrio;
|
||||
|
||||
return prioIdx;
|
||||
}
|
||||
|
||||
prio = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -237,23 +226,19 @@ void insert_dfs(uint localId, modelinfo minfo, int adjPrio, int distance, int pr
|
||||
void sort_and_insert(uint localId, modelinfo minfo, int thisPriority, int thisDistance, ivec4 thisrvA, ivec4 thisrvB, ivec4 thisrvC) {
|
||||
/* compute face distance */
|
||||
int size = minfo.size;
|
||||
int outOffset = minfo.idx;
|
||||
int uvOffset = minfo.uvOffset;
|
||||
int flags = minfo.flags;
|
||||
ivec4 pos = ivec4(minfo.x, minfo.y, minfo.z, 0);
|
||||
|
||||
int start, end, myOffset;
|
||||
if (localId < size) {
|
||||
int outOffset = minfo.idx;
|
||||
int uvOffset = minfo.uvOffset;
|
||||
int flags = minfo.flags;
|
||||
ivec4 pos = ivec4(minfo.x, minfo.y, minfo.z, 0);
|
||||
|
||||
const int priorityOffset = count_prio_offset(thisPriority);
|
||||
const int numOfPriority = totalMappedNum[thisPriority];
|
||||
start = priorityOffset; // index of first face with this priority
|
||||
end = priorityOffset + numOfPriority; // index of last face with this priority
|
||||
myOffset = priorityOffset;
|
||||
} else {
|
||||
start = end = myOffset = 0;
|
||||
}
|
||||
int start = priorityOffset; // index of first face with this priority
|
||||
int end = priorityOffset + numOfPriority; // index of last face with this priority
|
||||
int myOffset = priorityOffset;
|
||||
|
||||
if (localId < size) {
|
||||
// we only have to order faces against others of the same priority
|
||||
// calculate position this face will be in
|
||||
for (int i = start; i < end; ++i) {
|
||||
|
||||
Reference in New Issue
Block a user