Merge branch 'buffer_storage'
This commit is contained in:
commit
d36355e45c
|
@ -661,7 +661,7 @@ else()
|
||||||
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||||
include(FindGLEW)
|
include(FindGLEW)
|
||||||
endif()
|
endif()
|
||||||
if(NOT GLEW_FOUND OR NOT GLEW_HAS_1_9_METHODS)
|
if(NOT GLEW_FOUND OR NOT GLEW_HAS_1_10_METHODS)
|
||||||
message("Using static GLEW from Externals")
|
message("Using static GLEW from Externals")
|
||||||
add_subdirectory(Externals/GLew)
|
add_subdirectory(Externals/GLew)
|
||||||
include_directories(Externals/GLew/include)
|
include_directories(Externals/GLew/include)
|
||||||
|
|
|
@ -10,13 +10,14 @@ macro(test_glew)
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef GLEW_ARB_shader_image_load_store
|
#ifdef GLEW_ARB_buffer_storage
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
}"
|
}"
|
||||||
GLEW_HAS_1_9_METHODS)
|
GLEW_HAS_1_10_METHODS)
|
||||||
|
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
if(PKG_CONFIG_FOUND AND NOT ${var}_FOUND)
|
if(PKG_CONFIG_FOUND AND NOT ${var}_FOUND)
|
||||||
|
@ -25,7 +26,7 @@ endif()
|
||||||
|
|
||||||
if(GLEW_FOUND)
|
if(GLEW_FOUND)
|
||||||
test_glew()
|
test_glew()
|
||||||
if (GLEW_HAS_1_9_METHODS)
|
if (GLEW_HAS_1_10_METHODS)
|
||||||
include_directories(${GLEW_INCLUDE_DIRS})
|
include_directories(${GLEW_INCLUDE_DIRS})
|
||||||
message("GLEW found")
|
message("GLEW found")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -30,10 +30,13 @@
|
||||||
#define GL_READ_WRITE 0x88BA
|
#define GL_READ_WRITE 0x88BA
|
||||||
#define GL_SRC1_ALPHA 0
|
#define GL_SRC1_ALPHA 0
|
||||||
#define GL_BGRA GL_RGBA
|
#define GL_BGRA GL_RGBA
|
||||||
|
#define GL_MAP_COHERENT_BIT 0
|
||||||
|
#define GL_MAP_PERSISTENT_BIT 0
|
||||||
#define glDrawElementsBaseVertex(...)
|
#define glDrawElementsBaseVertex(...)
|
||||||
#define glDrawRangeElementsBaseVertex(...)
|
#define glDrawRangeElementsBaseVertex(...)
|
||||||
#define glRenderbufferStorageMultisampleCoverageNV(...)
|
#define glRenderbufferStorageMultisampleCoverageNV(...)
|
||||||
#define glViewportIndexedf(...)
|
#define glViewportIndexedf(...)
|
||||||
|
#define glBufferStorage(...)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define TEX2D GL_TEXTURE_RECTANGLE_ARB
|
#define TEX2D GL_TEXTURE_RECTANGLE_ARB
|
||||||
|
|
|
@ -486,7 +486,9 @@ Renderer::Renderer()
|
||||||
g_ogl_config.bSupportsGLSLCache = TO_BOOL(GLEW_ARB_get_program_binary);
|
g_ogl_config.bSupportsGLSLCache = TO_BOOL(GLEW_ARB_get_program_binary);
|
||||||
g_ogl_config.bSupportsGLPinnedMemory = TO_BOOL(GLEW_AMD_pinned_memory);
|
g_ogl_config.bSupportsGLPinnedMemory = TO_BOOL(GLEW_AMD_pinned_memory);
|
||||||
g_ogl_config.bSupportsGLSync = TO_BOOL(GLEW_ARB_sync);
|
g_ogl_config.bSupportsGLSync = TO_BOOL(GLEW_ARB_sync);
|
||||||
g_ogl_config.bSupportsGLBaseVertex = TO_BOOL(GLEW_ARB_draw_elements_base_vertex);
|
g_ogl_config.bSupportsGLBaseVertex = TO_BOOL(GLEW_ARB_draw_elements_base_vertex) &&
|
||||||
|
!DriverDetails::HasBug(DriverDetails::BUG_BROKENPINNEDMEMORY);
|
||||||
|
g_ogl_config.bSupportsGLBufferStorage = TO_BOOL(GLEW_ARB_buffer_storage);
|
||||||
g_ogl_config.bSupportCoverageMSAA = TO_BOOL(GLEW_NV_framebuffer_multisample_coverage);
|
g_ogl_config.bSupportCoverageMSAA = TO_BOOL(GLEW_NV_framebuffer_multisample_coverage);
|
||||||
g_ogl_config.bSupportSampleShading = TO_BOOL(GLEW_ARB_sample_shading);
|
g_ogl_config.bSupportSampleShading = TO_BOOL(GLEW_ARB_sample_shading);
|
||||||
g_ogl_config.bSupportOGL31 = TO_BOOL(GLEW_VERSION_3_1);
|
g_ogl_config.bSupportOGL31 = TO_BOOL(GLEW_VERSION_3_1);
|
||||||
|
@ -555,7 +557,7 @@ Renderer::Renderer()
|
||||||
g_ogl_config.gl_renderer,
|
g_ogl_config.gl_renderer,
|
||||||
g_ogl_config.gl_version), 5000);
|
g_ogl_config.gl_version), 5000);
|
||||||
|
|
||||||
WARN_LOG(VIDEO,"Missing OGL Extensions: %s%s%s%s%s%s%s%s%s%s",
|
WARN_LOG(VIDEO,"Missing OGL Extensions: %s%s%s%s%s%s%s%s%s%s%s",
|
||||||
g_ActiveConfig.backend_info.bSupportsDualSourceBlend ? "" : "DualSourceBlend ",
|
g_ActiveConfig.backend_info.bSupportsDualSourceBlend ? "" : "DualSourceBlend ",
|
||||||
g_ActiveConfig.backend_info.bSupportsGLSLUBO ? "" : "UniformBuffer ",
|
g_ActiveConfig.backend_info.bSupportsGLSLUBO ? "" : "UniformBuffer ",
|
||||||
g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? "" : "PrimitiveRestart ",
|
g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? "" : "PrimitiveRestart ",
|
||||||
|
@ -563,6 +565,7 @@ Renderer::Renderer()
|
||||||
g_ogl_config.bSupportsGLPinnedMemory ? "" : "PinnedMemory ",
|
g_ogl_config.bSupportsGLPinnedMemory ? "" : "PinnedMemory ",
|
||||||
g_ogl_config.bSupportsGLSLCache ? "" : "ShaderCache ",
|
g_ogl_config.bSupportsGLSLCache ? "" : "ShaderCache ",
|
||||||
g_ogl_config.bSupportsGLBaseVertex ? "" : "BaseVertex ",
|
g_ogl_config.bSupportsGLBaseVertex ? "" : "BaseVertex ",
|
||||||
|
g_ogl_config.bSupportsGLBufferStorage ? "" : "BufferStorage ",
|
||||||
g_ogl_config.bSupportsGLSync ? "" : "Sync ",
|
g_ogl_config.bSupportsGLSync ? "" : "Sync ",
|
||||||
g_ogl_config.bSupportCoverageMSAA ? "" : "CSAA ",
|
g_ogl_config.bSupportCoverageMSAA ? "" : "CSAA ",
|
||||||
g_ogl_config.bSupportSampleShading ? "" : "SSAA "
|
g_ogl_config.bSupportSampleShading ? "" : "SSAA "
|
||||||
|
|
|
@ -22,6 +22,7 @@ extern struct VideoConfig {
|
||||||
bool bSupportsGLPinnedMemory;
|
bool bSupportsGLPinnedMemory;
|
||||||
bool bSupportsGLSync;
|
bool bSupportsGLSync;
|
||||||
bool bSupportsGLBaseVertex;
|
bool bSupportsGLBaseVertex;
|
||||||
|
bool bSupportsGLBufferStorage;
|
||||||
bool bSupportCoverageMSAA;
|
bool bSupportCoverageMSAA;
|
||||||
bool bSupportSampleShading;
|
bool bSupportSampleShading;
|
||||||
GLSL_VERSION eSupportedGLSLVersion;
|
GLSL_VERSION eSupportedGLSLVersion;
|
||||||
|
|
|
@ -33,7 +33,11 @@ StreamBuffer::StreamBuffer(u32 type, size_t size, StreamType uploadType)
|
||||||
g_Config.bHackedBufferUpload = false;
|
g_Config.bHackedBufferUpload = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!g_ogl_config.bSupportsGLBaseVertex && (m_uploadtype & BUFFERSUBDATA)
|
if (g_ogl_config.bSupportsGLBufferStorage &&
|
||||||
|
!(DriverDetails::HasBug(DriverDetails::BUG_BROKENBUFFERSTORAGE) && type == GL_ARRAY_BUFFER) &&
|
||||||
|
(m_uploadtype & BUFFERSTORAGE))
|
||||||
|
m_uploadtype = BUFFERSTORAGE;
|
||||||
|
else if(!g_ogl_config.bSupportsGLBaseVertex && (m_uploadtype & BUFFERSUBDATA)
|
||||||
&& !DriverDetails::HasBug(DriverDetails::BUG_BROKENBUFFERSTREAM))
|
&& !DriverDetails::HasBug(DriverDetails::BUG_BROKENBUFFERSTREAM))
|
||||||
m_uploadtype = BUFFERSUBDATA;
|
m_uploadtype = BUFFERSUBDATA;
|
||||||
else if(!g_ogl_config.bSupportsGLBaseVertex && (m_uploadtype & BUFFERDATA))
|
else if(!g_ogl_config.bSupportsGLBaseVertex && (m_uploadtype & BUFFERDATA))
|
||||||
|
@ -81,9 +85,9 @@ void StreamBuffer::Alloc ( size_t size, u32 stride )
|
||||||
break;
|
break;
|
||||||
case MAP_AND_SYNC:
|
case MAP_AND_SYNC:
|
||||||
case PINNED_MEMORY:
|
case PINNED_MEMORY:
|
||||||
|
case BUFFERSTORAGE:
|
||||||
// insert waiting slots for used memory
|
// insert waiting slots for used memory
|
||||||
for(size_t i=SLOT(m_used_iterator); i<SLOT(m_iterator); i++)
|
for (size_t i = SLOT(m_used_iterator); i < SLOT(m_iterator); i++)
|
||||||
{
|
{
|
||||||
fences[i] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
fences[i] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||||
}
|
}
|
||||||
|
@ -98,7 +102,7 @@ void StreamBuffer::Alloc ( size_t size, u32 stride )
|
||||||
m_free_iterator = iter_end;
|
m_free_iterator = iter_end;
|
||||||
|
|
||||||
// if buffer is full
|
// if buffer is full
|
||||||
if(iter_end >= m_size) {
|
if (iter_end >= m_size) {
|
||||||
|
|
||||||
// insert waiting slots in unused space at the end of the buffer
|
// insert waiting slots in unused space at the end of the buffer
|
||||||
for (size_t i = SLOT(m_used_iterator); i < SYNC_POINTS; i++)
|
for (size_t i = SLOT(m_used_iterator); i < SYNC_POINTS; i++)
|
||||||
|
@ -111,7 +115,7 @@ void StreamBuffer::Alloc ( size_t size, u32 stride )
|
||||||
iter_end = size;
|
iter_end = size;
|
||||||
|
|
||||||
// wait for space at the start
|
// wait for space at the start
|
||||||
for(u32 i=0; i<=SLOT(iter_end); i++)
|
for (u32 i = 0; i <= SLOT(iter_end); i++)
|
||||||
{
|
{
|
||||||
glClientWaitSync(fences[i], GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);
|
glClientWaitSync(fences[i], GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);
|
||||||
glDeleteSync(fences[i]);
|
glDeleteSync(fences[i]);
|
||||||
|
@ -130,7 +134,7 @@ void StreamBuffer::Alloc ( size_t size, u32 stride )
|
||||||
m_iterator_aligned = 0;
|
m_iterator_aligned = 0;
|
||||||
break;
|
break;
|
||||||
case STREAM_DETECT:
|
case STREAM_DETECT:
|
||||||
case DETECT_MASK: // Just to shutup warnings
|
case DETECT_MASK: // To shutup compiler warnings
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_iterator = m_iterator_aligned;
|
m_iterator = m_iterator_aligned;
|
||||||
|
@ -151,8 +155,9 @@ size_t StreamBuffer::Upload ( u8* data, size_t size )
|
||||||
break;
|
break;
|
||||||
case PINNED_MEMORY:
|
case PINNED_MEMORY:
|
||||||
case MAP_AND_RISK:
|
case MAP_AND_RISK:
|
||||||
if(pointer)
|
case BUFFERSTORAGE:
|
||||||
memcpy(pointer+m_iterator, data, size);
|
if (pointer)
|
||||||
|
memcpy(pointer + m_iterator, data, size);
|
||||||
break;
|
break;
|
||||||
case BUFFERSUBDATA:
|
case BUFFERSUBDATA:
|
||||||
glBufferSubData(m_buffertype, m_iterator, size, data);
|
glBufferSubData(m_buffertype, m_iterator, size, data);
|
||||||
|
@ -161,7 +166,7 @@ size_t StreamBuffer::Upload ( u8* data, size_t size )
|
||||||
glBufferData(m_buffertype, size, data, GL_STREAM_DRAW);
|
glBufferData(m_buffertype, size, data, GL_STREAM_DRAW);
|
||||||
break;
|
break;
|
||||||
case STREAM_DETECT:
|
case STREAM_DETECT:
|
||||||
case DETECT_MASK: // Just to shutup warnings
|
case DETECT_MASK: // To shutup compiler warnings
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
size_t ret = m_iterator;
|
size_t ret = m_iterator;
|
||||||
|
@ -206,6 +211,26 @@ void StreamBuffer::Init()
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BUFFERSTORAGE:
|
||||||
|
glGetError(); // errors before this allocation should be ignored
|
||||||
|
fences = new GLsync[SYNC_POINTS];
|
||||||
|
for (u32 i = 0; i<SYNC_POINTS; i++)
|
||||||
|
fences[i] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||||
|
|
||||||
|
glBindBuffer(m_buffertype, m_buffer);
|
||||||
|
|
||||||
|
// PERSISTANT_BIT to make sure that the buffer can be used while mapped
|
||||||
|
// COHERENT_BIT is set so we don't have to use a MemoryBarrier on write
|
||||||
|
// CLIENT_STORAGE_BIT is set since we access the buffer more frequently on the client side then server side
|
||||||
|
glBufferStorage(m_buffertype, m_size, NULL,
|
||||||
|
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT);
|
||||||
|
pointer = (u8*)glMapBufferRange(m_buffertype, 0, m_size,
|
||||||
|
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||||
|
if(!pointer)
|
||||||
|
ERROR_LOG(VIDEO, "Buffer allocation failed");
|
||||||
|
break;
|
||||||
|
|
||||||
case MAP_AND_RISK:
|
case MAP_AND_RISK:
|
||||||
glBindBuffer(m_buffertype, m_buffer);
|
glBindBuffer(m_buffertype, m_buffer);
|
||||||
glBufferData(m_buffertype, m_size, NULL, GL_STREAM_DRAW);
|
glBufferData(m_buffertype, m_size, NULL, GL_STREAM_DRAW);
|
||||||
|
@ -218,7 +243,7 @@ void StreamBuffer::Init()
|
||||||
glBindBuffer(m_buffertype, m_buffer);
|
glBindBuffer(m_buffertype, m_buffer);
|
||||||
break;
|
break;
|
||||||
case STREAM_DETECT:
|
case STREAM_DETECT:
|
||||||
case DETECT_MASK: // Just to shutup warnings
|
case DETECT_MASK: // To shutup compiler warnings
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,8 +265,14 @@ void StreamBuffer::Shutdown()
|
||||||
glFinish(); // ogl pipeline must be flushed, else this buffer can be in use
|
glFinish(); // ogl pipeline must be flushed, else this buffer can be in use
|
||||||
FreeAlignedMemory(pointer);
|
FreeAlignedMemory(pointer);
|
||||||
break;
|
break;
|
||||||
|
case BUFFERSTORAGE:
|
||||||
|
DeleteFences();
|
||||||
|
glUnmapBuffer(m_buffertype);
|
||||||
|
glBindBuffer(m_buffertype, 0);
|
||||||
|
glFinish(); // ogl pipeline must be flushed, else this buffer can be in use
|
||||||
|
break;
|
||||||
case STREAM_DETECT:
|
case STREAM_DETECT:
|
||||||
case DETECT_MASK: // Just to shutup warnings
|
case DETECT_MASK: // To shutup compiler warnings
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,14 +18,15 @@
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
enum StreamType {
|
enum StreamType {
|
||||||
DETECT_MASK = 0x7F,
|
DETECT_MASK = 0xFF,
|
||||||
STREAM_DETECT = (1 << 0),
|
STREAM_DETECT = (1 << 0),
|
||||||
MAP_AND_ORPHAN = (1 << 1),
|
MAP_AND_ORPHAN = (1 << 1),
|
||||||
MAP_AND_SYNC = (1 << 2),
|
MAP_AND_SYNC = (1 << 2),
|
||||||
MAP_AND_RISK = (1 << 3),
|
MAP_AND_RISK = (1 << 3),
|
||||||
PINNED_MEMORY = (1 << 4),
|
PINNED_MEMORY = (1 << 4),
|
||||||
BUFFERSUBDATA = (1 << 5),
|
BUFFERSUBDATA = (1 << 5),
|
||||||
BUFFERDATA = (1 << 6)
|
BUFFERDATA = (1 << 6),
|
||||||
|
BUFFERSTORAGE = (1 << 7),
|
||||||
};
|
};
|
||||||
|
|
||||||
class StreamBuffer {
|
class StreamBuffer {
|
||||||
|
|
|
@ -54,6 +54,7 @@ namespace DriverDetails
|
||||||
{OS_ALL, VENDOR_ATI, DRIVER_ATI, -1, BUG_BROKENHACKEDBUFFER, -1.0, -1.0, true},
|
{OS_ALL, VENDOR_ATI, DRIVER_ATI, -1, BUG_BROKENHACKEDBUFFER, -1.0, -1.0, true},
|
||||||
{OS_LINUX, VENDOR_ATI, DRIVER_ATI, -1, BUG_BROKENPINNEDMEMORY, -1.0, -1.0, true},
|
{OS_LINUX, VENDOR_ATI, DRIVER_ATI, -1, BUG_BROKENPINNEDMEMORY, -1.0, -1.0, true},
|
||||||
{OS_ALL, VENDOR_MESA, DRIVER_NOUVEAU, -1, BUG_BROKENHACKEDBUFFER, -1.0, -1.0, true},
|
{OS_ALL, VENDOR_MESA, DRIVER_NOUVEAU, -1, BUG_BROKENHACKEDBUFFER, -1.0, -1.0, true},
|
||||||
|
{OS_ALL, VENDOR_NVIDIA, DRIVER_NVIDIA, -1, BUG_BROKENBUFFERSTORAGE, -1.0, -1.0, true},
|
||||||
{OS_OSX, VENDOR_INTEL, DRIVER_INTEL, 3000, BUG_PRIMITIVERESTART, -1.0, -1.0, true},
|
{OS_OSX, VENDOR_INTEL, DRIVER_INTEL, 3000, BUG_PRIMITIVERESTART, -1.0, -1.0, true},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,14 @@ namespace DriverDetails
|
||||||
// Ended Version: -1
|
// Ended Version: -1
|
||||||
// If a shader includes a textureSize function call then the shader compiler will call abort()
|
// If a shader includes a textureSize function call then the shader compiler will call abort()
|
||||||
BUG_BROKENTEXTURESIZE,
|
BUG_BROKENTEXTURESIZE,
|
||||||
|
// Bug: ARB_buffer_storage doesn't work with ARRAY_BUFFER type streams
|
||||||
|
// Affected devices: Geforce 4xx+
|
||||||
|
// Started Version: -1
|
||||||
|
// Ended Version: -1
|
||||||
|
// The buffer_storage streaming method is required for greater speed gains in our buffer streaming
|
||||||
|
// It reduces what is needed for streaming to basically a memcpy call
|
||||||
|
// It seems to work for all buffer types except GL_ARRAY_BUFFER
|
||||||
|
BUG_BROKENBUFFERSTORAGE,
|
||||||
// Bug: Intel HD 3000 on OS X has broken primitive restart
|
// Bug: Intel HD 3000 on OS X has broken primitive restart
|
||||||
// Affected devices: Intel HD 3000
|
// Affected devices: Intel HD 3000
|
||||||
// Affected OS: OS X
|
// Affected OS: OS X
|
||||||
|
|
Loading…
Reference in New Issue