~mmach/netext73/webkit2gtk

« back to all changes in this revision

Viewing changes to Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/shaders/src/ConvertIndex.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
// ConvertIndex.comp: Convert UINT_8 indices into UINT_16 using a compute shader.
 
7
//
 
8
// The following defines tweak the functionality, and a different shader is built based on these.
 
9
//
 
10
//  - Flags:
 
11
//    * IsPrimitiveRestartEnabled: enables conversion from 0xFF to 0xFFFF,
 
12
//                                 the restart indices for 8-bit and 16-bit indices.
 
13
//    * IsIndirect: Use indirect buffer for index info
 
14
//
 
15
 
 
16
#version 450 core
 
17
 
 
18
layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
 
19
 
 
20
layout (set = 0, binding = 0) buffer dst
 
21
{
 
22
    // Shader invocations output one packed 32-bit value with up to two 16-bit indices.
 
23
    uint dstIndexBuf[];
 
24
};
 
25
 
 
26
layout (set = 0, binding = 1) readonly buffer src
 
27
{
 
28
    // Shader invocations read at most 16 bits of one packed 32-bit value. (Two 8-bit indices.)
 
29
    uint srcIndexBuf[];
 
30
};
 
31
 
 
32
#if IsIndirect
 
33
layout (set = 0, binding = 2) readonly buffer srcIndirect
 
34
{
 
35
    // Shader invocations read from the srcIndirectBuf buffer to determine what indices to convert
 
36
    // The command data starts at offset srcIndirectOffsetDiv4 of the srcIndirectBuf buffer.
 
37
    uint srcIndirectBuf[];
 
38
};
 
39
 
 
40
layout (set = 0, binding = 3) buffer dstIndirect
 
41
{
 
42
    // output indirect buffer data, data starts at dstIndirectBufOffsetDiv4
 
43
    uint dstIndirectBuf[];
 
44
};
 
45
 
 
46
layout (push_constant) uniform PushConstants
 
47
{
 
48
    // Read offset in bytes into the srcIndirectBuf array, divided by four.
 
49
    uint srcIndirectOffsetDiv4;
 
50
    // Write offset in bytes into the dstIndexBuf array, divided by four.
 
51
    uint dstIndexBufOffsetDiv4;
 
52
    // Maximum size of the read buffer. The highest index value we will convert.
 
53
    uint maxIndex;
 
54
    // Write offset in bytes/4 of destinatio indirect buffer
 
55
    uint dstIndirectBufOffsetDiv4;
 
56
};
 
57
 
 
58
#else
 
59
 
 
60
layout (push_constant) uniform PushConstants
 
61
{
 
62
    // Read offset in bytes into the srcIndexBuf array.
 
63
    uint srcIndexOffset;
 
64
    // Write offset in bytes into the dstIndexBuf array, divided by four.
 
65
    uint dstIndexBufOffsetDiv4;
 
66
    // Maximum size of the read buffer. The highest index value we will convert.
 
67
    uint maxIndex;
 
68
    // Not used in the shader. Kept to pad "PushConstants" to the size of a vec4.
 
69
    uint _padding;
 
70
};
 
71
#endif
 
72
 
 
73
uint PullIndex(uint index)
 
74
{
 
75
#if IsIndirect
 
76
    uint srcIndex = index;
 
77
#else
 
78
    uint srcIndex = index + srcIndexOffset;
 
79
#endif
 
80
    uint srcBlock = srcIndexBuf[srcIndex >> 2];
 
81
    uint srcComponent = (srcIndex & 3);
 
82
 
 
83
    uint value = (srcBlock >> (srcComponent << 3)) & 0xFF;
 
84
#if IsPrimitiveRestartEnabled
 
85
    // convert 0xFF (restart value for 8-bit indices)
 
86
    // to 0xFFFF (restart value for 16-bit indices).
 
87
    if (value == 0xFF)
 
88
        value = 0xFFFF;
 
89
#endif
 
90
    return value;
 
91
}
 
