mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-10-07 11:36:40 +02:00
This pull request is for the pending reorganization of the folder structure on GSdx, making it better organized and easier to work with. Also remove unused GSTextureFX.cpp file.
168 lines
4.3 KiB
C++
168 lines
4.3 KiB
C++
/*
|
|
* Copyright (C) 2011-2011 Gregory hainaut
|
|
* Copyright (C) 2007-2009 Gabest
|
|
*
|
|
* This Program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This Program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with GNU Make; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "GLState.h"
|
|
|
|
#ifdef ENABLE_OGL_DEBUG_MEM_BW
|
|
extern uint64 g_uniform_upload_byte;
|
|
#endif
|
|
|
|
|
|
class GSUniformBufferOGL {
|
|
GLuint m_buffer; // data object
|
|
GLuint m_index; // GLSL slot
|
|
uint32 m_size; // size of the data
|
|
uint8* m_cache; // content of the previous upload
|
|
|
|
public:
|
|
GSUniformBufferOGL(const std::string& pretty_name, GLuint index, uint32 size)
|
|
: m_index(index), m_size(size)
|
|
{
|
|
glGenBuffers(1, &m_buffer);
|
|
bind();
|
|
glObjectLabel(GL_BUFFER, m_buffer, pretty_name.size(), pretty_name.c_str());
|
|
allocate();
|
|
attach();
|
|
m_cache = (uint8*)_aligned_malloc(m_size, 32);
|
|
memset(m_cache, 0, m_size);
|
|
}
|
|
|
|
void bind()
|
|
{
|
|
if (GLState::ubo != m_buffer) {
|
|
GLState::ubo = m_buffer;
|
|
glBindBuffer(GL_UNIFORM_BUFFER, m_buffer);
|
|
}
|
|
}
|
|
|
|
void allocate()
|
|
{
|
|
glBufferData(GL_UNIFORM_BUFFER, m_size, NULL, GL_DYNAMIC_DRAW);
|
|
}
|
|
|
|
void attach()
|
|
{
|
|
// From the opengl manpage:
|
|
// glBindBufferBase also binds buffer to the generic buffer binding point specified by target
|
|
GLState::ubo = m_buffer;
|
|
glBindBufferBase(GL_UNIFORM_BUFFER, m_index, m_buffer);
|
|
}
|
|
|
|
void upload(const void* src)
|
|
{
|
|
bind();
|
|
// glMapBufferRange allow to set various parameter but the call is
|
|
// synchronous whereas glBufferSubData could be asynchronous.
|
|
// TODO: investigate the extension ARB_invalidate_subdata
|
|
glBufferSubData(GL_UNIFORM_BUFFER, 0, m_size, src);
|
|
#ifdef ENABLE_OGL_DEBUG_MEM_BW
|
|
g_uniform_upload_byte += m_size;
|
|
#endif
|
|
}
|
|
|
|
void cache_upload(const void* src)
|
|
{
|
|
if (memcmp(m_cache, src, m_size) != 0) {
|
|
memcpy(m_cache, src, m_size);
|
|
upload(src);
|
|
}
|
|
}
|
|
|
|
~GSUniformBufferOGL()
|
|
{
|
|
glDeleteBuffers(1, &m_buffer);
|
|
_aligned_free(m_cache);
|
|
}
|
|
};
|
|
|
|
#define UBO_BUFFER_SIZE (4*1024*1024)
|
|
|
|
class GSUniformBufferStorageOGL {
|
|
GLuint m_buffer; // data object
|
|
GLuint m_index; // GLSL slot
|
|
uint32 m_size; // size of the data
|
|
uint8* m_buffer_ptr;
|
|
uint32 m_offset;
|
|
|
|
public:
|
|
GSUniformBufferStorageOGL(GLuint index, uint32 size) : m_index(index)
|
|
, m_size(size), m_offset(0)
|
|
{
|
|
glGenBuffers(1, &m_buffer);
|
|
bind();
|
|
allocate();
|
|
attach();
|
|
}
|
|
|
|
void bind()
|
|
{
|
|
if (GLState::ubo != m_buffer) {
|
|
GLState::ubo = m_buffer;
|
|
glBindBuffer(GL_UNIFORM_BUFFER, m_buffer);
|
|
}
|
|
}
|
|
|
|
void allocate()
|
|
{
|
|
const GLbitfield common_flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT /*| GL_MAP_COHERENT_BIT */;
|
|
const GLbitfield map_flags = common_flags | GL_MAP_FLUSH_EXPLICIT_BIT;
|
|
const GLbitfield create_flags = common_flags /*| GL_CLIENT_STORAGE_BIT */;
|
|
|
|
GLsizei buffer_size = UBO_BUFFER_SIZE;
|
|
glBufferStorage(GL_UNIFORM_BUFFER, buffer_size, NULL, create_flags);
|
|
m_buffer_ptr = (uint8*) glMapBufferRange(GL_UNIFORM_BUFFER, 0, buffer_size, map_flags);
|
|
ASSERT(m_buffer_ptr);
|
|
}
|
|
|
|
void attach()
|
|
{
|
|
// From the opengl manpage:
|
|
// glBindBufferBase also binds buffer to the generic buffer binding point specified by target
|
|
GLState::ubo = m_buffer;
|
|
//glBindBufferBase(GL_UNIFORM_BUFFER, m_index, m_buffer);
|
|
glBindBufferRange(GL_UNIFORM_BUFFER, m_index, m_buffer, m_offset, m_size);
|
|
}
|
|
|
|
void upload(const void* src)
|
|
{
|
|
#ifdef ENABLE_OGL_DEBUG_MEM_BW
|
|
g_uniform_upload_byte += m_size;
|
|
#endif
|
|
|
|
memcpy(m_buffer_ptr + m_offset, src, m_size);
|
|
|
|
attach();
|
|
glFlushMappedBufferRange(GL_UNIFORM_BUFFER, m_offset, m_size);
|
|
|
|
m_offset = (m_offset + m_size + 255u) & ~0xFF;
|
|
if (m_offset >= UBO_BUFFER_SIZE)
|
|
m_offset = 0;
|
|
}
|
|
|
|
~GSUniformBufferStorageOGL() {
|
|
glDeleteBuffers(1, &m_buffer);
|
|
}
|
|
};
|
|
|
|
#undef UBO_BUFFER_SIZE
|