mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +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 <Shader.h>
|
||||||
#include <PipelineState.h>
|
#include <PipelineState.h>
|
||||||
#include <InputLayout.h>
|
#include <InputLayout.h>
|
||||||
|
#include <Sampler.h>
|
||||||
|
|
||||||
#include <MG_State/GLState/Core.h>
|
#include <MG_State/GLState/Core.h>
|
||||||
#include <MG_State/GLState/ProgramState/ProgramObject.h>
|
#include <MG_State/GLState/ProgramState/ProgramObject.h>
|
||||||
@@ -431,6 +432,46 @@ void main()
|
|||||||
m_pContext->Draw(drawAttrs);
|
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) {
|
void DiligentRenderer::DrawFromState(GLenum mode, GLint first, GLsizei count, GLenum type, const void* indices) {
|
||||||
if (!m_initialized || !m_pContext || MG_State::pGLContext == nullptr) {
|
if (!m_initialized || !m_pContext || MG_State::pGLContext == nullptr) {
|
||||||
return;
|
return;
|
||||||
@@ -480,6 +521,9 @@ void main()
|
|||||||
const auto& front = MG_State::pGLContext->GetStencilState(StencilFace::Front);
|
const auto& front = MG_State::pGLContext->GetStencilState(StencilFace::Front);
|
||||||
m_pContext->SetStencilRef(static_cast<::Diligent::Uint32>(front.Ref));
|
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;
|
::Diligent::DrawAttribs drawAttrs;
|
||||||
drawAttrs.NumVertices = m_lastDrawVertexCount;
|
drawAttrs.NumVertices = m_lastDrawVertexCount;
|
||||||
@@ -649,6 +693,18 @@ void main()
|
|||||||
MGLOG_E("DiligentRenderer: failed to create state pipeline");
|
MGLOG_E("DiligentRenderer: failed to create state pipeline");
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ namespace Diligent {
|
|||||||
struct ITextureView;
|
struct ITextureView;
|
||||||
struct IPipelineState;
|
struct IPipelineState;
|
||||||
struct IBuffer;
|
struct IBuffer;
|
||||||
|
struct ISampler;
|
||||||
|
struct IShaderResourceBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MobileGL::MG_Backend::DiligentBackend {
|
namespace MobileGL::MG_Backend::DiligentBackend {
|
||||||
@@ -44,6 +46,9 @@ namespace MobileGL::MG_Backend::DiligentBackend {
|
|||||||
void ClearDepth(Float depth);
|
void ClearDepth(Float depth);
|
||||||
void DrawTriangle();
|
void DrawTriangle();
|
||||||
void DrawVertices(const Float* vertices, Uint32 vertexCount);
|
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
|
// Draws using the live MG_State GL context: current program, VAO and
|
||||||
// bound buffers. This is the front-end emulation entry point.
|
// bound buffers. This is the front-end emulation entry point.
|
||||||
void DrawFromState(GLenum mode, GLint first, GLsizei count, GLenum type, const void* indices);
|
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::ITextureView> m_pColorRTV;
|
||||||
::Diligent::RefCntAutoPtr<::Diligent::ITexture> m_pDepthTarget;
|
::Diligent::RefCntAutoPtr<::Diligent::ITexture> m_pDepthTarget;
|
||||||
::Diligent::RefCntAutoPtr<::Diligent::ITextureView> m_pDepthDSV;
|
::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::IPipelineState> m_pPSO;
|
||||||
::Diligent::RefCntAutoPtr<::Diligent::IBuffer> m_pVertexBuffer;
|
::Diligent::RefCntAutoPtr<::Diligent::IBuffer> m_pVertexBuffer;
|
||||||
Uint32 m_width = 256;
|
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_GT(corner[1], 200) << "corner should remain green after clear";
|
||||||
EXPECT_LT(corner[0], 50) << "corner should not be red";
|
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