Skip to content

Instantly share code, notes, and snippets.

@grondag
Created February 17, 2019 15:53
Show Gist options
  • Select an option

  • Save grondag/c1aa6af7c0815c3b00771e73293b2f15 to your computer and use it in GitHub Desktop.

Select an option

Save grondag/c1aa6af7c0815c3b00771e73293b2f15 to your computer and use it in GitHub Desktop.

Revisions

  1. grondag created this gist Feb 17, 2019.
    353 changes: 353 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,353 @@
    Benchmark Mode Cnt Score Error Units
    VertexAccess.testQuadIndexed thrpt 25 1792.170 ± 35.819 ops/s
    VertexAccess.testVertexDirect thrpt 25 1854.714 ± 7.662 ops/s
    VertexAccess.testVertexIndexed thrpt 25 1847.824 ± 26.582 ops/s

    public class VertexAccess {

    class Quad {
    static final int VERTEX_STRIDE = 16;
    static final int QUAD_STRIDE = VERTEX_STRIDE * 4;
    static final int TEX_START = 4;
    static final int TEX_STRIDE = 3;

    final Vertex[] vertex = new Vertex[4];
    int[] data;
    int baseIndex;

    Quad(int[] data, int baseIndex) {
    this.data = data;
    this.baseIndex = baseIndex;
    for(int i = 0; i < 4; i++) {
    vertex[i] = new Vertex(i);
    }
    }

    Vertex vertex(int i) {
    return vertex[i];
    }

    float x(int i) {
    return Float.intBitsToFloat(data[baseIndex + i * VERTEX_STRIDE]);
    }

    Quad x(int i, float x) {
    data[baseIndex + i * VERTEX_STRIDE] = Float.floatToRawIntBits(x);
    return this;
    }

    float y(int i) {
    return Float.intBitsToFloat(data[baseIndex + i * VERTEX_STRIDE + 1]);
    }

    Quad y(int i, float y) {
    data[baseIndex + i * VERTEX_STRIDE + 1] = Float.floatToRawIntBits(y);
    return this;
    }

    float z(int i) {
    return Float.intBitsToFloat(data[baseIndex + i * VERTEX_STRIDE + 2]);
    }

    Quad z(int i, float z) {
    data[baseIndex + i * VERTEX_STRIDE + 2] = Float.floatToRawIntBits(z);
    return this;
    }

    int color(int i, int j) {
    return data[baseIndex + i * VERTEX_STRIDE + TEX_START + j * TEX_STRIDE];
    }

    Quad color(int i, int j, int c) {
    data[baseIndex + i * VERTEX_STRIDE + TEX_START + j * TEX_STRIDE] = c;
    return this;
    }

    float u(int i, int j) {
    return Float.intBitsToFloat(data[baseIndex + i * VERTEX_STRIDE + TEX_START + j * TEX_STRIDE + 1]);
    }

    Quad u(int i, int j, float u) {
    data[baseIndex + i * VERTEX_STRIDE + TEX_START + j * TEX_STRIDE + 1] = Float.floatToRawIntBits(u);
    return this;
    }

    float v(int i, int j) {
    return Float.intBitsToFloat(data[baseIndex + i * VERTEX_STRIDE + TEX_START + j * TEX_STRIDE + 2]);
    }

    Quad v(int i, int j, float v) {
    data[baseIndex + i * VERTEX_STRIDE + TEX_START + j * TEX_STRIDE + 2] = Float.floatToRawIntBits(v);
    return this;
    }

    class Vertex {
    private final int texBase;
    private final int xOffset;
    private final int yOffset;
    private final int zOffset;
    private final int colorOffset1;
    private final int uOffset1;
    private final int vOffset1;
    private final int colorOffset2;
    private final int uOffset2;
    private final int vOffset2;
    private final int colorOffset3;
    private final int uOffset3;
    private final int vOffset3;

    Vertex(int index) {
    int baseIndex = index * VERTEX_STRIDE;
    texBase = baseIndex + TEX_START;
    xOffset = baseIndex++;
    yOffset = baseIndex++;
    zOffset = baseIndex++;
    colorOffset1 = baseIndex++;
    uOffset1 = baseIndex++;
    vOffset1 = baseIndex++;
    colorOffset2 = baseIndex++;
    uOffset2 = baseIndex++;
    vOffset2 = baseIndex++;
    colorOffset3 = baseIndex++;
    uOffset3 = baseIndex++;
    vOffset3 = baseIndex++;
    }

    float x() {
    return Float.intBitsToFloat(data[baseIndex + xOffset]);
    }

    Vertex x(float x) {
    data[baseIndex + xOffset] = Float.floatToRawIntBits(x);
    return this;
    }

    float y() {
    return Float.intBitsToFloat(data[baseIndex + yOffset]);
    }

    Vertex y(float y) {
    data[baseIndex + yOffset] = Float.floatToRawIntBits(y);
    return this;
    }

    float z() {
    return Float.intBitsToFloat(data[baseIndex + zOffset]);
    }

    Vertex z(float z) {
    data[baseIndex + zOffset] = Float.floatToRawIntBits(z);
    return this;
    }

    int color(int j) {
    return data[baseIndex + texBase + j * TEX_STRIDE];
    }

    Vertex color(int j, int c) {
    data[baseIndex + texBase + j * TEX_STRIDE] = c;
    return this;
    }

    float u(int j) {
    return Float.intBitsToFloat(data[baseIndex + texBase + j * TEX_STRIDE + 1]);
    }

    Vertex u(int j, float u) {
    data[baseIndex + texBase + j * TEX_STRIDE + 1] = Float.floatToRawIntBits(u);
    return this;
    }

    float v(int j) {
    return Float.intBitsToFloat(data[baseIndex + texBase + j * TEX_STRIDE + 2]);
    }

    Vertex v(int j, float v) {
    data[baseIndex + texBase + j * TEX_STRIDE + 2] = Float.floatToRawIntBits(v);
    return this;
    }

    int color1() {
    return data[baseIndex + colorOffset1];
    }

    Vertex color1(int c) {
    data[baseIndex + colorOffset1] = c;
    return this;
    }

    float u1() {
    return Float.intBitsToFloat(data[baseIndex + uOffset1]);
    }

    Vertex u1(float u) {
    data[baseIndex + uOffset1] = Float.floatToRawIntBits(u);
    return this;
    }

    float v1() {
    return Float.intBitsToFloat(data[baseIndex + + vOffset1]);
    }

    Vertex v1(float v) {
    data[baseIndex + vOffset1] = Float.floatToRawIntBits(v);
    return this;
    }

    int color2() {
    return data[baseIndex + colorOffset2];
    }

    Vertex color2(int c) {
    data[baseIndex + colorOffset2] = c;
    return this;
    }

    float u2() {
    return Float.intBitsToFloat(data[baseIndex + uOffset2]);
    }

    Vertex u2(float u) {
    data[baseIndex + uOffset2] = Float.floatToRawIntBits(u);
    return this;
    }

    float v2() {
    return Float.intBitsToFloat(data[baseIndex + + vOffset2]);
    }

    Vertex v2(float v) {
    data[baseIndex + vOffset2] = Float.floatToRawIntBits(v);
    return this;
    }

    int color3() {
    return data[baseIndex + colorOffset3];
    }

    Vertex color3(int c) {
    data[baseIndex + colorOffset3] = c;
    return this;
    }

    float u3() {
    return Float.intBitsToFloat(data[baseIndex + uOffset3]);
    }

    Vertex u3(float u) {
    data[baseIndex + uOffset3] = Float.floatToRawIntBits(u);
    return this;
    }

    float v3() {
    return Float.intBitsToFloat(data[baseIndex + + vOffset3]);
    }

    Vertex v3(float v) {
    data[baseIndex + vOffset3] = Float.floatToRawIntBits(v);
    return this;
    }
    }
    }

    @Benchmark
    public void testVertexDirect() {
    int[] data = new int[Quad.QUAD_STRIDE * 1000];
    Quad q = new Quad(data, 0);
    Random r = new Random();
    for(int i = 0; i < 1000; i++) {
    q.baseIndex = i * Quad.QUAD_STRIDE;
    for(int j = 0; j < 4; j++) {
    Vertex vt = q.vertex(j);
    vt.x(r.nextFloat()).x(vt.x() + .1f).y(r.nextFloat()).x(vt.y() + .1f).z(r.nextFloat()).z(vt.z() + .1f);
    vt.color1(r.nextInt());
    vt.color2(r.nextInt());
    vt.color3(r.nextInt());
    vt.color1(vt.color1() | 0xFF000000);
    vt.color2(vt.color2() | 0x00FFFFFF);
    vt.color3(vt.color3() & 0x00FFFFFF);

    vt.u1(r.nextFloat());
    vt.u2(r.nextFloat());
    vt.u3(r.nextFloat());
    vt.u1(vt.u1() * 0.8f);
    vt.u2(vt.u2() + 0.5f);
    vt.u3(1 - vt.u3());

    vt.v1(r.nextFloat());
    vt.v2(r.nextFloat());
    vt.v3(r.nextFloat());
    vt.v1(vt.v1() * 0.8f);
    vt.v2(vt.v2() + 0.5f);
    vt.v3(1 - vt.v3());
    }
    }
    }

    @Benchmark
    public void testVertexIndexed() {
    int[] data = new int[Quad.QUAD_STRIDE * 1000];
    Quad q = new Quad(data, 0);
    Random r = new Random();
    for(int i = 0; i < 1000; i++) {
    q.baseIndex = i * Quad.QUAD_STRIDE;
    for(int j = 0; j < 4; j++) {
    Vertex vt = q.vertex(j);
    vt.x(r.nextFloat()).x(vt.x() + .1f).y(r.nextFloat()).x(vt.y() + .1f).z(r.nextFloat()).z(vt.z() + .1f);
    vt.color(0, r.nextInt());
    vt.color(1, r.nextInt());
    vt.color(2, r.nextInt());
    vt.color(0, vt.color(0) | 0xFF000000);
    vt.color(1, vt.color(1) | 0x00FFFFFF);
    vt.color(2, vt.color(2) & 0x00FFFFFF);

    vt.u(0, r.nextFloat());
    vt.u(1, r.nextFloat());
    vt.u(2, r.nextFloat());
    vt.u(0, vt.u(0) * 0.8f);
    vt.u(1, vt.u(1) + 0.5f);
    vt.u(2, 1 - vt.u(2));

    vt.v(0, r.nextFloat());
    vt.v(1, r.nextFloat());
    vt.v(2, r.nextFloat());
    vt.v(0, vt.v(0) * 0.8f);
    vt.v(1, vt.v(1) + 0.5f);
    vt.v(2, 1 - vt.v(2));
    }
    }
    }

    @Benchmark
    public void testQuadIndexed() {
    int[] data = new int[Quad.QUAD_STRIDE * 1000];
    Quad q = new Quad(data, 0);
    Random r = new Random();
    for(int i = 0; i < 1000; i++) {
    q.baseIndex = i * Quad.QUAD_STRIDE;
    for(int j = 0; j < 4; j++) {
    q.x(j, r.nextFloat()).x(j, q.x(j) + .1f).y(j, r.nextFloat()).x(j, q.y(j) + .1f).z(j, r.nextFloat()).z(j, q.z(j) + .1f);
    q.color(j, 0, r.nextInt());
    q.color(j, 1, r.nextInt());
    q.color(j, 2, r.nextInt());
    q.color(j, 0, q.color(j, 0) | 0xFF000000);
    q.color(j, 1, q.color(j, 1) | 0x00FFFFFF);
    q.color(j, 2, q.color(j, 2) & 0x00FFFFFF);

    q.u(j, 0, r.nextFloat());
    q.u(j, 1, r.nextFloat());
    q.u(j, 2, r.nextFloat());
    q.u(j, 0, q.u(j, 0) * 0.8f);
    q.u(j, 1, q.u(j, 1) + 0.5f);
    q.u(j, 2, 1 - q.u(j, 2));

    q.v(j, 0, r.nextFloat());
    q.v(j, 1, r.nextFloat());
    q.v(j, 2, r.nextFloat());
    q.v(j, 0, q.v(j, 0) * 0.8f);
    q.v(j, 1, q.v(j, 1) + 0.5f);
    q.v(j, 2, 1 - q.v(j, 2));
    }
    }
    }
    }