[Test] (Diligent, MG_Test): verify state-driven draw with real MobileGL frontend state

Add DrawsFromMobileGLState test that creates a GL 3.2 program, buffer and VAO
through the real frontend, then draws through DiligentRenderer::DrawFromState
and verifies the offscreen pixels.

Also release PSO/vertex buffer before recreation to avoid Diligent debug
assertions about overwriting references.

All 3 Diligent local tests pass on Turnip Adreno 750.
This commit is contained in:
BZLZHH
2026-08-18 13:13:10 +08:00
parent f6b1ea635b
commit 53cac39d4e
2 changed files with 75 additions and 0 deletions
@@ -297,6 +297,7 @@ void main()
initialData.pData = vertices;
initialData.DataSize = static_cast<Uint32>(dataSize);
m_pVertexBuffer.Release();
m_pDevice->CreateBuffer(buffDesc, &initialData, &m_pVertexBuffer);
if (!m_pVertexBuffer) {
MGLOG_E("DiligentRenderer: failed to create dynamic vertex buffer");
@@ -452,6 +453,7 @@ void main()
psoCI.pVS = pVS;
psoCI.pPS = pPS;
m_pPSO.Release();
m_pDevice->CreateGraphicsPipelineState(psoCI, &m_pPSO);
if (!m_pPSO) {
MGLOG_E("DiligentRenderer: failed to create state pipeline");
@@ -576,6 +578,7 @@ void main()
::Diligent::BufferData initialData;
initialData.pData = vertexData.data();
initialData.DataSize = static_cast<::Diligent::Uint32>(vertexData.size());
m_pVertexBuffer.Release();
m_pDevice->CreateBuffer(buffDesc, &initialData, &m_pVertexBuffer);
if (!m_pVertexBuffer) {
return false;
@@ -10,9 +10,15 @@
#include <MG_Backend/Diligent/BackendObject_Diligent.h>
#include <MG_Backend/Diligent/Renderer/DiligentRenderer.h>
#include <MG_Backend/BackendObjects.h>
#include <MG_Impl/GLImpl/Buffer/GL_Buffer.h>
#include <MG_Impl/GLImpl/Program/GL_Program.h>
#include <MG_Impl/GLImpl/VertexArray/GL_VertexArray.h>
#include <MG_State/GLState/Core.h>
#include <Init.h>
using namespace MobileGL;
using namespace MobileGL::MG_Backend;
using namespace MobileGL::MG_Impl::GLImpl;
TEST(DiligentVulkanBackend, CreatesDiligentDeviceAndAdvertisesGL32) {
DiligentBackend::BackendObject_Diligent backend;
@@ -61,3 +67,69 @@ TEST(DiligentVulkanBackend, ClearsAndDrawsTriangleOffscreen) {
EXPECT_GT(corner[1], 200) << "corner should remain green after clear";
EXPECT_LT(corner[0], 50) << "corner should not be red";
}
TEST(DiligentVulkanBackend, DrawsFromMobileGLState) {
MobileGL::Initialize();
// Build a minimal GL 3.2-style program through the real frontend.
const char* vsSrc = R"(#version 330 core
layout(location = 0) in vec2 Position;
void main() { gl_Position = vec4(Position, 0.0, 1.0); }
)";
const char* fsSrc = R"(#version 330 core
out vec4 Color;
void main() { Color = vec4(1.0, 0.0, 0.0, 1.0); }
)";
const GLuint vs = CreateShader(GL_VERTEX_SHADER);
ShaderSource(vs, 1, &vsSrc, nullptr);
CompileShader(vs);
const GLuint fs = CreateShader(GL_FRAGMENT_SHADER);
ShaderSource(fs, 1, &fsSrc, nullptr);
CompileShader(fs);
const GLuint program = CreateProgram();
AttachShader(program, vs);
AttachShader(program, fs);
LinkProgram(program);
UseProgram(program);
// Upload a triangle into a real GL buffer and describe it through a VAO.
const float vertices[] = {
-0.5f, -0.5f,
0.5f, -0.5f,
0.0f, 0.5f,
};
GLuint vbo = 0;
GenBuffers(1, &vbo);
BindBuffer(GL_ARRAY_BUFFER, vbo);
BufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GLuint vao = 0;
GenVertexArrays(1, &vao);
BindVertexArray(vao);
EnableVertexAttribArray(0);
VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
DiligentBackend::BackendObject_Diligent backend;
backend.Initialize();
auto* renderer = backend.GetRenderer();
if (renderer == nullptr) {
GTEST_SKIP() << "No Vulkan adapter available; skipping state-driven test";
}
renderer->Clear(0.0f, 1.0f, 0.0f, 1.0f);
renderer->DrawFromState(GL_TRIANGLES, 0, 3, 0, nullptr);
renderer->Present();
std::uint8_t center[4] = {};
renderer->ReadPixels(128, 128, 1, 1, center);
EXPECT_GT(center[0], 200) << "center should be red from state-driven triangle";
EXPECT_LT(center[1], 50) << "center should not be green";
std::uint8_t corner[4] = {};
renderer->ReadPixels(0, 0, 1, 1, corner);
EXPECT_GT(corner[1], 200) << "corner should remain green after clear";
EXPECT_LT(corner[0], 50) << "corner should not be red";
}