~mmach/netext73/webkit2gtk

« back to all changes in this revision

Viewing changes to Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/shaders/src/OverlayCull.comp

  • Committer: mmach
  • Date: 2023-06-16 17:21:37 UTC
  • Revision ID: netbit73@gmail.com-20230616172137-2rqx6yr96ga9g3kp
1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
 
3
// Use of this source code is governed by a BSD-style license that can be
 
4
// found in the LICENSE file.
 
5
//
 
6
// OverlayCull.comp: Cull overlay widgets.  A maximum of 32 text widgets and 32 graph widgets is
 
7
// supported simultaneously.
 
8
 
 
9
#version 450 core
 
10
 
 
11
#extension GL_EXT_samplerless_texture_functions : require
 
12
#if SupportsBallot
 
13
#extension GL_KHR_shader_subgroup_ballot: require
 
14
#elif SupportsArithmetic
 
15
#extension GL_KHR_shader_subgroup_arithmetic: require
 
16
#endif
 
17
 
 
18
#if Is8x4
 
19
#define WORKGROUP_WIDTH 32
 
20
#define BLOCK_WIDTH 8
 
21
#define BLOCK_HEIGHT 4
 
22
#elif Is8x8
 
23
#define WORKGROUP_WIDTH 64
 
24
#define BLOCK_WIDTH 8
 
25
#define BLOCK_HEIGHT 8
 
26
#else
 
27
#error "Not all subgroup sizes are accounted for"
 
28
#endif
 
29
 
 
30
// Limits:
 
31
#define MAX_TEXT_WIDGETS 32
 
32
#define MAX_GRAPH_WIDGETS 32
 
33
 
 
34
layout (local_size_x = WORKGROUP_WIDTH, local_size_y = 1, local_size_z = 1) in;
 
35
 
 
36
layout(set = 0, binding = 0, rgba32ui) uniform writeonly uimage2D culledWidgetsOut;
 
37
 
 
38
layout (set = 0, binding = 1) uniform WidgetCoordinates
 
39
{
 
40
    uvec4 coordinates[MAX_TEXT_WIDGETS + MAX_GRAPH_WIDGETS];
 
41
};
 
42
 
 
43
#if SupportsNone
 
44
shared uint intersectingWidgets[32];
 
45
 
 
46
void accumulateWidgets(const uint localId)
 
47
{
 
48
    // Note: no barriers needed as the workgroup size is the same as hardware subgroup size.
 
49
    if (localId < 16)
 
50
    {
 
51
        intersectingWidgets[localId] |= intersectingWidgets[localId + 16];
 
52
        if (localId < 8)
 
53
        {
 
54
            intersectingWidgets[localId] |= intersectingWidgets[localId + 8];
 
55
            if (localId < 4)
 
56
            {
 
57
                intersectingWidgets[localId] |= intersectingWidgets[localId + 4];
 
58
                if (localId < 2)
 
59
                {
 
60
                    intersectingWidgets[localId] |= intersectingWidgets[localId + 2];
 
61
                    if (localId < 1)
 
62
                    {
 
63
                        intersectingWidgets[localId] |= intersectingWidgets[localId + 1];
 
64
                    }
 
65
                }
 
66
            }
 
67
        }
 
68
    }
 
69
}
 
70
#endif
 
71
 
 
72
uvec2 cullWidgets(const uint offset, const uvec2 blockCoordLow, const uvec2 blockCoordHigh)
 
73
{
 
74
    const uint localId = gl_LocalInvocationID.x;
 
75
    const uvec4 widgetCoords = coordinates[offset + localId];
 
76
 
 
77
    const bool intersects = widgetCoords.x < widgetCoords.z &&
 
78
                            all(lessThan(widgetCoords.xy, blockCoordHigh)) &&
 
79
                            all(greaterThanEqual(widgetCoords.zw, blockCoordLow));
 
80
 
 
81
#if SupportsBallot
 
82
 
 
83
    return subgroupBallot(intersects).xy;
 
84
 
 
85
#elif SupportsArithmetic
 
86
 
 
87
#if Is8x8
 
88
    const uint textWidgetBit =
 
89
        localId < MAX_TEXT_WIDGETS ? uint(intersects) << localId : 0;
 
90
    const uint graphWidgetBit =
 
91
        localId >= MAX_TEXT_WIDGETS ? uint(intersects) << (localId - MAX_TEXT_WIDGETS) : 0;
 
92
    return uvec2(subgroupOr(textWidgetBit), subgroupOr(graphWidgetBit));
 
93
#elif Is8x4
 
94
    return uvec2(subgroupOr(uint(intersects) << localId), 0);
 
95
#else
 
96
#error "Not all subgroup sizes are accounted for"
 
97
#endif
 
98
 
 
99
#elif SupportsNone
 
100
 
 
101
    uvec2 ballot = uvec2(0, 0);
 
102
#if Is8x8
 
103
    if (localId < MAX_TEXT_WIDGETS)
 
104
    {
 
105
        intersectingWidgets[localId] = uint(intersects) << localId;
 
106
        accumulateWidgets(localId);
 
107
        if (localId == 0)
 
108
        {
 
109
            ballot.x = intersectingWidgets[0];
 
110
        }
 
111
    }
 
112
    else
 
113
    {
 
114
        const uint graphLocalId = localId - MAX_TEXT_WIDGETS;
 
115
        intersectingWidgets[graphLocalId] = uint(intersects) << graphLocalId;
 
116
        accumulateWidgets(graphLocalId);
 
117
    }
 
118
    if (localId == 0)
 
119
    {
 
120
        ballot.y = intersectingWidgets[0];
 
121
    }
 
122
#elif Is8x4
 
123
    intersectingWidgets[localId] = uint(intersects) << localId;
 
124
    accumulateWidgets(localId);
 
125
    if (localId == 0)
 
126
    {
 
127
        ballot.x = intersectingWidgets[0];
 
128
    }
 
129
#else
 
130
#error "Not all subgroup sizes are accounted for"
 
131
#endif
 
132
 
 
133
    return ballot;
 
134
 
 
135
#else
 
136
#error "Not all subgroup operations are accounted for"
 
137
#endif
 
138
}
 
139
 
 
140
void main()
 
141
{
 
142
    // There is one workgroup invocation per pixel in culledWidgetsOut.  Depending on the subgroup
 
143
    // size, either all widgets and graphs are processed simultaneously (subgroup size 64) or
 
144
    // separately (subgroup size 32).
 
145
    const uvec2 outCoord = gl_WorkGroupID.xy;
 
146
    const uvec2 blockCoordLow = outCoord * uvec2(BLOCK_WIDTH, BLOCK_HEIGHT);
 
147
    const uvec2 blockCoordHigh = blockCoordLow + uvec2(BLOCK_WIDTH, BLOCK_HEIGHT);
 
148
 
 
149
    uvec2 culledWidgets;
 
150
 
 
151
#if Is8x8
 
152
    culledWidgets = cullWidgets(0, blockCoordLow, blockCoordHigh);
 
153
#elif Is8x4
 
154
    culledWidgets.x = cullWidgets(0, blockCoordLow, blockCoordHigh).x;
 
155
    culledWidgets.y = cullWidgets(MAX_TEXT_WIDGETS, blockCoordLow, blockCoordHigh).x;
 
156
#else
 
157
#error "Not all subgroup sizes are accounted for"
 
158
#endif
 
159
 
 
160
    if (gl_LocalInvocationID.x == 0)
 
161
    {
 
162
        imageStore(culledWidgetsOut, ivec2(outCoord), uvec4(culledWidgets, 0, 0));
 
163
    }
 
164
}