diff --git a/renderdoc/data/glsl/debuguniforms.h b/renderdoc/data/glsl/debuguniforms.h index 565a59dd0..38c9753c3 100644 --- a/renderdoc/data/glsl/debuguniforms.h +++ b/renderdoc/data/glsl/debuguniforms.h @@ -134,6 +134,8 @@ INST_NAME(general); #define MESH_TRIANGLE_LIST 1 #define MESH_TRIANGLE_STRIP 2 #define MESH_TRIANGLE_FAN 3 +#define MESH_TRIANGLE_LIST_ADJ 4 +#define MESH_TRIANGLE_STRIP_ADJ 5 BINDING(0) uniform MeshPickUBOData { vec3 rayPos; diff --git a/renderdoc/data/glsl/mesh.comp b/renderdoc/data/glsl/mesh.comp index 55423d949..456ac590b 100644 --- a/renderdoc/data/glsl/mesh.comp +++ b/renderdoc/data/glsl/mesh.comp @@ -79,15 +79,16 @@ bool TriangleRayIntersect(vec3 A, vec3 B, vec3 C, void trianglePath(uint threadID) { - uint vertid = threadID; - // NOTE(james): when I turn on following early out the shader doesn't do anything. // so I end up with a lot of duplicated work on smaller meshes - //if(vertid >= meshpick.numVerts) + //if(threadID >= meshpick.numVerts) // return; - vertid = uint(mod(float(vertid), float(meshpick.numVerts))); + uint vertid = uint(mod(float(threadID), float(meshpick.numVerts))); + uint vertid0 = 0; + uint vertid1 = 0; + uint vertid2 = 0; uint idx0 = 0; uint idx1 = 0; uint idx2 = 0; @@ -96,31 +97,46 @@ void trianglePath(uint threadID) case MESH_TRIANGLE_LIST: { vertid *= 3; - idx0 = meshpick.use_indices != 0u ? ib.data[vertid ] : vertid; - idx1 = meshpick.use_indices != 0u ? ib.data[vertid+1] : vertid+1; - idx2 = meshpick.use_indices != 0u ? ib.data[vertid+2] : vertid+2; + vertid0 = vertid; + vertid1 = vertid+1; + vertid2 = vertid+2; break; } case MESH_TRIANGLE_STRIP: { - idx0 = meshpick.use_indices != 0u ? ib.data[vertid ] : vertid; - idx1 = meshpick.use_indices != 0u ? ib.data[vertid+1] : vertid+1; - idx2 = meshpick.use_indices != 0u ? ib.data[vertid+2] : vertid+2; + vertid0 = vertid; + vertid1 = vertid+1; + vertid2 = vertid+2; break; } case MESH_TRIANGLE_FAN: + { + vertid0 = 0; + vertid1 = vertid+1; + vertid2 = vertid+2; + break; + } + case MESH_TRIANGLE_LIST_ADJ: + { + vertid *= 6; + vertid0 = vertid; + vertid1 = vertid+2; + vertid2 = vertid+4; + break; + } + case MESH_TRIANGLE_STRIP_ADJ: { vertid *= 2; - idx0 = meshpick.use_indices != 0u ? ib.data[0 ] : 0; - idx1 = meshpick.use_indices != 0u ? ib.data[vertid ] : vertid; - idx2 = meshpick.use_indices != 0u ? ib.data[vertid+1] : vertid+1; + vertid0 = vertid; + vertid1 = vertid+2; + vertid2 = vertid+4; break; } } - vec4 pos0 = vb.data[idx0]; - vec4 pos1 = vb.data[idx1]; - vec4 pos2 = vb.data[idx2]; + vec4 pos0 = meshpick.use_indices != 0u ? vb.data[ib.data[vertid0]] : vb.data[vertid0]; + vec4 pos1 = meshpick.use_indices != 0u ? vb.data[ib.data[vertid1]] : vb.data[vertid1]; + vec4 pos2 = meshpick.use_indices != 0u ? vb.data[ib.data[vertid2]] : vb.data[vertid2]; #ifdef VULKAN if(meshpick.unproject == 1u) pos = vec4(pos.x, -pos.y, pos.z, pos.w); @@ -128,8 +144,9 @@ void trianglePath(uint threadID) vec3 hitPosition; bool hit = TriangleRayIntersect(pos0.xyz, pos1.xyz, pos2.xyz, - meshpick.rayPos, meshpick.rayDir, hitPosition); - //push every vert of the triangle if its hit + meshpick.rayPos, meshpick.rayDir, + /*out*/ hitPosition); + if (hit) { float dist0 = distance(pos0.xyz, hitPosition); @@ -137,15 +154,17 @@ void trianglePath(uint threadID) float dist2 = distance(pos2.xyz, hitPosition); uint result_idx = atomicAdd(pickresult.counter.x, 1u); + + uint meshVert = vertid0; if (dist1 < dist0 && dist1 < dist2) { - vertid +=1; + meshVert = vertid1; } else if (dist2 < dist0 && dist2 < dist1) { - vertid +=2; + meshVert = vertid2; } - pickresult.results[result_idx] = uvec4(vertid, + pickresult.results[result_idx] = uvec4(meshVert, floatBitsToUint(hitPosition.x), floatBitsToUint(hitPosition.y), floatBitsToUint(hitPosition.z)); } @@ -186,14 +205,13 @@ void defaultPath(uint threadID) void main() { - if (meshpick.meshMode == MESH_TRIANGLE_LIST || - meshpick.meshMode == MESH_TRIANGLE_STRIP) - { - trianglePath(gl_GlobalInvocationID.x); - } - else + + if (meshpick.meshMode == MESH_OTHER) { defaultPath(gl_GlobalInvocationID.x); } - + else + { + trianglePath(gl_GlobalInvocationID.x); + } } diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index 7223de9f3..f4265bedc 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -1076,32 +1076,38 @@ uint32_t GLReplay::PickVertex(uint32_t eventID, const MeshDisplay &cfg, uint32_t cdata->rayDir = rayDir; cdata->use_indices = cfg.position.idxByteWidth ? 1U : 0U; cdata->numVerts = cfg.position.numVerts; - - bool isTriangleMesh = false; + bool isTriangleMesh = true; switch(cfg.position.topo) { case eTopology_TriangleList: { cdata->meshMode = MESH_TRIANGLE_LIST; - isTriangleMesh = true; break; }; case eTopology_TriangleStrip: { cdata->meshMode = MESH_TRIANGLE_STRIP; - isTriangleMesh = true; break; }; case eTopology_TriangleFan: { cdata->meshMode = MESH_TRIANGLE_FAN; - isTriangleMesh = true; break; }; - // TODO: TriangleList_Adj, TriangleStrip_Adj - default: // points, lines, patchlists + case eTopology_TriangleList_Adj: + { + cdata->meshMode = MESH_TRIANGLE_LIST_ADJ; + break; + }; + case eTopology_TriangleStrip_Adj: + { + cdata->meshMode = MESH_TRIANGLE_STRIP_ADJ; + break; + }; + default: // points, lines, patchlists, unknown { cdata->meshMode = MESH_OTHER; + isTriangleMesh = false; }; }