Skip to content

Commit

Permalink
Main: add support for Mesh & Task shaders
Browse files Browse the repository at this point in the history
  • Loading branch information
paroj committed Aug 9, 2024
1 parent 5863916 commit cd8697f
Show file tree
Hide file tree
Showing 24 changed files with 222 additions and 12 deletions.
6 changes: 4 additions & 2 deletions OgreMain/include/OgreGpuProgram.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@ namespace Ogre {
GPT_GEOMETRY_PROGRAM,
GPT_DOMAIN_PROGRAM,
GPT_HULL_PROGRAM,
GPT_COMPUTE_PROGRAM
GPT_MESH_PROGRAM, // aliases with vertex
GPT_COMPUTE_PROGRAM, // aliases with fragment
GPT_TASK_PROGRAM
};
enum {
GPT_COUNT = GPT_COMPUTE_PROGRAM + 1,
GPT_COUNT = GPT_TASK_PROGRAM + 1,
/// max programs that can be active in a pipeline (e.g compute is separate)
GPT_PIPELINE_COUNT = GPT_HULL_PROGRAM + 1
};
Expand Down
2 changes: 2 additions & 0 deletions OgreMain/include/OgreRenderSystemCapabilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ namespace Ogre
RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 15),
/// Supports using vertex buffers for instance data
RSC_VERTEX_BUFFER_INSTANCE_DATA = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 16),
/// Supports mesh and task programs
RSC_MESH_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 17),

// ***** DirectX specific caps *****
/// Is DirectX feature "per stage constants" supported
Expand Down
5 changes: 4 additions & 1 deletion OgreMain/include/OgreScriptCompiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,10 @@ namespace Ogre
ID_CAMERA,
ID_ALIGN_TO_FACE,
ID_UNORDERED_ACCESS_MIP,

