OpenGL Renderer: Add new rendering resource classes, and do some misc. refactoring.
- Using the new OpenGLGeometryResource and OpenGLRenderStatesResource classes, the 3.2 Core Profile and ES renderers now use triple-buffering for all geometry rendering resources and framebuffer constants. - Delete the InitFinalRenderStates() method, which has been obsoleted over the years. Its functionality has been rolled into the InitExtensions() and _RenderGeometryLoopBegin() methods.
This commit is contained in:
parent
f84a804499
commit
f910c6197c
|
@ -2384,6 +2384,14 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Mirrored Repeat Mode Support
|
||||||
|
const bool isTexMirroredRepeatSupported = this->IsVersionSupported(1, 4, 0) || this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_texture_mirrored_repeat");
|
||||||
|
OGLRef.stateTexMirroredRepeat = (isTexMirroredRepeatSupported) ? GL_MIRRORED_REPEAT : GL_REPEAT;
|
||||||
|
|
||||||
|
// Blending Support
|
||||||
|
this->_isBlendFuncSeparateSupported = this->IsVersionSupported(1, 4, 0) || this->IsExtensionPresent(&oglExtensionSet, "GL_EXT_blend_func_separate");
|
||||||
|
this->_isBlendEquationSeparateSupported = this->IsVersionSupported(2, 0, 0) || this->IsExtensionPresent(&oglExtensionSet, "GL_EXT_blend_equation_separate");
|
||||||
|
|
||||||
// Get host GPU device properties
|
// Get host GPU device properties
|
||||||
GLfloat maxAnisotropyOGL = 1.0f;
|
GLfloat maxAnisotropyOGL = 1.0f;
|
||||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyOGL);
|
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyOGL);
|
||||||
|
@ -2616,8 +2624,6 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
||||||
|
|
||||||
this->_enableMultisampledRendering = ((this->_selectedMultisampleSize >= 2) && this->isMultisampledFBOSupported);
|
this->_enableMultisampledRendering = ((this->_selectedMultisampleSize >= 2) && this->isMultisampledFBOSupported);
|
||||||
|
|
||||||
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
|
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3676,40 +3682,6 @@ void OpenGLRenderer_1_2::DestroyFramebufferOutput8888Programs()
|
||||||
OGLRef.fragmentFramebufferRGBA8888OutputShaderID = 0;
|
OGLRef.fragmentFramebufferRGBA8888OutputShaderID = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Render3DError OpenGLRenderer_1_2::InitFinalRenderStates(const std::set<std::string> *oglExtensionSet)
|
|
||||||
{
|
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
|
||||||
|
|
||||||
bool isTexMirroredRepeatSupported = this->IsExtensionPresent(oglExtensionSet, "GL_ARB_texture_mirrored_repeat");
|
|
||||||
bool isBlendFuncSeparateSupported = this->IsExtensionPresent(oglExtensionSet, "GL_EXT_blend_func_separate");
|
|
||||||
bool isBlendEquationSeparateSupported = this->IsExtensionPresent(oglExtensionSet, "GL_EXT_blend_equation_separate");
|
|
||||||
|
|
||||||
// Blending Support
|
|
||||||
if (isBlendFuncSeparateSupported)
|
|
||||||
{
|
|
||||||
if (isBlendEquationSeparateSupported)
|
|
||||||
{
|
|
||||||
// we want to use alpha destination blending so we can track the last-rendered alpha value
|
|
||||||
// test: new super mario brothers renders the stormclouds at the beginning
|
|
||||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_DST_ALPHA);
|
|
||||||
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_DST_ALPHA);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mirrored Repeat Mode Support
|
|
||||||
OGLRef.stateTexMirroredRepeat = (isTexMirroredRepeatSupported) ? GL_MIRRORED_REPEAT : GL_REPEAT;
|
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
Render3DError OpenGLRenderer_1_2::InitPostprocessingPrograms(const char *edgeMarkVtxShaderCString,
|
Render3DError OpenGLRenderer_1_2::InitPostprocessingPrograms(const char *edgeMarkVtxShaderCString,
|
||||||
const char *edgeMarkFragShaderCString,
|
const char *edgeMarkFragShaderCString,
|
||||||
const char *framebufferOutputVtxShaderCString,
|
const char *framebufferOutputVtxShaderCString,
|
||||||
|
@ -4384,6 +4356,25 @@ void OpenGLRenderer_1_2::_RenderGeometryLoopBegin()
|
||||||
if (this->_enableAlphaBlending)
|
if (this->_enableAlphaBlending)
|
||||||
{
|
{
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
|
if (this->_isBlendFuncSeparateSupported)
|
||||||
|
{
|
||||||
|
if (this->_isBlendEquationSeparateSupported)
|
||||||
|
{
|
||||||
|
// we want to use alpha destination blending so we can track the last-rendered alpha value
|
||||||
|
// test: new super mario brothers renders the stormclouds at the beginning
|
||||||
|
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_DST_ALPHA);
|
||||||
|
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_DST_ALPHA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4641,9 +4632,6 @@ Render3DError OpenGLRenderer_1_2::PostprocessFramebuffer()
|
||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_DST_ALPHA);
|
|
||||||
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->_FramebufferProcessVertexAttribDisable();
|
this->_FramebufferProcessVertexAttribDisable();
|
||||||
|
@ -5449,28 +5437,6 @@ OpenGLRenderer_2_0::OpenGLRenderer_2_0()
|
||||||
_variantID = OpenGLVariantID_Legacy_2_0;
|
_variantID = OpenGLVariantID_Legacy_2_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Render3DError OpenGLRenderer_2_0::InitFinalRenderStates(const std::set<std::string> *oglExtensionSet)
|
|
||||||
{
|
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
|
||||||
|
|
||||||
// we want to use alpha destination blending so we can track the last-rendered alpha value
|
|
||||||
// test: new super mario brothers renders the stormclouds at the beginning
|
|
||||||
|
|
||||||
// Blending Support
|
|
||||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_DST_ALPHA);
|
|
||||||
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
|
|
||||||
|
|
||||||
// Mirrored Repeat Mode Support
|
|
||||||
OGLRef.stateTexMirroredRepeat = GL_MIRRORED_REPEAT;
|
|
||||||
|
|
||||||
// Ignore our color buffer since we'll transfer the polygon alpha through a uniform.
|
|
||||||
OGLRef.position4fBuffer = NULL;
|
|
||||||
OGLRef.texCoord2fBuffer = NULL;
|
|
||||||
OGLRef.color4fBuffer = NULL;
|
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList)
|
Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList)
|
||||||
{
|
{
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
|
|
|
@ -303,10 +303,15 @@ EXTERNOGLEXT(PFNGLDELETERENDERBUFFERSEXTPROC, glDeleteRenderbuffersEXT)
|
||||||
|
|
||||||
#endif // GL_EXT_framebuffer_object
|
#endif // GL_EXT_framebuffer_object
|
||||||
|
|
||||||
// Some headers, such as the OpenGL ES headers, may not include this macro.
|
// Some headers, such as the OpenGL ES headers, may not include this token.
|
||||||
// Add it manually to avoid compiling issues.
|
// Add it manually to avoid compiling issues.
|
||||||
#ifndef GL_BGRA
|
#ifndef GL_BGRA
|
||||||
#define GL_BGRA GL_BGRA_EXT
|
#define GL_BGRA GL_BGRA_EXT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// OpenGL ES headers before 3.2 don't have this token, so manually define it here.
|
||||||
|
#ifndef GL_TEXTURE_BUFFER
|
||||||
|
#define GL_TEXTURE_BUFFER 0x8C2A
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// OPENGL CORE EQUIVALENTS FOR LEGACY FUNCTIONS
|
// OPENGL CORE EQUIVALENTS FOR LEGACY FUNCTIONS
|
||||||
|
@ -375,12 +380,25 @@ enum OpenGLVariantID
|
||||||
OpenGLVariantID_Unknown = 0,
|
OpenGLVariantID_Unknown = 0,
|
||||||
OpenGLVariantID_LegacyAuto = 0x1000,
|
OpenGLVariantID_LegacyAuto = 0x1000,
|
||||||
OpenGLVariantID_Legacy_1_2 = 0x1012,
|
OpenGLVariantID_Legacy_1_2 = 0x1012,
|
||||||
|
OpenGLVariantID_Legacy_1_3 = 0x1013,
|
||||||
|
OpenGLVariantID_Legacy_1_4 = 0x1014,
|
||||||
|
OpenGLVariantID_Legacy_1_5 = 0x1015,
|
||||||
OpenGLVariantID_Legacy_2_0 = 0x1020,
|
OpenGLVariantID_Legacy_2_0 = 0x1020,
|
||||||
OpenGLVariantID_Legacy_2_1 = 0x1021,
|
OpenGLVariantID_Legacy_2_1 = 0x1021,
|
||||||
OpenGLVariantID_CoreProfile_3_2 = 0x2032,
|
OpenGLVariantID_CoreProfile_3_2 = 0x2032,
|
||||||
|
OpenGLVariantID_CoreProfile_3_3 = 0x2033,
|
||||||
|
OpenGLVariantID_CoreProfile_4_0 = 0x2040,
|
||||||
|
OpenGLVariantID_CoreProfile_4_1 = 0x2041,
|
||||||
|
OpenGLVariantID_CoreProfile_4_2 = 0x2042,
|
||||||
|
OpenGLVariantID_CoreProfile_4_3 = 0x2043,
|
||||||
|
OpenGLVariantID_CoreProfile_4_4 = 0x2044,
|
||||||
|
OpenGLVariantID_CoreProfile_4_5 = 0x2045,
|
||||||
|
OpenGLVariantID_CoreProfile_4_6 = 0x2046,
|
||||||
OpenGLVariantID_StandardAuto = 0x3000,
|
OpenGLVariantID_StandardAuto = 0x3000,
|
||||||
OpenGLVariantID_ES3_Auto = 0x4000,
|
OpenGLVariantID_ES3_Auto = 0x4000,
|
||||||
OpenGLVariantID_ES3_3_0 = 0x4030,
|
OpenGLVariantID_ES3_3_0 = 0x4030,
|
||||||
|
OpenGLVariantID_ES3_3_1 = 0x4031,
|
||||||
|
OpenGLVariantID_ES3_3_2 = 0x4032,
|
||||||
OpenGLVariantID_ES_Auto = 0x6000
|
OpenGLVariantID_ES_Auto = 0x6000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -607,12 +625,6 @@ struct OGLRenderRef
|
||||||
// PBO
|
// PBO
|
||||||
GLuint pboRenderDataID;
|
GLuint pboRenderDataID;
|
||||||
|
|
||||||
// UBO / TBO
|
|
||||||
GLuint uboRenderStatesID;
|
|
||||||
GLuint uboPolyStatesID;
|
|
||||||
GLuint tboPolyStatesID;
|
|
||||||
GLuint texPolyStatesID;
|
|
||||||
|
|
||||||
// FBO
|
// FBO
|
||||||
GLuint texCIColorID;
|
GLuint texCIColorID;
|
||||||
GLuint texCIFogAttrID;
|
GLuint texCIFogAttrID;
|
||||||
|
@ -863,6 +875,8 @@ protected:
|
||||||
|
|
||||||
// OpenGL Feature Support
|
// OpenGL Feature Support
|
||||||
OpenGLVariantID _variantID;
|
OpenGLVariantID _variantID;
|
||||||
|
bool _isBlendFuncSeparateSupported;
|
||||||
|
bool _isBlendEquationSeparateSupported;
|
||||||
bool isVBOSupported;
|
bool isVBOSupported;
|
||||||
bool isPBOSupported;
|
bool isPBOSupported;
|
||||||
bool isFBOSupported;
|
bool isFBOSupported;
|
||||||
|
@ -950,7 +964,6 @@ protected:
|
||||||
virtual Render3DError CreateFramebufferOutput8888Program(const char *vtxShaderCString, const char *fragShaderCString) = 0;
|
virtual Render3DError CreateFramebufferOutput8888Program(const char *vtxShaderCString, const char *fragShaderCString) = 0;
|
||||||
virtual void DestroyFramebufferOutput8888Programs() = 0;
|
virtual void DestroyFramebufferOutput8888Programs() = 0;
|
||||||
|
|
||||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet) = 0;
|
|
||||||
virtual Render3DError InitPostprocessingPrograms(const char *edgeMarkVtxShader,
|
virtual Render3DError InitPostprocessingPrograms(const char *edgeMarkVtxShader,
|
||||||
const char *edgeMarkFragShader,
|
const char *edgeMarkFragShader,
|
||||||
const char *framebufferOutputVtxShader,
|
const char *framebufferOutputVtxShader,
|
||||||
|
@ -1032,7 +1045,6 @@ protected:
|
||||||
virtual Render3DError CreateFramebufferOutput8888Program(const char *vtxShaderCString, const char *fragShaderCString);
|
virtual Render3DError CreateFramebufferOutput8888Program(const char *vtxShaderCString, const char *fragShaderCString);
|
||||||
virtual void DestroyFramebufferOutput8888Programs();
|
virtual void DestroyFramebufferOutput8888Programs();
|
||||||
|
|
||||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
|
|
||||||
virtual Render3DError InitPostprocessingPrograms(const char *edgeMarkVtxShader,
|
virtual Render3DError InitPostprocessingPrograms(const char *edgeMarkVtxShader,
|
||||||
const char *edgeMarkFragShader,
|
const char *edgeMarkFragShader,
|
||||||
const char *framebufferOutputVtxShader,
|
const char *framebufferOutputVtxShader,
|
||||||
|
@ -1089,7 +1101,6 @@ public:
|
||||||
OpenGLRenderer_2_0();
|
OpenGLRenderer_2_0();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
|
|
||||||
virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList);
|
virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -60,18 +60,65 @@ extern const char *FramebufferOutput6665FragShader_150;
|
||||||
void OGLLoadEntryPoints_3_2();
|
void OGLLoadEntryPoints_3_2();
|
||||||
void OGLCreateRenderer_3_2(OpenGLRenderer **rendererPtr);
|
void OGLCreateRenderer_3_2(OpenGLRenderer **rendererPtr);
|
||||||
|
|
||||||
|
class OpenGLGeometryResource : public Render3DResourceGeometry
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
GLuint _vboID[3];
|
||||||
|
GLuint _eboID[3];
|
||||||
|
GLuint _vaoID[3];
|
||||||
|
GLuint _uboPolyStatesID[3];
|
||||||
|
GLuint _tboPolyStatesID[3];
|
||||||
|
GLuint _texPolyStatesID[3];
|
||||||
|
GLsync _syncGeometryRender[3];
|
||||||
|
|
||||||
|
u16 *_indexBuffer[3];
|
||||||
|
OGLPolyStates *_polyStatesBuffer[3];
|
||||||
|
|
||||||
|
public:
|
||||||
|
OpenGLGeometryResource(const OpenGLVariantID variantID);
|
||||||
|
~OpenGLGeometryResource();
|
||||||
|
|
||||||
|
size_t BindWrite(const size_t rawVtxCount, const size_t clippedPolyCount);
|
||||||
|
|
||||||
|
size_t BindUsage();
|
||||||
|
size_t UnbindUsage();
|
||||||
|
size_t RebindUsage();
|
||||||
|
|
||||||
|
u16* GetIndexBuffer(const size_t index);
|
||||||
|
OGLPolyStates* GetPolyStatesBuffer(const size_t index);
|
||||||
|
bool IsPolyStatesBufferUBO();
|
||||||
|
bool IsPolyStatesBufferTBO();
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpenGLRenderStatesResource : public Render3DResource
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
GLsync _sync[3];
|
||||||
|
GLuint _uboRenderStatesID[3];
|
||||||
|
OGLRenderStates *_buffer[3];
|
||||||
|
|
||||||
|
public:
|
||||||
|
OpenGLRenderStatesResource();
|
||||||
|
~OpenGLRenderStatesResource();
|
||||||
|
|
||||||
|
size_t BindWrite();
|
||||||
|
size_t BindUsage();
|
||||||
|
size_t UnbindUsage();
|
||||||
|
|
||||||
|
OGLRenderStates* GetRenderStatesBuffer(const size_t index);
|
||||||
|
};
|
||||||
|
|
||||||
class OpenGLRenderer_3_2 : public OpenGLRenderer_2_1
|
class OpenGLRenderer_3_2 : public OpenGLRenderer_2_1
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
bool _is64kUBOSupported;
|
|
||||||
bool _isTBOSupported;
|
|
||||||
bool _isShaderFixedLocationSupported;
|
bool _isShaderFixedLocationSupported;
|
||||||
bool _isConservativeDepthSupported;
|
bool _isConservativeDepthSupported;
|
||||||
bool _isConservativeDepthAMDSupported;
|
bool _isConservativeDepthAMDSupported;
|
||||||
|
|
||||||
GLsync _syncBufferSetup;
|
OpenGLGeometryResource *_gResource;
|
||||||
CACHE_ALIGN OGLPolyStates _pendingPolyStates[CLIPPED_POLYLIST_SIZE];
|
OpenGLRenderStatesResource *_rsResource;
|
||||||
|
|
||||||
|
virtual Render3DError CreateVBOs();
|
||||||
virtual Render3DError CreatePBOs();
|
virtual Render3DError CreatePBOs();
|
||||||
virtual Render3DError CreateFBOs();
|
virtual Render3DError CreateFBOs();
|
||||||
virtual void DestroyFBOs();
|
virtual void DestroyFBOs();
|
||||||
|
@ -82,7 +129,6 @@ protected:
|
||||||
virtual void DestroyVAOs();
|
virtual void DestroyVAOs();
|
||||||
|
|
||||||
virtual Render3DError CreateGeometryPrograms();
|
virtual Render3DError CreateGeometryPrograms();
|
||||||
virtual void DestroyGeometryPrograms();
|
|
||||||
virtual Render3DError CreateClearImageProgram(const char *vsCString, const char *fsCString);
|
virtual Render3DError CreateClearImageProgram(const char *vsCString, const char *fsCString);
|
||||||
virtual void DestroyClearImageProgram();
|
virtual void DestroyClearImageProgram();
|
||||||
virtual Render3DError CreateGeometryZeroDstAlphaProgram(const char *vtxShaderCString, const char *fragShaderCString);
|
virtual Render3DError CreateGeometryZeroDstAlphaProgram(const char *vtxShaderCString, const char *fragShaderCString);
|
||||||
|
|
|
@ -310,13 +310,12 @@ Render3DError OpenGLESRenderer_3_0::InitExtensions()
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get host GPU device properties
|
// Mirrored Repeat Mode Support
|
||||||
GLint maxUBOSize = 0;
|
OGLRef.stateTexMirroredRepeat = GL_MIRRORED_REPEAT;
|
||||||
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUBOSize);
|
|
||||||
this->_is64kUBOSupported = (maxUBOSize >= 65536);
|
|
||||||
|
|
||||||
// TBOs are only supported in OpenGL ES 3.2.
|
// Blending Support
|
||||||
this->_isTBOSupported = IsOpenGLDriverVersionSupported(3, 2, 0);
|
this->_isBlendFuncSeparateSupported = true;
|
||||||
|
this->_isBlendEquationSeparateSupported = true;
|
||||||
|
|
||||||
// Fixed locations in shaders are supported in ES 3.0 by default.
|
// Fixed locations in shaders are supported in ES 3.0 by default.
|
||||||
this->_isShaderFixedLocationSupported = true;
|
this->_isShaderFixedLocationSupported = true;
|
||||||
|
@ -357,6 +356,21 @@ Render3DError OpenGLESRenderer_3_0::InitExtensions()
|
||||||
// Load and create shaders. Return on any error, since ES 3.0 makes shaders mandatory.
|
// Load and create shaders. Return on any error, since ES 3.0 makes shaders mandatory.
|
||||||
this->isShaderSupported = true;
|
this->isShaderSupported = true;
|
||||||
|
|
||||||
|
this->_rsResource = new OpenGLRenderStatesResource();
|
||||||
|
|
||||||
|
if (IsOpenGLDriverVersionSupported(3, 2, 0))
|
||||||
|
{
|
||||||
|
this->_gResource = new OpenGLGeometryResource(OpenGLVariantID_ES3_3_2);
|
||||||
|
}
|
||||||
|
else if (IsOpenGLDriverVersionSupported(3, 1, 0))
|
||||||
|
{
|
||||||
|
this->_gResource = new OpenGLGeometryResource(OpenGLVariantID_ES3_3_1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->_gResource = new OpenGLGeometryResource(OpenGLVariantID_ES3_3_0);
|
||||||
|
}
|
||||||
|
|
||||||
error = this->CreateGeometryPrograms();
|
error = this->CreateGeometryPrograms();
|
||||||
if (error != OGLERROR_NOERR)
|
if (error != OGLERROR_NOERR)
|
||||||
{
|
{
|
||||||
|
@ -478,8 +492,6 @@ Render3DError OpenGLESRenderer_3_0::InitExtensions()
|
||||||
this->_isDepthLEqualPolygonFacingSupported = true;
|
this->_isDepthLEqualPolygonFacingSupported = true;
|
||||||
this->_enableMultisampledRendering = ((this->_selectedMultisampleSize >= 2) && this->isMultisampledFBOSupported);
|
this->_enableMultisampledRendering = ((this->_selectedMultisampleSize >= 2) && this->isMultisampledFBOSupported);
|
||||||
|
|
||||||
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
|
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,61 +501,6 @@ Render3DError OpenGLESRenderer_3_0::CreateGeometryPrograms()
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
|
|
||||||
// Create shader resources.
|
// Create shader resources.
|
||||||
if (OGLRef.uboRenderStatesID == 0)
|
|
||||||
{
|
|
||||||
glGenBuffers(1, &OGLRef.uboRenderStatesID);
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, OGLRef.uboRenderStatesID);
|
|
||||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(OGLRenderStates), NULL, GL_DYNAMIC_DRAW);
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, OGLBindingPointID_RenderStates, OGLRef.uboRenderStatesID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->_is64kUBOSupported)
|
|
||||||
{
|
|
||||||
// Try transferring the polygon states through a UBO first. This is the fastest method,
|
|
||||||
// but requires a GPU that supports 64k UBO transfers.
|
|
||||||
if (OGLRef.uboPolyStatesID == 0)
|
|
||||||
{
|
|
||||||
glGenBuffers(1, &OGLRef.uboPolyStatesID);
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, OGLRef.uboPolyStatesID);
|
|
||||||
glBufferData(GL_UNIFORM_BUFFER, MAX_CLIPPED_POLY_COUNT_FOR_UBO * sizeof(OGLPolyStates), NULL, GL_DYNAMIC_DRAW);
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, OGLBindingPointID_PolyStates, OGLRef.uboPolyStatesID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef GL_ES_VERSION_3_2
|
|
||||||
else if (this->_isTBOSupported)
|
|
||||||
{
|
|
||||||
// If for some reason the GPU doesn't support 64k UBOs but still supports OpenGL ES 3.2,
|
|
||||||
// then use a TBO as the second fastest method.
|
|
||||||
if (OGLRef.tboPolyStatesID == 0)
|
|
||||||
{
|
|
||||||
// Set up poly states TBO
|
|
||||||
glGenBuffers(1, &OGLRef.tboPolyStatesID);
|
|
||||||
glBindBuffer(GL_TEXTURE_BUFFER, OGLRef.tboPolyStatesID);
|
|
||||||
glBufferData(GL_TEXTURE_BUFFER, CLIPPED_POLYLIST_SIZE * sizeof(OGLPolyStates), NULL, GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
glGenTextures(1, &OGLRef.texPolyStatesID);
|
|
||||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_PolyStates);
|
|
||||||
glBindTexture(GL_TEXTURE_BUFFER, OGLRef.texPolyStatesID);
|
|
||||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, OGLRef.tboPolyStatesID);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// For compatibility reasons, we can transfer the polygon states through a plain old
|
|
||||||
// integer texture.
|
|
||||||
glGenTextures(1, &OGLRef.texPolyStatesID);
|
|
||||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_PolyStates);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texPolyStatesID);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32I, 256, 128, 0, GL_RED_INTEGER, GL_INT, NULL);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
}
|
|
||||||
|
|
||||||
glGenTextures(1, &OGLRef.texFogDensityTableID);
|
glGenTextures(1, &OGLRef.texFogDensityTableID);
|
||||||
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_LookupTable);
|
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_LookupTable);
|
||||||
glBindTexture(GL_TEXTURE_2D, OGLRef.texFogDensityTableID);
|
glBindTexture(GL_TEXTURE_2D, OGLRef.texFogDensityTableID);
|
||||||
|
@ -568,8 +525,8 @@ Render3DError OpenGLESRenderer_3_0::CreateGeometryPrograms()
|
||||||
vsHeader << "#define IN_VTX_TEXCOORD0 layout (location = " << OGLVertexAttributeID_TexCoord0 << ") in\n";
|
vsHeader << "#define IN_VTX_TEXCOORD0 layout (location = " << OGLVertexAttributeID_TexCoord0 << ") in\n";
|
||||||
vsHeader << "#define IN_VTX_COLOR layout (location = " << OGLVertexAttributeID_Color << ") in\n";
|
vsHeader << "#define IN_VTX_COLOR layout (location = " << OGLVertexAttributeID_Color << ") in\n";
|
||||||
vsHeader << "\n";
|
vsHeader << "\n";
|
||||||
vsHeader << "#define IS_USING_UBO_POLY_STATES " << ((OGLRef.uboPolyStatesID != 0) ? 1 : 0) << "\n";
|
vsHeader << "#define IS_USING_UBO_POLY_STATES " << ((this->_gResource->IsPolyStatesBufferUBO()) ? 1 : 0) << "\n";
|
||||||
vsHeader << "#define IS_USING_TBO_POLY_STATES " << ((OGLRef.tboPolyStatesID != 0) ? 1 : 0) << "\n";
|
vsHeader << "#define IS_USING_TBO_POLY_STATES " << ((this->_gResource->IsPolyStatesBufferTBO()) ? 1 : 0) << "\n";
|
||||||
vsHeader << "#define DEPTH_EQUALS_TEST_TOLERANCE " << DEPTH_EQUALS_TEST_TOLERANCE << ".0\n";
|
vsHeader << "#define DEPTH_EQUALS_TEST_TOLERANCE " << DEPTH_EQUALS_TEST_TOLERANCE << ".0\n";
|
||||||
vsHeader << "\n";
|
vsHeader << "\n";
|
||||||
|
|
||||||
|
@ -634,7 +591,7 @@ Render3DError OpenGLESRenderer_3_0::CreateGeometryPrograms()
|
||||||
const GLint uniformTexRenderObject = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "texRenderObject");
|
const GLint uniformTexRenderObject = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "texRenderObject");
|
||||||
glUniform1i(uniformTexRenderObject, 0);
|
glUniform1i(uniformTexRenderObject, 0);
|
||||||
|
|
||||||
if (OGLRef.uboPolyStatesID != 0)
|
if (this->_gResource->IsPolyStatesBufferUBO())
|
||||||
{
|
{
|
||||||
const GLuint uniformBlockPolyStates = glGetUniformBlockIndex(OGLRef.programGeometryID[flagsValue], "PolyStates");
|
const GLuint uniformBlockPolyStates = glGetUniformBlockIndex(OGLRef.programGeometryID[flagsValue], "PolyStates");
|
||||||
glUniformBlockBinding(OGLRef.programGeometryID[flagsValue], uniformBlockPolyStates, OGLBindingPointID_PolyStates);
|
glUniformBlockBinding(OGLRef.programGeometryID[flagsValue], uniformBlockPolyStates, OGLBindingPointID_PolyStates);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2006-2007 shash
|
Copyright (C) 2006-2007 shash
|
||||||
Copyright (C) 2008-2023 DeSmuME team
|
Copyright (C) 2008-2024 DeSmuME team
|
||||||
|
|
||||||
This file is free software: you can redistribute it and/or modify
|
This file is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -112,6 +112,115 @@ void FragmentAttributesBuffer::SetAtIndex(const size_t index, const FragmentAttr
|
||||||
this->polyFacing[index] = attr.polyFacing;
|
this->polyFacing[index] = attr.polyFacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Render3DResource::Render3DResource()
|
||||||
|
{
|
||||||
|
_state[0] = AsyncWriteState_Disabled;
|
||||||
|
_state[1] = AsyncWriteState_Disabled;
|
||||||
|
_state[2] = AsyncWriteState_Disabled;
|
||||||
|
|
||||||
|
_currentReadyIdx = RENDER3D_RESOURCE_INDEX_NONE;
|
||||||
|
_currentUsingIdx = RENDER3D_RESOURCE_INDEX_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Render3DResource::BindWrite()
|
||||||
|
{
|
||||||
|
size_t idxFree = RENDER3D_RESOURCE_INDEX_NONE;
|
||||||
|
|
||||||
|
if (this->_state[0] == AsyncWriteState_Free)
|
||||||
|
{
|
||||||
|
idxFree = 0;
|
||||||
|
}
|
||||||
|
else if (this->_state[1] == AsyncWriteState_Free)
|
||||||
|
{
|
||||||
|
idxFree = 1;
|
||||||
|
}
|
||||||
|
else if (this->_state[2] == AsyncWriteState_Free)
|
||||||
|
{
|
||||||
|
idxFree = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idxFree != RENDER3D_RESOURCE_INDEX_NONE)
|
||||||
|
{
|
||||||
|
this->_state[idxFree] = AsyncWriteState_Writing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return idxFree;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Render3DResource::UnbindWrite(const size_t idxWrite)
|
||||||
|
{
|
||||||
|
if (idxWrite > 2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->_currentReadyIdx != RENDER3D_RESOURCE_INDEX_NONE)
|
||||||
|
{
|
||||||
|
this->_state[this->_currentReadyIdx] = AsyncWriteState_Free;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->_state[idxWrite] = AsyncWriteState_Ready;
|
||||||
|
this->_currentReadyIdx = idxWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Render3DResource::BindUsage()
|
||||||
|
{
|
||||||
|
if (this->_currentReadyIdx == RENDER3D_RESOURCE_INDEX_NONE)
|
||||||
|
{
|
||||||
|
return RENDER3D_RESOURCE_INDEX_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->_state[this->_currentReadyIdx] = AsyncWriteState_Using;
|
||||||
|
this->_currentUsingIdx = this->_currentReadyIdx;
|
||||||
|
this->_currentReadyIdx = RENDER3D_RESOURCE_INDEX_NONE;
|
||||||
|
|
||||||
|
return this->_currentUsingIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Render3DResource::UnbindUsage()
|
||||||
|
{
|
||||||
|
size_t newFreeIdx = this->_currentUsingIdx;
|
||||||
|
|
||||||
|
if (newFreeIdx == RENDER3D_RESOURCE_INDEX_NONE)
|
||||||
|
{
|
||||||
|
return RENDER3D_RESOURCE_INDEX_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->_state[newFreeIdx] = AsyncWriteState_Free;
|
||||||
|
this->_currentUsingIdx = RENDER3D_RESOURCE_INDEX_NONE;
|
||||||
|
|
||||||
|
return newFreeIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
Render3DResourceGeometry::Render3DResourceGeometry()
|
||||||
|
{
|
||||||
|
_vertexBuffer[0] = NULL;
|
||||||
|
_vertexBuffer[1] = NULL;
|
||||||
|
_vertexBuffer[2] = NULL;
|
||||||
|
|
||||||
|
_rawVertexCount[0] = 0;
|
||||||
|
_rawVertexCount[1] = 0;
|
||||||
|
_rawVertexCount[2] = 0;
|
||||||
|
|
||||||
|
_clippedPolyCount[0] = 0;
|
||||||
|
_clippedPolyCount[1] = 0;
|
||||||
|
_clippedPolyCount[2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Render3DResourceGeometry::BindWrite(const size_t rawVtxCount, const size_t clippedPolyCount)
|
||||||
|
{
|
||||||
|
const size_t idxWrite = Render3DResource::BindWrite();
|
||||||
|
this->_rawVertexCount[idxWrite] = rawVtxCount;
|
||||||
|
this->_clippedPolyCount[idxWrite] = clippedPolyCount;
|
||||||
|
|
||||||
|
return idxWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
NDSVertex* Render3DResourceGeometry::GetVertexBuffer(const size_t index)
|
||||||
|
{
|
||||||
|
return this->_vertexBuffer[index];
|
||||||
|
}
|
||||||
|
|
||||||
Render3DTexture::Render3DTexture(TEXIMAGE_PARAM texAttributes, u32 palAttributes) : TextureStore(texAttributes, palAttributes)
|
Render3DTexture::Render3DTexture(TEXIMAGE_PARAM texAttributes, u32 palAttributes) : TextureStore(texAttributes, palAttributes)
|
||||||
{
|
{
|
||||||
_isSamplingEnabled = true;
|
_isSamplingEnabled = true;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2006-2007 shash
|
Copyright (C) 2006-2007 shash
|
||||||
Copyright (C) 2007-2023 DeSmuME team
|
Copyright (C) 2007-2024 DeSmuME team
|
||||||
|
|
||||||
This file is free software: you can redistribute it and/or modify
|
This file is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -122,6 +122,57 @@ struct Render3DDeviceInfo
|
||||||
u8 maxSamples;
|
u8 maxSamples;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum AsyncWriteState
|
||||||
|
{
|
||||||
|
AsyncWriteState_Disabled = 0, // The resources at this index are not available for use.
|
||||||
|
AsyncWriteState_Free = 1, // The resources at this index have no owner, but are made available to the emulation.
|
||||||
|
AsyncWriteState_Writing = 2, // The emulation has taken ownership of the resources at this index for writing new data.
|
||||||
|
AsyncWriteState_Ready = 3, // The emulation has finished writing to the resources at this index. The renderer is allowed to take ownership at any time.
|
||||||
|
AsyncWriteState_Using = 4 // The renderer has taken ownership of the resources at this index for reading the data.
|
||||||
|
};
|
||||||
|
|
||||||
|
enum AsyncReadState
|
||||||
|
{
|
||||||
|
AsyncReadState_Disabled = 0, // The resources at this index are not available for use.
|
||||||
|
AsyncReadState_Free = 1, // The resources at this index have no owner, but are made available to the renderer.
|
||||||
|
AsyncReadState_Using = 4, // The renderer has taken ownership of the resources at this index for writing new data.
|
||||||
|
AsyncReadState_Ready = 3, // The renderer has finished writing to the resources at this index. The emulation is allowed to take ownership at any time.
|
||||||
|
AsyncReadState_Reading = 2 // The emulation has taken ownership of the resources at this index for reading the data.
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RENDER3D_RESOURCE_INDEX_NONE 0xFFFF
|
||||||
|
|
||||||
|
class Render3DResource
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
AsyncWriteState _state[3];
|
||||||
|
size_t _currentReadyIdx;
|
||||||
|
size_t _currentUsingIdx;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Render3DResource();
|
||||||
|
|
||||||
|
size_t BindWrite();
|
||||||
|
void UnbindWrite(const size_t idxWrite);
|
||||||
|
|
||||||
|
size_t BindUsage();
|
||||||
|
size_t UnbindUsage();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Render3DResourceGeometry : public Render3DResource
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
NDSVertex *_vertexBuffer[3];
|
||||||
|
size_t _rawVertexCount[3];
|
||||||
|
size_t _clippedPolyCount[3];
|
||||||
|
|
||||||
|
public:
|
||||||
|
Render3DResourceGeometry();
|
||||||
|
|
||||||
|
size_t BindWrite(const size_t rawVtxCount, const size_t clippedPolyCount);
|
||||||
|
NDSVertex* GetVertexBuffer(const size_t index);
|
||||||
|
};
|
||||||
|
|
||||||
class Render3DTexture : public TextureStore
|
class Render3DTexture : public TextureStore
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Reference in New Issue