mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 20:28:32 +09:00
[Feat, Test] (Diligent, MG_Test): add basic texture binding and textured state-draw test
- Add CreateTestTexture(): creates an RGBA8 texture, SRV and default sampler, and attaches the sampler to the SRV. - State PSOs now bind a static pixel-shader variable 'g_Texture' to the test texture and commit shader resources before drawing. - Add DrawsTexturedFromMobileGLState test using a real GL program with sampler2D and interleaved position+UV attributes. - All 4 Diligent local tests pass on Turnip Adreno 750.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <Shader.h>
|
||||
#include <PipelineState.h>
|
||||
#include <InputLayout.h>
|
||||
#include <Sampler.h>
|
||||
|
||||
#include <MG_State/GLState/Core.h>
|
||||
#include <MG_State/GLState/ProgramState/ProgramObject.h>
|
||||
@@ -431,6 +432,46 @@ void main()
|
||||
m_pContext->Draw(drawAttrs);
|
||||
}
|
||||
|
||||
Bool DiligentRenderer::CreateTestTexture(const void* data, Uint32 width, Uint32 height) {
|
||||
if (m_pDevice == nullptr || data == nullptr || width == 0 || height == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::Diligent::TextureDesc texDesc;
|
||||
texDesc.Name = "MobileGL Diligent test texture";
|
||||
texDesc.Type = ::Diligent::RESOURCE_DIM_TEX_2D;
|
||||
texDesc.Format = ::Diligent::TEX_FORMAT_RGBA8_UNORM;
|
||||
texDesc.Width = width;
|
||||
texDesc.Height = height;
|
||||
texDesc.MipLevels = 1;
|
||||
texDesc.BindFlags = ::Diligent::BIND_SHADER_RESOURCE;
|
||||
texDesc.Usage = ::Diligent::USAGE_DEFAULT;
|
||||
|
||||
::Diligent::TextureSubResData subResData;
|
||||
subResData.pData = data;
|
||||
subResData.Stride = static_cast<::Diligent::Uint64>(width) * 4;
|
||||
|
||||
::Diligent::TextureData texData;
|
||||
texData.pSubResources = &subResData;
|
||||
texData.NumSubresources = 1;
|
||||
|
||||
m_pDevice->CreateTexture(texDesc, &texData, &m_pTestTexture);
|
||||
if (!m_pTestTexture) {
|
||||
return false;
|
||||
}
|
||||
m_pTestSRV = m_pTestTexture->GetDefaultView(::Diligent::TEXTURE_VIEW_SHADER_RESOURCE);
|
||||
if (!m_pTestSRV) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::Diligent::SamplerDesc samplerDesc;
|
||||
m_pDevice->CreateSampler(samplerDesc, &m_pTestSampler);
|
||||
if (m_pTestSampler) {
|
||||
m_pTestSRV->SetSampler(m_pTestSampler);
|
||||
}
|
||||
return m_pTestSampler != nullptr;
|
||||
}
|
||||
|
||||
void DiligentRenderer::DrawFromState(GLenum mode, GLint first, GLsizei count, GLenum type, const void* indices) {
|
||||
if (!m_initialized || !m_pContext || MG_State::pGLContext == nullptr) {
|
||||
return;
|
||||
@@ -480,6 +521,9 @@ void main()
|
||||
const auto& front = MG_State::pGLContext->GetStencilState(StencilFace::Front);
|
||||
m_pContext->SetStencilRef(static_cast<::Diligent::Uint32>(front.Ref));
|
||||
}
|
||||
if (m_pStateSRB) {
|
||||
m_pContext->CommitShaderResources(m_pStateSRB, ::Diligent::RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
|
||||
}
|
||||
|
||||
::Diligent::DrawAttribs drawAttrs;
|
||||
drawAttrs.NumVertices = m_lastDrawVertexCount;
|
||||
@@ -649,6 +693,18 @@ void main()
|
||||
MGLOG_E("DiligentRenderer: failed to create state pipeline");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pStateSRB = nullptr;
|
||||
if (m_pTestSRV) {
|
||||
auto* staticVar = m_pPSO->GetStaticVariableByName(::Diligent::SHADER_TYPE_PIXEL, "g_Texture");
|
||||
if (staticVar != nullptr) {
|
||||
staticVar->Set(m_pTestSRV);
|
||||
}
|
||||
m_pPSO->CreateShaderResourceBinding(&m_pStateSRB, false);
|
||||
if (m_pStateSRB) {
|
||||
m_pPSO->InitializeStaticSRBResources(m_pStateSRB);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ namespace Diligent {
|
||||
struct ITextureView;
|
||||
struct IPipelineState;
|
||||
struct IBuffer;
|
||||
struct ISampler;
|
||||
struct IShaderResourceBinding;
|
||||
}
|
||||
|
||||
namespace MobileGL::MG_Backend::DiligentBackend {
|
||||
@@ -44,6 +46,9 @@ namespace MobileGL::MG_Backend::DiligentBackend {
|
||||
void ClearDepth(Float depth);
|
||||
void DrawTriangle();
|
||||
void DrawVertices(const Float* vertices, Uint32 vertexCount);
|
||||
// Creates a simple 2D RGBA8 texture from CPU data and makes it available
|
||||
// to state PSOs under the shader variable name "g_Texture".
|
||||
Bool CreateTestTexture(const void* data, Uint32 width, Uint32 height);
|
||||
// Draws using the live MG_State GL context: current program, VAO and
|
||||
// bound buffers. This is the front-end emulation entry point.
|
||||
void DrawFromState(GLenum mode, GLint first, GLsizei count, GLenum type, const void* indices);
|
||||
@@ -66,6 +71,10 @@ namespace MobileGL::MG_Backend::DiligentBackend {
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ITextureView> m_pColorRTV;
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ITexture> m_pDepthTarget;
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ITextureView> m_pDepthDSV;
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ITexture> m_pTestTexture;
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ITextureView> m_pTestSRV;
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ISampler> m_pTestSampler;
|
||||
::Diligent::RefCntAutoPtr<::Diligent::IShaderResourceBinding> m_pStateSRB;
|
||||
::Diligent::RefCntAutoPtr<::Diligent::IPipelineState> m_pPSO;
|
||||
::Diligent::RefCntAutoPtr<::Diligent::IBuffer> m_pVertexBuffer;
|
||||
Uint32 m_width = 256;
|
||||
|
||||
@@ -135,3 +135,77 @@ void main() { Color = vec4(1.0, 0.0, 0.0, 1.0); }
|
||||
EXPECT_GT(corner[1], 200) << "corner should remain green after clear";
|
||||
EXPECT_LT(corner[0], 50) << "corner should not be red";
|
||||
}
|
||||
|
||||
TEST(DiligentVulkanBackend, DrawsTexturedFromMobileGLState) {
|
||||
MobileGL::Initialize();
|
||||
|
||||
const char* vsSrc = R"(#version 330 core
|
||||
layout(location = 0) in vec2 Position;
|
||||
layout(location = 1) in vec2 UV;
|
||||
out vec2 vUV;
|
||||
void main() { gl_Position = vec4(Position, 0.0, 1.0); vUV = UV; }
|
||||
)";
|
||||
const char* fsSrc = R"(#version 330 core
|
||||
uniform sampler2D g_Texture;
|
||||
in vec2 vUV;
|
||||
out vec4 Color;
|
||||
void main() { Color = texture(g_Texture, vUV); }
|
||||
)";
|
||||
|
||||
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);
|
||||
Viewport(0, 0, 256, 256);
|
||||
|
||||
// Position + UV interleaved.
|
||||
const float vertices[] = {
|
||||
-0.5f, -0.5f, 0.0f, 0.0f,
|
||||
0.5f, -0.5f, 1.0f, 0.0f,
|
||||
0.0f, 0.5f, 0.5f, 1.0f,
|
||||
};
|
||||
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, 16, nullptr);
|
||||
EnableVertexAttribArray(1);
|
||||
VertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 16, reinterpret_cast<const void*>(8));
|
||||
|
||||
DiligentBackend::BackendObject_Diligent backend;
|
||||
backend.Initialize();
|
||||
auto* renderer = backend.GetRenderer();
|
||||
if (renderer == nullptr) {
|
||||
GTEST_SKIP() << "No Vulkan adapter available; skipping textured state test";
|
||||
}
|
||||
|
||||
// 2x2 solid red texture.
|
||||
const std::uint8_t redTexture[2 * 2 * 4] = {
|
||||
255, 0, 0, 255, 255, 0, 0, 255,
|
||||
255, 0, 0, 255, 255, 0, 0, 255,
|
||||
};
|
||||
ASSERT_TRUE(renderer->CreateTestTexture(redTexture, 2, 2));
|
||||
|
||||
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 textured triangle";
|
||||
EXPECT_LT(center[1], 50) << "center should not be green";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user