96 lines
2.8 KiB
GLSL
96 lines
2.8 KiB
GLSL
#version 430
|
|
|
|
// pathfinder/shaders/sort.cs.glsl
|
|
//
|
|
// Copyright © 2020 The Pathfinder Project Developers.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
// option. This file may not be copied, modified, or distributed
|
|
// except according to those terms.
|
|
|
|
#extension GL_GOOGLE_include_directive : enable
|
|
|
|
precision highp float;
|
|
|
|
#ifdef GL_ES
|
|
precision highp sampler2D;
|
|
#endif
|
|
|
|
#define TILE_FIELD_NEXT_TILE_ID 0
|
|
#define TILE_FIELD_FIRST_FILL_ID 1
|
|
#define TILE_FIELD_BACKDROP_ALPHA_TILE_ID 2
|
|
#define TILE_FIELD_CONTROL 3
|
|
|
|
#define FILL_INDIRECT_DRAW_PARAMS_SIZE 8
|
|
|
|
uniform int uTileCount;
|
|
|
|
layout(std430, binding = 0) buffer bTiles {
|
|
// [0]: next tile ID
|
|
// [1]: first fill ID
|
|
// [2]: backdrop delta upper 8 bits, alpha tile ID lower 24
|
|
// [3]: color/ctrl/backdrop word
|
|
restrict uint iTiles[];
|
|
};
|
|
|
|
layout(std430, binding = 1) buffer bFirstTileMap {
|
|
restrict int iFirstTileMap[];
|
|
};
|
|
|
|
layout(std430, binding = 2) buffer bZBuffer {
|
|
restrict readonly int iZBuffer[];
|
|
};
|
|
|
|
layout(local_size_x = 64) in;
|
|
|
|
int getFirst(uint globalTileIndex) {
|
|
return iFirstTileMap[globalTileIndex];
|
|
}
|
|
|
|
int getNextTile(int tileIndex) {
|
|
return int(iTiles[tileIndex * 4 + TILE_FIELD_NEXT_TILE_ID]);
|
|
}
|
|
|
|
void setNextTile(int tileIndex, int newNextTileIndex) {
|
|
iTiles[tileIndex * 4 + TILE_FIELD_NEXT_TILE_ID] = uint(newNextTileIndex);
|
|
}
|
|
|
|
void main() {
|
|
uint globalTileIndex = gl_GlobalInvocationID.x;
|
|
if (globalTileIndex >= uint(uTileCount))
|
|
return;
|
|
|
|
int zValue = iZBuffer[FILL_INDIRECT_DRAW_PARAMS_SIZE + globalTileIndex];
|
|
|
|
int unsortedFirstTileIndex = getFirst(globalTileIndex);
|
|
int sortedFirstTileIndex = -1;
|
|
|
|
while (unsortedFirstTileIndex >= 0) {
|
|
int currentTileIndex = unsortedFirstTileIndex;
|
|
unsortedFirstTileIndex = getNextTile(currentTileIndex);
|
|
|
|
if (currentTileIndex >= zValue) {
|
|
int prevTrialTileIndex = -1;
|
|
int trialTileIndex = sortedFirstTileIndex;
|
|
while (true) {
|
|
if (trialTileIndex < 0 || currentTileIndex < trialTileIndex) {
|
|
if (prevTrialTileIndex < 0) {
|
|
setNextTile(currentTileIndex, sortedFirstTileIndex);
|
|
sortedFirstTileIndex = currentTileIndex;
|
|
} else {
|
|
setNextTile(currentTileIndex, trialTileIndex);
|
|
setNextTile(prevTrialTileIndex, currentTileIndex);
|
|
}
|
|
break;
|
|
}
|
|
prevTrialTileIndex = trialTileIndex;
|
|
trialTileIndex = getNextTile(trialTileIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
iFirstTileMap[globalTileIndex] = sortedFirstTileIndex;
|
|
}
|