From 7b227b3ec1e297148ac39b2e722d22ba5ccae1c7 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Sat, 1 May 2021 10:17:47 +0300 Subject: [PATCH] win_opengl: Add fallback feature for gpus without ARB__buffer_storage extension. --- src/win/win_opengl.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/win/win_opengl.c b/src/win/win_opengl.c index 9c7753151..3aac702b7 100644 --- a/src/win/win_opengl.c +++ b/src/win/win_opengl.c @@ -361,14 +361,26 @@ static int initialize_glcontext(gl_identifiers* gl) glGenBuffers(1, &gl->unpackBufferID); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl->unpackBufferID); - /* Create persistent buffer for pixel transfer. */ - glBufferStorage(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * BUFFERCOUNT, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); - - void* buf_ptr = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, BUFFERBYTES * BUFFERCOUNT, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + void* buf_ptr = NULL; + + if (GLAD_GL_ARB_buffer_storage) + { + /* Create persistent buffer for pixel transfer. */ + glBufferStorage(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * BUFFERCOUNT, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + + buf_ptr = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, BUFFERBYTES * BUFFERCOUNT, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + } + else + { + /* Fallback; create our own buffer. */ + buf_ptr = malloc(BUFFERBYTES * BUFFERCOUNT); + + glBufferData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * BUFFERCOUNT, NULL, GL_STREAM_DRAW); + } if (buf_ptr == NULL) - return 0; - + return 0; /* Most likely out of memory. */ + /* Split the buffer area for each blit_info and set them available for use. */ for (int i = 0; i < BUFFERCOUNT; i++) { @@ -389,8 +401,12 @@ static int initialize_glcontext(gl_identifiers* gl) */ static void finalize_glcontext(gl_identifiers* gl) { + if (GLAD_GL_ARB_buffer_storage) + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + else + free(blit_info[0].buffer); + glDeleteProgram(gl->shader_progID); - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); glDeleteBuffers(1, &gl->unpackBufferID); glDeleteTextures(1, &gl->textureID); glDeleteBuffers(1, &gl->vertexBufferID); @@ -440,7 +456,6 @@ static void __stdcall opengl_debugmsg_callback(GLenum source, GLenum type, GLuin OutputDebugStringA(message); OutputDebugStringA("\n"); } -#endif */ /** @@ -491,7 +506,7 @@ static void opengl_main(void* param) SDL_GL_SetSwapInterval(options.vsync); - if (!gladLoadGLLoader(SDL_GL_GetProcAddress) || !GLAD_GL_ARB_buffer_storage) + if (!gladLoadGLLoader(SDL_GL_GetProcAddress)) { SDL_GL_DeleteContext(context); opengl_fail(); @@ -608,6 +623,12 @@ static void opengl_main(void* param) SetEvent(sync_objects.resize); } + if (!GLAD_GL_ARB_buffer_storage) + { + /* Fallback method, copy data to pixel buffer. */ + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * read_pos, info->w * (info->y2 - info->y1) * sizeof(uint32_t), info->buffer); + } + /* Update texture from pixel buffer. */ glPixelStorei(GL_UNPACK_SKIP_PIXELS, BUFFERPIXELS * read_pos); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, info->y1, info->w, info->y2 - info->y1, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); @@ -765,7 +786,7 @@ static void opengl_blit(int x, int y, int y1, int y2, int w, int h) return; } - memcpy(blit_info[write_pos].buffer, &(render_buffer->dat)[y1 * w], w * (y2 - y1) * 4); + memcpy(blit_info[write_pos].buffer, &(render_buffer->dat)[y1 * w], w * (y2 - y1) * sizeof(uint32_t)); video_blit_complete();