mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 13:48:30 +09:00
[Improvement] (Diligent/PSO): Add UniformStageCache.
This commit is contained in:
@@ -5,10 +5,6 @@
|
|||||||
#include "../../../../Includes.h"
|
#include "../../../../Includes.h"
|
||||||
|
|
||||||
namespace MG_GL::GL {
|
namespace MG_GL::GL {
|
||||||
// void CreateRenderPassAndFramebuffer(GLuint framebuffer,
|
|
||||||
// const FramebufferObject& fbo,
|
|
||||||
// MG_Diligent::GLFramebufferInfo& fbInfo);
|
|
||||||
|
|
||||||
bool IsSamplerType(GLenum type) {
|
bool IsSamplerType(GLenum type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case GL_SAMPLER_2D:
|
case GL_SAMPLER_2D:
|
||||||
@@ -43,10 +39,6 @@ namespace MG_GL::GL {
|
|||||||
case GL_UNSIGNED_INT_VEC2: return 2 * sizeof(uint32_t);
|
case GL_UNSIGNED_INT_VEC2: return 2 * sizeof(uint32_t);
|
||||||
case GL_UNSIGNED_INT_VEC3: return 3 * sizeof(uint32_t);
|
case GL_UNSIGNED_INT_VEC3: return 3 * sizeof(uint32_t);
|
||||||
case GL_UNSIGNED_INT_VEC4: return 4 * sizeof(uint32_t);
|
case GL_UNSIGNED_INT_VEC4: return 4 * sizeof(uint32_t);
|
||||||
// case GL_DOUBLE: return sizeof(double); // Not supported
|
|
||||||
// case GL_DOUBLE_VEC2: return 2 * sizeof(double); // Not supported
|
|
||||||
// case GL_DOUBLE_VEC3: return 3 * sizeof(double); // Not supported
|
|
||||||
// case GL_DOUBLE_VEC4: return 4 * sizeof(double); // Not supported
|
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,6 +191,68 @@ namespace MG_GL::GL {
|
|||||||
return stage;
|
return stage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t HashPipelineResourceLayoutDesc(const Diligent::PipelineResourceLayoutDesc& desc)
|
||||||
|
{
|
||||||
|
size_t seed = 0;
|
||||||
|
auto hash_combine = [&](auto v) {
|
||||||
|
seed ^= std::hash<decltype(v)>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||||
|
};
|
||||||
|
|
||||||
|
hash_combine(static_cast<uint32_t>(desc.DefaultVariableType));
|
||||||
|
hash_combine(static_cast<uint32_t>(desc.DefaultVariableMergeStages));
|
||||||
|
hash_combine(desc.NumVariables);
|
||||||
|
hash_combine(desc.NumImmutableSamplers);
|
||||||
|
|
||||||
|
for (Diligent::Uint32 i = 0; i < desc.NumVariables; ++i)
|
||||||
|
{
|
||||||
|
const auto& var = desc.Variables[i];
|
||||||
|
if (var.Name)
|
||||||
|
hash_combine(std::string_view(var.Name));
|
||||||
|
else
|
||||||
|
hash_combine(0);
|
||||||
|
|
||||||
|
hash_combine(static_cast<uint32_t>(var.ShaderStages));
|
||||||
|
hash_combine(static_cast<uint32_t>(var.Type));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Diligent::Uint32 i = 0; i < desc.NumImmutableSamplers; ++i)
|
||||||
|
{
|
||||||
|
const auto& sampler = desc.ImmutableSamplers[i];
|
||||||
|
if (sampler.SamplerOrTextureName)
|
||||||
|
hash_combine(std::string_view(sampler.SamplerOrTextureName));
|
||||||
|
else
|
||||||
|
hash_combine(0);
|
||||||
|
|
||||||
|
hash_combine(static_cast<uint32_t>(sampler.ShaderStages));
|
||||||
|
|
||||||
|
const auto& desc = sampler.Desc;
|
||||||
|
|
||||||
|
hash_combine(static_cast<uint32_t>(desc.MinFilter));
|
||||||
|
hash_combine(static_cast<uint32_t>(desc.MagFilter));
|
||||||
|
hash_combine(static_cast<uint32_t>(desc.MipFilter));
|
||||||
|
|
||||||
|
hash_combine(static_cast<uint32_t>(desc.AddressU));
|
||||||
|
hash_combine(static_cast<uint32_t>(desc.AddressV));
|
||||||
|
hash_combine(static_cast<uint32_t>(desc.AddressW));
|
||||||
|
|
||||||
|
hash_combine(desc.MipLODBias);
|
||||||
|
hash_combine(desc.MaxAnisotropy);
|
||||||
|
hash_combine(static_cast<uint32_t>(desc.ComparisonFunc));
|
||||||
|
|
||||||
|
hash_combine(desc.BorderColor[0]);
|
||||||
|
hash_combine(desc.BorderColor[1]);
|
||||||
|
hash_combine(desc.BorderColor[2]);
|
||||||
|
hash_combine(desc.BorderColor[3]);
|
||||||
|
|
||||||
|
hash_combine(desc.MinLOD);
|
||||||
|
hash_combine(desc.MaxLOD);
|
||||||
|
hash_combine(static_cast<uint32_t>(desc.UnnormalizedCoords));
|
||||||
|
}
|
||||||
|
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateSamplerAndTextureUniforms(GLuint program, Diligent::IShaderResourceBinding& pSRB,
|
void UpdateSamplerAndTextureUniforms(GLuint program, Diligent::IShaderResourceBinding& pSRB,
|
||||||
Diligent::PipelineResourceLayoutDesc desc) {
|
Diligent::PipelineResourceLayoutDesc desc) {
|
||||||
MG_Util::Debug::LogD("Updating sampler and texture uniforms for program %u", program);
|
MG_Util::Debug::LogD("Updating sampler and texture uniforms for program %u", program);
|
||||||
@@ -227,7 +281,21 @@ namespace MG_GL::GL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pTextureView) {
|
if (pTextureView) {
|
||||||
Diligent::SHADER_TYPE stage = GetShaderStageForUniform(program, name, desc);
|
static MG_Global::unordered_map<std::tuple<GLuint, std::string, size_t>, Diligent::SHADER_TYPE> g_UniformStageCache;
|
||||||
|
|
||||||
|
size_t descKey = HashPipelineResourceLayoutDesc(desc);
|
||||||
|
auto key = std::make_tuple(program, name, descKey);
|
||||||
|
|
||||||
|
Diligent::SHADER_TYPE stage;
|
||||||
|
auto itStage = g_UniformStageCache.find(key);
|
||||||
|
if (itStage != g_UniformStageCache.end()) {
|
||||||
|
stage = itStage->second;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
stage = GetShaderStageForUniform(program, name, desc);
|
||||||
|
g_UniformStageCache[key] = stage;
|
||||||
|
}
|
||||||
|
|
||||||
MG_Util::Debug::LogD("Setting texture view for sampler '%s' in stage %d.", name.c_str(), stage);
|
MG_Util::Debug::LogD("Setting texture view for sampler '%s' in stage %d.", name.c_str(), stage);
|
||||||
auto* pVar = pSRB.GetVariableByName(stage, name.c_str());
|
auto* pVar = pSRB.GetVariableByName(stage, name.c_str());
|
||||||
if (pVar) {
|
if (pVar) {
|
||||||
@@ -357,60 +425,6 @@ namespace MG_GL::GL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// void EnsureRenderPassActive() {
|
|
||||||
// MG_Util::Debug::LogD("EnsureRenderPassActive called.");
|
|
||||||
// if (MG_Diligent::IsInRenderPass) {
|
|
||||||
// MG_Util::Debug::LogD("Render pass is already active.");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// MG_Util::Debug::LogD("Render pass is not active, attempting to begin one.");
|
|
||||||
// GLuint drawFB = MG_State_T::framebufferState->currentBindings_[GL_DRAW_FRAMEBUFFER];
|
|
||||||
// if (drawFB == 0) {
|
|
||||||
// MG_Util::Debug::LogD("drawFB is 0, using default framebuffer (0).");
|
|
||||||
// drawFB = 0;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// auto it = MG_Diligent::g_FramebufferMap.find(drawFB);
|
|
||||||
// if (it == MG_Diligent::g_FramebufferMap.end()) {
|
|
||||||
// MG_Util::Debug::LogE("Framebuffer %u not found in g_FramebufferMap.", drawFB);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// MG_Util::Debug::LogD("Found framebuffer %u in g_FramebufferMap.", drawFB);
|
|
||||||
// MG_Diligent::GLFramebufferInfo& fbInfo = it->second;
|
|
||||||
//
|
|
||||||
// if (!fbInfo.pRenderPass || !fbInfo.pFramebuffer) {
|
|
||||||
// MG_Util::Debug::LogD("RenderPass or Framebuffer not yet created for FBO %u. Creating now.", drawFB);
|
|
||||||
// FramebufferObject* pFBO = MG_State_T::framebufferState->GetCurrentFBO(GL_DRAW_FRAMEBUFFER);
|
|
||||||
// if (!pFBO) {
|
|
||||||
// MG_Util::Debug::LogE("No current FBO found for GL_DRAW_FRAMEBUFFER when trying to create RenderPass/Framebuffer.");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// CreateRenderPassAndFramebuffer(drawFB, *pFBO, fbInfo);
|
|
||||||
// if (!fbInfo.pRenderPass || !fbInfo.pFramebuffer) {
|
|
||||||
// MG_Util::Debug::LogE("Failed to create RenderPass or Framebuffer for FBO %u.", drawFB);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// MG_Util::Debug::LogD("Successfully created RenderPass and Framebuffer for FBO %u.", drawFB);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// MG_Util::Debug::LogD("Proceeding to begin render pass for FBO %u.", drawFB);
|
|
||||||
// if (fbInfo.pRenderPass && fbInfo.pFramebuffer) {
|
|
||||||
// Diligent::BeginRenderPassAttribs beginRenderPassAttribs;
|
|
||||||
// beginRenderPassAttribs.pFramebuffer = fbInfo.pFramebuffer;
|
|
||||||
// beginRenderPassAttribs.pRenderPass = fbInfo.pRenderPass;
|
|
||||||
// beginRenderPassAttribs.StateTransitionMode = Diligent::RESOURCE_STATE_TRANSITION_MODE_TRANSITION;
|
|
||||||
// beginRenderPassAttribs.ClearValueCount = fbInfo.ClearValues.size();
|
|
||||||
// beginRenderPassAttribs.pClearValues = fbInfo.ClearValues.data();
|
|
||||||
//
|
|
||||||
// MG_Diligent::g_pContext->BeginRenderPass(beginRenderPassAttribs);
|
|
||||||
// MG_Diligent::IsInRenderPass = true;
|
|
||||||
// } else {
|
|
||||||
// MG_Util::Debug::LogE("RenderPass or Framebuffer not yet created for FBO %u.", drawFB);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void generate_triangle_fan_indices(std::vector<uint8_t>& out_data, const void* in_indices, size_t count) {
|
void generate_triangle_fan_indices(std::vector<uint8_t>& out_data, const void* in_indices, size_t count) {
|
||||||
const auto* pIn = static_cast<const T*>(in_indices);
|
const auto* pIn = static_cast<const T*>(in_indices);
|
||||||
@@ -427,14 +441,6 @@ namespace MG_GL::GL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PrepareForDraw(GLenum mode, GLsizei* pCount, GLenum type, const void*& pIndices) {
|
void PrepareForDraw(GLenum mode, GLsizei* pCount, GLenum type, const void*& pIndices) {
|
||||||
// if (MG_Diligent::IsInRenderPass) {
|
|
||||||
// MG_Util::Debug::LogD("Ending current render pass.");
|
|
||||||
// MG_Diligent::g_pContext->EndRenderPass();
|
|
||||||
// MG_Diligent::IsInRenderPass = false;
|
|
||||||
// MG_Util::Debug::LogD("Current render pass ended.");
|
|
||||||
// } else {
|
|
||||||
// MG_Util::Debug::LogD("No active render pass to end.");
|
|
||||||
// }
|
|
||||||
GLuint program = MG_State::GetCurrentProgram();
|
GLuint program = MG_State::GetCurrentProgram();
|
||||||
|
|
||||||
if (program == 0) {
|
if (program == 0) {
|
||||||
@@ -587,8 +593,7 @@ namespace MG_GL::GL {
|
|||||||
}
|
}
|
||||||
MG_Diligent::g_pContext->SetIndexBuffer(MG_Diligent::g_TriangleFanIndexBuffer, 0, Diligent::RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
|
MG_Diligent::g_pContext->SetIndexBuffer(MG_Diligent::g_TriangleFanIndexBuffer, 0, Diligent::RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
|
||||||
}
|
}
|
||||||
}
|
} else if (pVAO->elementBuffer != 0) {
|
||||||
else if (pVAO->elementBuffer != 0) {
|
|
||||||
GLuint buffer = pVAO->elementBuffer;
|
GLuint buffer = pVAO->elementBuffer;
|
||||||
auto* pBufferObj = MG_State_T::bufferState->GetBufferObject(buffer);
|
auto* pBufferObj = MG_State_T::bufferState->GetBufferObject(buffer);
|
||||||
assert(pBufferObj != nullptr);
|
assert(pBufferObj != nullptr);
|
||||||
@@ -624,34 +629,37 @@ namespace MG_GL::GL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update data for all dynamic buffers
|
// Update data for all dynamic buffers
|
||||||
for (auto& [bufferID, pBuffer] : MG_Diligent::g_BufferMap) {
|
MG_Util::Debug::LogD("g_BufferMap size: %d", MG_Diligent::g_BufferMap.size()); // Moved out of loop
|
||||||
MG_Util::Debug::LogD("g_BufferMap size: %d", MG_Diligent::g_BufferMap.size());
|
|
||||||
|
|
||||||
|
for (auto& [bufferID, pBuffer] : MG_Diligent::g_BufferMap) {
|
||||||
auto* pBufferObject = MG_State_T::bufferState->GetBufferObject(bufferID);
|
auto* pBufferObject = MG_State_T::bufferState->GetBufferObject(bufferID);
|
||||||
if (!pBufferObject) {
|
if (!pBufferObject || !pBuffer) {
|
||||||
MG_Util::Debug::LogW("Buffer ID %u not found in bufferState. Skipping update.", bufferID);
|
if (!pBufferObject) {
|
||||||
|
MG_Util::Debug::LogW("Buffer ID %u not found in bufferState. Skipping update.", bufferID);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& bufferObj = *pBufferObject;
|
auto& bufferObj = *pBufferObject;
|
||||||
if (pBuffer && bufferObj.isDynamic) {
|
if (!bufferObj.isDynamic) continue;
|
||||||
void* pMappedData = nullptr;
|
|
||||||
MG_Util::Debug::LogD("Mapping dynamic buffer %u for data update.", bufferID);
|
|
||||||
MG_Diligent::g_pContext->MapBuffer(
|
|
||||||
pBuffer,
|
|
||||||
Diligent::MAP_WRITE,
|
|
||||||
Diligent::MAP_FLAG_DISCARD,
|
|
||||||
pMappedData);
|
|
||||||
|
|
||||||
if (pMappedData) {
|
MG_Util::Debug::LogD("Mapping dynamic buffer %u for data update.", bufferID);
|
||||||
memcpy(pMappedData, bufferObj.data.data(), bufferObj.data.size());
|
void* pMappedData = nullptr;
|
||||||
MG_Diligent::g_pContext->UnmapBuffer(pBuffer, Diligent::MAP_WRITE);
|
MG_Diligent::g_pContext->MapBuffer(
|
||||||
bufferObj.dirty = false;
|
pBuffer,
|
||||||
MG_Util::Debug::LogD("Successfully updated data for dynamic buffer %u.", bufferID);
|
Diligent::MAP_WRITE,
|
||||||
} else {
|
Diligent::MAP_FLAG_DISCARD,
|
||||||
MG_Util::Debug::LogE("Failed to map dynamic buffer %u for data update.", bufferID);
|
pMappedData);
|
||||||
}
|
|
||||||
|
if (!pMappedData) {
|
||||||
|
MG_Util::Debug::LogE("Failed to map dynamic buffer %u for data update.", bufferID);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(pMappedData, bufferObj.data.data(), bufferObj.data.size());
|
||||||
|
MG_Diligent::g_pContext->UnmapBuffer(pBuffer, Diligent::MAP_WRITE);
|
||||||
|
bufferObj.dirty = false;
|
||||||
|
MG_Util::Debug::LogD("Successfully updated data for dynamic buffer %u.", bufferID);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Diligent::IBuffer*> vertexBuffers;
|
std::vector<Diligent::IBuffer*> vertexBuffers;
|
||||||
@@ -776,10 +784,7 @@ namespace MG_GL::GL {
|
|||||||
MG_Util::Debug::LogD(" FirstIndexLocation: %u", drawAttrs.FirstIndexLocation);
|
MG_Util::Debug::LogD(" FirstIndexLocation: %u", drawAttrs.FirstIndexLocation);
|
||||||
MG_Util::Debug::LogD(" FirstInstanceLocation: %u", drawAttrs.FirstInstanceLocation);
|
MG_Util::Debug::LogD(" FirstInstanceLocation: %u", drawAttrs.FirstInstanceLocation);
|
||||||
|
|
||||||
// EnsureRenderPassActive();
|
|
||||||
MG_Diligent::g_pContext->DrawIndexed(drawAttrs);
|
MG_Diligent::g_pContext->DrawIndexed(drawAttrs);
|
||||||
// MG_Diligent::g_pContext->EndRenderPass();
|
|
||||||
// MG_Diligent::IsInRenderPass = false;
|
|
||||||
MG_Util::Debug::LogD("DrawIndexed (BaseVertex) completed.");
|
MG_Util::Debug::LogD("DrawIndexed (BaseVertex) completed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1005,10 +1010,7 @@ namespace MG_GL::GL {
|
|||||||
MG_Util::Debug::LogD(" BaseVertex: %d", item.BaseVertex);
|
MG_Util::Debug::LogD(" BaseVertex: %d", item.BaseVertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnsureRenderPassActive();
|
|
||||||
MG_Diligent::g_pContext->MultiDrawIndexed(drawAttrs);
|
MG_Diligent::g_pContext->MultiDrawIndexed(drawAttrs);
|
||||||
// MG_Diligent::g_pContext->EndRenderPass();
|
|
||||||
// MG_Diligent::IsInRenderPass = false;
|
|
||||||
MG_Util::Debug::LogD("MultiDrawIndexed completed.");
|
MG_Util::Debug::LogD("MultiDrawIndexed completed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user