Skip to content

Commit a3a408c

Browse files
committed
fix gpu timer support
1 parent 1c99a99 commit a3a408c

7 files changed

Lines changed: 110 additions & 23 deletions

File tree

jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ public class AndroidGL implements GL, GL2, GLES_30, GLExt, GLFbo {
5151
public void resetStats() {
5252
}
5353

54+
@Override
55+
public boolean supportsGpuTimerQuery() {
56+
return false;
57+
}
58+
5459
private static int getLimitBytes(ByteBuffer buffer) {
5560
checkLimit(buffer);
5661
return buffer.limit();
@@ -100,6 +105,9 @@ public void glAttachShader(int program, int shader) {
100105

101106
@Override
102107
public void glBeginQuery(int target, int query) {
108+
if (target == GL.GL_TIME_ELAPSED) {
109+
throw new UnsupportedOperationException("64-bit GPU timer queries are not exposed by the Android GLES bindings");
110+
}
103111
GLES30.glBeginQuery(target, query);
104112
}
105113

@@ -287,6 +295,9 @@ public void glEnableVertexAttribArray(int index) {
287295

288296
@Override
289297
public void glEndQuery(int target) {
298+
if (target == GL.GL_TIME_ELAPSED) {
299+
throw new UnsupportedOperationException("64-bit GPU timer queries are not exposed by the Android GLES bindings");
300+
}
290301
GLES30.glEndQuery(target);
291302
}
292303

@@ -348,10 +359,7 @@ public String glGetProgramInfoLog(int program, int maxLength) {
348359

349360
@Override
350361
public long glGetQueryObjectui64(int query, int pname) {
351-
IntBuffer buff = (IntBuffer)tmpBuff.clear();
352-
//FIXME This is wrong IMO should be glGetQueryObjectui64v with a LongBuffer but it seems the API doesn't provide it.
353-
GLES30.glGetQueryObjectuiv(query, pname, buff);
354-
return buff.get(0);
362+
throw new UnsupportedOperationException("64-bit query results are not exposed by the Android GLES bindings");
355363
}
356364

357365
@Override

jme3-core/src/main/java/com/jme3/app/DetailedProfiler.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
package com.jme3.app;
3333

3434
import com.jme3.profile.*;
35+
import com.jme3.renderer.Caps;
3536
import com.jme3.renderer.Renderer;
3637
import com.jme3.renderer.ViewPort;
3738
import com.jme3.renderer.queue.RenderQueue;
@@ -86,14 +87,16 @@ public void appStep(AppStep step) {
8687
frameTime.setNewFrameValueCpu(System.nanoTime());
8788

8889
frameEnded = false;
89-
for (StatLine statLine : data.values()) {
90-
for (Iterator<Integer> i = statLine.taskIds.iterator(); i.hasNext(); ) {
91-
int id = i.next();
92-
if (renderer.isTaskResultAvailable(id)) {
93-
long val = renderer.getProfilingTime(id);
94-
statLine.setValueGpu(val);
95-
i.remove();
96-
idsPool.push(id);
90+
if (renderer != null) {
91+
for (StatLine statLine : data.values()) {
92+
for (Iterator<Integer> i = statLine.taskIds.iterator(); i.hasNext(); ) {
93+
int id = i.next();
94+
if (renderer.isTaskResultAvailable(id)) {
95+
long val = renderer.getProfilingTime(id);
96+
statLine.setValueGpu(val);
97+
i.remove();
98+
idsPool.push(id);
99+
}
97100
}
98101
}
99102
}
@@ -222,8 +225,8 @@ private void addStep(String path, long value) {
222225
int id = getUnusedTaskId();
223226
line.taskIds.add(id);
224227
renderer.startProfiling(id);
228+
ongoingGpuProfiling = true;
225229
}
226-
ongoingGpuProfiling = true;
227230
prevPath = path;
228231

229232
}
@@ -239,8 +242,13 @@ private String getPath(String step, String... subPath) {
239242
}
240243

241244
public void setRenderer(Renderer renderer) {
242-
this.renderer = renderer;
243-
poolTaskIds(renderer);
245+
idsPool.clear();
246+
if (renderer != null && renderer.getCaps().contains(Caps.GpuTimerQuery)) {
247+
this.renderer = renderer;
248+
poolTaskIds(renderer);
249+
} else {
250+
this.renderer = null;
251+
}
244252
}
245253

246254
private void poolTaskIds(Renderer renderer) {

jme3-core/src/main/java/com/jme3/renderer/Caps.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,12 @@ public enum Caps {
467467
* GPU support for binary shaders.
468468
*/
469469
BinaryShader,
470+
471+
/**
472+
* Supports GPU timer queries with full 64-bit elapsed-time results.
473+
*/
474+
GpuTimerQuery,
475+
470476
/**
471477
* Supporting working with UniformBufferObject.
472478
*/

jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,16 @@ public void glCompressedTexSubImage2D(int target, int level, int xoffset, int yo
890890
*/
891891
public String glGetProgramInfoLog(int program, int maxSize);
892892

893+
/**
894+
* Returns whether this GL binding can execute elapsed-time timer queries
895+
* and read their full 64-bit results.
896+
*
897+
* @return true if full GPU timer query support is exposed by the binding
898+
*/
899+
public default boolean supportsGpuTimerQuery() {
900+
return true;
901+
}
902+
893903
/**
894904
* Unsigned version.
895905
*

jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,13 @@ && hasExtension("GL_ARB_half_float_pixel"))
681681
}
682682
}
683683

684+
if (gl.supportsGpuTimerQuery()
685+
&& (caps.contains(Caps.OpenGL33)
686+
|| hasExtension("GL_ARB_timer_query")
687+
|| (caps.contains(Caps.OpenGLES20) && hasExtension("GL_EXT_disjoint_timer_query")))) {
688+
caps.add(Caps.GpuTimerQuery);
689+
}
690+
684691
if (hasExtension("GL_OES_geometry_shader") || hasExtension("GL_EXT_geometry_shader")) {
685692
caps.add(Caps.GeometryShader);
686693
}
@@ -3828,28 +3835,43 @@ public void setLinearizeSrgbImages(boolean linearize) {
38283835

38293836
@Override
38303837
public int[] generateProfilingTasks(int numTasks) {
3838+
if (!caps.contains(Caps.GpuTimerQuery)) {
3839+
throw new RendererException("GPU timer queries are not supported by the current renderer");
3840+
}
38313841
IntBuffer ids = BufferUtils.createIntBuffer(numTasks);
38323842
gl.glGenQueries(numTasks, ids);
38333843
return BufferUtils.getIntArray(ids);
38343844
}
38353845

38363846
@Override
38373847
public void startProfiling(int taskId) {
3848+
if (!caps.contains(Caps.GpuTimerQuery)) {
3849+
throw new RendererException("GPU timer queries are not supported by the current renderer");
3850+
}
38383851
gl.glBeginQuery(GL.GL_TIME_ELAPSED, taskId);
38393852
}
38403853

38413854
@Override
38423855
public void stopProfiling() {
3856+
if (!caps.contains(Caps.GpuTimerQuery)) {
3857+
throw new RendererException("GPU timer queries are not supported by the current renderer");
3858+
}
38433859
gl.glEndQuery(GL.GL_TIME_ELAPSED);
38443860
}
38453861

38463862
@Override
38473863
public long getProfilingTime(int taskId) {
3864+
if (!caps.contains(Caps.GpuTimerQuery)) {
3865+
throw new RendererException("GPU timer queries are not supported by the current renderer");
3866+
}
38483867
return gl.glGetQueryObjectui64(taskId, GL.GL_QUERY_RESULT);
38493868
}
38503869

38513870
@Override
38523871
public boolean isTaskResultAvailable(int taskId) {
3872+
if (!caps.contains(Caps.GpuTimerQuery)) {
3873+
throw new RendererException("GPU timer queries are not supported by the current renderer");
3874+
}
38533875
return gl.glGetQueryObjectiv(taskId, GL.GL_QUERY_RESULT_AVAILABLE) == 1;
38543876
}
38553877

jme3-ios/src/main/java/com/jme3/renderer/ios/IosGL.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@ public class IosGL implements GL, GL2, GLES_30, GLExt, GLFbo {
5959
@Override
6060
public void resetStats() {
6161
}
62-
62+
63+
@Override
64+
public boolean supportsGpuTimerQuery() {
65+
return false;
66+
}
67+
6368
private static int getLimitBytes(ByteBuffer buffer) {
6469
checkLimit(buffer);
6570
return buffer.limit();
@@ -143,6 +148,9 @@ public void glAttachShader(int program, int shader) {
143148

144149
@Override
145150
public void glBeginQuery(int target, int query) {
151+
if (target == GL.GL_TIME_ELAPSED) {
152+
throw new UnsupportedOperationException("64-bit GPU timer queries are not implemented by the iOS GLES binding");
153+
}
146154
JmeIosGLES.glBeginQuery(target, query);
147155
}
148156

@@ -333,6 +341,9 @@ public void glEnableVertexAttribArray(int index) {
333341

334342
@Override
335343
public void glEndQuery(int target) {
344+
if (target == GL.GL_TIME_ELAPSED) {
345+
throw new UnsupportedOperationException("64-bit GPU timer queries are not implemented by the iOS GLES binding");
346+
}
336347
JmeIosGLES.glEndQuery(target);
337348
}
338349

@@ -398,8 +409,7 @@ public String glGetProgramInfoLog(int program, int maxLength) {
398409

399410
@Override
400411
public long glGetQueryObjectui64(int query, int pname) {
401-
JmeIosGLES.glGetQueryObjectuiv(query, pname, temp_array);
402-
return temp_array[0];
412+
throw new UnsupportedOperationException("64-bit query results are not implemented by the iOS GLES binding");
403413
}
404414

405415
@Override

jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGLES.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
import java.nio.IntBuffer;
1515
import java.nio.ShortBuffer;
1616

17+
import org.lwjgl.opengles.GLES;
1718
import org.lwjgl.opengles.GLES20;
1819
import org.lwjgl.opengles.GLES30;
1920
import org.lwjgl.opengles.GLES31;
21+
import org.lwjgl.opengles.EXTDisjointTimerQuery;
2022

2123

2224
/**
@@ -33,7 +35,6 @@ public class LwjglGLES extends LwjglRender implements GL, GL2, GLES_30, GLExt, G
3335
public void resetStats() {
3436
}
3537

36-
3738
public static void checkLimit(Buffer buffer) {
3839
if (buffer == null) return;
3940
if (buffer.limit() == 0) {
@@ -538,11 +539,25 @@ public void glViewport(int x, int y, int width, int height) {
538539

539540
@Override
540541
public void glBeginQuery(int target, int query) {
542+
if (target == GL.GL_TIME_ELAPSED) {
543+
if (!GLES.getCapabilities().GL_EXT_disjoint_timer_query) {
544+
throw new UnsupportedOperationException("GL_TIME_ELAPSED requires GL_EXT_disjoint_timer_query");
545+
}
546+
EXTDisjointTimerQuery.glBeginQueryEXT(target, query);
547+
return;
548+
}
541549
GLES30.glBeginQuery(target, query);
542550
}
543551

544552
@Override
545553
public void glEndQuery(int target) {
554+
if (target == GL.GL_TIME_ELAPSED) {
555+
if (!GLES.getCapabilities().GL_EXT_disjoint_timer_query) {
556+
throw new UnsupportedOperationException("GL_TIME_ELAPSED requires GL_EXT_disjoint_timer_query");
557+
}
558+
EXTDisjointTimerQuery.glEndQueryEXT(target);
559+
return;
560+
}
546561
GLES30.glEndQuery(target);
547562
}
548563

@@ -552,22 +567,30 @@ public void glGenQueries(int num, IntBuffer buff) {
552567
int oldLimit = buff.limit();
553568
int pos = buff.position();
554569
buff.limit(pos + num);
555-
GLES30.glGenQueries(buff);
570+
if (GLES.getCapabilities().GL_EXT_disjoint_timer_query) {
571+
EXTDisjointTimerQuery.glGenQueriesEXT(buff);
572+
} else {
573+
GLES30.glGenQueries(buff);
574+
}
556575
buff.limit(oldLimit);
557576
}
558577

559578
@Override
560579
public int glGetQueryObjectiv(int query, int pname) {
580+
if (GLES.getCapabilities().GL_EXT_disjoint_timer_query) {
581+
return EXTDisjointTimerQuery.glGetQueryObjectiEXT(query, pname);
582+
}
561583
IntBuffer b = (IntBuffer) tmpBuff.clear();
562584
GLES30.glGetQueryObjectuiv(query, pname, b);
563585
return b.get(0);
564586
}
565587

566588
@Override
567589
public long glGetQueryObjectui64(int query, int pname) {
568-
IntBuffer b = (IntBuffer) tmpBuff.clear();
569-
GLES30.glGetQueryObjectuiv(query, pname, b);
570-
return b.get(0) & 0xFFFFFFFFL;
590+
if (!GLES.getCapabilities().GL_EXT_disjoint_timer_query) {
591+
throw new UnsupportedOperationException("64-bit query results require GL_EXT_disjoint_timer_query");
592+
}
593+
return EXTDisjointTimerQuery.glGetQueryObjectui64EXT(query, pname);
571594
}
572595

573596
@Override

0 commit comments

Comments
 (0)