gpu: add shader for tiles
This has a measurable performance improvement on weaker GPUs since there are generally many tiles and they have few faces
This commit is contained in:
@@ -139,6 +139,9 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
private int glSmallComputeProgram;
|
private int glSmallComputeProgram;
|
||||||
private int glSmallComputeShader;
|
private int glSmallComputeShader;
|
||||||
|
|
||||||
|
private int glUnorderedComputeProgram;
|
||||||
|
private int glUnorderedComputeShader;
|
||||||
|
|
||||||
private int vaoHandle;
|
private int vaoHandle;
|
||||||
|
|
||||||
private int interfaceTexture;
|
private int interfaceTexture;
|
||||||
@@ -168,9 +171,12 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
private GpuIntBuffer vertexBuffer;
|
private GpuIntBuffer vertexBuffer;
|
||||||
private GpuFloatBuffer uvBuffer;
|
private GpuFloatBuffer uvBuffer;
|
||||||
|
|
||||||
|
private GpuIntBuffer modelBufferUnordered;
|
||||||
private GpuIntBuffer modelBufferSmall;
|
private GpuIntBuffer modelBufferSmall;
|
||||||
private GpuIntBuffer modelBuffer;
|
private GpuIntBuffer modelBuffer;
|
||||||
|
|
||||||
|
private int unorderedModels;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* number of models in small buffer
|
* number of models in small buffer
|
||||||
*/
|
*/
|
||||||
@@ -223,9 +229,12 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
bufferId = uvBufferId = uniformBufferId = -1;
|
bufferId = uvBufferId = uniformBufferId = -1;
|
||||||
|
unorderedModels = smallModels = largeModels = 0;
|
||||||
|
|
||||||
vertexBuffer = new GpuIntBuffer();
|
vertexBuffer = new GpuIntBuffer();
|
||||||
uvBuffer = new GpuFloatBuffer();
|
uvBuffer = new GpuFloatBuffer();
|
||||||
|
|
||||||
|
modelBufferUnordered = new GpuIntBuffer();
|
||||||
modelBufferSmall = new GpuIntBuffer();
|
modelBufferSmall = new GpuIntBuffer();
|
||||||
modelBuffer = new GpuIntBuffer();
|
modelBuffer = new GpuIntBuffer();
|
||||||
|
|
||||||
@@ -389,8 +398,10 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
|
|
||||||
vertexBuffer = null;
|
vertexBuffer = null;
|
||||||
uvBuffer = null;
|
uvBuffer = null;
|
||||||
|
|
||||||
modelBufferSmall = null;
|
modelBufferSmall = null;
|
||||||
modelBuffer = null;
|
modelBuffer = null;
|
||||||
|
modelBufferUnordered = null;
|
||||||
|
|
||||||
// force main buffer provider rebuild to turn off alpha channel
|
// force main buffer provider rebuild to turn off alpha channel
|
||||||
client.resizeCanvas();
|
client.resizeCanvas();
|
||||||
@@ -431,6 +442,12 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
source = template.process(resourceLoader.apply("comp_small.glsl"));
|
source = template.process(resourceLoader.apply("comp_small.glsl"));
|
||||||
GLUtil.loadComputeShader(gl, glSmallComputeProgram, glSmallComputeShader, source);
|
GLUtil.loadComputeShader(gl, glSmallComputeProgram, glSmallComputeShader, source);
|
||||||
|
|
||||||
|
glUnorderedComputeProgram = gl.glCreateProgram();
|
||||||
|
glUnorderedComputeShader = gl.glCreateShader(gl.GL_COMPUTE_SHADER);
|
||||||
|
template = new Template(resourceLoader);
|
||||||
|
source = template.process(resourceLoader.apply("comp_unordered.glsl"));
|
||||||
|
GLUtil.loadComputeShader(gl, glUnorderedComputeProgram, glUnorderedComputeShader, source);
|
||||||
|
|
||||||
glUiProgram = gl.glCreateProgram();
|
glUiProgram = gl.glCreateProgram();
|
||||||
glUiVertexShader = gl.glCreateShader(gl.GL_VERTEX_SHADER);
|
glUiVertexShader = gl.glCreateShader(gl.GL_VERTEX_SHADER);
|
||||||
glUiFragmentShader = gl.glCreateShader(gl.GL_FRAGMENT_SHADER);
|
glUiFragmentShader = gl.glCreateShader(gl.GL_FRAGMENT_SHADER);
|
||||||
@@ -484,6 +501,12 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
gl.glDeleteProgram(glSmallComputeProgram);
|
gl.glDeleteProgram(glSmallComputeProgram);
|
||||||
glSmallComputeProgram = -1;
|
glSmallComputeProgram = -1;
|
||||||
|
|
||||||
|
gl.glDeleteShader(glUnorderedComputeShader);
|
||||||
|
glUnorderedComputeShader = -1;
|
||||||
|
|
||||||
|
gl.glDeleteProgram(glUnorderedComputeProgram);
|
||||||
|
glUnorderedComputeProgram = -1;
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
gl.glDeleteShader(glUiVertexShader);
|
gl.glDeleteShader(glUiVertexShader);
|
||||||
@@ -672,7 +695,8 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
y -= client.getCameraY2();
|
y -= client.getCameraY2();
|
||||||
z -= client.getCameraZ2();
|
z -= client.getCameraZ2();
|
||||||
|
|
||||||
GpuIntBuffer b = bufferForTriangles(2);
|
GpuIntBuffer b = modelBufferUnordered;
|
||||||
|
++unorderedModels;
|
||||||
|
|
||||||
b.ensureCapacity(8);
|
b.ensureCapacity(8);
|
||||||
IntBuffer buffer = b.getBuffer();
|
IntBuffer buffer = b.getBuffer();
|
||||||
@@ -701,7 +725,8 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
y -= client.getCameraY2();
|
y -= client.getCameraY2();
|
||||||
z -= client.getCameraZ2();
|
z -= client.getCameraZ2();
|
||||||
|
|
||||||
GpuIntBuffer b = bufferForTriangles(model.getBufferLen() / 3);
|
GpuIntBuffer b = modelBufferUnordered;
|
||||||
|
++unorderedModels;
|
||||||
|
|
||||||
b.ensureCapacity(8);
|
b.ensureCapacity(8);
|
||||||
IntBuffer buffer = b.getBuffer();
|
IntBuffer buffer = b.getBuffer();
|
||||||
@@ -777,16 +802,19 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
uvBuffer.flip();
|
uvBuffer.flip();
|
||||||
modelBuffer.flip();
|
modelBuffer.flip();
|
||||||
modelBufferSmall.flip();
|
modelBufferSmall.flip();
|
||||||
|
modelBufferUnordered.flip();
|
||||||
|
|
||||||
int bufferId = glGenBuffers(gl); // temporary scene vertex buffer
|
int bufferId = glGenBuffers(gl); // temporary scene vertex buffer
|
||||||
int uvBufferId = glGenBuffers(gl); // temporary scene uv buffer
|
int uvBufferId = glGenBuffers(gl); // temporary scene uv buffer
|
||||||
int modelBufferId = glGenBuffers(gl); // scene model buffer, large
|
int modelBufferId = glGenBuffers(gl); // scene model buffer, large
|
||||||
int modelBufferSmallId = glGenBuffers(gl); // scene model buffer, small
|
int modelBufferSmallId = glGenBuffers(gl); // scene model buffer, small
|
||||||
|
int modelBufferUnorderedId = glGenBuffers(gl);
|
||||||
|
|
||||||
IntBuffer vertexBuffer = this.vertexBuffer.getBuffer();
|
IntBuffer vertexBuffer = this.vertexBuffer.getBuffer();
|
||||||
FloatBuffer uvBuffer = this.uvBuffer.getBuffer();
|
FloatBuffer uvBuffer = this.uvBuffer.getBuffer();
|
||||||
IntBuffer modelBuffer = this.modelBuffer.getBuffer();
|
IntBuffer modelBuffer = this.modelBuffer.getBuffer();
|
||||||
IntBuffer modelBufferSmall = this.modelBufferSmall.getBuffer();
|
IntBuffer modelBufferSmall = this.modelBufferSmall.getBuffer();
|
||||||
|
IntBuffer modelBufferUnordered = this.modelBufferUnordered.getBuffer();
|
||||||
|
|
||||||
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, bufferId);
|
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, bufferId);
|
||||||
gl.glBufferData(gl.GL_ARRAY_BUFFER, vertexBuffer.limit() * Integer.BYTES, vertexBuffer, gl.GL_STREAM_DRAW);
|
gl.glBufferData(gl.GL_ARRAY_BUFFER, vertexBuffer.limit() * Integer.BYTES, vertexBuffer, gl.GL_STREAM_DRAW);
|
||||||
@@ -800,6 +828,9 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, modelBufferSmallId);
|
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, modelBufferSmallId);
|
||||||
gl.glBufferData(gl.GL_ARRAY_BUFFER, modelBufferSmall.limit() * Integer.BYTES, modelBufferSmall, gl.GL_STREAM_DRAW);
|
gl.glBufferData(gl.GL_ARRAY_BUFFER, modelBufferSmall.limit() * Integer.BYTES, modelBufferSmall, gl.GL_STREAM_DRAW);
|
||||||
|
|
||||||
|
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, modelBufferUnorderedId);
|
||||||
|
gl.glBufferData(gl.GL_ARRAY_BUFFER, modelBufferUnordered.limit() * Integer.BYTES, modelBufferUnordered, gl.GL_STREAM_DRAW);
|
||||||
|
|
||||||
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0);
|
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
// allocate target vertex buffer for compute shaders
|
// allocate target vertex buffer for compute shaders
|
||||||
@@ -847,6 +878,19 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
* save on GPU resources. Small will sort <= 512 faces, large will do <= 4096.
|
* save on GPU resources. Small will sort <= 512 faces, large will do <= 4096.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// unordered
|
||||||
|
gl.glUseProgram(glUnorderedComputeProgram);
|
||||||
|
|
||||||
|
gl.glBindBufferBase(gl.GL_SHADER_STORAGE_BUFFER, 0, modelBufferUnorderedId);
|
||||||
|
gl.glBindBufferBase(gl.GL_SHADER_STORAGE_BUFFER, 1, this.bufferId);
|
||||||
|
gl.glBindBufferBase(gl.GL_SHADER_STORAGE_BUFFER, 2, bufferId);
|
||||||
|
gl.glBindBufferBase(gl.GL_SHADER_STORAGE_BUFFER, 3, outBufferId);
|
||||||
|
gl.glBindBufferBase(gl.GL_SHADER_STORAGE_BUFFER, 4, outUvBufferId);
|
||||||
|
gl.glBindBufferBase(gl.GL_SHADER_STORAGE_BUFFER, 5, this.uvBufferId);
|
||||||
|
gl.glBindBufferBase(gl.GL_SHADER_STORAGE_BUFFER, 6, uvBufferId);
|
||||||
|
|
||||||
|
gl.glDispatchCompute(unorderedModels, 1, 1);
|
||||||
|
|
||||||
// small
|
// small
|
||||||
gl.glUseProgram(glSmallComputeProgram);
|
gl.glUseProgram(glSmallComputeProgram);
|
||||||
|
|
||||||
@@ -943,9 +987,10 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
uvBuffer.clear();
|
uvBuffer.clear();
|
||||||
modelBuffer.clear();
|
modelBuffer.clear();
|
||||||
modelBufferSmall.clear();
|
modelBufferSmall.clear();
|
||||||
|
modelBufferUnordered.clear();
|
||||||
|
|
||||||
targetBufferOffset = 0;
|
targetBufferOffset = 0;
|
||||||
smallModels = largeModels = 0;
|
smallModels = largeModels = unorderedModels = 0;
|
||||||
tempOffset = 0;
|
tempOffset = 0;
|
||||||
tempUvOffset = 0;
|
tempUvOffset = 0;
|
||||||
|
|
||||||
@@ -953,6 +998,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
|||||||
glDeleteBuffer(gl, uvBufferId);
|
glDeleteBuffer(gl, uvBufferId);
|
||||||
glDeleteBuffer(gl, modelBufferId);
|
glDeleteBuffer(gl, modelBufferId);
|
||||||
glDeleteBuffer(gl, modelBufferSmallId);
|
glDeleteBuffer(gl, modelBufferSmallId);
|
||||||
|
glDeleteBuffer(gl, modelBufferUnorderedId);
|
||||||
glDeleteBuffer(gl, outBufferId);
|
glDeleteBuffer(gl, outBufferId);
|
||||||
glDeleteBuffer(gl, outUvBufferId);
|
glDeleteBuffer(gl, outUvBufferId);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#version 430 core
|
||||||
|
|
||||||
|
#include comp_common.glsl
|
||||||
|
|
||||||
|
layout(local_size_x = 6) in;
|
||||||
|
|
||||||
|
#include common.glsl
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
uint groupId = gl_WorkGroupID.x;
|
||||||
|
uint localId = gl_LocalInvocationID.x;
|
||||||
|
modelinfo minfo = ol[groupId];
|
||||||
|
|
||||||
|
int offset = minfo.offset;
|
||||||
|
int length = minfo.length;
|
||||||
|
int outOffset = minfo.idx;
|
||||||
|
int uvOffset = minfo.uvOffset;
|
||||||
|
int flags = minfo.flags;
|
||||||
|
int orientation = flags & 0x7ff;
|
||||||
|
ivec4 pos = ivec4(minfo.x, minfo.y, minfo.z, 0);
|
||||||
|
|
||||||
|
if (localId >= length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint ssboOffset = localId;
|
||||||
|
ivec4 thisA, thisB, thisC;
|
||||||
|
|
||||||
|
// Grab triangle vertices from the correct buffer
|
||||||
|
if (flags < 0) {
|
||||||
|
thisA = vb[offset + ssboOffset * 3 ];
|
||||||
|
thisB = vb[offset + ssboOffset * 3 + 1];
|
||||||
|
thisC = vb[offset + ssboOffset * 3 + 2];
|
||||||
|
} else {
|
||||||
|
thisA = tempvb[offset + ssboOffset * 3 ];
|
||||||
|
thisB = tempvb[offset + ssboOffset * 3 + 1];
|
||||||
|
thisC = tempvb[offset + ssboOffset * 3 + 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
ivec4 thisrvA = rotate(thisA, orientation);
|
||||||
|
ivec4 thisrvB = rotate(thisB, orientation);
|
||||||
|
ivec4 thisrvC = rotate(thisC, orientation);
|
||||||
|
|
||||||
|
uint myOffset = localId;
|
||||||
|
|
||||||
|
// position vertices in scene and write to out buffer
|
||||||
|
vout[outOffset + myOffset * 3] = pos + thisrvA;
|
||||||
|
vout[outOffset + myOffset * 3 + 1] = pos + thisrvB;
|
||||||
|
vout[outOffset + myOffset * 3 + 2] = pos + thisrvC;
|
||||||
|
|
||||||
|
if (uvOffset < 0) {
|
||||||
|
uvout[outOffset + myOffset * 3] = vec4(0, 0, 0, 0);
|
||||||
|
uvout[outOffset + myOffset * 3 + 1] = vec4(0, 0, 0, 0);
|
||||||
|
uvout[outOffset + myOffset * 3 + 2] = vec4(0, 0, 0, 0);
|
||||||
|
} else if (flags >= 0) {
|
||||||
|
uvout[outOffset + myOffset * 3] = tempuv[uvOffset + localId * 3];
|
||||||
|
uvout[outOffset + myOffset * 3 + 1] = tempuv[uvOffset + localId * 3 + 1];
|
||||||
|
uvout[outOffset + myOffset * 3 + 2] = tempuv[uvOffset + localId * 3 + 2];
|
||||||
|
} else {
|
||||||
|
uvout[outOffset + myOffset * 3] = uv[uvOffset + localId * 3];
|
||||||
|
uvout[outOffset + myOffset * 3 + 1] = uv[uvOffset + localId * 3 + 1];
|
||||||
|
uvout[outOffset + myOffset * 3 + 2] = uv[uvOffset + localId * 3 + 2];
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user