Skip to content

Commit 87fb92e

Browse files
committed
Shader reflection, store info inside compiled mshdr files
1 parent 8e94cd9 commit 87fb92e

File tree

9 files changed

+314
-39
lines changed

9 files changed

+314
-39
lines changed
Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,40 @@
1-
namespace Mocha.Common;
1+
using Mocha.Glue;
2+
using System.Runtime.InteropServices;
3+
4+
namespace Mocha.Common;
5+
6+
public enum ShaderReflectionType
7+
{
8+
Unknown,
9+
10+
Buffer,
11+
Texture,
12+
Sampler
13+
}
14+
15+
[StructLayout( LayoutKind.Sequential )]
16+
public struct ShaderReflectionBinding
17+
{
18+
public int Set { get; set; }
19+
public int Binding { get; set; }
20+
public ShaderReflectionType Type { get; set; }
21+
public string Name { get; set; }
22+
}
23+
24+
public struct ShaderReflectionInfo
25+
{
26+
public UtilArray Bindings { get; set; }
27+
}
28+
29+
public struct ShaderStageInfo
30+
{
31+
public int[] Data { get; set; }
32+
public ShaderReflectionInfo Reflection { get; set; }
33+
}
234

335
public struct ShaderInfo
436
{
5-
public int[] VertexShaderData { get; set; }
6-
public int[] FragmentShaderData { get; set; }
7-
public int[] ComputeShaderData { get; set; }
37+
public ShaderStageInfo Vertex { get; set; }
38+
public ShaderStageInfo Fragment { get; set; }
39+
public ShaderStageInfo Compute { get; set; }
840
}

Source/Mocha.Engine/Render/Assets/Material.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ public Material( string path )
6565

6666
NativeMaterial = new(
6767
Path,
68-
shaderFormat.Data.VertexShaderData.ToInterop(),
69-
shaderFormat.Data.FragmentShaderData.ToInterop(),
68+
shaderFormat.Data.Vertex.Data.ToInterop(),
69+
shaderFormat.Data.Fragment.Data.ToInterop(),
7070
Vertex.VertexAttributes.ToInterop(),
7171
textures.ToInterop(),
7272
SamplerType.Point,
@@ -85,8 +85,8 @@ public Material( string path )
8585
var shaderFormat = Serializer.Deserialize<MochaFile<ShaderInfo>>( shaderFileBytes );
8686

8787
NativeMaterial.SetShaderData(
88-
shaderFormat.Data.VertexShaderData.ToInterop(),
89-
shaderFormat.Data.FragmentShaderData.ToInterop()
88+
shaderFormat.Data.Vertex.Data.ToInterop(),
89+
shaderFormat.Data.Fragment.Data.ToInterop()
9090
);
9191

9292
NativeMaterial.Reload();
@@ -122,8 +122,8 @@ public Material( string shaderPath, VertexAttribute[] vertexAttributes, Texture?
122122

123123
NativeMaterial = new(
124124
Path,
125-
shaderFormat.Data.VertexShaderData.ToInterop(),
126-
shaderFormat.Data.FragmentShaderData.ToInterop(),
125+
shaderFormat.Data.Vertex.Data.ToInterop(),
126+
shaderFormat.Data.Fragment.Data.ToInterop(),
127127
vertexAttributes.ToInterop(),
128128
textures.ToInterop(),
129129
sampler,
@@ -144,8 +144,8 @@ public static Material FromShader( string shaderPath, VertexAttribute[] vertexAt
144144

145145
material.NativeMaterial = new(
146146
material.Path,
147-
shaderFormat.Data.VertexShaderData.ToInterop(),
148-
shaderFormat.Data.FragmentShaderData.ToInterop(),
147+
shaderFormat.Data.Vertex.Data.ToInterop(),
148+
shaderFormat.Data.Fragment.Data.ToInterop(),
149149
vertexAttributes.ToInterop()
150150
);
151151

Source/Mocha.Host/Rendering/Platform/Vulkan/vulkanrendercontext.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,23 +1162,27 @@ void VulkanRenderContext::CreateFullScreenTri()
11621162

11631163
// Vertex
11641164
{
1165-
if ( !ShaderCompiler::Instance().Compile( SHADER_TYPE_VERTEX, g_fullScreenTriVertexShader.c_str(), vertexShaderBits ) )
1165+
ShaderCompilerResult result;
1166+
if ( !ShaderCompiler::Instance().Compile( SHADER_TYPE_VERTEX, g_fullScreenTriVertexShader.c_str(), result ) )
11661167
{
11671168
ErrorMessage( "Fullscreen triangle vertex shader failed to compile." );
11681169
abort();
11691170
}
1171+
vertexShaderBits = result.ShaderData.GetData<unsigned int>();
11701172

11711173
pipelineInfo.shaderInfo.vertexShaderData = vertexShaderBits;
11721174
}
11731175

11741176
// Fragment
11751177
{
1178+
ShaderCompilerResult result;
11761179
if ( !ShaderCompiler::Instance().Compile(
1177-
SHADER_TYPE_FRAGMENT, g_fullScreenTriFragmentShader.c_str(), fragmentShaderBits ) )
1180+
SHADER_TYPE_FRAGMENT, g_fullScreenTriFragmentShader.c_str(), result ) )
11781181
{
11791182
ErrorMessage( "Fullscreen triangle fragment shader failed to compile." );
11801183
abort();
11811184
}
1185+
fragmentShaderBits = result.ShaderData.GetData<unsigned int>();
11821186

11831187
pipelineInfo.shaderInfo.fragmentShaderData = fragmentShaderBits;
11841188
}

Source/Mocha.Host/Rendering/baserendercontext.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ struct PipelineInfo_t
188188
bool renderToSwapchain = false;
189189
};
190190

191+
// todo: remove me
191192
struct RenderPushConstants
192193
{
193194
glm::vec4 data = glm::vec4{ 1.0f };
@@ -202,6 +203,15 @@ struct RenderPushConstants
202203
glm::vec4 vLightInfoWS[4] = {};
203204
};
204205

206+
// These need to be aligned
207+
struct ViewConstants
208+
{
209+
glm::mat4 render_matrix = {}; // view/projection
210+
glm::vec4 vCameraPosWS = {}; // camera pos
211+
glm::vec4 vLightInfoWS[4] = {}; // light data
212+
glm::vec4 data = {}; // misc data
213+
};
214+
205215
struct GPUInfo
206216
{
207217
const char* gpuName = "Unnamed";

Source/Mocha.Host/Rendering/rendermanager.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,16 @@ void RenderManager::Shutdown()
121121

122122
void SceneMeshPass::Execute()
123123
{
124-
for ( auto& sceneMesh : m_meshes )
124+
// Make a copy here so that nothing can affect what we draw while we're drawing it
125+
std::vector<std::shared_ptr<SceneMesh>> meshes = std::vector<std::shared_ptr<SceneMesh>>( m_meshes );
126+
127+
/*std::vector<glm::mat4> objectMatrices = {};
128+
for ( auto& sceneMesh : meshes )
129+
{
130+
objectMatrices.push_back( sceneMesh->m_transform.GetModelMatrix() );
131+
}*/
132+
133+
for ( auto& sceneMesh : meshes )
125134
{
126135
bool materialWasDirty = false;
127136

@@ -193,6 +202,7 @@ void SceneMeshPass::AddMesh( std::shared_ptr<SceneMesh> sceneMesh )
193202
m_meshes.push_back( sceneMesh );
194203
}
195204

205+
// todo: remove
196206
void SceneMeshPass::SetConstants( RenderPushConstants constants )
197207
{
198208
m_constants = constants;

Source/Mocha.Host/Rendering/shadercompiler.cpp

Lines changed: 160 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,123 @@
11
#include "shadercompiler.h"
22

33
#include "baserendercontext.h"
4-
#include <vector>
54
#include "spdlog/spdlog.h"
65

6+
#include <vector>
7+
78
using namespace slang;
89

910
ShaderCompiler::ShaderCompiler()
1011
{
1112
createGlobalSession( m_globalSession.writeRef() );
1213
}
1314

14-
ShaderCompiler::~ShaderCompiler() { }
15+
ShaderCompiler::~ShaderCompiler()
16+
{
17+
}
18+
19+
const char* KindToString( slang::TypeReflection::Kind kind )
20+
{
21+
switch ( kind )
22+
{
23+
case slang::TypeReflection::Kind::None:
24+
return "None";
25+
case slang::TypeReflection::Kind::Struct:
26+
return "Struct";
27+
case slang::TypeReflection::Kind::Array:
28+
return "Array";
29+
case slang::TypeReflection::Kind::Matrix:
30+
return "Matrix";
31+
case slang::TypeReflection::Kind::Vector:
32+
return "Vector";
33+
case slang::TypeReflection::Kind::Scalar:
34+
return "Scalar";
35+
case slang::TypeReflection::Kind::ConstantBuffer:
36+
return "ConstantBuffer";
37+
case slang::TypeReflection::Kind::Resource:
38+
return "Resource";
39+
case slang::TypeReflection::Kind::SamplerState:
40+
return "SamplerState";
41+
case slang::TypeReflection::Kind::TextureBuffer:
42+
return "TextureBuffer";
43+
case slang::TypeReflection::Kind::ShaderStorageBuffer:
44+
return "ShaderStorageBuffer";
45+
case slang::TypeReflection::Kind::ParameterBlock:
46+
return "ParameterBlock";
47+
case slang::TypeReflection::Kind::GenericTypeParameter:
48+
return "GenericTypeParameter";
49+
case slang::TypeReflection::Kind::Interface:
50+
return "Interface";
51+
case slang::TypeReflection::Kind::OutputStream:
52+
return "OutputStream";
53+
case slang::TypeReflection::Kind::Specialized:
54+
return "Specialized";
55+
case slang::TypeReflection::Kind::Feedback:
56+
return "Feedback";
57+
case slang::TypeReflection::Kind::Pointer:
58+
return "Pointer";
59+
case slang::TypeReflection::Kind::DynamicResource:
60+
return "DynamicResource";
61+
default:
62+
return "Unknown";
63+
}
64+
}
65+
66+
const char* BindingTypeToString( slang::BindingType type )
67+
{
68+
switch ( type )
69+
{
70+
case slang::BindingType::Unknown:
71+
return "Unknown";
72+
case slang::BindingType::Sampler:
73+
return "Sampler";
74+
case slang::BindingType::Texture:
75+
return "Texture";
76+
case slang::BindingType::ConstantBuffer:
77+
return "ConstantBuffer";
78+
case slang::BindingType::ParameterBlock:
79+
return "ParameterBlock";
80+
case slang::BindingType::TypedBuffer:
81+
return "TypedBuffer";
82+
case slang::BindingType::RawBuffer:
83+
return "RawBuffer";
84+
case slang::BindingType::CombinedTextureSampler:
85+
return "CombinedTextureSampler";
86+
case slang::BindingType::InputRenderTarget:
87+
return "InputRenderTarget";
88+
case slang::BindingType::InlineUniformData:
89+
return "InlineUniformData";
90+
case slang::BindingType::RayTracingAccelerationStructure:
91+
return "RayTracingAccelerationStructure";
92+
case slang::BindingType::VaryingInput:
93+
return "VaryingInput";
94+
case slang::BindingType::VaryingOutput:
95+
return "VaryingOutput";
96+
case slang::BindingType::ExistentialValue:
97+
return "ExistentialValue";
98+
case slang::BindingType::PushConstant:
99+
return "PushConstant";
100+
case slang::BindingType::MutableFlag:
101+
return "MutableFlag";
102+
case slang::BindingType::MutableTexture:
103+
return "MutableTexture";
104+
case slang::BindingType::MutableTypedBuffer:
105+
return "MutableTypedBuffer";
106+
case slang::BindingType::MutableRawBuffer:
107+
return "MutableRawBuffer";
108+
case slang::BindingType::BaseMask:
109+
return "BaseMask";
110+
case slang::BindingType::ExtMask:
111+
return "ExtMask";
112+
default:
113+
return "Unknown";
114+
}
115+
}
15116

16-
bool ShaderCompiler::Compile( const ShaderType shaderType, const char* pShader, std::vector<uint32_t>& outSpirv )
117+
bool ShaderCompiler::Compile( const ShaderType shaderType, const char* pShader, ShaderCompilerResult& outResult )
17118
{
119+
outResult = ShaderCompilerResult();
120+
18121
Slang::ComPtr<ISession> session;
19122

20123
TargetDesc targetDesc{};
@@ -34,8 +137,7 @@ bool ShaderCompiler::Compile( const ShaderType shaderType, const char* pShader,
34137
m_globalSession->createSession( sessionDesc, session.writeRef() );
35138

36139
Slang::ComPtr<IBlob> diagnostics;
37-
IModule* module =
38-
session->loadModuleFromSourceString( "Shader", "Shader.slang", pShader, diagnostics.writeRef() );
140+
IModule* module = session->loadModuleFromSourceString( "Shader", "Shader.slang", pShader, diagnostics.writeRef() );
39141

40142
if ( diagnostics )
41143
spdlog::error( "Shader compiler: {}", ( const char* )diagnostics->getBufferPointer() );
@@ -68,6 +170,58 @@ bool ShaderCompiler::Compile( const ShaderType shaderType, const char* pShader,
68170

69171
const uint32_t* data = static_cast<const uint32_t*>( kernelBlob->getBufferPointer() );
70172
size_t wordCount = kernelBlob->getBufferSize() / sizeof( uint32_t );
71-
outSpirv = std::vector<uint32_t>( data, data + wordCount );
173+
174+
outResult.ShaderData = UtilArray::FromVector( std::vector<uint32_t>( data, data + wordCount ) );
175+
176+
std::vector<ShaderReflectionBinding> reflectionBindings = {};
177+
ShaderReflectionInfo shaderReflectionInfo = {};
178+
179+
{
180+
slang::ProgramLayout* layout = program->getLayout( targetIndex );
181+
auto globalScope = layout->getGlobalParamsVarLayout();
182+
auto globalTypeLayout = globalScope->getTypeLayout();
183+
184+
int paramCount = globalTypeLayout->getFieldCount();
185+
for ( int i = 0; i < paramCount; i++ )
186+
{
187+
auto param = globalTypeLayout->getFieldByIndex( i );
188+
auto type = globalTypeLayout->getBindingRangeType( i );
189+
190+
// get binding info
191+
size_t binding = param->getOffset( SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT );
192+
size_t set = param->getBindingSpace( SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT );
193+
194+
SlangResourceShape shape = param->getType()->getResourceShape();
195+
196+
// get param name/type
197+
const char* name = param->getName();
198+
slang::TypeReflection::Kind kind = param->getType()->getKind();
199+
200+
spdlog::info( "[{}, {}] {} {}, {}", binding, set, KindToString( kind ), name, BindingTypeToString( type ) );
201+
202+
auto mochaReflectionType = SHADER_REFLECTION_TYPE_UNKNOWN;
203+
switch ( type )
204+
{
205+
case slang::BindingType::Unknown:
206+
mochaReflectionType = SHADER_REFLECTION_TYPE_UNKNOWN;
207+
break;
208+
case slang::BindingType::Texture:
209+
mochaReflectionType = SHADER_REFLECTION_TYPE_TEXTURE;
210+
break;
211+
case slang::BindingType::Sampler:
212+
mochaReflectionType = SHADER_REFLECTION_TYPE_SAMPLER;
213+
break;
214+
case slang::BindingType::ConstantBuffer:
215+
mochaReflectionType = SHADER_REFLECTION_TYPE_BUFFER;
216+
break;
217+
}
218+
219+
reflectionBindings.push_back( ShaderReflectionBinding{
220+
.Set = ( int )set, .Binding = ( int )binding, .Type = mochaReflectionType, .Name = name } );
221+
}
222+
}
223+
224+
outResult.ReflectionData = ShaderReflectionInfo { .Bindings = UtilArray::FromVector( reflectionBindings ) };
225+
72226
return true;
73227
}

0 commit comments

Comments
 (0)