/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package tests.gl_450; import com.jogamp.opengl.GL; import static com.jogamp.opengl.GL2GL3.*; import static com.jogamp.opengl.GL3ES3.*; import com.jogamp.opengl.GL4; import com.jogamp.opengl.util.GLBuffers; import com.jogamp.opengl.util.glsl.ShaderCode; import com.jogamp.opengl.util.glsl.ShaderProgram; import glm.glm; import glm.mat._4.Mat4; import glm.vec._2.Vec2; import framework.BufferUtils; import framework.Profile; import framework.Semantic; import framework.Test; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.ShortBuffer; import java.util.logging.Level; import java.util.logging.Logger; import jgli.Texture2d; /** * * @author GBarbieri */ public class Gl_450_query_statistics_arb extends Test { public static void main(String[] args) { Gl_450_query_statistics_arb gl_450_query_statistics_arb = new Gl_450_query_statistics_arb(); } public Gl_450_query_statistics_arb() { super("gl-450-query-statistics-arb", Profile.CORE, 4, 5); } private final String SHADERS_SOURCE = "query-statistics"; private final String SHADERS_ROOT = "src/data/gl_450"; private final String TEXTURE_DIFFUSE = "kueken7_rgba8_srgb.dds"; private int vertexCount = 4; private int vertexSize = vertexCount * glf.Vertex_v2fv2f.SIZE; private float[] vertexData = { -1.0f, -1.0f,/**/ 0.0f, 1.0f, +1.0f, -1.0f,/**/ 1.0f, 1.0f, +1.0f, +1.0f,/**/ 1.0f, 0.0f, -1.0f, +1.0f,/**/ 0.0f, 0.0f}; private int elementCount = 6; private int elementSize = elementCount * Short.BYTES; private short[] elementData = { 0, 1, 2, 2, 3, 0}; private class Program { public static final int VERTEX = 0; public static final int FRAGMENT = 1; public static final int MAX = 2; } private class Buffer { public static final int VERTEX = 0; public static final int ELEMENT = 1; public static final int TRANSFORM = 2; public static final int MAX = 3; } private class Statistics { public static final int VERTICES_SUBMITTED = 0; public static final int PRIMITIVES_SUBMITTED = 1; public static final int VERTEX_SHADER_INVOCATIONS = 2; public static final int TESS_CONTROL_SHADER_PATCHES = 3; public static final int TESS_EVALUATION_SHADER_INVOCATIONS = 4; public static final int GEOMETRY_SHADER_INVOCATIONS = 5; public static final int GEOMETRY_SHADER_PRIMITIVES_EMITTED = 6; public static final int FRAGMENT_SHADER_INVOCATIONS = 7; public static final int COMPUTE_SHADER_INVOCATIONS = 8; public static final int CLIPPING_INPUT_PRIMITIVES = 9; public static final int CLIPPING_OUTPUT_PRIMITIVES = 10; public static final int MAX = 11; } private IntBuffer pipelineName = GLBuffers.newDirectIntBuffer(1), vertexArrayName = GLBuffers.newDirectIntBuffer(1), textureName = GLBuffers.newDirectIntBuffer(1), bufferName = GLBuffers.newDirectIntBuffer(Buffer.MAX), queryName = GLBuffers.newDirectIntBuffer(Statistics.MAX); private int[] programName = new int[Program.MAX]; @Override protected boolean begin(GL gl) { GL4 gl4 = (GL4) gl; boolean validated = gl4.isExtensionAvailable("GL_ARB_pipeline_statistics_query"); if (validated) { validated = initQuery(gl4); } if (validated) { validated = initProgram(gl4); } if (validated) { validated = initBuffer(gl4); } if (validated) { validated = initVertexArray(gl4); } if (validated) { validated = initTexture(gl4); } return validated; } private boolean initProgram(GL4 gl4) { boolean validated = true; if (validated) { ShaderCode vertShaderCode = ShaderCode.create(gl4, GL_VERTEX_SHADER, this.getClass(), SHADERS_ROOT, null, SHADERS_SOURCE, "vert", null, true); ShaderCode fragShaderCode = ShaderCode.create(gl4, GL_FRAGMENT_SHADER, this.getClass(), SHADERS_ROOT, null, SHADERS_SOURCE, "frag", null, true); ShaderProgram shaderProgram = new ShaderProgram(); shaderProgram.init(gl4); programName[Program.VERTEX] = shaderProgram.program(); gl4.glProgramParameteri(programName[Program.VERTEX], GL_PROGRAM_SEPARABLE, GL_TRUE); shaderProgram.add(vertShaderCode); shaderProgram.link(gl4, System.out); shaderProgram = new ShaderProgram(); shaderProgram.init(gl4); programName[Program.FRAGMENT] = shaderProgram.program(); gl4.glProgramParameteri(programName[Program.FRAGMENT], GL_PROGRAM_SEPARABLE, GL_TRUE); shaderProgram.add(fragShaderCode); shaderProgram.link(gl4, System.out); } if (validated) { gl4.glGenProgramPipelines(1, pipelineName); gl4.glUseProgramStages(pipelineName.get(0), GL_VERTEX_SHADER_BIT, programName[Program.VERTEX]); gl4.glUseProgramStages(pipelineName.get(0), GL_FRAGMENT_SHADER_BIT, programName[Program.FRAGMENT]); } return validated & checkError(gl4, "initProgram"); } private boolean initBuffer(GL4 gl4) { boolean validated = true; gl4.glGenBuffers(Buffer.MAX, bufferName); gl4.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferName.get(Buffer.ELEMENT)); ShortBuffer elementBuffer = GLBuffers.newDirectShortBuffer(elementData); gl4.glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementSize, elementBuffer, GL_STATIC_DRAW); BufferUtils.destroyDirectBuffer(elementBuffer); gl4.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); gl4.glBindBuffer(GL_ARRAY_BUFFER, bufferName.get(Buffer.VERTEX)); FloatBuffer vertexBuffer = GLBuffers.newDirectFloatBuffer(vertexData); gl4.glBufferData(GL_ARRAY_BUFFER, vertexSize, vertexBuffer, GL_STATIC_DRAW); BufferUtils.destroyDirectBuffer(vertexBuffer); gl4.glBindBuffer(GL_ARRAY_BUFFER, 0); int[] uniformBufferOffset = {0}; gl4.glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, uniformBufferOffset, 0); int uniformBlockSize = Math.max(Mat4.SIZE, uniformBufferOffset[0]); gl4.glBindBuffer(GL_UNIFORM_BUFFER, bufferName.get(Buffer.TRANSFORM)); gl4.glBufferData(GL_UNIFORM_BUFFER, uniformBlockSize, null, GL_DYNAMIC_DRAW); gl4.glBindBuffer(GL_UNIFORM_BUFFER, 0); return validated; } private boolean initTexture(GL4 gl4) { boolean validated = true; try { jgli.Texture2d texture = new Texture2d(jgli.Load.load(TEXTURE_ROOT + "/" + TEXTURE_DIFFUSE)); jgli.Gl.Format format = jgli.Gl.translate(texture.format()); gl4.glPixelStorei(GL_UNPACK_ALIGNMENT, 1); gl4.glGenTextures(1, textureName); gl4.glActiveTexture(GL_TEXTURE0); gl4.glBindTexture(GL_TEXTURE_2D_ARRAY, textureName.get(0)); gl4.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_R, GL_RED); gl4.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_G, GL_GREEN); gl4.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_B, GL_BLUE); gl4.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); gl4.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0); gl4.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, texture.levels() - 1); gl4.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); gl4.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl4.glTexStorage3D(GL_TEXTURE_2D_ARRAY, texture.levels(), format.internal.value, texture.dimensions(0)[0], texture.dimensions(0)[1], 1); for (int level = 0; level < texture.levels(); ++level) { gl4.glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, 0, texture.dimensions(level)[0], texture.dimensions(level)[1], 1, format.external.value, format.type.value, texture.data(level)); } gl4.glPixelStorei(GL_UNPACK_ALIGNMENT, 4); } catch (IOException ex) { Logger.getLogger(Gl_450_query_statistics_arb.class.getName()).log(Level.SEVERE, null, ex); } return validated; } private boolean initVertexArray(GL4 gl4) { boolean validated = true; gl4.glGenVertexArrays(1, vertexArrayName); gl4.glBindVertexArray(vertexArrayName.get(0)); { gl4.glVertexAttribBinding(Semantic.Attr.POSITION, Semantic.Buffer.STATIC); gl4.glVertexAttribFormat(Semantic.Attr.POSITION, 2, GL_FLOAT, false, 0); gl4.glVertexAttribBinding(Semantic.Attr.TEXCOORD, Semantic.Buffer.STATIC); gl4.glVertexAttribFormat(Semantic.Attr.TEXCOORD, 2, GL_FLOAT, false, Vec2.SIZE); gl4.glEnableVertexAttribArray(Semantic.Attr.POSITION); gl4.glEnableVertexAttribArray(Semantic.Attr.TEXCOORD); gl4.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferName.get(Buffer.ELEMENT)); gl4.glBindVertexBuffer(0, bufferName.get(Buffer.VERTEX), 0, glf.Vertex_v2fv2f.SIZE); } gl4.glBindVertexArray(0); return validated; } private boolean initQuery(GL4 gl4) { gl4.glGenQueries(Statistics.MAX, queryName); int[] queryCounterBits = new int[Statistics.MAX]; gl4.glGetQueryiv(GL_VERTICES_SUBMITTED_ARB, GL_QUERY_COUNTER_BITS, queryCounterBits, Statistics.VERTICES_SUBMITTED); gl4.glGetQueryiv(GL_PRIMITIVES_SUBMITTED_ARB, GL_QUERY_COUNTER_BITS, queryCounterBits, Statistics.PRIMITIVES_SUBMITTED); gl4.glGetQueryiv(GL_VERTEX_SHADER_INVOCATIONS_ARB, GL_QUERY_COUNTER_BITS, queryCounterBits, Statistics.VERTEX_SHADER_INVOCATIONS); gl4.glGetQueryiv(GL_TESS_CONTROL_SHADER_PATCHES_ARB, GL_QUERY_COUNTER_BITS, queryCounterBits, Statistics.TESS_CONTROL_SHADER_PATCHES); gl4.glGetQueryiv(GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB, GL_QUERY_COUNTER_BITS, queryCounterBits, Statistics.TESS_EVALUATION_SHADER_INVOCATIONS); gl4.glGetQueryiv(GL_GEOMETRY_SHADER_INVOCATIONS, GL_QUERY_COUNTER_BITS, queryCounterBits, Statistics.GEOMETRY_SHADER_INVOCATIONS); gl4.glGetQueryiv(GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB, GL_QUERY_COUNTER_BITS, queryCounterBits, Statistics.GEOMETRY_SHADER_PRIMITIVES_EMITTED); gl4.glGetQueryiv(GL_FRAGMENT_SHADER_INVOCATIONS_ARB, GL_QUERY_COUNTER_BITS, queryCounterBits, Statistics.FRAGMENT_SHADER_INVOCATIONS); gl4.glGetQueryiv(GL_COMPUTE_SHADER_INVOCATIONS_ARB, GL_QUERY_COUNTER_BITS, queryCounterBits, Statistics.COMPUTE_SHADER_INVOCATIONS); gl4.glGetQueryiv(GL_CLIPPING_INPUT_PRIMITIVES_ARB, GL_QUERY_COUNTER_BITS, queryCounterBits, Statistics.CLIPPING_INPUT_PRIMITIVES); gl4.glGetQueryiv(GL_CLIPPING_OUTPUT_PRIMITIVES_ARB, GL_QUERY_COUNTER_BITS, queryCounterBits, Statistics.CLIPPING_OUTPUT_PRIMITIVES); boolean validated = true; for (int i = 0; i < queryCounterBits.length; ++i) { validated = validated && queryCounterBits[i] >= 18; } return validated; } @Override protected boolean render(GL gl) { GL4 gl4 = (GL4) gl; { gl4.glBindBuffer(GL_UNIFORM_BUFFER, bufferName.get(Buffer.TRANSFORM)); ByteBuffer pointer = gl4.glMapBufferRange(GL_UNIFORM_BUFFER, 0, Mat4.SIZE, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); Mat4 projection = glm.perspectiveFov_((float) Math.PI * 0.25f, windowSize.x, windowSize.y, 0.1f, 100.0f); Mat4 model = new Mat4(1.0f); pointer.asFloatBuffer().put(projection.mul(viewMat4()).mul(model).toFa_()); // Make sure the uniform buffer is uploaded gl4.glUnmapBuffer(GL_UNIFORM_BUFFER); } gl4.glViewportIndexedf(0, 0, 0, windowSize.x, windowSize.y); gl4.glClearBufferfv(GL_COLOR, 0, new float[]{1.0f, 1.0f, 1.0f, 1.0f}, 0); gl4.glBindProgramPipeline(pipelineName.get(0)); gl4.glActiveTexture(GL_TEXTURE0); gl4.glBindTexture(GL_TEXTURE_2D_ARRAY, textureName.get(0)); gl4.glBindVertexArray(vertexArrayName.get(0)); gl4.glBindBufferBase(GL_UNIFORM_BUFFER, Semantic.Uniform.TRANSFORM0, bufferName.get(Buffer.TRANSFORM)); gl4.glBeginQuery(GL_VERTICES_SUBMITTED_ARB, queryName.get(Statistics.VERTICES_SUBMITTED)); gl4.glBeginQuery(GL_PRIMITIVES_SUBMITTED_ARB, queryName.get(Statistics.PRIMITIVES_SUBMITTED)); gl4.glBeginQuery(GL_VERTEX_SHADER_INVOCATIONS_ARB, queryName.get(Statistics.VERTEX_SHADER_INVOCATIONS)); gl4.glBeginQuery(GL_TESS_CONTROL_SHADER_PATCHES_ARB, queryName.get(Statistics.TESS_CONTROL_SHADER_PATCHES)); gl4.glBeginQuery(GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB, queryName.get(Statistics.TESS_EVALUATION_SHADER_INVOCATIONS)); gl4.glBeginQuery(GL_GEOMETRY_SHADER_INVOCATIONS, queryName.get(Statistics.GEOMETRY_SHADER_INVOCATIONS)); gl4.glBeginQuery(GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB, queryName.get(Statistics.GEOMETRY_SHADER_PRIMITIVES_EMITTED)); gl4.glBeginQuery(GL_FRAGMENT_SHADER_INVOCATIONS_ARB, queryName.get(Statistics.FRAGMENT_SHADER_INVOCATIONS)); gl4.glBeginQuery(GL_COMPUTE_SHADER_INVOCATIONS_ARB, queryName.get(Statistics.COMPUTE_SHADER_INVOCATIONS)); gl4.glBeginQuery(GL_CLIPPING_INPUT_PRIMITIVES_ARB, queryName.get(Statistics.CLIPPING_INPUT_PRIMITIVES)); gl4.glBeginQuery(GL_CLIPPING_OUTPUT_PRIMITIVES_ARB, queryName.get(Statistics.CLIPPING_OUTPUT_PRIMITIVES)); { gl4.glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLES, elementCount, GL_UNSIGNED_SHORT, 0, 1, 0, 0); } gl4.glEndQuery(GL_VERTICES_SUBMITTED_ARB); gl4.glEndQuery(GL_PRIMITIVES_SUBMITTED_ARB); gl4.glEndQuery(GL_VERTEX_SHADER_INVOCATIONS_ARB); gl4.glEndQuery(GL_TESS_CONTROL_SHADER_PATCHES_ARB); gl4.glEndQuery(GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB); gl4.glEndQuery(GL_GEOMETRY_SHADER_INVOCATIONS); gl4.glEndQuery(GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB); gl4.glEndQuery(GL_FRAGMENT_SHADER_INVOCATIONS_ARB); gl4.glEndQuery(GL_COMPUTE_SHADER_INVOCATIONS_ARB); gl4.glEndQuery(GL_CLIPPING_INPUT_PRIMITIVES_ARB); gl4.glEndQuery(GL_CLIPPING_OUTPUT_PRIMITIVES_ARB); IntBuffer queryResult = GLBuffers.newDirectIntBuffer(Statistics.MAX); for (int i = 0; i < queryResult.capacity(); ++i) { gl4.glGetQueryObjectuiv(queryName.get(i), GL_QUERY_RESULT, queryResult); } System.out.println("Verts: " + queryResult.get(Statistics.VERTICES_SUBMITTED) + "; Prims: (" + queryResult.get(Statistics.PRIMITIVES_SUBMITTED) + ", " + queryResult.get(Statistics.GEOMETRY_SHADER_PRIMITIVES_EMITTED) + "); Shaders(" + queryResult.get(Statistics.VERTEX_SHADER_INVOCATIONS) + ", " + queryResult.get(Statistics.TESS_CONTROL_SHADER_PATCHES) + ", " + queryResult.get(Statistics.TESS_EVALUATION_SHADER_INVOCATIONS) + ", " + queryResult.get(Statistics.GEOMETRY_SHADER_INVOCATIONS) + ", " + queryResult.get(Statistics.FRAGMENT_SHADER_INVOCATIONS) + ", " + queryResult.get(Statistics.COMPUTE_SHADER_INVOCATIONS) + "); Clip(" + queryResult.get(Statistics.CLIPPING_INPUT_PRIMITIVES) + ", " + queryResult.get(Statistics.CLIPPING_OUTPUT_PRIMITIVES) + ")\r"); return true; } @Override protected boolean end(GL gl) { GL4 gl4 = (GL4) gl; gl4.glDeleteProgramPipelines(1, pipelineName); BufferUtils.destroyDirectBuffer(pipelineName); gl4.glDeleteProgram(programName[Program.FRAGMENT]); gl4.glDeleteProgram(programName[Program.VERTEX]); gl4.glDeleteBuffers(Buffer.MAX, bufferName); BufferUtils.destroyDirectBuffer(bufferName); gl4.glDeleteTextures(1, textureName); BufferUtils.destroyDirectBuffer(textureName); gl4.glDeleteVertexArrays(1, vertexArrayName); BufferUtils.destroyDirectBuffer(vertexArrayName); return true; } }