ID_MESH_PROGRAM,
ID_MESH_PROGRAM_REF,
ID_TASK_PROGRAM,
ID_TASK_PROGRAM_REF,
ID_END_BUILTIN_IDS
};
/** @} */
Expand Down
7 changes: 6 additions & 1 deletion OgreMain/src/OgreGpuProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ namespace Ogre
if ((getType() == GPT_GEOMETRY_PROGRAM && !caps->hasCapability(RSC_GEOMETRY_PROGRAM)) ||
((getType() == GPT_DOMAIN_PROGRAM || getType() == GPT_HULL_PROGRAM) &&
!caps->hasCapability(RSC_TESSELLATION_PROGRAM)) ||
(getType() == GPT_COMPUTE_PROGRAM && !caps->hasCapability(RSC_COMPUTE_PROGRAM)))
(getType() == GPT_COMPUTE_PROGRAM && !caps->hasCapability(RSC_COMPUTE_PROGRAM)) ||
((getType() == GPT_MESH_PROGRAM || getType() == GPT_TASK_PROGRAM) && !caps->hasCapability(RSC_MESH_PROGRAM)))
{
return false;
}
Expand Down Expand Up @@ -376,6 +377,10 @@ namespace Ogre
return "hull";
case GPT_COMPUTE_PROGRAM:
return "compute";
case GPT_MESH_PROGRAM:
return "mesh";
case GPT_TASK_PROGRAM:
return "task";
default:
OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
"Unexpected GPU program type",
Expand Down
1 change: 1 addition & 0 deletions OgreMain/src/OgreRenderSystemCapabilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ namespace Ogre {
pLog->logMessage(" - Domain program constant 4-vectors: " +
StringConverter::toString(mConstantFloatCount[GPT_DOMAIN_PROGRAM]));
}
pLog->logMessage(" * Mesh programs: " + StringConverter::toString(hasCapability(RSC_MESH_PROGRAM), true));
pLog->logMessage(" * Compute programs: " + StringConverter::toString(hasCapability(RSC_COMPUTE_PROGRAM), true));
if (hasCapability(RSC_COMPUTE_PROGRAM))
{
Expand Down
6 changes: 4 additions & 2 deletions OgreMain/src/OgreSceneManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreGpuProgram.h"
#include "OgreStableHeaders.h"

#include "OgreControllerManager.h"
Expand Down Expand Up @@ -667,7 +668,8 @@ const Pass* SceneManager::_setPass(const Pass* pass, bool shadowDerivation)
{
bindGpuProgram(vprog->_getBindingDelegate());
}
else if (!mDestRenderSystem->getCapabilities()->hasCapability(RSC_FIXED_FUNCTION))
else if (!mDestRenderSystem->getCapabilities()->hasCapability(RSC_FIXED_FUNCTION) &&
!pass->hasGpuProgram(GPT_MESH_PROGRAM))
{
OGRE_EXCEPT(Exception::ERR_INVALID_STATE,
"RenderSystem does not support FixedFunction, "
Expand All @@ -686,7 +688,7 @@ const Pass* SceneManager::_setPass(const Pass* pass, bool shadowDerivation)
// Set fixed-function vertex parameters
}

for(auto gptype : {GPT_DOMAIN_PROGRAM, GPT_HULL_PROGRAM, GPT_GEOMETRY_PROGRAM})
for(auto gptype : {GPT_DOMAIN_PROGRAM, GPT_HULL_PROGRAM, GPT_GEOMETRY_PROGRAM, GPT_MESH_PROGRAM, GPT_TASK_PROGRAM})
{
if (pass->hasGpuProgram(gptype))
{
Expand Down
4 changes: 4 additions & 0 deletions OgreMain/src/OgreScriptCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,8 @@ namespace Ogre
mIds["tessellation_hull_program"] = ID_TESSELLATION_HULL_PROGRAM;
mIds["tessellation_domain_program"] = ID_TESSELLATION_DOMAIN_PROGRAM;
mIds["compute_program"] = ID_COMPUTE_PROGRAM;
mIds["mesh_program"] = ID_MESH_PROGRAM;
mIds["task_program"] = ID_TASK_PROGRAM;
mIds["technique"] = ID_TECHNIQUE;
mIds["pass"] = ID_PASS;
mIds["texture_unit"] = ID_TEXTURE_UNIT;
Expand All @@ -923,6 +925,8 @@ namespace Ogre
mIds["tessellation_hull_program_ref"] = ID_TESSELLATION_HULL_PROGRAM_REF;
mIds["tessellation_domain_program_ref"] = ID_TESSELLATION_DOMAIN_PROGRAM_REF;
mIds["compute_program_ref"] = ID_COMPUTE_PROGRAM_REF;
mIds["mesh_program_ref"] = ID_MESH_PROGRAM_REF;
mIds["task_program_ref"] = ID_TASK_PROGRAM_REF;
mIds["shadow_caster_vertex_program_ref"] = ID_SHADOW_CASTER_VERTEX_PROGRAM_REF;
mIds["shadow_caster_fragment_program_ref"] = ID_SHADOW_CASTER_FRAGMENT_PROGRAM_REF;
mIds["shadow_receiver_vertex_program_ref"] = ID_SHADOW_RECEIVER_VERTEX_PROGRAM_REF;
Expand Down
15 changes: 14 additions & 1 deletion OgreMain/src/OgreScriptTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreScriptCompiler.h"
#include "OgreStableHeaders.h"
#include "OgreBuiltinScriptTranslators.h"
#include "OgreGpuProgramManager.h"
Expand Down Expand Up @@ -533,6 +534,12 @@ namespace Ogre{
case ID_COMPUTE_PROGRAM:
case ID_COMPUTE_PROGRAM_REF:
return GPT_COMPUTE_PROGRAM;
case ID_MESH_PROGRAM:
case ID_MESH_PROGRAM_REF:
return GPT_MESH_PROGRAM;
case ID_TASK_PROGRAM:
case ID_TASK_PROGRAM_REF:
return GPT_TASK_PROGRAM;
}
}

Expand Down Expand Up @@ -2212,6 +2219,8 @@ namespace Ogre{
case ID_TESSELLATION_HULL_PROGRAM_REF:
case ID_TESSELLATION_DOMAIN_PROGRAM_REF:
case ID_COMPUTE_PROGRAM_REF:
case ID_MESH_PROGRAM_REF:
case ID_TASK_PROGRAM_REF:
translateProgramRef(getProgramType(child->id), compiler, child);
break;
case ID_SHADOW_CASTER_VERTEX_PROGRAM_REF:
Expand All @@ -2235,6 +2244,8 @@ namespace Ogre{
case ID_TESSELLATION_HULL_PROGRAM:
case ID_TESSELLATION_DOMAIN_PROGRAM:
case ID_COMPUTE_PROGRAM:
case ID_MESH_PROGRAM:
case ID_TASK_PROGRAM:
{
// auto assign inline defined programs
processNode(compiler, i);
Expand Down Expand Up @@ -5264,7 +5275,9 @@ namespace Ogre{
obj->id == ID_GEOMETRY_PROGRAM ||
obj->id == ID_TESSELLATION_HULL_PROGRAM ||
obj->id == ID_TESSELLATION_DOMAIN_PROGRAM ||
obj->id == ID_COMPUTE_PROGRAM)
obj->id == ID_COMPUTE_PROGRAM ||
obj->id == ID_MESH_PROGRAM ||
obj->id == ID_TASK_PROGRAM)
translator = &mGpuProgramTranslator;
else if(obj->id == ID_SHARED_PARAMS)
translator = &mSharedParamsTranslator;
Expand Down
2 changes: 1 addition & 1 deletion OgreMain/src/OgreTechnique.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ namespace Ogre {
if (!caps->hasCapability(RSC_FIXED_FUNCTION) && currPass->isProgrammable() &&
!currPass->hasGpuProgram(GPT_COMPUTE_PROGRAM))
{
if (!currPass->hasVertexProgram() ||
if ((!currPass->hasVertexProgram() && !currPass->hasGpuProgram(GPT_MESH_PROGRAM)) ||
(!currPass->hasFragmentProgram() && !currPass->hasGeometryProgram()))
{
compileErrors << "Pass " << passNum << ": RenderSystem requires both vertex and fragment programs";
Expand Down
7 changes: 7 additions & 0 deletions PlugIns/CgProgramManager/src/OgreCgFxScriptLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreCgFxScriptLoader.h"
#include "OgreGpuProgram.h"
#include "OgreResourceGroupManager.h"
#include "OgreMaterialManager.h"
#include "OgreTechnique.h"
Expand Down Expand Up @@ -2814,6 +2815,8 @@ namespace Ogre {
case GPT_COMPUTE_PROGRAM:
case GPT_DOMAIN_PROGRAM:
case GPT_HULL_PROGRAM:
case GPT_MESH_PROGRAM:
case GPT_TASK_PROGRAM:
break;
}
CGstateassignment cgStateAssignment = cgGetNamedStateAssignment(cgPass, stateName);
Expand All @@ -2833,6 +2836,8 @@ namespace Ogre {
case GPT_COMPUTE_PROGRAM:
case GPT_DOMAIN_PROGRAM:
case GPT_HULL_PROGRAM:
case GPT_MESH_PROGRAM:
case GPT_TASK_PROGRAM:
break;
}

Expand Down Expand Up @@ -2906,6 +2911,8 @@ namespace Ogre {
case GPT_DOMAIN_PROGRAM:
case GPT_COMPUTE_PROGRAM:
case GPT_HULL_PROGRAM:
case GPT_MESH_PROGRAM:
case GPT_TASK_PROGRAM:
break;
}

Expand Down
17 changes: 17 additions & 0 deletions PlugIns/GLSLang/src/OgreGLSLang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ static EShLanguage getShLanguage(GpuProgramType type)
case GPT_HULL_PROGRAM: return EShLangTessControl;
case GPT_DOMAIN_PROGRAM: return EShLangTessEvaluation;
case GPT_COMPUTE_PROGRAM: return EShLangCompute;
case GPT_MESH_PROGRAM: return EShLangMeshNV;
case GPT_TASK_PROGRAM: return EShLangTaskNV;
// clang-format on
}

Expand All @@ -331,6 +333,13 @@ GLSLangProgram::GLSLangProgram(ResourceManager* creator, const String& name, Res
{
setupBaseParamDictionary();
memset(&DefaultTBuiltInResource.limits, 1, sizeof(TLimits));

if(sizeof(TBuiltInResource) == 420) // replace with build_info.h, when it is universally available
{
// copy VK_NV_mesh_shader limits to VK_EXT_mesh_shader
memcpy(&DefaultTBuiltInResource.maxMeshViewCountNV + 1, &DefaultTBuiltInResource.maxMeshOutputVerticesNV,
9 * sizeof(int));
}
}
}

Expand Down Expand Up @@ -412,8 +421,16 @@ void GLSLangProgram::prepareImpl()
if(mSyntaxCode == "gl_spirv")
shader.setEnvClient(glslang::EShClientOpenGL, glslang::EShTargetOpenGL_450);
else if(mSyntaxCode == "spirv")
{
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_0);

if(mType == GPT_MESH_PROGRAM || mType == GPT_TASK_PROGRAM)
{
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_2);
shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_4);
}
}

// minimal version is 430 for explicit uniform location, but we use latest to get all features
if (!shader.parse(&DefaultTBuiltInResource, 460, false, EShMsgSpvRules))
{
Expand Down
4 changes: 4 additions & 0 deletions RenderSystems/Direct3D11/src/OgreD3D11HLSLProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,10 @@ namespace Ogre {
case GPT_COMPUTE_PROGRAM:
CreateComputeShader();
break;
case GPT_MESH_PROGRAM:
case GPT_TASK_PROGRAM:
OgreAssertDbg(false, "should never get here");
break;
}
}

Expand Down
4 changes: 4 additions & 0 deletions RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2250,6 +2250,10 @@ namespace Ogre
mBoundComputeProgram = static_cast<D3D11HLSLProgram*>(prg);
}
break;
case GPT_MESH_PROGRAM:
case GPT_TASK_PROGRAM:
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Mesh and task shaders are not supported in D3D11");
break;
};

RenderSystem::bindGpuProgram(prg);
Expand Down
2 changes: 2 additions & 0 deletions RenderSystems/GL/src/GLSL/src/OgreGLSLProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ namespace Ogre {
case GPT_COMPUTE_PROGRAM:
case GPT_DOMAIN_PROGRAM:
case GPT_HULL_PROGRAM:
case GPT_MESH_PROGRAM:
case GPT_TASK_PROGRAM:
break;
}
mGLShaderHandle = (size_t)glCreateShaderObjectARB(shaderType);
Expand Down
4 changes: 4 additions & 0 deletions RenderSystems/GL/src/OgreGLRenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2389,6 +2389,8 @@ namespace Ogre {
case GPT_COMPUTE_PROGRAM:
case GPT_DOMAIN_PROGRAM:
case GPT_HULL_PROGRAM:
case GPT_MESH_PROGRAM:
case GPT_TASK_PROGRAM:
break;
}

Expand Down Expand Up @@ -2444,6 +2446,8 @@ namespace Ogre {
case GPT_COMPUTE_PROGRAM:
case GPT_DOMAIN_PROGRAM:
case GPT_HULL_PROGRAM:
case GPT_MESH_PROGRAM:
case GPT_TASK_PROGRAM:
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,14 @@ namespace Ogre
}
}

#define GL_MESH_SHADER_BIT_NV 0x00000040
GLenum ogre2gltype[GPT_COUNT] = {
GL_VERTEX_SHADER_BIT,
GL_FRAGMENT_SHADER_BIT,
GL_GEOMETRY_SHADER_BIT,
GL_TESS_EVALUATION_SHADER_BIT,
GL_TESS_CONTROL_SHADER_BIT,
GL_MESH_SHADER_BIT_NV,
GL_COMPUTE_SHADER_BIT
};

Expand Down
8 changes: 8 additions & 0 deletions RenderSystems/GL3Plus/src/GLSL/src/OgreGLSLShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ namespace Ogre {
/// Get OpenGL GLSL shader type from OGRE GPU program type.
static GLenum getGLShaderType(GpuProgramType programType)
{
#define GL_MESH_SHADER_NV 0x9559
#define GL_TASK_SHADER_NV 0x955A
switch (programType)
{
case GPT_VERTEX_PROGRAM:
Expand All @@ -249,6 +251,10 @@ namespace Ogre {
return GL_FRAGMENT_SHADER;
case GPT_COMPUTE_PROGRAM:
return GL_COMPUTE_SHADER;
case GPT_MESH_PROGRAM:
return GL_MESH_SHADER_NV;
case GPT_TASK_PROGRAM:
return GL_TASK_SHADER_NV;
}

return 0;
Expand Down Expand Up @@ -345,6 +351,8 @@ namespace Ogre {
break;
case GPT_FRAGMENT_PROGRAM:
case GPT_COMPUTE_PROGRAM:
case GPT_MESH_PROGRAM:
case GPT_TASK_PROGRAM:
// Fragment and compute shaders do
// not have standard blocks.
break;
Expand Down
13 changes: 13 additions & 0 deletions RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,11 @@ namespace Ogre {
// OGRE_CHECK_GL_ERROR(glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &workgroupInvocations));
}

if (checkExtension("GL_NV_mesh_shader"))
{
rsc->setCapability(RSC_MESH_PROGRAM);
}

if (hasMinGLVersion(4, 1) || checkExtension("GL_ARB_get_program_binary"))
{
GLint formats = 0;
Expand Down Expand Up @@ -1102,6 +1107,14 @@ namespace Ogre {
// OGRE_CHECK_GL_ERROR(glDrawArraysInstanced(GL_PATCHES, 0, primCount, 1));
}
}
else if (mCurrentShader[GPT_MESH_PROGRAM])
{
OgreAssert(op.indexData, "indexData required for mesh shader");

typedef void (APIENTRYP PFNGLDRAWMESHTASKSNVPROC) (GLuint first, GLuint count);
auto glDrawMeshTasksNV = (PFNGLDRAWMESHTASKSNVPROC)mGLSupport->getProcAddress("glDrawMeshTasksNV");
OGRE_CHECK_GL_ERROR(glDrawMeshTasksNV(0, op.indexData->indexCount));
}
else if (op.useIndexes)
{
void *pBufferData = VBO_BUFFER_OFFSET(op.indexData->indexStart *
Expand Down
Loading

0 comments on commit cd8697f

Please sign in to comment.