Merge remote-tracking branch 'origin/master' into claude/issue-47
# Conflicts: # interfaces/Crafter.Graphics-UI.cppm # project.cpp
This commit is contained in:
commit
e8f1c7cff9
15 changed files with 732 additions and 39 deletions
|
|
@ -46,6 +46,16 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
|||
const float ON_EDGE = 128.0 / 255.0;
|
||||
const float DIST_SCALE = 32.0;
|
||||
|
||||
// Per-category clip-active bits packed into pc.misc.w (the fused analogue of
|
||||
// ui-shared.glsl's UI_FLAG_CLIP). A bit is set only when that category's clip
|
||||
// rect is narrower than the surface; when clear, the category skips its four
|
||||
// per-pixel clip compares entirely (the common full-surface case). The branch
|
||||
// is push-constant-uniform, so it never diverges.
|
||||
const uint UI_FUSED_CLIP_QUADS = 0x1u;
|
||||
const uint UI_FUSED_CLIP_CIRCLES = 0x2u;
|
||||
const uint UI_FUSED_CLIP_IMAGES = 0x4u;
|
||||
const uint UI_FUSED_CLIP_TEXT = 0x8u;
|
||||
|
||||
// Generic per-chunk cooperative-cull scratch, REUSED across the four phases
|
||||
// (they composite sequentially with a barrier between, so the storage is free
|
||||
// once a phase's last read completes). Keeping one shared set instead of four
|
||||
|
|
@ -95,7 +105,8 @@ void main() {
|
|||
{
|
||||
uint heap = pc.itemBuffers.x;
|
||||
uint count = pc.itemCounts.x;
|
||||
bool inClip = inSurface && uiPixelInClipRect(pxu, pc.clipQuads);
|
||||
bool inClip = inSurface &&
|
||||
((pc.misc.w & UI_FUSED_CLIP_QUADS) == 0u || uiPixelInClipRect(pxu, pc.clipQuads));
|
||||
for (uint base = 0u; base < count; base += UI_CHUNK) {
|
||||
uint idx = base + lid;
|
||||
bool keep = false;
|
||||
|
|
@ -151,7 +162,8 @@ void main() {
|
|||
{
|
||||
uint heap = pc.itemBuffers.y;
|
||||
uint count = pc.itemCounts.y;
|
||||
bool inClip = inSurface && uiPixelInClipRect(pxu, pc.clipCircles);
|
||||
bool inClip = inSurface &&
|
||||
((pc.misc.w & UI_FUSED_CLIP_CIRCLES) == 0u || uiPixelInClipRect(pxu, pc.clipCircles));
|
||||
for (uint base = 0u; base < count; base += UI_CHUNK) {
|
||||
uint idx = base + lid;
|
||||
bool keep = false;
|
||||
|
|
@ -210,7 +222,8 @@ void main() {
|
|||
{
|
||||
uint heap = pc.itemBuffers.z;
|
||||
uint count = pc.itemCounts.z;
|
||||
bool inClip = inSurface && uiPixelInClipRect(pxu, pc.clipImages);
|
||||
bool inClip = inSurface &&
|
||||
((pc.misc.w & UI_FUSED_CLIP_IMAGES) == 0u || uiPixelInClipRect(pxu, pc.clipImages));
|
||||
for (uint base = 0u; base < count; base += UI_CHUNK) {
|
||||
uint idx = base + lid;
|
||||
bool keep = false;
|
||||
|
|
@ -260,7 +273,8 @@ void main() {
|
|||
{
|
||||
uint heap = pc.itemBuffers.w;
|
||||
uint count = pc.itemCounts.w;
|
||||
bool inClip = inSurface && uiPixelInClipRect(pxu, pc.clipText);
|
||||
bool inClip = inSurface &&
|
||||
((pc.misc.w & UI_FUSED_CLIP_TEXT) == 0u || uiPixelInClipRect(pxu, pc.clipText));
|
||||
for (uint base = 0u; base < count; base += UI_CHUNK) {
|
||||
uint idx = base + lid;
|
||||
bool keep = false;
|
||||
|
|
|
|||
|
|
@ -27,10 +27,19 @@ struct UIDispatchHeader {
|
|||
vec4 clipRectPx; // (xy, wh) — every standard shader honors this
|
||||
uint itemCount;
|
||||
uint frameIdx;
|
||||
uint flags; // user-defined feature bits
|
||||
uint flags; // feature bits — high bit reserved by the renderer
|
||||
uint _pad; // reserved — keep zeroed
|
||||
};
|
||||
|
||||
// ─── header flag bits ───────────────────────────────────────────────────
|
||||
// `flags` is otherwise free for user-defined feature bits, but the renderer
|
||||
// reserves the high bit: UI_FLAG_CLIP is set by UIRenderer::FillHeader when
|
||||
// the clip rect does not already cover the whole surface. uiResolveScreenPixel
|
||||
// gates its four clipRectPx compares on this bit so the overwhelmingly common
|
||||
// full-surface case (clipRect == {0,0,1e9,1e9}) skips them entirely. The
|
||||
// branch is push-constant-uniform across the dispatch, so it never diverges.
|
||||
const uint UI_FLAG_CLIP = 0x80000000u;
|
||||
|
||||
// ─── standard item structs ──────────────────────────────────────────────
|
||||
// These match the C++ Crafter::QuadItem / CircleItem / ImageItem / GlyphItem
|
||||
// byte-for-byte under std430.
|
||||
|
|
@ -121,9 +130,11 @@ QuadItem LoadQuadItem(uint heap, uint i) {
|
|||
bool uiResolveScreenPixel(UIDispatchHeader hdr, out ivec2 screenPx) {
|
||||
uvec2 px = gl_GlobalInvocationID.xy;
|
||||
if (px.x >= hdr.surfaceSize.x || px.y >= hdr.surfaceSize.y) return false;
|
||||
if (float(px.x) < hdr.clipRectPx.x || float(px.y) < hdr.clipRectPx.y) return false;
|
||||
if (float(px.x) >= hdr.clipRectPx.x + hdr.clipRectPx.z) return false;
|
||||
if (float(px.y) >= hdr.clipRectPx.y + hdr.clipRectPx.w) return false;
|
||||
if ((hdr.flags & UI_FLAG_CLIP) != 0u) {
|
||||
if (float(px.x) < hdr.clipRectPx.x || float(px.y) < hdr.clipRectPx.y) return false;
|
||||
if (float(px.x) >= hdr.clipRectPx.x + hdr.clipRectPx.z) return false;
|
||||
if (float(px.y) >= hdr.clipRectPx.y + hdr.clipRectPx.w) return false;
|
||||
}
|
||||
screenPx = ivec2(px);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue