mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-25 23:07:18 +00:00
[opengl] numerous improvements to buffer transfer
This commit is contained in:
parent
da2bcfdf9a
commit
cf4d16b528
@ -31,11 +31,10 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include <GL/glx.h>
|
#include <GL/glx.h>
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "memcpySSE.h"
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "lg-decoders.h"
|
#include "lg-decoders.h"
|
||||||
|
|
||||||
#define BUFFER_COUNT 4
|
#define BUFFER_COUNT 2
|
||||||
|
|
||||||
#define FPS_TEXTURE 0
|
#define FPS_TEXTURE 0
|
||||||
#define MOUSE_TEXTURE 1
|
#define MOUSE_TEXTURE 1
|
||||||
@ -49,6 +48,7 @@ struct Options
|
|||||||
bool mipmap;
|
bool mipmap;
|
||||||
bool vsync;
|
bool vsync;
|
||||||
bool preventBuffer;
|
bool preventBuffer;
|
||||||
|
bool amdPinnedMem;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct Options defaultOptions =
|
static struct Options defaultOptions =
|
||||||
@ -56,6 +56,7 @@ static struct Options defaultOptions =
|
|||||||
.mipmap = true,
|
.mipmap = true,
|
||||||
.vsync = true,
|
.vsync = true,
|
||||||
.preventBuffer = false,
|
.preventBuffer = false,
|
||||||
|
.amdPinnedMem = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Inst
|
struct Inst
|
||||||
@ -472,6 +473,16 @@ static void handle_opt_prevent_buffer(void * opaque, const char *value)
|
|||||||
this->opt.preventBuffer = LG_RendererValueToBool(value);
|
this->opt.preventBuffer = LG_RendererValueToBool(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_opt_amd_pinned_mem(void * opaque, const char *value)
|
||||||
|
{
|
||||||
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
|
if (!this)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this->opt.amdPinnedMem = LG_RendererValueToBool(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static LG_RendererOpt opengl_options[] =
|
static LG_RendererOpt opengl_options[] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@ -491,6 +502,12 @@ static LG_RendererOpt opengl_options[] =
|
|||||||
.desc = "Prevent the driver from buffering frames [default: disabled]",
|
.desc = "Prevent the driver from buffering frames [default: disabled]",
|
||||||
.validator = LG_RendererValidatorBool,
|
.validator = LG_RendererValidatorBool,
|
||||||
.handler = handle_opt_prevent_buffer
|
.handler = handle_opt_prevent_buffer
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "amdPinnedMem",
|
||||||
|
.desc = "Use GL_AMD_pinned_memory if it is available [default: enabled]",
|
||||||
|
.validator = LG_RendererValidatorBool,
|
||||||
|
.handler = handle_opt_amd_pinned_mem
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -551,10 +568,15 @@ static bool configure(struct Inst * this, SDL_Window *window)
|
|||||||
for(GLint i = 0; i < n; ++i)
|
for(GLint i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
const GLubyte *ext = glGetStringi(GL_EXTENSIONS, i);
|
const GLubyte *ext = glGetStringi(GL_EXTENSIONS, i);
|
||||||
this->amdPinnedMemSupport = (strcmp((const char *)ext, "GL_AMD_pinned_memory") == 0);
|
if (strcmp((const char *)ext, "GL_AMD_pinned_memory") == 0)
|
||||||
if (this->amdPinnedMemSupport)
|
|
||||||
{
|
{
|
||||||
|
if (this->opt.amdPinnedMem)
|
||||||
|
{
|
||||||
|
this->amdPinnedMemSupport = true;
|
||||||
DEBUG_INFO("Using GL_AMD_pinned_memory");
|
DEBUG_INFO("Using GL_AMD_pinned_memory");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DEBUG_INFO("GL_AMD_pinned_memory is available but not in use");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -564,26 +586,12 @@ static bool configure(struct Inst * this, SDL_Window *window)
|
|||||||
|
|
||||||
SDL_GL_SetSwapInterval(this->opt.vsync ? 1 : 0);
|
SDL_GL_SetSwapInterval(this->opt.vsync ? 1 : 0);
|
||||||
|
|
||||||
// check if the GPU supports GL_ARB_buffer_storage first
|
|
||||||
// there is no advantage to this renderer if it is not present.
|
|
||||||
const GLubyte * extensions = glGetString(GL_EXTENSIONS);
|
|
||||||
if (!gluCheckExtension((const GLubyte *)"GL_ARB_buffer_storage", extensions))
|
|
||||||
{
|
|
||||||
DEBUG_INFO("The GPU doesn't support GL_ARB_buffer_storage");
|
|
||||||
LG_UNLOCK(this->formatLock);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(this->format.comp)
|
switch(this->format.comp)
|
||||||
{
|
{
|
||||||
case LG_COMPRESSION_NONE:
|
case LG_COMPRESSION_NONE:
|
||||||
this->decoder = &LGD_NULL;
|
this->decoder = &LGD_NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LG_COMPRESSION_H264:
|
|
||||||
this->decoder = &LGD_H264;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DEBUG_ERROR("Unknown/unsupported compression type");
|
DEBUG_ERROR("Unknown/unsupported compression type");
|
||||||
return false;
|
return false;
|
||||||
@ -661,7 +669,6 @@ static bool configure(struct Inst * this, SDL_Window *window)
|
|||||||
LG_UNLOCK(this->formatLock);
|
LG_UNLOCK(this->formatLock);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
glBufferData(
|
glBufferData(
|
||||||
GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD,
|
GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD,
|
||||||
this->texSize,
|
this->texSize,
|
||||||
@ -687,29 +694,13 @@ static bool configure(struct Inst * this, SDL_Window *window)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
glBufferStorage(
|
glBufferData(
|
||||||
GL_PIXEL_UNPACK_BUFFER,
|
GL_PIXEL_UNPACK_BUFFER,
|
||||||
this->texSize,
|
this->texSize,
|
||||||
NULL,
|
NULL,
|
||||||
GL_MAP_WRITE_BIT |
|
GL_STREAM_DRAW
|
||||||
GL_MAP_PERSISTENT_BIT
|
|
||||||
);
|
);
|
||||||
if (check_gl_error("glBufferStorage"))
|
if (check_gl_error("glBufferData"))
|
||||||
{
|
|
||||||
LG_UNLOCK(this->formatLock);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->texPixels[i] = glMapBufferRange(
|
|
||||||
GL_PIXEL_UNPACK_BUFFER,
|
|
||||||
0,
|
|
||||||
this->texSize,
|
|
||||||
GL_MAP_WRITE_BIT |
|
|
||||||
GL_MAP_PERSISTENT_BIT |
|
|
||||||
GL_MAP_FLUSH_EXPLICIT_BIT
|
|
||||||
);
|
|
||||||
|
|
||||||
if (check_gl_error("glMapBufferRange"))
|
|
||||||
{
|
{
|
||||||
LG_UNLOCK(this->formatLock);
|
LG_UNLOCK(this->formatLock);
|
||||||
return false;
|
return false;
|
||||||
@ -1049,7 +1040,7 @@ static bool draw_frame(struct Inst * this)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (this->amdPinnedMemSupport && glIsSync(this->fences[this->texIndex]))
|
if (glIsSync(this->fences[this->texIndex]))
|
||||||
{
|
{
|
||||||
switch(glClientWaitSync(this->fences[this->texIndex], 0, GL_TIMEOUT_IGNORED))
|
switch(glClientWaitSync(this->fences[this->texIndex], 0, GL_TIMEOUT_IGNORED))
|
||||||
{
|
{
|
||||||
@ -1081,21 +1072,22 @@ static bool draw_frame(struct Inst * this)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpySSE(this->texPixels[this->texIndex], data, this->texSize);
|
|
||||||
|
|
||||||
if (this->amdPinnedMemSupport)
|
|
||||||
this->fences[this->texIndex] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, this->frames[this->texIndex]);
|
glBindTexture(GL_TEXTURE_2D, this->frames[this->texIndex]);
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, this->vboID[this->texIndex]);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vboID[this->texIndex]);
|
||||||
|
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT , 4);
|
glPixelStorei(GL_UNPACK_ALIGNMENT , 4);
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH ,
|
glPixelStorei(GL_UNPACK_ROW_LENGTH ,
|
||||||
this->decoder->get_frame_stride(this->decoderData)
|
this->decoder->get_frame_stride(this->decoderData)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!this->amdPinnedMemSupport)
|
// update the buffer, this performs a DMA transfer if possible
|
||||||
glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, this->texSize);
|
glBufferSubData(
|
||||||
|
GL_PIXEL_UNPACK_BUFFER,
|
||||||
|
0,
|
||||||
|
this->texSize,
|
||||||
|
data
|
||||||
|
);
|
||||||
|
check_gl_error("glBufferSubData");
|
||||||
|
|
||||||
// update the texture
|
// update the texture
|
||||||
glTexSubImage2D(
|
glTexSubImage2D(
|
||||||
@ -1116,8 +1108,12 @@ static bool draw_frame(struct Inst * this)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set a fence so we don't overwrite a buffer in use
|
||||||
|
this->fences[this->texIndex] =
|
||||||
|
glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||||
|
|
||||||
// unbind the buffer
|
// unbind the buffer
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool mipmap = this->opt.mipmap && (
|
const bool mipmap = this->opt.mipmap && (
|
||||||
|
Loading…
Reference in New Issue
Block a user