Skip to content

Instantly share code, notes, and snippets.

@pendingchaos
Last active September 19, 2018 20:29
Show Gist options
  • Save pendingchaos/036407c96bcbfb760327e26871363457 to your computer and use it in GitHub Desktop.
Save pendingchaos/036407c96bcbfb760327e26871363457 to your computer and use it in GitHub Desktop.
glBufferSubData p2mf/m2mf performance test
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
index 2c604419ce..c846678dde 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -147,7 +147,9 @@ nouveau_transfer_staging(struct nouveau_context *nv,
if (!nv->push_data)
permit_pb = false;
- if ((size <= NOUVEAU_TRANSFER_PUSHBUF_THRESHOLD) && permit_pb) {
+ int pb = atoi(getenv("PB"));
+
+ if (permit_pb && pb) {
tx->map = align_malloc(size, NOUVEAU_MIN_BUFFER_MAP_ALIGN);
if (tx->map)
tx->map += adj;
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <SDL2/SDL.h>
#include <stdbool.h>
#include <stdint.h>
static const float positions[] = {-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f};
int main(int argc, char **argv) {
setenv("PB", "0", 1);
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *window = SDL_CreateWindow("",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
128,
128,
SDL_WINDOW_OPENGL |
SDL_WINDOW_HIDDEN);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GLContext context = SDL_GL_CreateContext(window);
//Position buffer
GLuint pos_buffer;
glGenBuffers(1, &pos_buffer);
glBindBuffer(GL_ARRAY_BUFFER, pos_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
//Vertex
GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
static const char* vert_source = "#version 130\n"
"in vec3 position;\n"
"void main() {\n"
" gl_Position = vec4(position, 1.0);\n"
"}\n";
glShaderSource(vertex, 1, &vert_source, NULL);
glCompileShader(vertex);
//Fragment
GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER);
static const char* frag_source = "#version 130\n"
"out vec4 out_color;\n"
"void main() {\n"
" out_color = vec4(1.0);\n"
"}\n";
glShaderSource(fragment, 1, &frag_source, NULL);
glCompileShader(fragment);
//Program
GLuint program = glCreateProgram();
glAttachShader(program, vertex);
glAttachShader(program, fragment);
glLinkProgram(program);
glValidateProgram(program);
glDetachShader(program, vertex);
glDetachShader(program, fragment);
//VAO
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, pos_buffer);
glEnableVertexAttribArray(glGetAttribLocation(program, "position"));
GLint loc = glGetAttribLocation(program, "position");
glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0);
int sizes[] = {128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 128*1024, 256*1024, 512*1024, 1048576, 2*1048576/*, 4*1048576, 8*1048576, 16*1048576*//*, 32*1048576, 64*1048576*/};
GLuint buf;
glGenBuffers(1, &buf);
glBindBuffer(GL_ARRAY_BUFFER, buf);
glBufferData(GL_ARRAY_BUFFER, 256*1024*1024, NULL, GL_STATIC_DRAW);
for (int i = 0; i < sizeof(sizes)/sizeof(sizes[0]); i++) {
void *data = malloc(sizes[i]);
SDL_Event ev;
while (SDL_PollEvent(&ev)) {
if (ev.type == SDL_QUIT) {
return 1;
}
}
double results[4];
for (int pb = 0; pb < 4; pb++) {
setenv("PB", (pb & 1) ? "1":"0", 1);
if (pb & 2) { // Not very interesting
continue;
}
if (pb & 2) {
glBindBufferBase(GL_UNIFORM_BUFFER, 0, buf);
glFinish();
} else {
glBindBufferBase(GL_UNIFORM_BUFFER, 0, 0);
glFinish();
}
GLuint query;
glGenQueries(1, &query);
glBeginQuery(GL_TIME_ELAPSED, query);
int count = 10;
if (sizes[i] < 8*1024*1024)
count = 100;
if (sizes[i] < 1024*1024)
count = 1000;
if (sizes[i] < 64*1024)
count = 10000;
for (int j = 0; j < count; j++) {
glBufferSubData(GL_ARRAY_BUFFER, 0, sizes[i], data);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
glEndQuery(GL_TIME_ELAPSED);
GLuint64 time;
PFNGLGETQUERYOBJECTUI64VPROC GetQueryObjectui64v = SDL_GL_GetProcAddress("glGetQueryObjectui64v");
GetQueryObjectui64v(query, GL_QUERY_RESULT, &time);
double MiB = (uint64_t)count * sizes[i] / (1024.0 * 1024.0);
double seconds = time / 1000000000.0;
const char *test;
switch (pb) {
case 0b00: test = "copy"; break;
case 0b01: test = "push"; break;
case 0b10: test = "copy_cbuf"; break;
case 0b11: test = "push_cbuf"; break;
}
results[pb] = MiB / seconds;
printf("%s, %d (%.3f MiB) (%d draws): %.3f ms, %.3f MiB/s\n", test, sizes[i], sizes[i]/(1024.0*1024.0), count, time / 1000000.0, MiB/seconds);
}
printf(" copy -> push: %.0f%% improvement\n", results[1]/results[0]*100-100.0);
//printf(" copy_cbuf -> push_cbuf: %.0f%% improvement\n", results[3]/results[2]*100-100.0);
free(data);
printf("\n");
}
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <SDL2/SDL.h>
#include <stdbool.h>
#include <stdint.h>
int main(int argc, char **argv) {
setenv("PB", "0", 1);
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *window = SDL_CreateWindow("",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
640,
640,
SDL_WINDOW_OPENGL |
SDL_WINDOW_HIDDEN);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GLContext context = SDL_GL_CreateContext(window);
int sizes[] = {128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 128*1024, 256*1024, 512*1024, 1048576, 2*1048576/*, 4*1048576, 8*1048576, 16*1048576*//*, 32*1048576, 64*1048576*/};
GLuint buf;
glGenBuffers(1, &buf);
glBindBuffer(GL_ARRAY_BUFFER, buf);
glBufferData(GL_ARRAY_BUFFER, 256*1024*1024, NULL, GL_STATIC_DRAW);
for (int i = 0; i < sizeof(sizes)/sizeof(sizes[0]); i++) {
void *data = malloc(sizes[i]);
SDL_Event ev;
while (SDL_PollEvent(&ev)) {
if (ev.type == SDL_QUIT) {
return 1;
}
}
double results[3];
for (int pb = 0; pb < 3; pb++) {
setenv("PB", pb?"1":"0", 1);
if (pb == 2) { // Doesn't seem to yield anything interesting
continue;
}
if (pb == 2) {
glBindBufferBase(GL_UNIFORM_BUFFER, 0, buf);
glFinish();
} else {
glBindBufferBase(GL_UNIFORM_BUFFER, 0, 0);
glFinish();
}
GLuint query;
glGenQueries(1, &query);
glBeginQuery(GL_TIME_ELAPSED, query);
int count = 50;
if (sizes[i] < 8*1024*1024)
count = 500;
if (sizes[i] < 1024*1024)
count = 5000;
if (sizes[i] < 64*1024)
count = 50000;
for (int j = 0; j < count; j++)
glBufferSubData(GL_ARRAY_BUFFER, 0, sizes[i], data);
glEndQuery(GL_TIME_ELAPSED);
GLuint64 time;
PFNGLGETQUERYOBJECTUI64VPROC GetQueryObjectui64v = SDL_GL_GetProcAddress("glGetQueryObjectui64v");
GetQueryObjectui64v(query, GL_QUERY_RESULT, &time);
double MiB = (uint64_t)count * sizes[i] / (1024.0 * 1024.0);
double seconds = time / 1000000000.0;
const char *test;
switch (pb) {
case 0: test = "copy"; break;
case 1: test = "push"; break;
case 2: test = "cbuf"; break;
}
results[pb] = MiB / seconds;
printf("%s, %d (%.3f MiB) (%d uploads): %.3f ms, %.3f MiB/s\n", test, sizes[i], sizes[i]/(1024.0*1024.0), count, time / 1000000.0, MiB/seconds);
}
printf(" copy -> push: %.0f%% improvement\n", results[1]/results[0]*100-100.0);
free(data);
printf("\n");
}
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment