[Fix] (MG_State/VertexArray): use array to save attribs to maintain order and optimize performance

This commit is contained in:
2025-06-25 16:22:16 +08:00
parent 0359a4e97f
commit bf8aaaa9c1
6 changed files with 25 additions and 19 deletions
+4
View File
@@ -98,6 +98,10 @@ namespace MG_Constants {
}; // OpenGL 3 }; // OpenGL 3
} }
namespace VertexArray {
constexpr uint32_t MAX_VERTEX_ATTRIBS = 32;
}
namespace PixelStore { namespace PixelStore {
static const MG_Global::unordered_map<GLenum, GLint> DEFAULT_VALUES_MAP = { static const MG_Global::unordered_map<GLenum, GLint> DEFAULT_VALUES_MAP = {
{GL_PACK_SWAP_BYTES, GL_FALSE}, {GL_PACK_SWAP_BYTES, GL_FALSE},
@@ -33,7 +33,9 @@ namespace MG_Diligent {
auto& programObj = MG_State_T::programState->programs_[program]; auto& programObj = MG_State_T::programState->programs_[program];
for (const auto& [attribIndex, attrib] : vaState.vaos_[vaState.currentVao_].attribs) { // for (const auto& [attribIndex, attrib] : vaState.vaos_[vaState.currentVao_].attribs) {
for (uint32_t attribIndex = 0; attribIndex < MG_Constants::VertexArray::MAX_VERTEX_ATTRIBS; ++attribIndex) {
const auto& attrib = vaState.vaos_[vaState.currentVao_].attribs[attribIndex];
if (!attrib.enabled) continue; if (!attrib.enabled) continue;
std::string attribName; std::string attribName;
@@ -125,14 +127,10 @@ namespace MG_Diligent {
auto *pVAO = vaState.GetCurrentVAO(); auto *pVAO = vaState.GetCurrentVAO();
std::vector<uint32_t> attribIndices; for (uint32_t i = 0; i < MG_Constants::VertexArray::MAX_VERTEX_ATTRIBS; ++i) {
for (const auto& [index, _] : pVAO->attribs) const auto& attrib = pVAO->attribs[i];
attribIndices.push_back(index);
std::sort(attribIndices.begin(), attribIndices.end());
for (auto index : attribIndices) {
const auto& attrib = pVAO->attribs.at(index);
if (attrib.enabled) { if (attrib.enabled) {
hash_combine(hash, index); hash_combine(hash, i);
hash_combine(hash, attrib.size); hash_combine(hash, attrib.size);
hash_combine(hash, attrib.type); hash_combine(hash, attrib.type);
hash_combine(hash, attrib.normalized); hash_combine(hash, attrib.normalized);
@@ -476,7 +476,9 @@ namespace MG_GL::GL {
std::unordered_map<GLuint, Diligent::IBuffer*> createdBuffers; std::unordered_map<GLuint, Diligent::IBuffer*> createdBuffers;
for (const auto& [attribIndex, attrib] : pVAO->attribs) { // for (const auto& [attribIndex, attrib] : pVAO->attribs) {
for (uint32_t attribIndex = 0; attribIndex < MG_Constants::VertexArray::MAX_VERTEX_ATTRIBS; ++attribIndex) {
const auto& attrib = pVAO->attribs[attribIndex];
if (!attrib.enabled || attrib.buffer == 0) continue; if (!attrib.enabled || attrib.buffer == 0) continue;
GLuint buffer = attrib.buffer; GLuint buffer = attrib.buffer;
@@ -569,7 +571,8 @@ namespace MG_GL::GL {
std::vector<Diligent::IBuffer*> vertexBuffers; std::vector<Diligent::IBuffer*> vertexBuffers;
std::vector<Diligent::Uint64> offsets; std::vector<Diligent::Uint64> offsets;
for (const auto& [attribIndex, attrib] : pVAO->attribs) { for (uint32_t attribIndex = 0; attribIndex < MG_Constants::VertexArray::MAX_VERTEX_ATTRIBS; ++attribIndex) {
const auto& attrib = pVAO->attribs[attribIndex];
if (!attrib.enabled || attrib.buffer == 0) continue; if (!attrib.enabled || attrib.buffer == 0) continue;
GLuint buffer = attrib.buffer; GLuint buffer = attrib.buffer;
@@ -379,7 +379,9 @@ namespace MG_GL::GL {
auto* pVAO = MG_State_T::vertexArrayState->GetCurrentVAO(); auto* pVAO = MG_State_T::vertexArrayState->GetCurrentVAO();
if (!pVAO) return; if (!pVAO) return;
for (const auto& [index, attrib] : pVAO->attribs) { // for (const auto& [index, attrib] : pVAO->attribs) {
for (uint32_t index = 0; index < MG_Constants::VertexArray::MAX_VERTEX_ATTRIBS; ++index) {
const auto& attrib = pVAO->attribs[index];
if (attrib.enabled) { if (attrib.enabled) {
Diligent::LayoutElement elem; Diligent::LayoutElement elem;
elem.InputIndex = index; elem.InputIndex = index;
@@ -107,7 +107,7 @@ bool VertexArrayState::ValidateAllocatedHandle(GLuint array) {
GLenum VertexArrayState::EnableAttrib(GLuint index) { GLenum VertexArrayState::EnableAttrib(GLuint index) {
if (!ValidateAllocatedHandle(currentVao_)) if (!ValidateAllocatedHandle(currentVao_))
return GL_INVALID_OPERATION; return GL_INVALID_OPERATION;
if (index >= GL_MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE; if (index >= MG_Constants::VertexArray::MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE;
GetCurrentVAO()->attribs[index].enabled = true; GetCurrentVAO()->attribs[index].enabled = true;
MG_Util::Debug::LogD("Attrib vaos_[%u].attribs[%u].enabled = %d", currentVao_, index, vaos_[currentVao_].attribs[index].enabled); MG_Util::Debug::LogD("Attrib vaos_[%u].attribs[%u].enabled = %d", currentVao_, index, vaos_[currentVao_].attribs[index].enabled);
@@ -118,7 +118,7 @@ GLenum VertexArrayState::EnableAttrib(GLuint index) {
GLenum VertexArrayState::DisableAttrib(GLuint index) { GLenum VertexArrayState::DisableAttrib(GLuint index) {
if (!ValidateAllocatedHandle(currentVao_)) if (!ValidateAllocatedHandle(currentVao_))
return GL_INVALID_OPERATION; return GL_INVALID_OPERATION;
if (index >= GL_MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE; if (index >= MG_Constants::VertexArray::MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE;
GetCurrentVAO()->attribs[index].enabled = false; GetCurrentVAO()->attribs[index].enabled = false;
MG_Util::Debug::LogD("Attrib vaos_[%u].attribs[%u].enabled = %d", currentVao_, index, vaos_[currentVao_].attribs[index].enabled); MG_Util::Debug::LogD("Attrib vaos_[%u].attribs[%u].enabled = %d", currentVao_, index, vaos_[currentVao_].attribs[index].enabled);
@@ -132,7 +132,7 @@ GLenum VertexArrayState::SetAttribPointer(GLuint index, GLint size, GLenum type,
GLuint currentArrayBuffer) { GLuint currentArrayBuffer) {
if (!ValidateAllocatedHandle(currentVao_)) if (!ValidateAllocatedHandle(currentVao_))
return GL_INVALID_OPERATION; return GL_INVALID_OPERATION;
if (index >= GL_MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE; if (index >= MG_Constants::VertexArray::MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE;
VertexAttribState state; VertexAttribState state;
state.size = size; state.size = size;
@@ -142,8 +142,7 @@ GLenum VertexArrayState::SetAttribPointer(GLuint index, GLint size, GLenum type,
state.pointer = pointer; state.pointer = pointer;
state.buffer = currentArrayBuffer; state.buffer = currentArrayBuffer;
state.isInteger = isInteger; state.isInteger = isInteger;
if (vaos_[currentVao_].attribs.count(index) && vaos_[currentVao_].attribs[index].enabled) state.enabled = vaos_[currentVao_].attribs[index].enabled;
state.enabled = true;
vaos_[currentVao_].attribs[index] = state; vaos_[currentVao_].attribs[index] = state;
@@ -10,7 +10,7 @@
#include "../../../Includes.h" #include "../../../Includes.h"
struct VertexAttribState { struct VertexAttribState {
bool enabled; bool enabled = false;
GLint size = 4; GLint size = 4;
GLenum type = GL_FLOAT; GLenum type = GL_FLOAT;
GLboolean normalized = GL_FALSE; GLboolean normalized = GL_FALSE;
@@ -25,7 +25,7 @@ struct VertexArrayObject {
bool attribDirty = false; bool attribDirty = false;
bool eboDirty = false; bool eboDirty = false;
GLuint elementBuffer = 0; GLuint elementBuffer = 0;
MG_Global::unordered_map<GLuint, VertexAttribState> attribs; std::array<VertexAttribState, MG_Constants::VertexArray::MAX_VERTEX_ATTRIBS> attribs;
}; };
class VertexArrayState { class VertexArrayState {