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:
rogerman 2024-08-15 16:49:42 -07:00
parent f84a804499
commit f910c6197c
7 changed files with 1073 additions and 390 deletions

View File

@ -2384,6 +2384,14 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
}
#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
GLfloat maxAnisotropyOGL = 1.0f;
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->InitFinalRenderStates(&oglExtensionSet); // This must be done last
return OGLERROR_NOERR;
}
@ -3676,40 +3682,6 @@ void OpenGLRenderer_1_2::DestroyFramebufferOutput8888Programs()
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,
const char *edgeMarkFragShaderCString,
const char *framebufferOutputVtxShaderCString,
@ -4384,6 +4356,25 @@ void OpenGLRenderer_1_2::_RenderGeometryLoopBegin()
if (this->_enableAlphaBlending)
{
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
{
@ -4641,9 +4632,6 @@ Render3DError OpenGLRenderer_1_2::PostprocessFramebuffer()
glDisable(GL_STENCIL_TEST);
glEnable(GL_BLEND);
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();
@ -5449,28 +5437,6 @@ OpenGLRenderer_2_0::OpenGLRenderer_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)
{
OGLRenderRef &OGLRef = *this->ref;

View File

@ -303,12 +303,17 @@ EXTERNOGLEXT(PFNGLDELETERENDERBUFFERSEXTPROC, glDeleteRenderbuffersEXT)
#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.
#ifndef GL_BGRA
#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
// OPENGL CORE EQUIVALENTS FOR LEGACY FUNCTIONS
// Some OpenGL variants, such as OpenGL ES, do not include certain legacy functions in their
// API. The loss of these functions will cause compile time errors when referenced, and so
@ -375,12 +380,25 @@ enum OpenGLVariantID
OpenGLVariantID_Unknown = 0,
OpenGLVariantID_LegacyAuto = 0x1000,
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_1 = 0x1021,
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_ES3_Auto = 0x4000,
OpenGLVariantID_ES3_3_0 = 0x4030,
OpenGLVariantID_ES3_3_1 = 0x4031,
OpenGLVariantID_ES3_3_2 = 0x4032,
OpenGLVariantID_ES_Auto = 0x6000
};
@ -607,12 +625,6 @@ struct OGLRenderRef
// PBO
GLuint pboRenderDataID;
// UBO / TBO
GLuint uboRenderStatesID;
GLuint uboPolyStatesID;
GLuint tboPolyStatesID;
GLuint texPolyStatesID;
// FBO
GLuint texCIColorID;
GLuint texCIFogAttrID;
@ -863,6 +875,8 @@ protected:
// OpenGL Feature Support
OpenGLVariantID _variantID;
bool _isBlendFuncSeparateSupported;
bool _isBlendEquationSeparateSupported;
bool isVBOSupported;
bool isPBOSupported;
bool isFBOSupported;
@ -950,7 +964,6 @@ protected:
virtual Render3DError CreateFramebufferOutput8888Program(const char *vtxShaderCString, const char *fragShaderCString) = 0;
virtual void DestroyFramebufferOutput8888Programs() = 0;
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet) = 0;
virtual Render3DError InitPostprocessingPrograms(const char *edgeMarkVtxShader,
const char *edgeMarkFragShader,
const char *framebufferOutputVtxShader,
@ -1032,7 +1045,6 @@ protected:
virtual Render3DError CreateFramebufferOutput8888Program(const char *vtxShaderCString, const char *fragShaderCString);
virtual void DestroyFramebufferOutput8888Programs();
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
virtual Render3DError InitPostprocessingPrograms(const char *edgeMarkVtxShader,
const char *edgeMarkFragShader,
const char *framebufferOutputVtxShader,
@ -1089,7 +1101,6 @@ public:
OpenGLRenderer_2_0();
protected:
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList);
};

File diff suppressed because it is too large Load Diff

View File

@ -60,18 +60,65 @@ extern const char *FramebufferOutput6665FragShader_150;
void OGLLoadEntryPoints_3_2();
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
{
protected:
bool _is64kUBOSupported;
bool _isTBOSupported;
bool _isShaderFixedLocationSupported;
bool _isConservativeDepthSupported;
bool _isConservativeDepthAMDSupported;
GLsync _syncBufferSetup;
CACHE_ALIGN OGLPolyStates _pendingPolyStates[CLIPPED_POLYLIST_SIZE];
OpenGLGeometryResource *_gResource;
OpenGLRenderStatesResource *_rsResource;
virtual Render3DError CreateVBOs();
virtual Render3DError CreatePBOs();
virtual Render3DError CreateFBOs();
virtual void DestroyFBOs();
@ -82,7 +129,6 @@ protected:
virtual void DestroyVAOs();
virtual Render3DError CreateGeometryPrograms();
virtual void DestroyGeometryPrograms();
virtual Render3DError CreateClearImageProgram(const char *vsCString, const char *fsCString);
virtual void DestroyClearImageProgram();
virtual Render3DError CreateGeometryZeroDstAlphaProgram(const char *vtxShaderCString, const char *fragShaderCString);

View File

@ -310,13 +310,12 @@ Render3DError OpenGLESRenderer_3_0::InitExtensions()
return error;
}
// Get host GPU device properties
GLint maxUBOSize = 0;
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUBOSize);
this->_is64kUBOSupported = (maxUBOSize >= 65536);
// Mirrored Repeat Mode Support
OGLRef.stateTexMirroredRepeat = GL_MIRRORED_REPEAT;
// TBOs are only supported in OpenGL ES 3.2.
this->_isTBOSupported = IsOpenGLDriverVersionSupported(3, 2, 0);
// Blending Support
this->_isBlendFuncSeparateSupported = true;
this->_isBlendEquationSeparateSupported = true;
// Fixed locations in shaders are supported in ES 3.0 by default.
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.
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();
if (error != OGLERROR_NOERR)
{
@ -478,8 +492,6 @@ Render3DError OpenGLESRenderer_3_0::InitExtensions()
this->_isDepthLEqualPolygonFacingSupported = true;
this->_enableMultisampledRendering = ((this->_selectedMultisampleSize >= 2) && this->isMultisampledFBOSupported);
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
return OGLERROR_NOERR;
}
@ -489,61 +501,6 @@ Render3DError OpenGLESRenderer_3_0::CreateGeometryPrograms()
OGLRenderRef &OGLRef = *this->ref;
// 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);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_LookupTable);
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_COLOR layout (location = " << OGLVertexAttributeID_Color << ") in\n";
vsHeader << "\n";
vsHeader << "#define IS_USING_UBO_POLY_STATES " << ((OGLRef.uboPolyStatesID != 0) ? 1 : 0) << "\n";
vsHeader << "#define IS_USING_TBO_POLY_STATES " << ((OGLRef.tboPolyStatesID != 0) ? 1 : 0) << "\n";
vsHeader << "#define IS_USING_UBO_POLY_STATES " << ((this->_gResource->IsPolyStatesBufferUBO()) ? 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 << "\n";
@ -634,7 +591,7 @@ Render3DError OpenGLESRenderer_3_0::CreateGeometryPrograms()
const GLint uniformTexRenderObject = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "texRenderObject");
glUniform1i(uniformTexRenderObject, 0);
if (OGLRef.uboPolyStatesID != 0)
if (this->_gResource->IsPolyStatesBufferUBO())
{
const GLuint uniformBlockPolyStates = glGetUniformBlockIndex(OGLRef.programGeometryID[flagsValue], "PolyStates");
glUniformBlockBinding(OGLRef.programGeometryID[flagsValue], uniformBlockPolyStates, OGLBindingPointID_PolyStates);

View File

@ -1,6 +1,6 @@
/*
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
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;
}
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)
{
_isSamplingEnabled = true;

View File

@ -1,6 +1,6 @@
/*
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
it under the terms of the GNU General Public License as published by
@ -122,6 +122,57 @@ struct Render3DDeviceInfo
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
{
protected: