Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
glslang
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
glslang
Commits
34cccdc6
Unverified
Commit
34cccdc6
authored
Aug 20, 2019
by
John Kessenich
Committed by
GitHub
Aug 20, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1872 from kainino0x/js-interface
make glslang.js easy to use and work on node, and related changes
parents
3aac2d44
a761284f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
129 additions
and
91 deletions
+129
-91
CMakeLists.txt
CMakeLists.txt
+9
-1
CMakeLists.txt
glslang/CMakeLists.txt
+2
-1
glslang.js.cpp
glslang/glslang.js.cpp
+73
-89
glslang.pre.js
glslang/glslang.pre.js
+45
-0
No files found.
CMakeLists.txt
View file @
34cccdc6
...
@@ -33,6 +33,7 @@ option(ENABLE_NV_EXTENSIONS "Enables support of Nvidia-specific extensions" ON)
...
@@ -33,6 +33,7 @@ option(ENABLE_NV_EXTENSIONS "Enables support of Nvidia-specific extensions" ON)
option
(
ENABLE_GLSLANG_WEB
"Reduces glslang to minumum needed for web use"
OFF
)
option
(
ENABLE_GLSLANG_WEB
"Reduces glslang to minumum needed for web use"
OFF
)
option
(
ENABLE_EMSCRIPTEN_SINGLE_FILE
"If using emscripten, enables SINGLE_FILE build"
OFF
)
option
(
ENABLE_EMSCRIPTEN_SINGLE_FILE
"If using emscripten, enables SINGLE_FILE build"
OFF
)
option
(
ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE
"If using emscripten, builds to run on Node instead of Web"
OFF
)
CMAKE_DEPENDENT_OPTION
(
ENABLE_HLSL
"Enables HLSL input support"
ON
"NOT ENABLE_GLSLANG_WEB"
OFF
)
CMAKE_DEPENDENT_OPTION
(
ENABLE_HLSL
"Enables HLSL input support"
ON
"NOT ENABLE_GLSLANG_WEB"
OFF
)
...
@@ -113,13 +114,20 @@ if(ENABLE_GLSLANG_WEB)
...
@@ -113,13 +114,20 @@ if(ENABLE_GLSLANG_WEB)
add_link_options
(
"SHELL: -s FILESYSTEM=0"
)
add_link_options
(
"SHELL: -s FILESYSTEM=0"
)
add_link_options
(
"SHELL: --llvm-lto 1"
)
add_link_options
(
"SHELL: --llvm-lto 1"
)
add_link_options
(
"SHELL: --closure 1"
)
add_link_options
(
"SHELL: --closure 1"
)
add_link_options
(
"SHELL: -s ENVIRONMENT=web,worker"
)
add_link_options
(
"SHELL: -s ALLOW_MEMORY_GROWTH=1"
)
add_link_options
(
"SHELL: -s ALLOW_MEMORY_GROWTH=1"
)
add_link_options
(
"SHELL: -s MODULARIZE=1"
)
add_link_options
(
"SHELL: -s MODULARIZE=1"
)
if
(
ENABLE_EMSCRIPTEN_SINGLE_FILE
)
if
(
ENABLE_EMSCRIPTEN_SINGLE_FILE
)
add_link_options
(
"SHELL: -s SINGLE_FILE=1"
)
add_link_options
(
"SHELL: -s SINGLE_FILE=1"
)
endif
(
ENABLE_EMSCRIPTEN_SINGLE_FILE
)
endif
(
ENABLE_EMSCRIPTEN_SINGLE_FILE
)
if
(
ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE
)
add_link_options
(
"SHELL: -s ENVIRONMENT=node"
)
add_link_options
(
"SHELL: -s BINARYEN_ASYNC_COMPILATION=0"
)
else
()
add_link_options
(
"SHELL: -s ENVIRONMENT=web,worker"
)
add_link_options
(
"SHELL: -s EXPORT_ES6=1"
)
endif
()
else
()
else
()
if
(
MSVC
)
if
(
MSVC
)
add_compile_options
(
/Os /GR-
)
add_compile_options
(
/Os /GR-
)
...
...
glslang/CMakeLists.txt
View file @
34cccdc6
...
@@ -131,6 +131,7 @@ if(ENABLE_GLSLANG_WEB)
...
@@ -131,6 +131,7 @@ if(ENABLE_GLSLANG_WEB)
set_target_properties
(
glslang.js PROPERTIES
set_target_properties
(
glslang.js PROPERTIES
OUTPUT_NAME
"glslang"
OUTPUT_NAME
"glslang"
SUFFIX
".js"
SUFFIX
".js"
LINK_FLAGS
"--bind"
)
LINK_FLAGS
"--bind -s EXPORT_NAME=
\"
glslangModule
\"
"
)
em_link_pre_js
(
glslang.js
${
CMAKE_CURRENT_SOURCE_DIR
}
/glslang.pre.js
)
endif
(
EMSCRIPTEN
)
endif
(
EMSCRIPTEN
)
endif
(
ENABLE_GLSLANG_WEB
)
endif
(
ENABLE_GLSLANG_WEB
)
glslang/glslang.js.cpp
View file @
34cccdc6
...
@@ -34,6 +34,8 @@
...
@@ -34,6 +34,8 @@
//
//
#include <cstdio>
#include <cstdio>
#include <cstdint>
#ifdef __EMSCRIPTEN__
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#include <emscripten.h>
#endif // __EMSCRIPTEN__
#endif // __EMSCRIPTEN__
...
@@ -43,6 +45,10 @@
...
@@ -43,6 +45,10 @@
#include "../SPIRV/doc.h"
#include "../SPIRV/doc.h"
#include "./../glslang/Public/ShaderLang.h"
#include "./../glslang/Public/ShaderLang.h"
#ifndef EMSCRIPTEN_KEEPALIVE
#define EMSCRIPTEN_KEEPALIVE
#endif
const
TBuiltInResource
DefaultTBuiltInResource
=
{
const
TBuiltInResource
DefaultTBuiltInResource
=
{
/* .MaxLights = */
32
,
/* .MaxLights = */
32
,
/* .MaxClipPlanes = */
6
,
/* .MaxClipPlanes = */
6
,
...
@@ -149,113 +155,95 @@ const TBuiltInResource DefaultTBuiltInResource = {
...
@@ -149,113 +155,95 @@ const TBuiltInResource DefaultTBuiltInResource = {
/* .generalConstantMatrixVectorIndexing = */
1
,
/* .generalConstantMatrixVectorIndexing = */
1
,
}};
}};
static
bool
initialized
=
false
;
extern
"C"
{
/*
/*
* Takes in a GLSL shader as a string and converts it to SPIR-V in binary form.
* Takes in a GLSL shader as a string and converts it to SPIR-V in binary form.
*
*
* |glsl| Char array created using create_input_buffer and populated
* |glsl| Null-terminated string containing the shader to be converted.
* with the shader to be converted.
* |stage_int| Magic number indicating the type of shader being processed.
* This buffer must be destroyed using destroy_input_buffer.
* Legal values are as follows:
* |shader_type| Magic number indicating the type of shader being processed.
* Legal values are as follows:
* Vertex = 0
* Vertex = 0
* Geometry = 3
* Fragment = 4
* Fragment = 4
* |spirv| Pointer to an output buffer that will be updated with the
* Compute = 5
* resulting SPIR-V shader.
* This buffer must be destroyed using destroy_output_buffer.
*
* |spirv_len| Length of the output binary buffer.
* |gen_debug| Flag to indicate if debug information should be generated.
* |gen_debug| Flag to indicate if debug information should be generated.
* |spirv| Output parameter for a pointer to the resulting SPIR-V data.
* |spirv_len| Output parameter for the length of the output binary buffer.
*
*
* Return 0 on success, non-0 on failure.
* Returns a void* pointer which, if not null, must be destroyed by
* destroy_output_buffer.o. (This is not the same pointer returned in |spirv|.)
* If null, the compilation failed.
*/
*/
#ifdef __EMSCRIPTEN__
EMSCRIPTEN_KEEPALIVE
EMSCRIPTEN_KEEPALIVE
#endif // __EMSCRIPTEN__
void
*
convert_glsl_to_spirv
(
const
char
*
glsl
,
int
stage_int
,
bool
gen_debug
,
uint32_t
**
spirv
,
size_t
*
spirv_len
)
int
convert_glsl_to_spirv
(
const
char
*
glsl
,
int
shader_type
,
unsigned
int
**
spirv
,
size_t
*
spirv_len
,
bool
gen_debug
)
{
{
int
ret_val
=
0
;
if
(
glsl
==
nullptr
)
{
if
(
glsl
==
nullptr
||
spirv
==
nullptr
)
{
fprintf
(
stderr
,
"Input pointer null
\n
"
);
return
1
;
return
nullptr
;
}
if
(
spirv
==
nullptr
||
spirv_len
==
nullptr
)
{
fprintf
(
stderr
,
"Output pointer null
\n
"
);
return
nullptr
;
}
}
*
spirv
=
nullptr
;
*
spirv
=
nullptr
;
*
spirv_len
=
0
;
if
(
shader_type
!=
0
&&
shader_type
!=
3
&&
shader_type
!=
4
)
{
if
(
stage_int
!=
0
&&
stage_int
!=
4
&&
stage_int
!=
5
)
{
return
2
;
fprintf
(
stderr
,
"Invalid shader stage
\n
"
);
return
nullptr
;
}
}
EShLanguage
stage
=
static_cast
<
EShLanguage
>
(
stage_int
);
EShLanguage
shader_lang
=
static_cast
<
EShLanguage
>
(
shader_type
);
if
(
!
initialized
)
{
glslang
::
InitializeProcess
();
glslang
::
InitializeProcess
();
initialized
=
true
;
{
}
glslang
::
TShader
shader
(
shader_lang
);
shader
.
setStrings
(
&
glsl
,
1
);
shader
.
setEnvInput
(
glslang
::
EShSourceGlsl
,
shader_lang
,
glslang
::
EShClientOpenGL
,
100
);
shader
.
setEnvClient
(
glslang
::
EShClientVulkan
,
glslang
::
EShTargetVulkan_1_1
);
shader
.
setEnvTarget
(
glslang
::
EShTargetSpv
,
glslang
::
EShTargetSpv_1_3
);
shader
.
parse
(
&
DefaultTBuiltInResource
,
100
,
true
,
EShMsgDefault
);
glslang
::
TProgram
program
;
program
.
addShader
(
&
shader
);
program
.
link
(
EShMsgDefault
);
std
::
vector
<
unsigned
int
>
output
;
std
::
string
warningsErrors
;
glslang
::
SpvOptions
spvOptions
;
spvOptions
.
generateDebugInfo
=
gen_debug
;
spvOptions
.
disableOptimizer
=
false
;
spvOptions
.
optimizeSize
=
false
;
spvOptions
.
disassemble
=
false
;
spvOptions
.
validate
=
false
;
glslang
::
GlslangToSpv
(
*
program
.
getIntermediate
(
EShLangFragment
),
output
,
nullptr
,
&
spvOptions
);
glslang
::
TShader
shader
(
stage
);
shader
.
setStrings
(
&
glsl
,
1
);
shader
.
setEnvInput
(
glslang
::
EShSourceGlsl
,
stage
,
glslang
::
EShClientVulkan
,
100
);
shader
.
setEnvClient
(
glslang
::
EShClientVulkan
,
glslang
::
EShTargetVulkan_1_1
);
shader
.
setEnvTarget
(
glslang
::
EShTargetSpv
,
glslang
::
EShTargetSpv_1_3
);
if
(
!
shader
.
parse
(
&
DefaultTBuiltInResource
,
100
,
true
,
EShMsgDefault
))
{
fprintf
(
stderr
,
"Parse failed
\n
"
);
fprintf
(
stderr
,
"%s
\n
"
,
shader
.
getInfoLog
());
return
nullptr
;
}
*
spirv_len
=
output
.
size
();
glslang
::
TProgram
program
;
*
spirv
=
static_cast
<
unsigned
int
*>
(
malloc
(
*
spirv_len
*
sizeof
(
unsigned
int
)));
program
.
addShader
(
&
shader
);
if
(
*
spirv
!=
nullptr
)
{
if
(
!
program
.
link
(
EShMsgDefault
))
{
memcpy
(
*
spirv
,
output
.
data
(),
*
spirv_len
);
fprintf
(
stderr
,
"Link failed
\n
"
);
}
else
{
fprintf
(
stderr
,
"%s
\n
"
,
program
.
getInfoLog
());
ret_val
=
3
;
return
nullptr
;
}
}
}
glslang
::
FinalizeProcess
();
return
ret_val
;
}
/*
glslang
::
SpvOptions
spvOptions
;
* Created a valid input buffer.
spvOptions
.
generateDebugInfo
=
gen_debug
;
*
spvOptions
.
optimizeSize
=
false
;
* Must be destroyed later using destroy_input_buffer.
spvOptions
.
disassemble
=
false
;
*/
spvOptions
.
validate
=
false
;
#ifdef __EMSCRIPTEN__
EMSCRIPTEN_KEEPALIVE
#endif // __EMSCRIPTEN__
char
*
create_input_buffer
(
int
count
)
{
return
static_cast
<
char
*>
(
malloc
(
count
*
sizeof
(
char
)));
}
/*
std
::
vector
<
uint32_t
>*
output
=
new
std
::
vector
<
uint32_t
>
;
* Destroys a buffer created by create_input_buffer
glslang
::
GlslangToSpv
(
*
program
.
getIntermediate
(
stage
),
*
output
,
nullptr
,
&
spvOptions
);
*/
#ifdef __EMSCRIPTEN__
*
spirv_len
=
output
->
size
();
EMSCRIPTEN_KEEPALIVE
*
spirv
=
output
->
data
();
#endif // __EMSCRIPTEN__
return
output
;
void
destroy_input_buffer
(
char
*
p
)
{
if
(
p
!=
nullptr
)
free
(
p
);
}
}
/*
/*
* Destroys a buffer created by convert_glsl_to_spirv
* Destroys a buffer created by convert_glsl_to_spirv
*/
*/
#ifdef __EMSCRIPTEN__
EMSCRIPTEN_KEEPALIVE
EMSCRIPTEN_KEEPALIVE
#endif // __EMSCRIPTEN__
void
destroy_output_buffer
(
void
*
p
)
void
destroy_ouput_buffer
(
unsigned
int
*
p
)
{
{
if
(
p
!=
nullptr
)
delete
static_cast
<
std
::
vector
<
uint32_t
>*>
(
p
);
free
(
p
);
}
}
}
// extern "C"
/*
/*
* For non-Emscripten builds we supply a generic main, so that the glslang.js
* For non-Emscripten builds we supply a generic main, so that the glslang.js
...
@@ -266,21 +254,17 @@ void destroy_ouput_buffer(unsigned int* p)
...
@@ -266,21 +254,17 @@ void destroy_ouput_buffer(unsigned int* p)
*/
*/
#ifndef __EMSCRIPTEN__
#ifndef __EMSCRIPTEN__
int
main
()
{
int
main
()
{
const
char
*
input
_text
=
R"(#version 310 es
const
char
*
input
=
R"(#version 310 es
void main() { })"
;
void main() { })"
;
char
*
input
;
uint32_t
*
output
;
unsigned
int
*
output
;
size_t
output_len
;
size_t
output_len
;
input
=
create_input_buffer
(
sizeof
(
input_text
));
void
*
id
=
convert_glsl_to_spirv
(
input
,
4
,
false
,
&
output
,
&
output_len
);
assert
(
input
!=
nullptr
);
assert
(
output
!=
nullptr
);
memcpy
(
input
,
input_text
,
sizeof
(
input_text
));
assert
(
output_len
!=
0
);
destroy_output_buffer
(
id
);
convert_glsl_to_spirv
(
input
,
4
,
&
output
,
&
output_len
,
false
);
destroy_ouput_buffer
(
output
);
destroy_input_buffer
(
input
);
return
0
;
return
0
;
}
}
#endif //
!
__EMSCRIPTEN__
#endif //
ifndef
__EMSCRIPTEN__
glslang/glslang.pre.js
0 → 100644
View file @
34cccdc6
Module
[
'compileGLSLZeroCopy'
]
=
function
(
glsl
,
shader_stage
,
gen_debug
)
{
gen_debug
=
!!
gen_debug
;
var
shader_stage_int
;
if
(
shader_stage
===
'vertex'
)
{
shader_stage_int
=
0
;
}
else
if
(
shader_stage
===
'fragment'
)
{
shader_stage_int
=
4
;
}
else
if
(
shader_stage
===
'compute'
)
{
shader_stage_int
=
5
;
}
else
{
throw
new
Error
(
"shader_stage must be 'vertex', 'fragment', or 'compute'"
);
}
var
p_output
=
Module
[
'_malloc'
](
4
);
var
p_output_len
=
Module
[
'_malloc'
](
4
);
var
id
=
ccall
(
'convert_glsl_to_spirv'
,
'number'
,
[
'string'
,
'number'
,
'boolean'
,
'number'
,
'number'
],
[
glsl
,
shader_stage_int
,
gen_debug
,
p_output
,
p_output_len
]);
var
output
=
getValue
(
p_output
,
'i32'
);
var
output_len
=
getValue
(
p_output_len
,
'i32'
);
Module
[
'_free'
](
p_output
);
Module
[
'_free'
](
p_output_len
);
if
(
id
===
0
)
{
throw
new
Error
(
'GLSL compilation failed'
);
}
var
ret
=
{};
var
outputIndexU32
=
output
/
4
;
ret
.
data
=
Module
[
'HEAPU32'
].
subarray
(
outputIndexU32
,
outputIndexU32
+
output_len
);
ret
.
free
=
function
()
{
Module
[
'_destroy_output_buffer'
](
id
);
};
return
ret
;
};
Module
[
'compileGLSL'
]
=
function
(
glsl
,
shader_stage
,
gen_debug
)
{
var
compiled
=
Module
[
'compileGLSLZeroCopy'
](
glsl
,
shader_stage
,
gen_debug
);
var
ret
=
compiled
.
data
.
slice
()
compiled
.
free
();
return
ret
;
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment