Commit 6863a781 by Philipp Adolf

Remove use of glBindBufferRange

Fixes #10 Didn't work with some models. I'm guessing that there are requirements for the offset (divisible by some power of 2 or something) that we just happen to meet with some models but not with others. New version binds the full output buffer but adds another buffer that contains the offset into the output buffer.
parent 19594b3f
......@@ -20,8 +20,12 @@ layout(std430, binding=2) writeonly buffer Output {
Vertex edges[];
};
layout(std430, binding=3) readonly buffer OutputOffset {
unsigned int output_offset;
};
void main(){
edges[gl_GlobalInvocationID.x].uv = vec2(0.0, 0.0);
edges[output_offset + gl_GlobalInvocationID.x].uv = vec2(0.0, 0.0);
Vertex a = vertices[indices[gl_GlobalInvocationID.x][0]];
Vertex b = vertices[indices[gl_GlobalInvocationID.x][1]];
......@@ -30,6 +34,6 @@ void main(){
vec3 pos;
edges[gl_GlobalInvocationID.x].pos = 3.0f/8.0f * a.pos + 3.0f/8.0f * b.pos + 1.0f/8.0f * c.pos + 1.0f/8.0f * d.pos;
edges[gl_GlobalInvocationID.x].norm = normalize(3.0f/8.0f * a.norm + 3.0f/8.0f * b.norm + 1.0f/8.0f * c.norm + 1.0f/8.0f * d.norm);
edges[output_offset + gl_GlobalInvocationID.x].pos = 3.0f/8.0f * a.pos + 3.0f/8.0f * b.pos + 1.0f/8.0f * c.pos + 1.0f/8.0f * d.pos;
edges[output_offset + gl_GlobalInvocationID.x].norm = normalize(3.0f/8.0f * a.norm + 3.0f/8.0f * b.norm + 1.0f/8.0f * c.norm + 1.0f/8.0f * d.norm);
}
......@@ -26,10 +26,14 @@ layout(std430, binding=3) writeonly buffer Output {
Vertex new_vertices[];
};
layout(std430, binding=4) readonly buffer OutputOffset {
unsigned int output_offset;
};
void main(){
unsigned int size = offsets[gl_GlobalInvocationID.x + 1] - offsets[gl_GlobalInvocationID.x];
new_vertices[gl_GlobalInvocationID.x].uv = vec2(0.0f, 0.0f);
new_vertices[output_offset + gl_GlobalInvocationID.x].uv = vec2(0.0f, 0.0f);
// FIXME: size or size - 1?
float t = 3.0f/8.0f + 2.0f/8.0f * cos(2.0f * M_PI / (float(size) - 1.0f));
......@@ -42,6 +46,6 @@ void main(){
norm += vertices[indices[offsets[gl_GlobalInvocationID.x] + i]].norm;
}
new_vertices[gl_GlobalInvocationID.x].pos = (1.0f - alpha) * vertices[indices[offsets[gl_GlobalInvocationID.x]]].pos + alpha / (float(size) - 1.0f) * pos;
new_vertices[gl_GlobalInvocationID.x].norm = normalize((1.0f - alpha) * vertices[indices[offsets[gl_GlobalInvocationID.x]]].norm + alpha / (float(size) - 1.0f) * norm);
new_vertices[output_offset + gl_GlobalInvocationID.x].pos = (1.0f - alpha) * vertices[indices[offsets[gl_GlobalInvocationID.x]]].pos + alpha / (float(size) - 1.0f) * pos;
new_vertices[output_offset + gl_GlobalInvocationID.x].norm = normalize((1.0f - alpha) * vertices[indices[offsets[gl_GlobalInvocationID.x]]].norm + alpha / (float(size) - 1.0f) * norm);
}
......@@ -736,18 +736,35 @@ Subdivision::Result Subdivision::runShader(Input input, Tables &tables) {
f->glBufferData(GL_SHADER_STORAGE_BUFFER, output_size * sizeof(Vertex), NULL, GL_DYNAMIC_DRAW);
result.vb_handle = output_handle;
// Create a buffer for holding the offset into the output
GLuint offset_handle;
f->glGenBuffers(1, &offset_handle);
f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, offset_handle);
f->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_DRAW);
// copy old vertices
f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
QTime timer;
timer.start();
runCopyShader(input.vertex_buffer.size(), input.vb_handle, output_handle);
int copyTime = timer.elapsed();
// calculate positions of new vertices
timer.restart();
int edge_offset = input.vertex_buffer.size();
runEdgeShader(tables.edge_indices.size() / 4, input.vb_handle, edge_indices_handle, output_handle, edge_offset);
f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, offset_handle);
GLuint *offset_buffer = (GLuint *) f->glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
*offset_buffer = input.vertex_buffer.size();
f->glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
runEdgeShader(tables.edge_indices.size() / 4, input.vb_handle, edge_indices_handle, output_handle, offset_handle);
int edgeTime = timer.elapsed();
// move old vertices
timer.restart();
int vertex_offset = edge_offset + tables.edge_indices.size() / 4;
runVertexShader(tables.vertex_offsets.size() - 1, input.vb_handle, vertex_indices_handle, vertex_offsets_handle, output_handle, vertex_offset);
f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, offset_handle);
offset_buffer = (GLuint *) f->glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
*offset_buffer = input.vertex_buffer.size() + tables.edge_indices.size() / 4;
f->glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
runVertexShader(tables.vertex_offsets.size() - 1, input.vb_handle, vertex_indices_handle, vertex_offsets_handle, output_handle, offset_handle);
int vertexTime = timer.elapsed();
timer.restart();
......@@ -766,6 +783,7 @@ Subdivision::Result Subdivision::runShader(Input input, Tables &tables) {
f->glDeleteBuffers(1, &vertex_indices_handle);
f->glDeleteBuffers(1, &vertex_offsets_handle);
f->glDeleteBuffers(1, &edge_indices_handle);
f->glDeleteBuffers(1, &offset_handle);
qCDebug(log_timing)<<"Compute Shader done. Copyshader"<<copyTime<<"ms; Vertexshader"<<vertexTime<<"ms; EdgeShader"<<edgeTime<<" BufferToCPU"<<bufferbildTime<<"ms";
return result;
......@@ -790,13 +808,14 @@ void Subdivision::runCopyShader(GLuint size, GLuint vb_in, GLuint vb_out) {
copyShader->release();
}
void Subdivision::runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_indices_handle, GLuint vertex_offsets_handle, GLuint output_handle, GLuint offset) {
void Subdivision::runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_indices_handle, GLuint vertex_offsets_handle, GLuint output_handle, GLuint offset_handle) {
vertexShader->bind();
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, vb_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, vertex_indices_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, vertex_offsets_handle);
f->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 3, output_handle, offset * sizeof(Vertex), size * sizeof(Vertex));
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, output_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, offset_handle);
// Run the shader
f->glDispatchCompute(size, 1, 1);
......@@ -809,16 +828,18 @@ void Subdivision::runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_i
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, 0);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, 0);
vertexShader->release();
}
void Subdivision::runEdgeShader(GLuint size, GLuint vb_handle, GLuint edge_indices_handle, GLuint output_handle, GLuint offset) {
void Subdivision::runEdgeShader(GLuint size, GLuint vb_handle, GLuint edge_indices_handle, GLuint output_handle, GLuint offset_handle) {
edgeShader->bind();
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, vb_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, edge_indices_handle);
f->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 2, output_handle, offset * sizeof(Vertex), size * sizeof(Vertex));
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, output_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, offset_handle);
// Run the shader
f->glDispatchCompute(size, 1, 1);
......@@ -830,6 +851,7 @@ void Subdivision::runEdgeShader(GLuint size, GLuint vb_handle, GLuint edge_indic
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, 0);
edgeShader->release();
}
......@@ -63,8 +63,8 @@ private:
void findRegular(QVector<unsigned int> index_buffer, QVector<Vertex> vertex_buffer, QVector<unsigned int> &regular, QVector<unsigned int> &irregular);
Result runShader(Input input, Tables &tables);
void runCopyShader(GLuint size, GLuint vb_in, GLuint vb_out);
void runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_indices_handle, GLuint vertex_offsets_handle, GLuint output_handle, GLuint offset);
void runEdgeShader(GLuint size, GLuint vb_handle, GLuint edge_indices_handle, GLuint output_handle, GLuint offset);
void runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_indices_handle, GLuint vertex_offsets_handle, GLuint output_handle, GLuint offset_handle);
void runEdgeShader(GLuint size, GLuint vb_handle, GLuint edge_indices_handle, GLuint output_handle, GLuint offset_handle);
QVector<unsigned int> patchIBToTriangleIB(QVector<unsigned int> ib);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment