mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
Compare commits
2
Commits
dev
...
nv_mesh_shader
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3fac5e9fa | ||
|
|
3823fe528c |
@@ -521,7 +521,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
Vector<GLExtension> BuildAdvertisedExtensions(Bool shaderSubgroupSupported, Bool timerQueriesSupported,
|
||||
Bool anisotropicFilteringSupported,
|
||||
Bool nonZeroIndirectBaseInstanceSupported,
|
||||
Bool cubeMapArraySupported) {
|
||||
Bool cubeMapArraySupported,
|
||||
Bool nvMeshShader) {
|
||||
Vector<GLExtension> extensions = {
|
||||
// The version tokens have to reach the version the backend actually claims:
|
||||
// TargetGLVersion is {4,6,0}, and a list that stopped at OpenGL40 told an
|
||||
@@ -685,6 +686,11 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
if (cubeMapArraySupported) {
|
||||
extensions.push_back(E_GL_ARB_texture_cube_map_array);
|
||||
}
|
||||
|
||||
if (nvMeshShader) {
|
||||
extensions.push_back(E_GL_NV_mesh_shader);
|
||||
}
|
||||
|
||||
return extensions;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
Vector<GLExtension> BuildAdvertisedExtensions(Bool shaderSubgroupSupported, Bool timerQueriesSupported,
|
||||
Bool anisotropicFilteringSupported,
|
||||
Bool nonZeroIndirectBaseInstanceSupported,
|
||||
Bool cubeMapArraySupported);
|
||||
Bool cubeMapArraySupported,
|
||||
Bool nvMeshShader = true);
|
||||
|
||||
// Format: <GPU Name>, Vulkan <Vulkan Version>, Driver <Driver Version> — the exact
|
||||
// string an initialized backend returns from GetBackendAPIVersionString (and that
|
||||
|
||||
@@ -687,6 +687,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::GetIntegeri_v called with null VulkanRenderer");
|
||||
switch (target) {
|
||||
case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
|
||||
if (!pVulkanRenderer) {
|
||||
*data = 0;
|
||||
return;
|
||||
}
|
||||
if (index >= 3) {
|
||||
*data = 0;
|
||||
return;
|
||||
@@ -695,6 +699,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
pVulkanRenderer->GetPhysicalDevice().properties.limits.maxComputeWorkGroupCount[index]);
|
||||
return;
|
||||
case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
|
||||
if (!pVulkanRenderer) {
|
||||
*data = 0;
|
||||
return;
|
||||
}
|
||||
if (index >= 3) {
|
||||
*data = 0;
|
||||
return;
|
||||
|
||||
@@ -1196,6 +1196,15 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
DrawElements_Backend(mode, count, type, indices);
|
||||
}
|
||||
|
||||
void DrawMeshTasksNV(GLuint first, GLuint count) {}
|
||||
|
||||
void DrawMeshTasksIndirectNV(GLintptr indirect) {}
|
||||
|
||||
void MultiDrawMeshTasksIndirectNV(GLintptr indirect, GLsizei drawcount, GLsizei stride) {}
|
||||
|
||||
void MultiDrawMeshTasksIndirectCountNV(GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount,
|
||||
GLsizei stride) {}
|
||||
|
||||
void BeginTransformFeedback(GLenum primitiveMode) {
|
||||
if (primitiveMode != GL_POINTS && primitiveMode != GL_LINES && primitiveMode != GL_TRIANGLES) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
|
||||
@@ -66,4 +66,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
GLsizei drawcount, const GLint* basevertex);
|
||||
void Clear(GLbitfield mask);
|
||||
void DrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices);
|
||||
|
||||
void DrawMeshTasksNV(GLuint first, GLuint count);
|
||||
void DrawMeshTasksIndirectNV(GLintptr indirect);
|
||||
void MultiDrawMeshTasksIndirectNV(GLintptr indirect, GLsizei drawcount, GLsizei stride);
|
||||
void MultiDrawMeshTasksIndirectCountNV(GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
|
||||
} // namespace MobileGL::MG_Impl::GLImpl
|
||||
|
||||
@@ -2412,10 +2412,10 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, BufferPageCommitmentMemNV, GLenum target, GL
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexPageCommitmentMemNV, GLenum target, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexPageCommitmentMemNV, target, layer, level, xoffset, yoffset, zoffset, width, height, depth, memory, offset, commit)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, NamedBufferPageCommitmentMemNV, GLuint buffer, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, NamedBufferPageCommitmentMemNV, buffer, offset, size, memory, memOffset, commit)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, TexturePageCommitmentMemNV, GLuint texture, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, TexturePageCommitmentMemNV, texture, layer, level, xoffset, yoffset, zoffset, width, height, depth, memory, offset, commit)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, DrawMeshTasksNV, GLuint first, GLuint count) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DrawMeshTasksNV, first, count)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, DrawMeshTasksIndirectNV, GLintptr indirect) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DrawMeshTasksIndirectNV, indirect)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, MultiDrawMeshTasksIndirectNV, GLintptr indirect, GLsizei drawcount, GLsizei stride) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, MultiDrawMeshTasksIndirectNV, indirect, drawcount, stride)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, MultiDrawMeshTasksIndirectCountNV, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, MultiDrawMeshTasksIndirectCountNV, indirect, drawcount, maxdrawcount, stride)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, DrawMeshTasksNV, GLuint first, GLuint count) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DrawMeshTasksNV, first, count)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, DrawMeshTasksIndirectNV, GLintptr indirect) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DrawMeshTasksIndirectNV, indirect)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, MultiDrawMeshTasksIndirectNV, GLintptr indirect, GLsizei drawcount, GLsizei stride) DECLARE_GL_FUNCTION_END_NO_RETURN(void, MultiDrawMeshTasksIndirectNV, indirect, drawcount, stride)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, MultiDrawMeshTasksIndirectCountNV, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride) DECLARE_GL_FUNCTION_END_NO_RETURN(void, MultiDrawMeshTasksIndirectCountNV, indirect, drawcount, maxdrawcount, stride)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, GenOcclusionQueriesNV, GLsizei n, GLuint* ids) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GenOcclusionQueriesNV, n, ids)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, DeleteOcclusionQueriesNV, GLsizei n, const GLuint* ids) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DeleteOcclusionQueriesNV, n, ids)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(GLboolean, IsOcclusionQueryNV, GLuint id) DECLARE_GL_FUNCTION_STUB_END(GLboolean, IsOcclusionQueryNV, id)
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace MobileGL {
|
||||
TessEval,
|
||||
Geometry,
|
||||
Fragment,
|
||||
Task,
|
||||
Mesh,
|
||||
Compute,
|
||||
ShaderStageCount,
|
||||
Unknown = -1
|
||||
|
||||
@@ -89,6 +89,7 @@ add_subdirectory(Swapchain)
|
||||
add_subdirectory(ShaderTranspiler)
|
||||
add_subdirectory(Util)
|
||||
add_subdirectory(SelfTest)
|
||||
add_subdirectory(MeshShader)
|
||||
# The DirectGLES post-transpile ESSL passes are pure String -> String, so unlike the
|
||||
# DirectVulkan suite below this one needs no device and always builds.
|
||||
add_subdirectory(Backend/DirectGLES)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
add_executable(
|
||||
MeshShaderTest
|
||||
MeshShaderTest.cpp
|
||||
)
|
||||
|
||||
target_include_directories(MeshShaderTest PRIVATE
|
||||
${MGL_ROOT}/include
|
||||
${MGL_ROOT}/MobileGL
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
MeshShaderTest PRIVATE
|
||||
GTest::gtest_main
|
||||
${LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(MeshShaderTest DISCOVERY_TIMEOUT 30 PROPERTIES LABELS unit)
|
||||
@@ -0,0 +1,69 @@
|
||||
// MobileGL - MobileGL/MG_Test/MeshShader/MeshShader.cpp
|
||||
// Copyright (c) 2025-2026 MobileGL-Dev
|
||||
// Licensed under the GNU Lesser General Public License v3.0:
|
||||
// https://www.gnu.org/licenses/gpl-3.0.txt
|
||||
// https://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
// End of Source File Header
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "Includes.h"
|
||||
#include "Init.h"
|
||||
#include "MG_Impl/GLImpl/Program/GL_Program.h"
|
||||
|
||||
#include <MG_Impl/GLImpl/Buffer/GL_Buffer.h>
|
||||
#include <MG_Impl/GLImpl/Getter/GL_Getter.h>
|
||||
#include <MG_Impl/GLImpl/VertexArray/GL_VertexArray.h>
|
||||
#include <MG_Impl/GLImpl/VertexArray/Validators.h>
|
||||
#include <MG_State/GLState/Core.h>
|
||||
|
||||
using namespace MobileGL;
|
||||
|
||||
class MeshShaderTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override { MobileGL::Initialize(); }
|
||||
|
||||
void TearDown() override {
|
||||
EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR) << "test left an unconsumed GL error behind";
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(MeshShaderTest, IsHaveExt) {
|
||||
const auto* extensionsString = reinterpret_cast<const char*>(MG_Impl::GLImpl::GetString(GL_EXTENSIONS));
|
||||
ASSERT_NE(extensionsString, nullptr);
|
||||
// std::cout << extensionsString << std::endl;
|
||||
const Bool isHaveExt = String(extensionsString).find("GL_NV_mesh_shader") != String::npos;
|
||||
ASSERT_EQ(isHaveExt, true);
|
||||
}
|
||||
|
||||
TEST_F(MeshShaderTest, TaskShaderCompile) {
|
||||
const GLuint shader = MG_Impl::GLImpl::CreateShader(GL_TASK_SHADER_NV);
|
||||
const char* src = R"GLSL(
|
||||
#version 460
|
||||
#extension GL_NV_mesh_shader : require
|
||||
|
||||
layout(local_size_x = 32) in;
|
||||
|
||||
layout(location = 0) uniform vec4 uParams; // x = grid, y = aspect, z = time
|
||||
|
||||
void main()
|
||||
{
|
||||
if (gl_LocalInvocationID.x != 0u)
|
||||
return;
|
||||
|
||||
uint grid = uint(uParams.x);
|
||||
|
||||
gl_TaskCountNV = grid * grid;
|
||||
}
|
||||
)GLSL";
|
||||
MG_Impl::GLImpl::ShaderSource(shader, 1, &src, nullptr);
|
||||
MG_Impl::GLImpl::CompileShader(shader);
|
||||
|
||||
GLint ok = GL_FALSE;
|
||||
MG_Impl::GLImpl::GetShaderiv(shader, GL_COMPILE_STATUS, &ok);
|
||||
|
||||
ASSERT_EQ(ok, GL_TRUE);
|
||||
}
|
||||
@@ -18,6 +18,10 @@ namespace MobileGL {
|
||||
return EShLanguage::EShLangFragment;
|
||||
case GL_COMPUTE_SHADER:
|
||||
return EShLanguage::EShLangCompute;
|
||||
case GL_TASK_SHADER_NV:
|
||||
return EShLanguage::EShLangTaskNV;
|
||||
case GL_MESH_SHADER_NV:
|
||||
return EShLanguage::EShLangMeshNV;
|
||||
case GL_TESS_CONTROL_SHADER:
|
||||
return EShLanguage::EShLangTessControl;
|
||||
case GL_TESS_EVALUATION_SHADER:
|
||||
|
||||
@@ -22,6 +22,10 @@ namespace MobileGL {
|
||||
return ShaderStage::Geometry;
|
||||
case GL_FRAGMENT_SHADER:
|
||||
return ShaderStage::Fragment;
|
||||
case GL_TASK_SHADER_NV:
|
||||
return ShaderStage::Task;
|
||||
case GL_MESH_SHADER_NV:
|
||||
return ShaderStage::Mesh;
|
||||
case GL_COMPUTE_SHADER:
|
||||
return ShaderStage::Compute;
|
||||
default:
|
||||
|
||||
@@ -409,6 +409,8 @@ namespace MobileGL {
|
||||
CASE(GL_MAX_TEXTURE_IMAGE_UNITS)
|
||||
CASE(GL_FRAGMENT_SHADER)
|
||||
CASE(GL_VERTEX_SHADER)
|
||||
CASE(GL_TASK_SHADER_NV)
|
||||
CASE(GL_MESH_SHADER_NV)
|
||||
CASE(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS)
|
||||
CASE(GL_MAX_VERTEX_UNIFORM_COMPONENTS)
|
||||
CASE(GL_MAX_VARYING_FLOATS)
|
||||
|
||||
@@ -22,6 +22,10 @@ namespace MobileGL {
|
||||
return GL_GEOMETRY_SHADER;
|
||||
case ShaderStage::Fragment:
|
||||
return GL_FRAGMENT_SHADER;
|
||||
case ShaderStage::Task:
|
||||
return GL_TASK_SHADER_NV;
|
||||
case ShaderStage::Mesh:
|
||||
return GL_MESH_SHADER_NV;
|
||||
case ShaderStage::Compute:
|
||||
return GL_COMPUTE_SHADER;
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user