Skip to content

Commit 266921f

Browse files
committed
Version 3.4.0
1 parent da1974a commit 266921f

File tree

5 files changed

+256
-174
lines changed

5 files changed

+256
-174
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ It uses [glslang](https://github.com/KhronosGroup/glslang) for parsing GLSL and
99

1010
## ChangeLog
1111

12+
### 3.4.0
13+
14+
- Add support for compiling to multi shader targets with option `--cross-args`
15+
1216
### 3.3.1
1317

1418
- Use debian-11 do build linux executable (self-hosted runner)

src/axslc-spec.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// The Axmol Shader Compiler spec, define macros and structs
2-
// match with axslcc-3.2.0+
2+
// match with axslcc-3.4.0+
33

44
#pragma once
55

@@ -42,6 +42,15 @@ enum Dim : uint16_t
4242
DimSubpassData = 6
4343
};
4444

45+
enum ShaderLang {
46+
SHADER_LANG_ESSL = 0,
47+
SHADER_LANG_HLSL,
48+
SHADER_LANG_MSL,
49+
SHADER_LANG_GLSL,
50+
SHADER_LANG_SPIRV,
51+
SHADER_LANG_COUNT
52+
};
53+
4554
enum SCType : uint16_t
4655
{
4756
// Float
@@ -73,8 +82,14 @@ struct sc_chunk
7382
{
7483
uint16_t major; // SC_VERSION_MAJOR
7584
uint16_t minor; // SC_VERSION_MINOR
76-
uint32_t lang; // shader lang
77-
uint32_t profile_ver; // target profile version
85+
uint16_t num_targets;
86+
uint16_t reserved;
87+
};
88+
89+
struct sc_target_entry {
90+
uint32_t lang; // SC_LANG_GLES / HLSL / MSL / SPIRV ...
91+
uint32_t profile_ver;
92+
uint32_t offset;
7893
};
7994

8095
// REFL

src/axslc-writer.cpp

Lines changed: 69 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@
1414

1515
namespace axslc {
1616

17-
struct sc_stage {
17+
struct sc_target {
18+
uint32_t lang;
19+
uint32_t profile_ver;
20+
uint32_t offset;
21+
1822
uint32_t stage;
23+
1924
union {
2025
char* code;
2126
void* data;
@@ -35,48 +40,46 @@ struct sc_file
3540
std::string filepath = {};
3641
uint16_t major_ver = 0;
3742
uint16_t minor_ver = 0;
38-
uint32_t lang = 0;
39-
uint16_t profile_ver = 0;
40-
sc_stage* stages = nullptr;
43+
sc_target* targets = nullptr;
4144
};
4245

43-
sc_file* sc_create_file(const sx_alloc* alloc, const char* filepath, uint16_t major_ver, uint16_t min_ver, uint32_t lang, uint32_t profile_ver)
46+
sc_file* sc_create_file(const sx_alloc* alloc, const char* filepath, uint16_t major_ver, uint16_t min_ver)
4447
{
4548
sc_file* sc = new (sx_malloc(alloc, sizeof(sc_file))) sc_file;
4649
sc->alloc = alloc;
4750
sc->filepath = filepath;
4851

4952
sc->major_ver = major_ver;
5053
sc->minor_ver = min_ver;
51-
sc->lang = lang;
52-
sc->profile_ver = profile_ver;
5354

5455
return sc;
5556
}
5657

5758
void sc_destroy_file(sc_file* f)
5859
{
5960
sx_assert(f);
60-
sx_array_free(f->alloc, f->stages);
61+
sx_array_free(f->alloc, f->targets);
6162
f->~sc_file();
6263
sx_free(f->alloc, f);
6364
}
6465

65-
void sc_add_stage_code(sc_file* f, uint32_t stage, const char* code)
66+
void sc_add_stage_code(sc_file* f, uint32_t stage, const char* code, int lang, int profile_ver)
6667
{
67-
sc_stage* s = nullptr;
68+
sc_target* s = nullptr;
6869
// search in stages and see if find it
69-
for (int i = 0; i < sx_array_count(f->stages); i++) {
70-
if (f->stages[i].stage == stage) {
71-
s = &f->stages[i];
70+
for (int i = 0; i < sx_array_count(f->targets); i++) {
71+
if (f->targets[i].lang == lang && f->targets[i].profile_ver == profile_ver) {
72+
s = &f->targets[i];
7273
break;
7374
}
7475
}
7576

7677
if (!s) {
77-
s = sx_array_add(f->alloc, f->stages, 1);
78-
sx_memset(s, 0x0, sizeof(sc_stage));
78+
s = sx_array_add(f->alloc, f->targets, 1);
79+
sx_memset(s, 0x0, sizeof(sc_target));
7980
s->stage = stage;
81+
s->lang = lang;
82+
s->profile_ver = profile_ver;
8083
}
8184

8285
int len = sx_strlen(code) + 1;
@@ -88,23 +91,25 @@ void sc_add_stage_code(sc_file* f, uint32_t stage, const char* code)
8891
sx_memcpy(s->code, code, len);
8992
}
9093

91-
void sc_add_stage_code_bin(sc_file* f, uint32_t stage, const void* bytecode, int len)
94+
void sc_add_stage_code_bin(sc_file* f, uint32_t stage, const void* bytecode, int len, int lang, int profile_ver)
9295
{
9396
sx_assert(len > 0);
9497

95-
sc_stage* s = nullptr;
98+
sc_target* s = nullptr;
9699
// search in stages and see if find it
97-
for (int i = 0; i < sx_array_count(f->stages); i++) {
98-
if (f->stages[i].stage == (int)stage) {
99-
s = &f->stages[i];
100+
for (int i = 0; i < sx_array_count(f->targets); i++) {
101+
if (f->targets[i].lang == (int)lang && f->targets[i].profile_ver == profile_ver) {
102+
s = &f->targets[i];
100103
break;
101104
}
102105
}
103106

104107
if (!s) {
105-
s = sx_array_add(f->alloc, f->stages, 1);
106-
sx_memset(s, 0x0, sizeof(sc_stage));
108+
s = sx_array_add(f->alloc, f->targets, 1);
109+
sx_memset(s, 0x0, sizeof(sc_target));
107110
s->stage = stage;
111+
s->lang = lang;
112+
s->profile_ver = profile_ver;
108113
}
109114

110115
sx_assert(s->data == nullptr);
@@ -115,21 +120,23 @@ void sc_add_stage_code_bin(sc_file* f, uint32_t stage, const void* bytecode, int
115120
s->data_size = len;
116121
}
117122

118-
void sc_add_stage_reflect(sc_file* f, uint32_t stage, const void* reflect, int refl_size)
123+
void sc_add_stage_reflect(sc_file* f, uint32_t stage, const void* reflect, int refl_size, int lang, int profile_ver)
119124
{
120-
sc_stage* s = nullptr;
121-
// search in stages and see if find it
122-
for (int i = 0; i < sx_array_count(f->stages); i++) {
123-
if (f->stages[i].stage == (int)stage) {
124-
s = &f->stages[i];
125+
sc_target* s = nullptr;
126+
// search in targets and see if find it
127+
for (int i = 0; i < sx_array_count(f->targets); i++) {
128+
if (f->targets[i].lang == (int)lang && f->targets[i].profile_ver == profile_ver) {
129+
s = &f->targets[i];
125130
break;
126131
}
127132
}
128133

129134
if (!s) {
130-
s = sx_array_add(f->alloc, f->stages, 1);
131-
sx_memset(s, 0x0, sizeof(sc_stage));
135+
s = sx_array_add(f->alloc, f->targets, 1);
136+
sx_memset(s, 0x0, sizeof(sc_target));
132137
s->stage = stage;
138+
s->lang = lang;
139+
s->profile_ver = profile_ver;
133140
}
134141

135142
sx_assert(s->refl == nullptr);
@@ -154,56 +161,69 @@ bool sc_commit(sc_file* f)
154161
const uint32_t sc_size_offset = sizeof(sc_magic);
155162
sc_size += sx_file_write_var(&writer, sc_size);
156163

157-
sc_chunk sc_header;
164+
sc_chunk sc_header{};
158165
sc_header.major = f->major_ver;
159166
sc_header.minor = f->minor_ver;
160-
sc_header.lang = f->lang;
161-
sc_header.profile_ver = f->profile_ver;
167+
sc_header.num_targets = sx_array_count(f->targets);
162168
sc_size += sx_file_write_var(&writer, sc_header);
163169

170+
const uint32_t indices_offset = sc_size;
171+
172+
// placehold
173+
for (int i = 0; i < sc_header.num_targets; i++) {
174+
sc_target_entry dummy{};
175+
sc_size += sx_file_write_var(&writer, dummy);
176+
}
177+
164178
// write stages
165-
for (int i = 0; i < sx_array_count(f->stages); i++) {
166-
const sc_stage* s = &f->stages[i];
179+
for (int i = 0; i < sc_header.num_targets; i++) {
180+
sc_target* t = &f->targets[i];
181+
182+
t->offset = sc_size; // record target STAG offset
167183

168-
const uint32_t code_size = (s->data_size == 0 ? (sx_strlen(s->code)+1) : 0);
169-
const uint32_t data_size = s->data_size;
184+
const uint32_t code_size = (t->data_size == 0 ? (sx_strlen(t->code)+1) : 0);
185+
const uint32_t data_size = t->data_size;
170186
sx_assert(code_size || data_size);
171187

172-
const uint32_t stage_size =
173-
(s->refl ? (8 + s->refl_size) : 0) +
174-
(8 + code_size + data_size) +
175-
sizeof(uint32_t);
188+
const uint32_t stage_size = (t->refl ? (8 + t->refl_size) : 0) + (8 + code_size + data_size) + sizeof(uint32_t) /* stage */;
176189

177190
// `STAG`
178191
const uint32_t _stage = SC_CHUNK_STAG;
179192
sc_size += sx_file_write_var(&writer, _stage);
180193
sc_size += sx_file_write_var(&writer, stage_size);
181-
sc_size += sx_file_write_var(&writer, s->stage);
194+
sc_size += sx_file_write_var(&writer, t->stage);
182195

183196
if (code_size) {
184197
// `CODE`
185198
const uint32_t _code = SC_CHUNK_CODE;
186-
const uint32_t code_size = sx_strlen(s->code) + 1;
199+
const uint32_t code_size = sx_strlen(t->code) + 1;
187200
sc_size += sx_file_write_var(&writer, _code);
188201
sc_size += sx_file_write_var(&writer, code_size);
189-
sc_size += sx_file_write(&writer, s->code, code_size);
202+
sc_size += sx_file_write(&writer, t->code, code_size);
190203
} else if (data_size) {
191204
// `DATA`
192205
const uint32_t _data = SC_CHUNK_DATA;
193206
sc_size += sx_file_write_var(&writer, _data);
194-
sc_size += sx_file_write_var(&writer, s->data_size);
195-
sc_size += sx_file_write(&writer, s->data, s->data_size);
207+
sc_size += sx_file_write_var(&writer, t->data_size);
208+
sc_size += sx_file_write(&writer, t->data, t->data_size);
196209
}
197210

198211
// `REFL`
199-
if (s->refl) {
212+
if (t->refl) {
200213
const uint32_t _refl = SC_CHUNK_REFL;
201214
sc_size += sx_file_write_var(&writer, _refl);
202-
sc_size += sx_file_write_var(&writer, s->refl_size);
203-
sc_size += sx_file_write(&writer, s->refl, s->refl_size);
215+
sc_size += sx_file_write_var(&writer, t->refl_size);
216+
sc_size += sx_file_write(&writer, t->refl, t->refl_size);
204217
}
205218
}
206219

220+
sx_file_seekw(&writer, indices_offset, SX_WHENCE_BEGIN);
221+
for (int i = 0; i < sc_header.num_targets; i++) {
222+
const sc_target* t = &f->targets[i];
223+
sc_target_entry entry_info { .lang = t->lang, .profile_ver = t->profile_ver, .offset = t->offset };
224+
sx_file_write_var(&writer, entry_info); // write base info first
225+
}
226+
207227
// finish sc size
208228
sx_file_seekw(&writer, sc_size_offset, SX_WHENCE_BEGIN);
209229
sx_file_write_var(&writer, sc_size);

src/axslc-writer.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ namespace axslc {
2222

2323
struct sc_file;
2424

25-
sc_file* sc_create_file(const sx_alloc* alloc, const char* filepath, uint16_t major_ver, uint16_t min_ver, uint32_t lang, uint32_t profile_ver);
25+
sc_file* sc_create_file(const sx_alloc* alloc, const char* filepath, uint16_t major_ver, uint16_t min_ver);
2626
void sc_destroy_file(sc_file* f);
27-
void sc_add_stage_code(sc_file* f, uint32_t stage, const char* code);
28-
void sc_add_stage_code_bin(sc_file* f, uint32_t stage, const void* bytecode, int len);
29-
void sc_add_stage_reflect(sc_file* f, uint32_t stage, const void* reflect, int reflect_size);
27+
void sc_add_stage_code(sc_file* f, uint32_t stage, const char* code, int lang, int profile_ver);
28+
void sc_add_stage_code_bin(sc_file* f, uint32_t stage, const void* bytecode, int len, int lang, int profile_ver);
29+
void sc_add_stage_reflect(sc_file* f, uint32_t stage, const void* reflect, int reflect_size, int lang, int profile_ver);
3030
bool sc_commit(sc_file* f);
3131

3232
}

0 commit comments

Comments
 (0)