92
 
 
93
void PackIndexValue(uint srcValue, uint indexIndex, inout uint dstValue)
 
94
{
 
95
    // Pack 16-byte index into the 32-byte destination.
 
96
    dstValue |= srcValue << (indexIndex << 4);
 
97
}
 
98
 
 
99
void main()
 
100
{
 
101
#if IsIndirect
 
102
    uint indexCount = srcIndirectBuf[srcIndirectOffsetDiv4];
 
103
    uint firstIndex = srcIndirectBuf[srcIndirectOffsetDiv4 + 2];
 
104
    uint endIndex = firstIndex + indexCount;
 
105
#else
 
106
    uint firstIndex = 0;
 
107
    uint endIndex = firstIndex + maxIndex;
 
108
#endif
 
109
 
 
110
    // The element index is invocation ID times two plus
 
111
    // the firstIndex / 2.
 
112
    // This way the first indexCount/2 invocations will transform
 
113
    // the data and any additional invocations will be a no-op
 
114
    uint index = ((gl_GlobalInvocationID.x + (firstIndex >> 1)) << 1);
 
115
 
 
116
    // Don't write anything to dest if we're entirely past the end of the buffer.
 
117
    // We assume buffer size is uint-aligned.
 
118
    if (index >= endIndex)
 
119
        return;
 
120
 
 
121
    uint dstValue = 0;
 
122
 
 
123
    // Skip packing the first index if we're before the first element.
 
124
    if (index >= firstIndex)
 
125
    {
 
126
        uint srcValue = PullIndex(index);
 
127
        PackIndexValue(srcValue, 0, dstValue);
 
128
    }
 
129
 
 
130
    // Skip packing the second index if we're after the last element.
 
131
    if (index + 1 < endIndex)
 
132
    {
 
133
        uint srcValue = PullIndex(index + 1);
 
134
        PackIndexValue(srcValue, 1, dstValue);
 
135
    }
 
136
 
 
137
    dstIndexBuf[dstIndexBufOffsetDiv4 + gl_GlobalInvocationID.x] = dstValue;
 
138
 
 
139
#if IsIndirect
 
140
    // Copy the source indirect draw info (DrawElementsIndirectCommand) to the destination
 
141
    // indirect draw buffer adjusting the firstIndex to account for the offset into dstIndirectBuf
 
142
    // typedef struct {
 
143
    //    uint count;
 
144
    //    uint instanceCount;
 
145
    //    uint firstIndex;
 
146
    //    int baseVertex;
 
147
    //    uint reservedMustBeZero;
 
148
    // } DrawElementsIndirectCommand;
 
149
    if (gl_GlobalInvocationID.x == 0)
 
150
    {
 
151
        dstIndirectBuf[dstIndirectBufOffsetDiv4] = srcIndirectBuf[srcIndirectOffsetDiv4]; // count
 
152
        // instanceCount
 
153
        dstIndirectBuf[dstIndirectBufOffsetDiv4 + 1] = srcIndirectBuf[srcIndirectOffsetDiv4 + 1];
 
154
        // ANGLE will supply dstIndexBufOffset when binding the index buffer so don't
 
155
        // need to worry about that as part of firstIndex for the new indirect buffer command.
 
156
        // firstIndex can be in 2nd half of word so add one if incoming firstIndex is odd
 
157
        dstIndirectBuf[dstIndirectBufOffsetDiv4 + 2] = firstIndex & 1; // firstIndex
 
158
        // baseVertex
 
159
        dstIndirectBuf[dstIndirectBufOffsetDiv4 + 3] = srcIndirectBuf[srcIndirectOffsetDiv4 + 3];
 
160
        dstIndirectBuf[dstIndirectBufOffsetDiv4 + 4] = 0; // reservedMustBeZero
 
161
    }
 
162
#endif
 
163
}