mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-26 15:49:50 -06:00
Merge branch 'Graphic_Update' into GLSL-master
Conflicts: Source/Core/VideoCommon/Src/VertexManagerBase.cpp Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp Source/Plugins/Plugin_VideoOGL/Src/Render.cpp Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp
This commit is contained in:
@ -26,48 +26,9 @@
|
||||
#include "NativeVertexFormat.h"
|
||||
#include "VertexManager.h"
|
||||
|
||||
#define COMPILED_CODE_SIZE 4096
|
||||
|
||||
// TODO: Use this again for performance, but without VAO we never know exactly the last configuration
|
||||
static u32 s_prevcomponents; // previous state set
|
||||
|
||||
/*
|
||||
#ifdef _WIN32
|
||||
#ifdef _M_IX86
|
||||
#define USE_JIT
|
||||
#endif
|
||||
#endif
|
||||
*/
|
||||
// Note the use of CallCdeclFunction3I etc.
|
||||
// This is a horrible hack that is necessary because in 64-bit mode, Opengl32.dll is based way, way above the 32-bit
|
||||
// address space that is within reach of a CALL, and just doing &fn gives us these high uncallable addresses. So we
|
||||
// want to grab the function pointers from the import table instead.
|
||||
|
||||
// This problem does not apply to glew functions, only core opengl32 functions.
|
||||
|
||||
// Here's some global state. We only use this to keep track of what we've sent to the OpenGL state
|
||||
// machine.
|
||||
|
||||
#ifdef USE_JIT
|
||||
DECLARE_IMPORT(glNormalPointer);
|
||||
DECLARE_IMPORT(glVertexPointer);
|
||||
DECLARE_IMPORT(glColorPointer);
|
||||
DECLARE_IMPORT(glTexCoordPointer);
|
||||
#endif
|
||||
|
||||
class GLVertexFormat : public NativeVertexFormat
|
||||
{
|
||||
u8 *m_compiledCode;
|
||||
PortableVertexDeclaration vtx_decl;
|
||||
|
||||
public:
|
||||
GLVertexFormat();
|
||||
~GLVertexFormat();
|
||||
|
||||
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
||||
virtual void SetupVertexPointers();
|
||||
};
|
||||
|
||||
namespace OGL
|
||||
{
|
||||
|
||||
@ -76,23 +37,14 @@ NativeVertexFormat* VertexManager::CreateNativeVertexFormat()
|
||||
return new GLVertexFormat();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GLVertexFormat::GLVertexFormat()
|
||||
{
|
||||
#ifdef USE_JIT
|
||||
m_compiledCode = (u8 *)AllocateExecutableMemory(COMPILED_CODE_SIZE, false);
|
||||
if (m_compiledCode)
|
||||
memset(m_compiledCode, 0, COMPILED_CODE_SIZE);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
GLVertexFormat::~GLVertexFormat()
|
||||
{
|
||||
#ifdef USE_JIT
|
||||
FreeMemoryPages(m_compiledCode, COMPILED_CODE_SIZE);
|
||||
m_compiledCode = 0;
|
||||
#endif
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
}
|
||||
|
||||
inline GLuint VarToGL(VarType t)
|
||||
@ -105,105 +57,44 @@ inline GLuint VarToGL(VarType t)
|
||||
|
||||
void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
|
||||
{
|
||||
s_prevcomponents = 0;
|
||||
|
||||
vertex_stride = _vtx_decl.stride;
|
||||
using namespace Gen;
|
||||
this->vtx_decl = _vtx_decl;
|
||||
vertex_stride = vtx_decl.stride;
|
||||
|
||||
// We will not allow vertex components causing uneven strides.
|
||||
if (_vtx_decl.stride & 3)
|
||||
PanicAlert("Uneven vertex stride: %i", _vtx_decl.stride);
|
||||
|
||||
#ifdef USE_JIT
|
||||
Gen::XEmitter emit(m_compiledCode);
|
||||
// Alright, we have our vertex declaration. Compile some crazy code to set it quickly using GL.
|
||||
emit.ABI_EmitPrologue(6);
|
||||
if (vertex_stride & 3)
|
||||
PanicAlert("Uneven vertex stride: %i", vertex_stride);
|
||||
|
||||
emit.CallCdeclFunction4_I(glVertexPointer, 3, GL_FLOAT, _vtx_decl.stride, 0);
|
||||
|
||||
if (_vtx_decl.num_normals >= 1)
|
||||
{
|
||||
emit.CallCdeclFunction3_I(glNormalPointer, VarToGL(_vtx_decl.normal_gl_type), _vtx_decl.stride, _vtx_decl.normal_offset[0]);
|
||||
if (_vtx_decl.num_normals == 3) {
|
||||
emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM1_ATTRIB, _vtx_decl.normal_gl_size, VarToGL(_vtx_decl.normal_gl_type), GL_TRUE, _vtx_decl.stride, _vtx_decl.normal_offset[1]);
|
||||
emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM2_ATTRIB, _vtx_decl.normal_gl_size, VarToGL(_vtx_decl.normal_gl_type), GL_TRUE, _vtx_decl.stride, _vtx_decl.normal_offset[2]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (_vtx_decl.color_offset[i] != -1)
|
||||
{
|
||||
if (i == 0)
|
||||
emit.CallCdeclFunction4_I(glColorPointer, 4, GL_UNSIGNED_BYTE, _vtx_decl.stride, _vtx_decl.color_offset[i]);
|
||||
else
|
||||
emit.CallCdeclFunction4((void *)glSecondaryColorPointer, 4, GL_UNSIGNED_BYTE, _vtx_decl.stride, _vtx_decl.color_offset[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (_vtx_decl.texcoord_offset[i] != -1)
|
||||
{
|
||||
int id = GL_TEXTURE0 + i;
|
||||
#ifdef _M_X64
|
||||
#ifdef _MSC_VER
|
||||
emit.MOV(32, R(RCX), Imm32(id));
|
||||
#else
|
||||
emit.MOV(32, R(RDI), Imm32(id));
|
||||
#endif
|
||||
#else
|
||||
emit.ABI_AlignStack(1 * 4);
|
||||
emit.PUSH(32, Imm32(id));
|
||||
#endif
|
||||
emit.CALL((void *)glClientActiveTexture);
|
||||
#ifndef _M_X64
|
||||
#ifdef _WIN32
|
||||
// don't inc stack on windows, stdcall
|
||||
#else
|
||||
emit.ABI_RestoreStack(1 * 4);
|
||||
#endif
|
||||
#endif
|
||||
emit.CallCdeclFunction4_I(
|
||||
glTexCoordPointer, _vtx_decl.texcoord_size[i], VarToGL(_vtx_decl.texcoord_gl_type[i]),
|
||||
_vtx_decl.stride, _vtx_decl.texcoord_offset[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (_vtx_decl.posmtx_offset != -1)
|
||||
emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, _vtx_decl.stride, _vtx_decl.posmtx_offset);
|
||||
|
||||
emit.ABI_EmitEpilogue(6);
|
||||
|
||||
if (emit.GetCodePtr() - (u8*)m_compiledCode > COMPILED_CODE_SIZE)
|
||||
Crash();
|
||||
|
||||
#endif
|
||||
this->vtx_decl = _vtx_decl;
|
||||
}
|
||||
|
||||
void GLVertexFormat::SetupVertexPointers() {
|
||||
// Cast a pointer to compiled code to a pointer to a function taking no parameters, through a (void *) cast first to
|
||||
// get around type checking errors, and call it.
|
||||
#ifdef USE_JIT
|
||||
((void (*)())(void*)m_compiledCode)();
|
||||
#else
|
||||
VertexManager *vm = (OGL::VertexManager*)g_vertex_manager;
|
||||
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
// the element buffer is bound directly to the vao, so we must it set for every vao
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->m_index_buffers);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, vtx_decl.stride, (u8*)NULL);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, vtx_decl.stride, VertexManager::s_pBaseBufferPointer);
|
||||
if (vtx_decl.num_normals >= 1) {
|
||||
glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[0]));
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[0]);
|
||||
if (vtx_decl.num_normals == 3) {
|
||||
glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[1]));
|
||||
glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[2]));
|
||||
glEnableVertexAttribArray(SHADER_NORM1_ATTRIB);
|
||||
glEnableVertexAttribArray(SHADER_NORM2_ATTRIB);
|
||||
glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[1]);
|
||||
glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[2]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (vtx_decl.color_offset[i] != -1) {
|
||||
if (i == 0)
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.color_offset[i]));
|
||||
else {
|
||||
glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.color_offset[i]));
|
||||
if (i == 0) {
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]);
|
||||
} else {
|
||||
glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
|
||||
glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -212,75 +103,21 @@ void GLVertexFormat::SetupVertexPointers() {
|
||||
if (vtx_decl.texcoord_offset[i] != -1) {
|
||||
int id = GL_TEXTURE0 + i;
|
||||
glClientActiveTexture(id);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]),
|
||||
vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.texcoord_offset[i]));
|
||||
vtx_decl.stride, (u8*)NULL + vtx_decl.texcoord_offset[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (vtx_decl.posmtx_offset != -1) {
|
||||
glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.posmtx_offset));
|
||||
glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB);
|
||||
glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (u8*)NULL + vtx_decl.posmtx_offset);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (s_prevcomponents != m_components)
|
||||
{
|
||||
// vertices
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
// matrices
|
||||
if ((m_components & VB_HAS_POSMTXIDX) != (s_prevcomponents & VB_HAS_POSMTXIDX))
|
||||
{
|
||||
if (m_components & VB_HAS_POSMTXIDX)
|
||||
glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB);
|
||||
else
|
||||
glDisableVertexAttribArray(SHADER_POSMTX_ATTRIB);
|
||||
}
|
||||
|
||||
// normals
|
||||
if ((m_components & VB_HAS_NRM0) != (s_prevcomponents & VB_HAS_NRM0))
|
||||
{
|
||||
if (m_components & VB_HAS_NRM0)
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
else
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
}
|
||||
if ((m_components & VB_HAS_NRM1) != (s_prevcomponents & VB_HAS_NRM1))
|
||||
{
|
||||
if (m_components & VB_HAS_NRM1) {
|
||||
glEnableVertexAttribArray(SHADER_NORM1_ATTRIB);
|
||||
glEnableVertexAttribArray(SHADER_NORM2_ATTRIB);
|
||||
}
|
||||
else {
|
||||
glDisableVertexAttribArray(SHADER_NORM1_ATTRIB);
|
||||
glDisableVertexAttribArray(SHADER_NORM2_ATTRIB);
|
||||
}
|
||||
}
|
||||
|
||||
// color
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
if ((m_components & (VB_HAS_COL0 << i)) != (s_prevcomponents & (VB_HAS_COL0 << i)))
|
||||
{
|
||||
if (m_components & (VB_HAS_COL0 << i))
|
||||
glEnableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
|
||||
else
|
||||
glDisableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
// tex
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
if ((m_components & (VB_HAS_UV0 << i)) != (s_prevcomponents & (VB_HAS_UV0 << i)))
|
||||
{
|
||||
glClientActiveTexture(GL_TEXTURE0 + i);
|
||||
if (m_components & (VB_HAS_UV0 << i))
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
else
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
s_prevcomponents = m_components;
|
||||
}
|
||||
vm->m_last_vao = VAO;
|
||||
}
|
||||
|
||||
void GLVertexFormat::SetupVertexPointers() {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -193,10 +193,6 @@ RasterFont::RasterFont()
|
||||
glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, NULL);
|
||||
glEnableVertexAttribArray(SHADER_TEXTURE0_ATTRIB);
|
||||
glVertexAttribPointer(SHADER_TEXTURE0_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL+2);
|
||||
|
||||
// TODO: this after merging with graphic_update
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
RasterFont::~RasterFont()
|
||||
@ -288,10 +284,6 @@ void RasterFont::printMultilineText(const char *text, double start_x, double sta
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glDrawArrays(GL_TRIANGLES, 0, usage/4);
|
||||
|
||||
// TODO: this after merging with graphic_update
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,7 @@
|
||||
#include "BPFunctions.h"
|
||||
#include "FPSCounter.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "VertexManager.h"
|
||||
|
||||
#include "main.h" // Local
|
||||
#ifdef _WIN32
|
||||
@ -296,6 +297,20 @@ Renderer::Renderer()
|
||||
"GPU: Does your video card support OpenGL 3.0?");
|
||||
bSuccess = false;
|
||||
}
|
||||
|
||||
if (!GLEW_ARB_map_buffer_range)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_map_buffer_range.\n"
|
||||
"GPU: Does your video card support OpenGL 3.0?");
|
||||
bSuccess = false;
|
||||
}
|
||||
|
||||
if (!GLEW_ARB_draw_elements_base_vertex)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_draw_elements_base_vertex.\n"
|
||||
"GPU: Does your video card support OpenGL 3.2?");
|
||||
bSuccess = false;
|
||||
}
|
||||
|
||||
s_bHaveCoverageMSAA = strstr(ptoken, "GL_NV_framebuffer_multisample_coverage") != NULL;
|
||||
|
||||
@ -415,10 +430,6 @@ Renderer::Renderer()
|
||||
glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*5, NULL);
|
||||
glEnableVertexAttribArray(SHADER_COLOR0_ATTRIB);
|
||||
glVertexAttribPointer(SHADER_COLOR0_ATTRIB, 3, GL_FLOAT, 0, sizeof(GLfloat)*5, (GLfloat*)NULL+2);
|
||||
|
||||
// TODO: this after merging with graphic_update
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glStencilFunc(GL_ALWAYS, 0, 0);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
@ -603,10 +614,6 @@ void Renderer::DrawDebugInfo()
|
||||
ProgramShaderCache::SetBothShaders(s_ShowEFBCopyRegions_PS.glprogid, s_ShowEFBCopyRegions_VS.glprogid);
|
||||
glBindVertexArray( s_ShowEFBCopyRegions_VAO );
|
||||
glDrawArrays(GL_LINES, 0, stats.efb_regions.size() * 2*6);
|
||||
|
||||
// TODO: this after merging with graphic_update
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// Restore Line Size
|
||||
glLineWidth(lSize);
|
||||
@ -1429,6 +1436,10 @@ void Renderer::RestoreAPIState()
|
||||
glPolygonMode(GL_FRONT_AND_BACK, g_ActiveConfig.bWireFrame ? GL_LINE : GL_FILL);
|
||||
|
||||
ProgramShaderCache::SetBothShaders(0, 0);
|
||||
|
||||
VertexManager *vm = (OGL::VertexManager*)g_vertex_manager;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers);
|
||||
vm->m_last_vao = 0;
|
||||
}
|
||||
|
||||
void Renderer::SetGenerationMode()
|
||||
|
@ -375,10 +375,6 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||
|
||||
glBindVertexArray(vbo_it->second.vao);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
// TODO: this after merging with graphic_update
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||
|
||||
|
@ -183,10 +183,6 @@ void Init()
|
||||
glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL);
|
||||
glEnableVertexAttribArray(SHADER_TEXTURE0_ATTRIB);
|
||||
glVertexAttribPointer(SHADER_TEXTURE0_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL+2);
|
||||
|
||||
// TODO: this after merging with graphic_update
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glGenRenderbuffers(1, &s_dstRenderBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, s_dstRenderBuffer);
|
||||
@ -285,10 +281,6 @@ void EncodeToRamUsingShader(GLuint srcTexture, const TargetRectangle& sourceRc,
|
||||
glBindVertexArray( s_encode_VAO );
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
// TODO: this after merging with graphic_update
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||
|
||||
GL_REPORT_ERRORD();
|
||||
@ -475,10 +467,6 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
|
||||
glBindVertexArray( s_decode_VAO );
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
// TODO: this after merging with graphic_update
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
// reset state
|
||||
|
@ -49,58 +49,177 @@ extern NativeVertexFormat *g_nativeVertexFmt;
|
||||
|
||||
namespace OGL
|
||||
{
|
||||
|
||||
//static GLint max_Index_size = 0;
|
||||
|
||||
//static GLuint s_vboBuffers[MAXVBOBUFFERCOUNT] = {0};
|
||||
//static int s_nCurVBOIndex = 0; // current free buffer
|
||||
//This are the initially requeted size for the buffers expresed in bytes
|
||||
const u32 MAX_IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16 * sizeof(u16);
|
||||
const u32 MAX_VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16;
|
||||
const u32 MIN_IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 1 * sizeof(u16);
|
||||
const u32 MIN_VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 1;
|
||||
|
||||
VertexManager::VertexManager()
|
||||
{
|
||||
// TODO: doesn't seem to be used anywhere
|
||||
CreateDeviceObjects();
|
||||
}
|
||||
|
||||
//glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*)&max_Index_size);
|
||||
//
|
||||
//if (max_Index_size > MAXIBUFFERSIZE)
|
||||
// max_Index_size = MAXIBUFFERSIZE;
|
||||
//
|
||||
//GL_REPORT_ERRORD();
|
||||
VertexManager::~VertexManager()
|
||||
{
|
||||
DestroyDeviceObjects();
|
||||
}
|
||||
|
||||
void VertexManager::CreateDeviceObjects()
|
||||
{
|
||||
GL_REPORT_ERRORD();
|
||||
u32 max_Index_size = 0;
|
||||
u32 max_Vertex_size = 0;
|
||||
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*)&max_Index_size);
|
||||
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*)&max_Vertex_size);
|
||||
max_Index_size *= sizeof(u16);
|
||||
GL_REPORT_ERROR();
|
||||
|
||||
m_index_buffer_size = std::min(MAX_IBUFFER_SIZE, std::max(max_Index_size, MIN_IBUFFER_SIZE));
|
||||
m_vertex_buffer_size = std::min(MAX_VBUFFER_SIZE, std::max(max_Vertex_size, MIN_VBUFFER_SIZE));
|
||||
|
||||
// should be not bigger, but we need it. so try and have luck
|
||||
if (m_index_buffer_size > max_Index_size) {
|
||||
ERROR_LOG(VIDEO, "GL_MAX_ELEMENTS_INDICES to small, so try it anyway. good luck\n");
|
||||
}
|
||||
if (m_vertex_buffer_size > max_Vertex_size) {
|
||||
ERROR_LOG(VIDEO, "GL_MAX_ELEMENTS_VERTICES to small, so try it anyway. good luck\n");
|
||||
}
|
||||
|
||||
glGenBuffers(1, &m_vertex_buffers);
|
||||
GL_REPORT_ERROR();
|
||||
glGenBuffers(1, &m_index_buffers);
|
||||
GL_REPORT_ERROR();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers );
|
||||
GL_REPORT_ERROR();
|
||||
glBufferData(GL_ARRAY_BUFFER, m_vertex_buffer_size, NULL, GL_STREAM_DRAW );
|
||||
GL_REPORT_ERROR();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers );
|
||||
GL_REPORT_ERROR();
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_size, NULL, GL_STREAM_DRAW );
|
||||
GL_REPORT_ERROR();
|
||||
m_index_buffer_cursor = 0;
|
||||
m_vertex_buffer_cursor = 0;
|
||||
m_CurrentVertexFmt = NULL;
|
||||
m_last_vao = 0;
|
||||
}
|
||||
void VertexManager::DestroyDeviceObjects()
|
||||
{
|
||||
GL_REPORT_ERRORD();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0 );
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0 );
|
||||
GL_REPORT_ERROR();
|
||||
|
||||
glDeleteBuffers(1, &m_vertex_buffers);
|
||||
GL_REPORT_ERROR();
|
||||
|
||||
glDeleteBuffers(1, &m_index_buffers);
|
||||
GL_REPORT_ERROR();
|
||||
}
|
||||
|
||||
void VertexManager::Draw()
|
||||
void VertexManager::PrepareDrawBuffers(u32 stride)
|
||||
{
|
||||
if (IndexGenerator::GetNumTriangles() > 0)
|
||||
u8* pVertices = NULL;
|
||||
u16* pIndices = NULL;
|
||||
int vertex_data_size = IndexGenerator::GetNumVerts() * stride;
|
||||
int triangle_index_size = IndexGenerator::GetTriangleindexLen();
|
||||
int line_index_size = IndexGenerator::GetLineindexLen();
|
||||
int point_index_size = IndexGenerator::GetPointindexLen();
|
||||
int index_data_size = (triangle_index_size + line_index_size + point_index_size) * sizeof(u16);
|
||||
GLbitfield LockMode = GL_MAP_WRITE_BIT;
|
||||
|
||||
m_vertex_buffer_cursor--;
|
||||
m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride;
|
||||
|
||||
if (m_vertex_buffer_cursor >= m_vertex_buffer_size - vertex_data_size || m_index_buffer_cursor >= m_index_buffer_size - index_data_size)
|
||||
{
|
||||
glDrawElements(GL_TRIANGLES, IndexGenerator::GetTriangleindexLen(), GL_UNSIGNED_SHORT, TIBuffer);
|
||||
LockMode |= GL_MAP_INVALIDATE_BUFFER_BIT;
|
||||
m_vertex_buffer_cursor = 0;
|
||||
m_index_buffer_cursor = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LockMode |= /*GL_MAP_INVALIDATE_RANGE_BIT |*/ GL_MAP_UNSYNCHRONIZED_BIT;
|
||||
}
|
||||
|
||||
pVertices = (u8*)glMapBufferRange(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LockMode);
|
||||
if(pVertices)
|
||||
{
|
||||
memcpy(pVertices, LocalVBuffer, vertex_data_size);
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
}
|
||||
else // could that happen? out-of-memory?
|
||||
{
|
||||
glBufferSubData(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LocalVBuffer);
|
||||
}
|
||||
|
||||
pIndices = (u16*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor , index_data_size, LockMode);
|
||||
if(pIndices)
|
||||
{
|
||||
if(triangle_index_size)
|
||||
{
|
||||
memcpy(pIndices, TIBuffer, triangle_index_size * sizeof(u16));
|
||||
pIndices += triangle_index_size;
|
||||
}
|
||||
if(line_index_size)
|
||||
{
|
||||
memcpy(pIndices, LIBuffer, line_index_size * sizeof(u16));
|
||||
pIndices += line_index_size;
|
||||
}
|
||||
if(point_index_size)
|
||||
{
|
||||
memcpy(pIndices, PIBuffer, point_index_size * sizeof(u16));
|
||||
}
|
||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||
}
|
||||
else // could that happen? out-of-memory?
|
||||
{
|
||||
if(triangle_index_size)
|
||||
{
|
||||
triangle_index_size *= sizeof(u16);
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor, triangle_index_size, TIBuffer);
|
||||
}
|
||||
if(line_index_size)
|
||||
{
|
||||
line_index_size *= sizeof(u16);
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor + triangle_index_size, line_index_size, LIBuffer);
|
||||
}
|
||||
if(point_index_size)
|
||||
{
|
||||
point_index_size *= sizeof(u16);
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor + triangle_index_size + line_index_size, point_index_size, PIBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VertexManager::Draw(u32 stride)
|
||||
{
|
||||
int triangle_index_size = IndexGenerator::GetTriangleindexLen();
|
||||
int line_index_size = IndexGenerator::GetLineindexLen();
|
||||
int point_index_size = IndexGenerator::GetPointindexLen();
|
||||
int StartIndex = m_index_buffer_cursor;
|
||||
int basevertex = m_vertex_buffer_cursor / stride;
|
||||
if (triangle_index_size > 0)
|
||||
{
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, triangle_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+StartIndex, basevertex);
|
||||
StartIndex += triangle_index_size * sizeof(u16);
|
||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||
}
|
||||
if (IndexGenerator::GetNumLines() > 0)
|
||||
if (line_index_size > 0)
|
||||
{
|
||||
glDrawElements(GL_LINES, IndexGenerator::GetLineindexLen(), GL_UNSIGNED_SHORT, LIBuffer);
|
||||
glDrawElementsBaseVertex(GL_LINES, line_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+StartIndex, basevertex);
|
||||
StartIndex += line_index_size * sizeof(u16);
|
||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||
}
|
||||
if (IndexGenerator::GetNumPoints() > 0)
|
||||
if (point_index_size > 0)
|
||||
{
|
||||
glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, PIBuffer);
|
||||
glDrawElementsBaseVertex(GL_POINTS, point_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+StartIndex, basevertex);
|
||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||
}
|
||||
}
|
||||
|
||||
void VertexManager::vFlush()
|
||||
{
|
||||
if (LocalVBuffer == s_pCurBufferPointer) return;
|
||||
if (Flushed) return;
|
||||
Flushed=true;
|
||||
VideoFifo_CheckEFBAccess();
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfregs.numTexGen.numTexGens,
|
||||
@ -132,10 +251,15 @@ void VertexManager::vFlush()
|
||||
|
||||
(void)GL_REPORT_ERROR();
|
||||
|
||||
//glBindBuffer(GL_ARRAY_BUFFER, s_vboBuffers[s_nCurVBOIndex]);
|
||||
//glBufferData(GL_ARRAY_BUFFER, s_pCurBufferPointer - LocalVBuffer, LocalVBuffer, GL_STREAM_DRAW);
|
||||
GL_REPORT_ERRORD();
|
||||
GLVertexFormat *nativeVertexFmt = (GLVertexFormat*)g_nativeVertexFmt;
|
||||
u32 stride = nativeVertexFmt->GetVertexStride();
|
||||
|
||||
if(m_last_vao != nativeVertexFmt->VAO) {
|
||||
glBindVertexArray(nativeVertexFmt->VAO);
|
||||
m_last_vao = nativeVertexFmt->VAO;
|
||||
}
|
||||
|
||||
PrepareDrawBuffers(stride);
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
u32 usedtextures = 0;
|
||||
@ -148,7 +272,7 @@ void VertexManager::vFlush()
|
||||
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
|
||||
usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
for (u32 i = 0; i < 8; i++)
|
||||
{
|
||||
if (usedtextures & (1 << i))
|
||||
{
|
||||
@ -215,7 +339,7 @@ void VertexManager::vFlush()
|
||||
g_nativeVertexFmt->SetupVertexPointers();
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
Draw();
|
||||
Draw(stride);
|
||||
|
||||
// run through vertex groups again to set alpha
|
||||
if (useDstAlpha && !dualSourcePossible)
|
||||
@ -235,7 +359,8 @@ void VertexManager::vFlush()
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
Draw();
|
||||
Draw(stride);
|
||||
|
||||
// restore color mask
|
||||
g_renderer->SetColorMask();
|
||||
|
||||
@ -243,11 +368,11 @@ void VertexManager::vFlush()
|
||||
glEnable(GL_BLEND);
|
||||
}
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true);
|
||||
|
||||
//s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers);
|
||||
s_pCurBufferPointer = LocalVBuffer;
|
||||
IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer);
|
||||
|
||||
|
||||
m_index_buffer_cursor += (IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen()) * sizeof(u16);
|
||||
m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride;
|
||||
|
||||
ResetBuffer();
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
if (g_ActiveConfig.iLog & CONF_SAVESHADERS)
|
||||
{
|
||||
|
@ -24,6 +24,19 @@
|
||||
|
||||
namespace OGL
|
||||
{
|
||||
class GLVertexFormat : public NativeVertexFormat
|
||||
{
|
||||
PortableVertexDeclaration vtx_decl;
|
||||
|
||||
public:
|
||||
GLVertexFormat();
|
||||
~GLVertexFormat();
|
||||
|
||||
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
||||
virtual void SetupVertexPointers();
|
||||
|
||||
GLuint VAO;
|
||||
};
|
||||
|
||||
// Handles the OpenGL details of drawing lots of vertices quickly.
|
||||
// Other functionality is moving out.
|
||||
@ -31,14 +44,24 @@ class VertexManager : public ::VertexManager
|
||||
{
|
||||
public:
|
||||
VertexManager();
|
||||
|
||||
~VertexManager();
|
||||
NativeVertexFormat* CreateNativeVertexFormat();
|
||||
void CreateDeviceObjects();
|
||||
void DestroyDeviceObjects();
|
||||
|
||||
// NativeVertexFormat use this
|
||||
GLuint m_vertex_buffers;
|
||||
GLuint m_index_buffers;
|
||||
GLuint m_last_vao;
|
||||
private:
|
||||
void Draw();
|
||||
// temp
|
||||
void Draw(u32 stride);
|
||||
void vFlush();
|
||||
void PrepareDrawBuffers(u32 stride);
|
||||
u32 m_vertex_buffer_cursor;
|
||||
u32 m_vertex_buffer_size;
|
||||
u32 m_index_buffer_cursor;
|
||||
u32 m_index_buffer_size;
|
||||
NativeVertexFormat *m_CurrentVertexFmt;
|
||||
};
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user