Skip to content

Commit fc420a6

Browse files
committed
Some simple spirv-opt intergration
1 parent 95a38b6 commit fc420a6

File tree

11 files changed

+162
-22
lines changed

11 files changed

+162
-22
lines changed

include/irr/asset/IAssetManager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "irr/core/Types.h"
1919
#include "irr/asset/IGLSLCompiler.h"
20+
#include "irr/asset/ISPIRVOptimizer.h"
2021

2122
#include "irr/asset/IGeometryCreator.h"/*
2223
#include "irr/asset/IMeshManipulator.h"
@@ -126,6 +127,7 @@ class IAssetManager : public core::IReferenceCounted, public core::QuitSignallin
126127
core::smart_refctd_ptr<IGeometryCreator> m_geometryCreator;
127128
core::smart_refctd_ptr<IMeshManipulator> m_meshManipulator;
128129
core::smart_refctd_ptr<IGLSLCompiler> m_glslCompiler;
130+
core::smart_refctd_ptr<ISPIRVOptimizer> m_spirvOptimizer;
129131
// called as a part of constructor only
130132
void initializeMeshTools();
131133

@@ -151,6 +153,7 @@ class IAssetManager : public core::IReferenceCounted, public core::QuitSignallin
151153
const IGeometryCreator* getGeometryCreator() const;
152154
IMeshManipulator* getMeshManipulator();
153155
IGLSLCompiler* getGLSLCompiler() const { return m_glslCompiler.get(); }
156+
ISPIRVOptimizer* getSPIRVOptimizer() const { return m_spirvOptimizer.get(); }
154157

155158
protected:
156159
virtual ~IAssetManager()

include/irr/asset/IGLSLCompiler.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include "irr/asset/ICPUSpecializedShader.h"
1111
#include "irr/asset/IIncludeHandler.h"
1212

13+
#include "irr/asset/ISPIRVOptimizer.h"
14+
1315
namespace irr
1416
{
1517

@@ -58,9 +60,9 @@ class IGLSLCompiler final : public core::IReferenceCounted
5860
5961
@returns Shader containing SPIR-V bytecode.
6062
*/
61-
core::smart_refctd_ptr<ICPUShader> createSPIRVFromGLSL(const char* _glslCode, ISpecializedShader::E_SHADER_STAGE _stage, const char* _entryPoint, const char* _compilationId, bool _genDebugInfo = true, std::string* _outAssembly = nullptr) const;
63+
core::smart_refctd_ptr<ICPUShader> createSPIRVFromGLSL(const char* _glslCode, ISpecializedShader::E_SHADER_STAGE _stage, const char* _entryPoint, const char* _compilationId, const ISPIRVOptimizer* _opt = nullptr, bool _genDebugInfo = true, std::string* _outAssembly = nullptr) const;
6264

63-
core::smart_refctd_ptr<ICPUShader> createSPIRVFromGLSL(io::IReadFile* _sourcefile, ISpecializedShader::E_SHADER_STAGE _stage, const char* _entryPoint, const char* _compilationId, bool _genDebugInfo = true, std::string* _outAssembly = nullptr) const;
65+
core::smart_refctd_ptr<ICPUShader> createSPIRVFromGLSL(io::IReadFile* _sourcefile, ISpecializedShader::E_SHADER_STAGE _stage, const char* _entryPoint, const char* _compilationId, const ISPIRVOptimizer* _opt = nullptr, bool _genDebugInfo = true, std::string* _outAssembly = nullptr) const;
6466

6567
/**
6668
Resolves ALL #include directives regardless of any other preprocessor directive.

include/irr/asset/ISPIRVOptimizer.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#ifndef __IRR_I_SPIRV_OPTIMIZER_H_INCLUDED__
2+
#define __IRR_I_SPIRV_OPTIMIZER_H_INCLUDED__
3+
4+
#include "irr/core/core.h"
5+
#include "irr/asset/ICPUBuffer.h"
6+
7+
namespace irr
8+
{
9+
10+
namespace asset
11+
{
12+
13+
class ISPIRVOptimizer final : public core::IReferenceCounted
14+
{
15+
public:
16+
core::smart_refctd_ptr<ICPUBuffer> optimize(const uint32_t* _spirv, uint32_t _dwordCount) const;
17+
core::smart_refctd_ptr<ICPUBuffer> optimize(const ICPUBuffer* _spirv) const;
18+
};
19+
20+
}
21+
22+
}
23+
24+
#endif

source/Irrlicht/CIrrDeviceLinux.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ namespace irr
5858
namespace video
5959
{
6060
IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
61-
io::IFileSystem* io, CIrrDeviceLinux* device, const asset::IGLSLCompiler* glslcomp
61+
io::IFileSystem* io, CIrrDeviceLinux* device, const asset::IGLSLCompiler* glslcomp,
62+
const asset::ISPIRVOptimizer* spvopt
6263
#ifdef _IRR_COMPILE_WITH_OPENGL_
6364
,COpenGLDriver::SAuxContext* auxCtxts
6465
#endif // _IRR_COMPILE_WITH_OPENGL_

source/Irrlicht/CIrrDeviceWin32.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ namespace irr
3939
{
4040
#ifdef _IRR_COMPILE_WITH_OPENGL_
4141
IVideoDriver* createOpenGLDriver(const irr::SIrrlichtCreationParameters& params,
42-
io::IFileSystem* io, CIrrDeviceWin32* device, const asset::IGLSLCompiler* glslcomp);
42+
io::IFileSystem* io, CIrrDeviceWin32* device, const asset::IGLSLCompiler* glslcomp, const asset::ISPIRVOptimizer* spvoptimizer);
4343
#endif
4444
}
4545
} // end namespace irr
@@ -1098,7 +1098,7 @@ void CIrrDeviceWin32::createDriver()
10981098
#ifdef _IRR_COMPILE_WITH_OPENGL_
10991099
switchToFullScreen();
11001100

1101-
VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem.get(), this, getAssetManager()->getGLSLCompiler());
1101+
VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem.get(), this, getAssetManager()->getGLSLCompiler(), getAssetManager()->getSPIRVOptimizer());
11021102
if (!VideoDriver)
11031103
{
11041104
os::Printer::log("Could not create OpenGL driver.", ELL_ERROR);

source/Irrlicht/COpenGLDriver.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,11 @@ namespace video
181181
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
182182
//! Windows constructor and init code
183183
COpenGLDriver::COpenGLDriver(const irr::SIrrlichtCreationParameters& params,
184-
io::IFileSystem* io, CIrrDeviceWin32* device, const asset::IGLSLCompiler* glslcomp)
184+
io::IFileSystem* io, CIrrDeviceWin32* device, const asset::IGLSLCompiler* glslcomp, const asset::ISPIRVOptimizer* spvoptimizer)
185185
: CNullDriver(device, io, params), COpenGLExtensionHandler(),
186186
runningInRenderDoc(false), ColorFormat(asset::EF_R8G8B8_UNORM),
187187
HDc(0), Window(static_cast<HWND>(params.WindowId)), Win32Device(device),
188-
AuxContexts(0), GLSLCompiler(glslcomp), DeviceType(EIDT_WIN32)
188+
AuxContexts(0), GLSLCompiler(glslcomp), SPIRVOptimizer(spvoptimizer), DeviceType(EIDT_WIN32)
189189
{
190190
#ifdef _IRR_DEBUG
191191
setDebugName("COpenGLDriver");
@@ -1258,7 +1258,7 @@ core::smart_refctd_ptr<IGPUSpecializedShader> COpenGLDriver::createGPUSpecialize
12581258
const std::string& EP = _specInfo.entryPoint;
12591259
const asset::ISpecializedShader::E_SHADER_STAGE stage = _specInfo.shaderStage;
12601260

1261-
core::smart_refctd_ptr<asset::ICPUShader> spvCPUShader = nullptr;
1261+
core::smart_refctd_ptr<asset::ICPUBuffer> spirv;
12621262
if (glUnspec->containsGLSL())
12631263
{
12641264
auto begin = reinterpret_cast<const char*>(glUnspec->getSPVorGLSL()->getPointer());
@@ -1271,21 +1271,29 @@ core::smart_refctd_ptr<IGPUSpecializedShader> COpenGLDriver::createGPUSpecialize
12711271
// fwrite(reinterpret_cast<const char*>(glslShader_woIncludes->getSPVorGLSL()->getPointer()), 1, glslShader_woIncludes->getSPVorGLSL()->getSize(), fl);
12721272
// fclose(fl);
12731273
//}
1274-
core::smart_refctd_ptr<asset::ICPUBuffer> spvCode = GLSLCompiler->compileSPIRVFromGLSL(
1274+
spirv = GLSLCompiler->compileSPIRVFromGLSL(
12751275
reinterpret_cast<const char*>(glslShader_woIncludes->getSPVorGLSL()->getPointer()),
12761276
stage,
12771277
EP.c_str(),
12781278
_specInfo.m_filePathHint.c_str()
12791279
);
12801280

1281-
if (!spvCode)
1281+
if (!spirv)
12821282
return nullptr;
1283-
1284-
spvCPUShader = core::make_smart_refctd_ptr<asset::ICPUShader>(std::move(spvCode));
12851283
}
12861284
else
1287-
spvCPUShader = core::make_smart_refctd_ptr<asset::ICPUShader>(core::smart_refctd_ptr<asset::ICPUBuffer>(glUnspec->m_code));
1285+
{
1286+
spirv = glUnspec->m_code;
1287+
}
1288+
#ifndef _IRR_DEBUG
1289+
if (SPIRVOptimizer)
1290+
spirv = SPIRVOptimizer->optimize(spirv.get());
1291+
#endif
1292+
if (!spirv)
1293+
return nullptr;
12881294

1295+
core::smart_refctd_ptr<asset::ICPUShader> spvCPUShader = core::make_smart_refctd_ptr<asset::ICPUShader>(std::move(spirv));
1296+
12891297
asset::CShaderIntrospector::SIntrospectionParams introspectionParams{ _specInfo.shaderStage, _specInfo.entryPoint, getSupportedGLSLExtensions(), _specInfo.m_filePathHint};
12901298
asset::CShaderIntrospector introspector(GLSLCompiler.get()); // TODO: shouldn't the introspection be cached for all calls to `createGPUSpecializedShader` (or somehow embedded into the OpenGL pipeline cache?)
12911299
const asset::CIntrospectionData* introspection = introspector.introspect(spvCPUShader.get(), introspectionParams);
@@ -3203,10 +3211,10 @@ namespace video
32033211
// -----------------------------------
32043212
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
32053213
IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
3206-
io::IFileSystem* io, CIrrDeviceWin32* device, const asset::IGLSLCompiler* glslcomp)
3214+
io::IFileSystem* io, CIrrDeviceWin32* device, const asset::IGLSLCompiler* glslcomp, const asset::ISPIRVOptimizer* spvoptimizer)
32073215
{
32083216
#ifdef _IRR_COMPILE_WITH_OPENGL_
3209-
COpenGLDriver* ogl = new COpenGLDriver(params, io, device, glslcomp);
3217+
COpenGLDriver* ogl = new COpenGLDriver(params, io, device, glslcomp, spvoptimizer);
32103218
if (!ogl->initDriver(device))
32113219
{
32123220
ogl->drop();
@@ -3224,14 +3232,15 @@ IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
32243232
// -----------------------------------
32253233
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
32263234
IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
3227-
io::IFileSystem* io, CIrrDeviceLinux* device, const asset::IGLSLCompiler* glslcomp
3235+
io::IFileSystem* io, CIrrDeviceLinux* device, const asset::IGLSLCompiler* glslcomp,
3236+
const asset::ISPIRVOptimizer* spvopt
32283237
#ifdef _IRR_COMPILE_WITH_OPENGL_
32293238
, COpenGLDriver::SAuxContext* auxCtxts
32303239
#endif // _IRR_COMPILE_WITH_OPENGL_
32313240
)
32323241
{
32333242
#ifdef _IRR_COMPILE_WITH_OPENGL_
3234-
COpenGLDriver* ogl = new COpenGLDriver(params, io, device, glslcomp);
3243+
COpenGLDriver* ogl = new COpenGLDriver(params, io, device, glslcomp, spvopt);
32353244
if (!ogl->initDriver(device,auxCtxts))
32363245
{
32373246
ogl->drop();

source/Irrlicht/COpenGLDriver.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ class COpenGLDriver final : public CNullDriver, public COpenGLExtensionHandler
218218
struct SAuxContext;
219219

220220
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
221-
COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceWin32* device, const asset::IGLSLCompiler* glslcomp);
221+
COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceWin32* device, const asset::IGLSLCompiler* glslcomp, const asset::ISPIRVOptimizer* spvoptimizer);
222222
//! inits the windows specific parts of the open gl driver
223223
bool initDriver(CIrrDeviceWin32* device);
224224
bool changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceWin32* device);
@@ -1081,6 +1081,7 @@ class COpenGLDriver final : public CNullDriver, public COpenGLExtensionHandler
10811081
std::mutex glContextMutex;
10821082
SAuxContext* AuxContexts;
10831083
core::smart_refctd_ptr<const asset::IGLSLCompiler> GLSLCompiler;
1084+
core::smart_refctd_ptr<const asset::ISPIRVOptimizer> SPIRVOptimizer;
10841085

10851086
E_DEVICE_TYPE DeviceType;
10861087
};

src/irr/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ set(IRR_ASSET_SOURCES
141141

142142
# Shaders
143143
${IRR_ROOT_PATH}/src/irr/asset/IGLSLCompiler.cpp
144+
${IRR_ROOT_PATH}/src/irr/asset/ISPIRVOptimizer.cpp
144145
${IRR_ROOT_PATH}/src/irr/asset/CShaderIntrospector.cpp
145146
${IRR_ROOT_PATH}/src/irr/asset/CGLSLLoader.cpp
146147
${IRR_ROOT_PATH}/src/irr/asset/CSPVLoader.cpp
@@ -362,6 +363,17 @@ macro(irr_target_link_gli _trgt)
362363
)
363364
target_include_directories(${_trgt} PUBLIC ${THIRD_PARTY_SOURCE_DIR}/gli)
364365
endmacro()
366+
macro(irr_target_link_spirv_tools _trgt)
367+
add_dependencies(${_trgt} SPIRV)
368+
add_dependencies(${_trgt} SPIRV-Tools)
369+
add_dependencies(${_trgt} SPIRV-Tools-opt)
370+
target_link_libraries(${_trgt} INTERFACE
371+
SPIRV SPIRV-Tools SPIRV-Tools-opt
372+
)
373+
target_include_directories(${_trgt} PUBLIC
374+
${THIRD_PARTY_SOURCE_DIR}/SPIRV-Tools/include
375+
)
376+
endmacro()
365377

366378
add_library(Irrlicht STATIC
367379
${IRRLICHT_SRCS_COMMON}
@@ -389,6 +401,7 @@ if(_IRR_COMPILE_WITH_GLI_)
389401
irr_target_link_gli(Irrlicht)
390402
endif()
391403
irr_target_include_parallel_hashmap(Irrlicht)
404+
irr_target_link_spirv_tools(Irrlicht)
392405

393406
target_link_libraries(Irrlicht INTERFACE ${OPENGL_gl_LIBRARY})
394407
if (UNIX)

src/irr/asset/IAssetManager.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ void IAssetManager::initializeMeshTools()
109109
m_meshManipulator = core::make_smart_refctd_ptr<CMeshManipulator>();
110110
m_geometryCreator = core::make_smart_refctd_ptr<CGeometryCreator>(m_meshManipulator.get());
111111
m_glslCompiler = core::make_smart_refctd_ptr<IGLSLCompiler>(m_fileSystem.get());
112+
m_spirvOptimizer = core::make_smart_refctd_ptr<ISPIRVOptimizer>();
112113
}
113114

114115
const IGeometryCreator* IAssetManager::getGeometryCreator() const

src/irr/asset/IGLSLCompiler.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
#include "irr/asset/CGLSLVirtualTexturingBuiltinIncludeLoader.h"
1313

14-
1514
#include "os.h"
1615

1716
namespace irr
@@ -62,19 +61,22 @@ core::smart_refctd_ptr<ICPUBuffer> IGLSLCompiler::compileSPIRVFromGLSL(const cha
6261
return spirv;
6362
}
6463

65-
core::smart_refctd_ptr<ICPUShader> IGLSLCompiler::createSPIRVFromGLSL(const char* _glslCode, ISpecializedShader::E_SHADER_STAGE _stage, const char* _entryPoint, const char* _compilationId, bool _genDebugInfo, std::string* _outAssembly) const
64+
core::smart_refctd_ptr<ICPUShader> IGLSLCompiler::createSPIRVFromGLSL(const char* _glslCode, ISpecializedShader::E_SHADER_STAGE _stage, const char* _entryPoint, const char* _compilationId, const ISPIRVOptimizer* _opt, bool _genDebugInfo, std::string* _outAssembly) const
6665
{
6766
auto spirvBuffer = compileSPIRVFromGLSL(_glslCode,_stage,_entryPoint,_compilationId,_genDebugInfo,_outAssembly);
6867
if (!spirvBuffer)
6968
return nullptr;
69+
if (_opt)
70+
spirvBuffer = _opt->optimize(spirvBuffer.get());
71+
7072
return core::make_smart_refctd_ptr<asset::ICPUShader>(std::move(spirvBuffer));
7173
}
7274

73-
core::smart_refctd_ptr<ICPUShader> IGLSLCompiler::createSPIRVFromGLSL(io::IReadFile* _sourcefile, ISpecializedShader::E_SHADER_STAGE _stage, const char* _entryPoint, const char* _compilationId, bool _genDebugInfo, std::string* _outAssembly) const
75+
core::smart_refctd_ptr<ICPUShader> IGLSLCompiler::createSPIRVFromGLSL(io::IReadFile* _sourcefile, ISpecializedShader::E_SHADER_STAGE _stage, const char* _entryPoint, const char* _compilationId, const ISPIRVOptimizer* _opt, bool _genDebugInfo, std::string* _outAssembly) const
7476
{
7577
std::string glsl(_sourcefile->getSize(), '\0');
7678
_sourcefile->read(glsl.data(), glsl.size());
77-
return createSPIRVFromGLSL(glsl.c_str(), _stage, _entryPoint, _compilationId, _outAssembly);
79+
return createSPIRVFromGLSL(glsl.c_str(), _stage, _entryPoint, _compilationId, _opt, _outAssembly);
7880
}
7981

8082
namespace impl

0 commit comments

Comments
 (0)