Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 74b28e45 authored by Jason Sams's avatar Jason Sams
Browse files

Rework gl perf test to focus on important use cases.

Change-Id: I82825dbe3b24a520b79f6b05d01f37e1b5008b62
parent fc92bdc7
Loading
Loading
Loading
Loading
+69 −87
Original line number Diff line number Diff line
@@ -14,9 +14,15 @@
 * limitations under the License.
 */

#include "fragment_shaders.cpp"

FILE * fOut = NULL;
void ptSwap();

static char gCurrentTestName[1024];
static uint32_t gWidth = 0;
static uint32_t gHeight = 0;

static void checkGlError(const char* op) {
    for (GLint error = glGetError(); error; error
            = glGetError()) {
@@ -112,20 +118,21 @@ void startTimer() {
    gTime = getTime();
}

void endTimer(const char *str, int w, int h, double dc, int count) {

static void endTimer(int count) {
    uint64_t t2 = getTime();
    double delta = ((double)(t2 - gTime)) / 1000000000;
    double pixels = dc * (w * h) * count;
    double pixels = (gWidth * gHeight) * count;
    double mpps = pixels / delta / 1000000;
    double dc60 = pixels / delta / (w * h) / 60;
    double dc60 = ((double)count) / delta / 60;

    if (fOut) {
        fprintf(fOut, "%s, %f, %f\r\n", str, mpps, dc60);
        fprintf(fOut, "%s, %f, %f\r\n", gCurrentTestName, mpps, dc60);
        fflush(fOut);
    } else {
        printf("%s, %f, %f\n", str, mpps, dc60);
        printf("%s, %f, %f\n", gCurrentTestName, mpps, dc60);
    }
    LOGI("%s, %f, %f\r\n", str, mpps, dc60);
    LOGI("%s, %f, %f\r\n", gCurrentTestName, mpps, dc60);
}


@@ -137,86 +144,17 @@ static const char gVertexShader[] =
    "varying vec4 v_color;\n"
    "varying vec2 v_tex0;\n"
    "varying vec2 v_tex1;\n"
    "uniform vec2 u_texOff;\n"

    "void main() {\n"
    "    v_color = a_color;\n"
    "    v_tex0 = a_tex0;\n"
    "    v_tex1 = a_tex1;\n"
    "    v_tex0.x += u_texOff.x;\n"
    "    v_tex1.y += u_texOff.y;\n"
    "    gl_Position = a_pos;\n"
    "}\n";

static const char gShaderPrefix[] =
    "precision mediump float;\n"
    "uniform vec4 u_color;\n"
    "uniform vec4 u_0;\n"
    "uniform vec4 u_1;\n"
    "uniform vec4 u_2;\n"
    "uniform vec4 u_3;\n"
    "varying vec4 v_color;\n"
    "varying vec2 v_tex0;\n"
    "varying vec2 v_tex1;\n"
    "uniform sampler2D u_tex0;\n"
    "uniform sampler2D u_tex1;\n"
    "void main() {\n";

static const char gShaderPostfix[] =
    "  gl_FragColor = c;\n"
    "}\n";


static char * append(char *d, const char *s) {
    size_t len = strlen(s);
    memcpy(d, s, len);
    return d + len;
}

static char * genShader(
    bool useVarColor,
    int texCount,
    bool modulateFirstTex,
    int extraMath)
{
    char *str = (char *)calloc(16 * 1024, 1);
    char *tmp = append(str, gShaderPrefix);

    if (modulateFirstTex || !texCount) {
        if (useVarColor) {
            tmp = append(tmp, "  vec4 c = v_color;\n");
        } else {
            tmp = append(tmp, "  vec4 c = u_color;\n");
        }
    } else {
        tmp = append(tmp, "  vec4 c = texture2D(u_tex0, v_tex0);\n");
    }

    if (modulateFirstTex && texCount) {
        tmp = append(tmp, "  c *= texture2D(u_tex0, v_tex0);\n");
    }
    if (texCount > 1) {
        tmp = append(tmp, "  c *= texture2D(u_tex1, v_tex1);\n");
    }

    if (extraMath > 0) {
        tmp = append(tmp, "  c *= u_0;\n");
    }
    if (extraMath > 1) {
        tmp = append(tmp, "  c += u_1;\n");
    }
    if (extraMath > 2) {
        tmp = append(tmp, "  c *= u_2;\n");
    }
    if (extraMath > 3) {
        tmp = append(tmp, "  c += u_3;\n");
    }


    tmp = append(tmp, gShaderPostfix);
    tmp[0] = 0;

    //printf("%s", str);
    return str;
}

static void setupVA() {
    static const float vtx[] = {
        -1.0f,-1.0f,
@@ -231,8 +169,8 @@ static void setupVA() {
    static const float tex0[] = {
        0.0f,0.0f,
        1.0f,0.0f,
        1.0f,1.0f,
        0.0f,1.0f };
        0.0f,1.0f,
        1.0f,1.0f };
    static const float tex1[] = {
        1.0f,0.0f,
        1.0f,1.0f,
@@ -261,8 +199,8 @@ static void randUniform(int pgm, const char *var) {
    }
}

static void doLoop(bool clear, int pgm, uint32_t w, uint32_t h, const char *str) {
    if (clear) {
static void doLoop(bool warmup, int pgm, uint32_t passCount) {
    if (warmup) {
        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        ptSwap();
@@ -272,7 +210,10 @@ static void doLoop(bool clear, int pgm, uint32_t w, uint32_t h, const char *str)

    startTimer();
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    for (int ct=0; ct < 100; ct++) {
    for (uint32_t ct=0; ct < passCount; ct++) {
        int loc = glGetUniformLocation(pgm, "u_texOff");
        glUniform2f(loc, ((float)ct) / passCount, ((float)ct) / 2.f / passCount);

        randUniform(pgm, "u_color");
        randUniform(pgm, "u_0");
        randUniform(pgm, "u_1");
@@ -282,14 +223,24 @@ static void doLoop(bool clear, int pgm, uint32_t w, uint32_t h, const char *str)
    }
    ptSwap();
    glFinish();
    endTimer(str, w, h, 1, 100);
    endTimer(passCount);
}


static uint32_t rgb(uint32_t r, uint32_t g, uint32_t b)
{
    uint32_t ret = 0xff000000;
    ret |= r & 0xff;
    ret |= (g & 0xff) << 8;
    ret |= (b & 0xff) << 16;
    return ret;
}

void genTextures() {
    uint32_t *m = (uint32_t *)malloc(1024*1024*4);
    for (int y=0; y < 1024; y++){
        for (int x=0; x < 1024; x++){
            m[y*1024 + x] = 0xff0000ff | ((x & 0xff) << 8) | (y << 16);
            m[y*1024 + x] = rgb(x, (((x+y) & 0xff) == 0x7f) * 0xff, y);
        }
    }
    glBindTexture(GL_TEXTURE_2D, 1);
@@ -301,7 +252,7 @@ void genTextures() {

    for (int y=0; y < 16; y++){
        for (int x=0; x < 16; x++){
            m[y*16 + x] = 0xff0000ff | (x<<12) | (y<<20);
            m[y*16 + x] = rgb(x << 4, (((x+y) & 0xf) == 0x7) * 0xff, y << 4);
        }
    }
    glBindTexture(GL_TEXTURE_2D, 2);
@@ -310,7 +261,38 @@ void genTextures() {
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    free(m);
}

static void doSingleTest(uint32_t pgmNum, int tex) {
    const char *pgmTxt = gFragmentTests[pgmNum]->txt;
    int pgm = createProgram(gVertexShader, pgmTxt);
    if (!pgm) {
        printf("error running test\n");
        return;
    }
    int loc = glGetUniformLocation(pgm, "u_tex0");
    if (loc >= 0) glUniform1i(loc, 0);
    loc = glGetUniformLocation(pgm, "u_tex1");
    if (loc >= 0) glUniform1i(loc, 1);


    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, tex);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, tex);
    glActiveTexture(GL_TEXTURE0);

    glBlendFunc(GL_ONE, GL_ONE);
    glDisable(GL_BLEND);
    //sprintf(str2, "%i, %i, %i, %i, %i, 0",
            //useVarColor, texCount, modulateFirstTex, extraMath, tex0);
    //doLoop(true, pgm, w, h, str2);
    //doLoop(false, pgm, w, h, str2);

    glEnable(GL_BLEND);
    sprintf(gCurrentTestName, "%s, %i, %i, 1", gFragmentTests[pgmNum]->name, pgmNum, tex);
    doLoop(true, pgm, 100);
    doLoop(false, pgm, 100);
}
+6 −52
Original line number Diff line number Diff line
@@ -33,65 +33,19 @@ using namespace android;

#include "fill_common.cpp"

static void doSingleTest(uint32_t w, uint32_t h,
                         bool useVarColor,
                         int texCount,
                         bool modulateFirstTex,
                         int extraMath,
                         int tex0, int tex1) {
    char *pgmTxt = genShader(useVarColor, texCount, modulateFirstTex, extraMath);
    int pgm = createProgram(gVertexShader, pgmTxt);
    if (!pgm) {
        printf("error running test\n");
        return;
    }
    int loc = glGetUniformLocation(pgm, "u_tex0");
    if (loc >= 0) glUniform1i(loc, 0);
    loc = glGetUniformLocation(pgm, "u_tex1");
    if (loc >= 0) glUniform1i(loc, 1);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, tex0);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, tex1);
    glActiveTexture(GL_TEXTURE0);

    char str2[1024];

    glBlendFunc(GL_ONE, GL_ONE);
    glDisable(GL_BLEND);
    //sprintf(str2, "%i, %i, %i, %i, %i, 0",
            //useVarColor, texCount, modulateFirstTex, extraMath, tex0);
    //doLoop(true, pgm, w, h, str2);
    //doLoop(false, pgm, w, h, str2);

    glEnable(GL_BLEND);
    sprintf(str2, "%i, %i, %i, %i, %i, 1",
            useVarColor, texCount, modulateFirstTex, extraMath, tex0);
    doLoop(true, pgm, w, h, str2);
    doLoop(false, pgm, w, h, str2);
}

bool doTest(uint32_t w, uint32_t h) {
    gWidth = w;
    gHeight = h;
    setupVA();
    genTextures();

    printf("\nvarColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\n");

    for (int texCount = 0; texCount < 2; texCount++) {
        for (int extraMath = 0; extraMath < 5; extraMath++) {

            doSingleTest(w, h, false, texCount, false, extraMath, 1, 1);
            doSingleTest(w, h, true, texCount, false, extraMath, 1, 1);
            if (texCount) {
                doSingleTest(w, h, false, texCount, true, extraMath, 1, 1);
                doSingleTest(w, h, true, texCount, true, extraMath, 1, 1);

                doSingleTest(w, h, false, texCount, false, extraMath, 2, 2);
                doSingleTest(w, h, true, texCount, false, extraMath, 2, 2);
                doSingleTest(w, h, false, texCount, true, extraMath, 2, 2);
                doSingleTest(w, h, true, texCount, true, extraMath, 2, 2);
            }
    for (uint32_t num = 0; num < gFragmentTestCount; num++) {
        doSingleTest(num, 2);
        if (gFragmentTests[num]->texCount) {
            doSingleTest(num, 1);
        }
    }

+139 −0
Original line number Diff line number Diff line

typedef struct FragmentTestRec {
	const char * name;
	uint32_t texCount;
	const char * txt;
} FragmentTest;

static FragmentTest fpFill = {
	"Solid color", 0,

    "precision mediump float;\n"
    "uniform vec4 u_color;\n"
    "void main() {\n"
    "  gl_FragColor = u_color;\n"
    "}\n"
};

static FragmentTest fpGradient = {
	"Solid gradient", 0,

    "precision mediump float;\n"
    "varying lowp vec4 v_color;\n"
    "void main() {\n"
    "  gl_FragColor = v_color;\n"
    "}\n"
};

static FragmentTest fpCopyTex = {
	"Texture copy", 1,

    "precision mediump float;\n"
    "varying vec2 v_tex0;\n"
    "uniform sampler2D u_tex0;\n"
    "void main() {\n"
    "  gl_FragColor = texture2D(u_tex0, v_tex0);\n"
    "}\n"
};

static FragmentTest fpCopyTexGamma = {
	"Texture copy with gamma", 1,

    "precision mediump float;\n"
    "varying vec2 v_tex0;\n"
    "uniform sampler2D u_tex0;\n"
    "void main() {\n"
    "  vec4 t = texture2D(u_tex0, v_tex0);\n"
    "  t.rgb = pow(t.rgb, vec3(1.4, 1.4, 1.4));\n"
    "  gl_FragColor = t;\n"
    "}\n"
};

static FragmentTest fpTexSpec = {
	"Texture spec", 1,

    "precision mediump float;\n"
    "varying vec2 v_tex0;\n"
    "uniform sampler2D u_tex0;\n"
    "void main() {\n"
    "  vec4 t = texture2D(u_tex0, v_tex0);\n"
    "  float simSpec = dot(gl_FragCoord.xyz, gl_FragCoord.xyz);\n"
    "  simSpec = pow(clamp(simSpec, 0.1, 1.0), 40.0);\n"
    "  gl_FragColor = t + vec4(simSpec, simSpec, simSpec, simSpec);\n"
    "}\n"
};

static FragmentTest fpDepTex = {
	"Dependent Lookup", 1,

    "precision mediump float;\n"
    "varying vec2 v_tex0;\n"
    "uniform sampler2D u_tex0;\n"
    "void main() {\n"
    "  vec4 t = texture2D(u_tex0, v_tex0);\n"
    "  t += texture2D(u_tex0, t.xy);\n"
    "  gl_FragColor = t;\n"
    "}\n"
};

static FragmentTest fpModulateConstantTex = {
	"Texture modulate constant", 1,

    "precision mediump float;\n"
    "varying vec2 v_tex0;\n"
    "uniform sampler2D u_tex0;\n"
    "uniform vec4 u_color;\n"

    "void main() {\n"
    "  lowp vec4 c = texture2D(u_tex0, v_tex0);\n"
	"  c *= u_color;\n"
    "  gl_FragColor = c;\n"
    "}\n"
};

static FragmentTest fpModulateVaryingTex = {
	"Texture modulate gradient", 1,

    "precision mediump float;\n"
    "varying vec2 v_tex0;\n"
    "varying lowp vec4 v_color;\n"
    "uniform sampler2D u_tex0;\n"

    "void main() {\n"
    "  lowp vec4 c = texture2D(u_tex0, v_tex0);\n"
	"  c *= v_color;\n"
    "  gl_FragColor = c;\n"
    "}\n"
};

static FragmentTest fpModulateVaryingConstantTex = {
	"Texture modulate gradient constant", 1,

    "precision mediump float;\n"
    "varying vec2 v_tex0;\n"
    "varying lowp vec4 v_color;\n"
    "uniform sampler2D u_tex0;\n"
    "uniform vec4 u_color;\n"

    "void main() {\n"
    "  lowp vec4 c = texture2D(u_tex0, v_tex0);\n"
	"  c *= v_color;\n"
	"  c *= u_color;\n"
    "  gl_FragColor = c;\n"
    "}\n"
};

static FragmentTest *gFragmentTests[] = {
	&fpFill,
	&fpGradient,
	&fpCopyTex,
	&fpCopyTexGamma,
   &fpTexSpec,
   &fpDepTex,
	&fpModulateConstantTex,
	&fpModulateVaryingTex,
	&fpModulateVaryingConstantTex,

};

static const size_t gFragmentTestCount = sizeof(gFragmentTests) / sizeof(gFragmentTests[0]);
+24 −115
Original line number Diff line number Diff line
@@ -32,82 +32,17 @@ bool done;

// Saves the parameters of the test (so we can print them out when we finish the timing.)

char saveBuf[1024];


int pgm;

void ptSwap() {
}

static void doSingleTest(uint32_t w, uint32_t h,
                         bool useVarColor,
                         int texCount,
                         bool modulateFirstTex,
                         int extraMath,
                         int tex0, int tex1) {
    int doSingleTestState = (stateClock / doLoopStates) % doSingleTestStates;
    // LOGI("doSingleTest %d\n", doSingleTestState);
    switch (doSingleTestState) {
	case 0: {
	    char *pgmTxt = genShader(useVarColor, texCount, modulateFirstTex, extraMath);
	    pgm = createProgram(gVertexShader, pgmTxt);
	    if (!pgm) {
		LOGE("error running test\n");
		return;
	    }
	    int loc = glGetUniformLocation(pgm, "u_tex0");
	    if (loc >= 0) glUniform1i(loc, 0);
	    loc = glGetUniformLocation(pgm, "u_tex1");
	    if (loc >= 0) glUniform1i(loc, 1);

	    glActiveTexture(GL_TEXTURE0);
	    glBindTexture(GL_TEXTURE_2D, tex0);
	    glActiveTexture(GL_TEXTURE1);
	    glBindTexture(GL_TEXTURE_2D, tex1);
	    glActiveTexture(GL_TEXTURE0);

void doTest() {
    uint32_t testNum = stateClock >> 2;
    int texSize = ((stateClock >> 1) & 0x1) + 1;

	    glBlendFunc(GL_ONE, GL_ONE);
	    glDisable(GL_BLEND);
            char str2[1024];
	    sprintf(str2, "%i, %i, %i, %i, %i, 0",
		    useVarColor, texCount, modulateFirstTex, extraMath, tex0);

    	    doLoop((stateClock % doLoopStates) != 0, pgm, w, h, str2);
	 }
         break;
         case 1: {
            char str2[1024];
	    glEnable(GL_BLEND);
	    sprintf(str2, "%i, %i, %i, %i, %i, 1",
		    useVarColor, texCount, modulateFirstTex, extraMath, tex0);
	    doLoop((stateClock % doLoopStates) != 0, pgm, w, h, str2);
        }
        break;
    }
}


void doTest(uint32_t w, uint32_t h) {
    int testState = stateClock / (doLoopStates * doSingleTestStates);
    int texCount;
    int extraMath;
    int testSubState;
    const int extraMathCount = 5;
    const int texCount0SubTestCount = 2;
    const int texCountNSubTestCount = 8;

    if ( testState < extraMathCount * texCount0SubTestCount) {
       texCount = 0; // Only 10 tests for texCount 0
       extraMath = (testState / texCount0SubTestCount) % extraMathCount;
       testSubState = testState % texCount0SubTestCount;
    } else {
       texCount = 1 + (testState - extraMathCount * texCount0SubTestCount) / (extraMathCount * texCountNSubTestCount);
       extraMath = (testState / texCountNSubTestCount) % extraMathCount;
       testSubState = testState % texCountNSubTestCount;
    }
    if (texCount >= 3) {
    if (testNum >= gFragmentTestCount) {
       LOGI("done\n");
       if (fOut) {
           fclose(fOut);
@@ -117,36 +52,10 @@ void doTest(uint32_t w, uint32_t h) {
       return;
    }


    // LOGI("doTest %d %d %d\n", texCount, extraMath, testSubState);

    switch(testSubState) {
	case 0:
            doSingleTest(w, h, false, texCount, false, extraMath, 1, 1);
	break;
	case 1:
            doSingleTest(w, h, true, texCount, false, extraMath, 1, 1);
	break;
	case 2:
                doSingleTest(w, h, false, texCount, true, extraMath, 1, 1);
	break;
	case 3:
                doSingleTest(w, h, true, texCount, true, extraMath, 1, 1);
	break;

	case 4:
                doSingleTest(w, h, false, texCount, false, extraMath, 2, 2);
	break;
	case 5:
                doSingleTest(w, h, true, texCount, false, extraMath, 2, 2);
	break;
	case 6:
                doSingleTest(w, h, false, texCount, true, extraMath, 2, 2);
	break;
	case 7:
                doSingleTest(w, h, true, texCount, true, extraMath, 2, 2);
	break;
    }
//        for (uint32_t num = 0; num < gFragmentTestCount; num++) {
    doSingleTest(testNum, texSize);
}

extern "C" {
@@ -156,9 +65,9 @@ extern "C" {

JNIEXPORT void JNICALL Java_com_android_glperf_GLPerfLib_init(JNIEnv * env, jobject obj,  jint width, jint height)
{
    gWidth = width;
    gHeight = height;
    if (!done) {
	    w = width;
	    h = height;
            stateClock = 0;
            done = false;
            setupVA();
@@ -184,9 +93,9 @@ JNIEXPORT void JNICALL Java_com_android_glperf_GLPerfLib_step(JNIEnv * env, jobj
{
    if (! done) {
        if (stateClock > 0 && ((stateClock & 1) == 0)) {
	    endTimer(saveBuf, w, h, 1, 100);
            //endTimer(100);
        }
        doTest(w, h);
        doTest();
        stateClock++;
    } else {
            glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);