Улучшение безопасности PBO
This commit is contained in:
@@ -23,6 +23,7 @@ public final class FogChunkStreamer {
|
||||
// Битовые маски вместо массивов статусов
|
||||
private static final AtomicLongArray pendingMask = new AtomicLongArray(TOTAL_WORDS);
|
||||
private static final AtomicLongArray readyMask = new AtomicLongArray(TOTAL_WORDS);
|
||||
private static final Object sharedStateLock = new Object();
|
||||
|
||||
// Pre-allocated массивы данных
|
||||
private static final byte[][] preparedData = new byte[TOTAL_CHUNKS][CHUNK_DATA_SIZE];
|
||||
@@ -130,6 +131,7 @@ public final class FogChunkStreamer {
|
||||
int newOriginChunkX, int newOriginChunkZ,
|
||||
int ringChunkOffsetX, int ringChunkOffsetZ
|
||||
) {
|
||||
synchronized (sharedStateLock) {
|
||||
currentOriginChunkX = newOriginChunkX;
|
||||
currentOriginChunkZ = newOriginChunkZ;
|
||||
currentRingChunkOffsetX = ringChunkOffsetX;
|
||||
@@ -191,6 +193,7 @@ public final class FogChunkStreamer {
|
||||
|
||||
uploadReadyData();
|
||||
}
|
||||
}
|
||||
|
||||
private static void markPendingRange(int worldX, int worldZ, int countX, int countZ) {
|
||||
for (int i = 0; i < countX; i++) {
|
||||
@@ -305,6 +308,7 @@ public final class FogChunkStreamer {
|
||||
}
|
||||
|
||||
public static void processPending() {
|
||||
synchronized (sharedStateLock) {
|
||||
int originX = currentOriginChunkX;
|
||||
int originZ = currentOriginChunkZ;
|
||||
int ringOffsetX = currentRingChunkOffsetX;
|
||||
@@ -336,8 +340,10 @@ public final class FogChunkStreamer {
|
||||
}
|
||||
if (burstFrames > 0) burstFrames--;
|
||||
}
|
||||
}
|
||||
|
||||
public static void uploadReadyData() {
|
||||
synchronized (sharedStateLock) {
|
||||
int originX = currentOriginChunkX;
|
||||
int originZ = currentOriginChunkZ;
|
||||
int ringOffsetX = currentRingChunkOffsetX;
|
||||
@@ -375,6 +381,7 @@ public final class FogChunkStreamer {
|
||||
FogWorldVolume.endUpload();
|
||||
if (burstFrames > 0) burstFrames--;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setBurst(int frames) {
|
||||
burstFrames = Math.max(burstFrames, frames);
|
||||
|
||||
@@ -18,6 +18,7 @@ public final class FogLightStreamer {
|
||||
private static final AtomicLongArray readySkyMask = new AtomicLongArray(TOTAL_WORDS);
|
||||
private static final AtomicLongArray initialBlockMask = new AtomicLongArray(TOTAL_WORDS);
|
||||
private static final AtomicLongArray initialSkyMask = new AtomicLongArray(TOTAL_WORDS);
|
||||
private static final Object sharedStateLock = new Object();
|
||||
|
||||
// Flat массивы для мировых координат
|
||||
private static final int[] preparedBlockWorldX = new int[TOTAL_SECTIONS];
|
||||
@@ -159,6 +160,7 @@ public final class FogLightStreamer {
|
||||
int newOriginChunkX, int newOriginChunkZ,
|
||||
int ringChunkOffsetX, int ringChunkOffsetZ
|
||||
) {
|
||||
synchronized (sharedStateLock) {
|
||||
currentOriginChunkX = newOriginChunkX;
|
||||
currentOriginChunkZ = newOriginChunkZ;
|
||||
currentRingChunkOffsetX = ringChunkOffsetX;
|
||||
@@ -205,6 +207,7 @@ public final class FogLightStreamer {
|
||||
FogLightVolume.clearRegions(regionPhysX, regionPhysZ, regionWidth, regionDepth, regionCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addInitialLoadForRange(int worldX, int worldZ, int countX, int countZ) {
|
||||
int minY = FogWorldVolume.MIN_Y >> 4;
|
||||
@@ -290,6 +293,7 @@ public final class FogLightStreamer {
|
||||
* обрабатываем и initial, и pending параллельно, чтобы избежать пиков.
|
||||
*/
|
||||
public static void prepareAllSections() {
|
||||
synchronized (sharedStateLock) {
|
||||
int processedBlock = 0;
|
||||
int processedSky = 0;
|
||||
|
||||
@@ -344,8 +348,10 @@ public final class FogLightStreamer {
|
||||
}
|
||||
if (burstFrames > 0) burstFrames--;
|
||||
}
|
||||
}
|
||||
|
||||
public static void uploadReadySections() {
|
||||
synchronized (sharedStateLock) {
|
||||
int processedBlock = 0;
|
||||
int processedSky = 0;
|
||||
int index = 0;
|
||||
@@ -375,6 +381,7 @@ public final class FogLightStreamer {
|
||||
FogLightVolume.endUpload();
|
||||
if (burstFrames > 0) burstFrames--;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setBurst(int frames) {
|
||||
burstFrames = Math.max(burstFrames, frames);
|
||||
|
||||
@@ -42,8 +42,9 @@ public final class FogWorldVolume {
|
||||
|
||||
// PBO для быстрой очистки регионов
|
||||
private static int clearPBO = -1;
|
||||
// PBO для загрузки чанков
|
||||
private static int uploadPBO = -1;
|
||||
// Ring of PBOs for chunk uploads to avoid overwriting a buffer while the GPU is still using it
|
||||
private static final int[] uploadPBOs = new int[3];
|
||||
private static int uploadPBOIndex = 0;
|
||||
private static final int MAX_CLEAR_SIZE = SIZE_X * SIZE_Y * SIZE_Z;
|
||||
|
||||
private FogWorldVolume() {
|
||||
@@ -213,10 +214,11 @@ public final class FogWorldVolume {
|
||||
int textureChunkZ,
|
||||
byte[] data
|
||||
) {
|
||||
// Use PBO to upload without stalling the driver
|
||||
if (uploadPBO != -1) {
|
||||
GL15.glBindBuffer(GL31.GL_PIXEL_UNPACK_BUFFER, uploadPBO);
|
||||
// Orphan and allocate
|
||||
// Use a ring of PBOs so one upload never overwrites another still pending on the GPU
|
||||
if (uploadPBOs[0] != 0) {
|
||||
int pbo = uploadPBOs[uploadPBOIndex % uploadPBOs.length];
|
||||
uploadPBOIndex++;
|
||||
GL15.glBindBuffer(GL31.GL_PIXEL_UNPACK_BUFFER, pbo);
|
||||
GL15.glBufferData(GL31.GL_PIXEL_UNPACK_BUFFER, CHUNK_SIZE * SIZE_Y * CHUNK_SIZE, GL15.GL_STREAM_DRAW);
|
||||
ByteBuffer mapped = GL15.glMapBuffer(GL31.GL_PIXEL_UNPACK_BUFFER, GL15.GL_WRITE_ONLY);
|
||||
if (mapped != null) {
|
||||
@@ -263,10 +265,11 @@ public final class FogWorldVolume {
|
||||
}
|
||||
|
||||
private static void initUploadPBO() {
|
||||
if (uploadPBO != -1) return;
|
||||
uploadPBO = GL15.glGenBuffers();
|
||||
GL15.glBindBuffer(GL31.GL_PIXEL_UNPACK_BUFFER, uploadPBO);
|
||||
for (int i = 0; i < uploadPBOs.length; i++) {
|
||||
uploadPBOs[i] = GL15.glGenBuffers();
|
||||
GL15.glBindBuffer(GL31.GL_PIXEL_UNPACK_BUFFER, uploadPBOs[i]);
|
||||
GL15.glBufferData(GL31.GL_PIXEL_UNPACK_BUFFER, CHUNK_SIZE * SIZE_Y * CHUNK_SIZE, GL15.GL_STREAM_DRAW);
|
||||
}
|
||||
GL15.glBindBuffer(GL31.GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ const float SCATTERING_COEFF = 1.0;
|
||||
const float AMBIENT_INTENSITY = 0.10;
|
||||
const float MIN_TRANSMITTANCE = 0.01;
|
||||
|
||||
const float AMBIENT_FOG = 0.01;
|
||||
const float AMBIENT_FOG = 0.0025;
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
@@ -99,7 +99,7 @@ float density(vec3 worldPos)
|
||||
{
|
||||
vec3 uv = worldToUV(worldPos);
|
||||
if (uv.x < 0.0) return 0.0;
|
||||
return max(texture(BlockLightVolume, uv).r, 1.0-texture(SkyLightVolume, uv).r)*0.1;
|
||||
return max(texture(FogVolume, uv).r, AMBIENT_FOG*texture(SkyLightVolume, uv).r);
|
||||
}
|
||||
|
||||
vec2 light(vec3 worldPos)
|
||||
|
||||
Reference in New Issue
Block a user