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:
degasus
2013-01-14 21:36:31 +01:00
20 changed files with 691 additions and 546 deletions

View File

@ -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() {
}
}