mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -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() {
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user