Skip to content

Latest commit

 

History

History
858 lines (728 loc) · 25.3 KB

mojoshader_vulkan.c

File metadata and controls

858 lines (728 loc) · 25.3 KB
 
Jul 1, 2020
Jul 1, 2020
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* MojoShader; generate shader programs from bytecode of compiled
* Direct3D shaders.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
#define __MOJOSHADER_INTERNAL__ 1
#include "mojoshader_internal.h"
#if SUPPORT_PROFILE_SPIRV
Mar 10, 2022
Mar 10, 2022
15
#define VK_NO_PROTOTYPES
Jul 2, 2020
Jul 2, 2020
16
#include "vulkan/vulkan.h"
Jul 1, 2020
Jul 1, 2020
17
Jul 6, 2020
Jul 6, 2020
18
#define UBO_BUFFER_SIZE 8000000 // 8MB
Oct 1, 2020
Oct 1, 2020
19
#define UBO_ACTUAL_SIZE (UBO_BUFFER_SIZE * 2) // Double so we can "rotate" the buffer and unblock main thread
Jul 1, 2020
Jul 1, 2020
20
21
22
23
24
25
// Internal struct defs...
typedef struct MOJOSHADER_vkShader
{
const MOJOSHADER_parseData *parseData;
Jul 7, 2020
Jul 7, 2020
26
uint16_t tag;
Jul 1, 2020
Jul 1, 2020
27
28
29
uint32_t refcount;
} MOJOSHADER_vkShader;
Jul 7, 2020
Jul 7, 2020
30
31
32
33
34
35
36
37
typedef struct MOJOSHADER_vkProgram
{
VkShaderModule vertexModule;
VkShaderModule pixelModule;
MOJOSHADER_vkShader *vertexShader;
MOJOSHADER_vkShader *pixelShader;
} MOJOSHADER_vkProgram;
Jul 1, 2020
Jul 1, 2020
38
39
40
typedef struct MOJOSHADER_vkUniformBuffer
{
VkBuffer buffer;
Jul 6, 2020
Jul 6, 2020
41
VkDeviceMemory deviceMemory;
Jul 1, 2020
Jul 1, 2020
42
43
44
VkDeviceSize bufferSize;
VkDeviceSize dynamicOffset;
VkDeviceSize currentBlockSize;
Oct 22, 2020
Oct 22, 2020
45
VkDeviceSize currentBlockIncrement;
Jul 6, 2020
Jul 6, 2020
46
uint8_t *mapPointer;
Jul 1, 2020
Jul 1, 2020
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
} MOJOSHADER_vkUniformBuffer;
// Error state...
static char error_buffer[1024] = { '\0' };
static void set_error(const char *str)
{
snprintf(error_buffer, sizeof (error_buffer), "%s", str);
} // set_error
static inline void out_of_memory(void)
{
set_error("out of memory");
} // out_of_memory
Jul 6, 2020
Jul 6, 2020
62
// Max entries for each register file type
Jul 1, 2020
Jul 1, 2020
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#define MAX_REG_FILE_F 8192
#define MAX_REG_FILE_I 2047
#define MAX_REG_FILE_B 2047
typedef struct MOJOSHADER_vkContext
{
VkInstance *instance;
VkPhysicalDevice *physical_device;
VkDevice *logical_device;
PFN_vkGetInstanceProcAddr instance_proc_lookup;
PFN_vkGetDeviceProcAddr device_proc_lookup;
uint32_t graphics_queue_family_index;
uint32_t maxUniformBufferRange;
uint32_t minUniformBufferOffsetAlignment;
Oct 1, 2020
Oct 1, 2020
78
uint32_t frameIndex;
Jul 1, 2020
Jul 1, 2020
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
MOJOSHADER_malloc malloc_fn;
MOJOSHADER_free free_fn;
void *malloc_data;
// The constant register files...
// !!! FIXME: Man, it kills me how much memory this takes...
// !!! FIXME: ... make this dynamically allocated on demand.
float vs_reg_file_f[MAX_REG_FILE_F * 4];
int32_t vs_reg_file_i[MAX_REG_FILE_I * 4];
uint8_t vs_reg_file_b[MAX_REG_FILE_B * 4];
float ps_reg_file_f[MAX_REG_FILE_F * 4];
int32_t ps_reg_file_i[MAX_REG_FILE_I * 4];
uint8_t ps_reg_file_b[MAX_REG_FILE_B * 4];
Jul 6, 2020
Jul 6, 2020
94
95
MOJOSHADER_vkUniformBuffer *vertUboBuffer;
MOJOSHADER_vkUniformBuffer *fragUboBuffer;
Jul 1, 2020
Jul 1, 2020
96
Jul 7, 2020
Jul 7, 2020
97
98
MOJOSHADER_vkProgram *bound_program;
HashTable *linker_cache;
Jul 1, 2020
Jul 1, 2020
99
Aug 27, 2020
Aug 27, 2020
100
101
102
103
104
// Note that these may not necessarily align with bound_program!
// We need to store these so effects can have overlapping shaders.
MOJOSHADER_vkShader *bound_vshader;
MOJOSHADER_vkShader *bound_pshader;
Mar 10, 2022
Mar 10, 2022
105
106
107
108
#define VULKAN_INSTANCE_FUNCTION(name) \
PFN_##name name;
#define VULKAN_DEVICE_FUNCTION(name) \
PFN_##name name;
Jul 1, 2020
Jul 1, 2020
109
110
111
#include "mojoshader_vulkan_vkfuncs.h"
} MOJOSHADER_vkContext;
Jul 7, 2020
Jul 7, 2020
112
static uint16_t tagCounter = 1;
Jul 1, 2020
Jul 1, 2020
113
114
115
static uint8_t find_memory_type(
MOJOSHADER_vkContext *ctx,
Nov 24, 2021
Nov 24, 2021
116
117
118
uint32_t typeFilter,
VkMemoryPropertyFlags properties,
uint32_t *result
Jul 1, 2020
Jul 1, 2020
119
) {
Nov 24, 2021
Nov 24, 2021
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
uint32_t i;
VkPhysicalDeviceMemoryProperties memoryProperties;
ctx->vkGetPhysicalDeviceMemoryProperties(*ctx->physical_device, &memoryProperties);
for (i = 0; i < memoryProperties.memoryTypeCount; i++)
{
if ((typeFilter & (1 << i))
&& (memoryProperties.memoryTypes[i].propertyFlags & properties) == properties)
{
*result = i;
return 1;
} // if
} // for
return 0;
Jul 1, 2020
Jul 1, 2020
135
136
} // find_memory_type
Nov 24, 2021
Nov 24, 2021
137
138
139
140
static uint32_t next_highest_offset_alignment(
MOJOSHADER_vkContext *ctx,
uint32_t offset
) {
Jul 1, 2020
Jul 1, 2020
141
142
143
144
145
146
147
return (
(offset + ctx->minUniformBufferOffsetAlignment - 1) /
ctx->minUniformBufferOffsetAlignment *
ctx->minUniformBufferOffsetAlignment
);
} // next_highest_offset_alignment
Jul 6, 2020
Jul 6, 2020
148
149
150
static MOJOSHADER_vkUniformBuffer *create_ubo(MOJOSHADER_vkContext *ctx)
{
MOJOSHADER_vkUniformBuffer *result = (MOJOSHADER_vkUniformBuffer *) ctx->malloc_fn(
Jul 1, 2020
Jul 1, 2020
151
sizeof(MOJOSHADER_vkUniformBuffer),
Jul 6, 2020
Jul 6, 2020
152
ctx->malloc_data
Jul 1, 2020
Jul 1, 2020
153
154
155
156
157
);
VkBufferCreateInfo bufferCreateInfo =
{
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
};
Jul 6, 2020
Jul 6, 2020
158
159
160
161
162
VkMemoryRequirements memoryRequirements;
VkMemoryAllocateInfo allocateInfo =
{
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO
};
Jul 1, 2020
Jul 1, 2020
163
164
bufferCreateInfo.flags = 0;
Oct 1, 2020
Oct 1, 2020
165
bufferCreateInfo.size = UBO_ACTUAL_SIZE;
Jul 1, 2020
Jul 1, 2020
166
167
168
169
170
171
172
173
174
175
176
177
bufferCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
bufferCreateInfo.queueFamilyIndexCount = 1;
bufferCreateInfo.pQueueFamilyIndices = &ctx->graphics_queue_family_index;
ctx->vkCreateBuffer(
*ctx->logical_device,
&bufferCreateInfo,
NULL,
&result->buffer
);
Jul 6, 2020
Jul 6, 2020
178
179
180
181
182
183
ctx->vkGetBufferMemoryRequirements(
*ctx->logical_device,
result->buffer,
&memoryRequirements
);
Oct 1, 2020
Oct 1, 2020
184
allocateInfo.allocationSize = UBO_ACTUAL_SIZE;
Jul 6, 2020
Jul 6, 2020
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
if (!find_memory_type(ctx,
memoryRequirements.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
&allocateInfo.memoryTypeIndex))
{
set_error("failed to find suitable memory type for UBO memory");
return NULL;
} // if
ctx->vkAllocateMemory(*ctx->logical_device,
&allocateInfo,
NULL,
&result->deviceMemory
);
ctx->vkBindBufferMemory(*ctx->logical_device,
result->buffer,
result->deviceMemory,
0
);
ctx->vkMapMemory(*ctx->logical_device,
result->deviceMemory,
0,
Oct 1, 2020
Oct 1, 2020
210
UBO_ACTUAL_SIZE,
Jul 6, 2020
Jul 6, 2020
211
212
213
214
0,
(void**) &result->mapPointer
);
Oct 1, 2020
Oct 1, 2020
215
result->bufferSize = UBO_ACTUAL_SIZE;
Jul 1, 2020
Jul 1, 2020
216
result->currentBlockSize = 0;
Oct 22, 2020
Oct 22, 2020
217
result->currentBlockIncrement = 0;
Jul 1, 2020
Jul 1, 2020
218
219
220
221
222
223
224
225
226
result->dynamicOffset = 0;
return result;
} // create_ubo
static uint32_t uniform_data_size(MOJOSHADER_vkShader *shader)
{
int32_t i;
int32_t buflen = 0;
Jul 6, 2020
Jul 6, 2020
227
const int32_t uniformSize = 16; // Yes, even the bool registers
Jul 1, 2020
Jul 1, 2020
228
229
230
231
232
233
234
235
236
for (i = 0; i < shader->parseData->uniform_count; i++)
{
const int32_t arrayCount = shader->parseData->uniforms[i].array_count;
buflen += (arrayCount ? arrayCount : 1) * uniformSize;
} // for
return buflen;
} // uniform_data_size
Nov 24, 2021
Nov 24, 2021
237
238
239
240
static VkBuffer get_uniform_buffer(
MOJOSHADER_vkContext *ctx,
MOJOSHADER_vkShader *shader
) {
Jul 1, 2020
Jul 1, 2020
241
242
243
244
if (shader == NULL || shader->parseData->uniform_count == 0)
return VK_NULL_HANDLE;
if (shader->parseData->shader_type == MOJOSHADER_TYPE_VERTEX)
Jul 6, 2020
Jul 6, 2020
245
return ctx->vertUboBuffer->buffer;
Jul 1, 2020
Jul 1, 2020
246
else
Jul 6, 2020
Jul 6, 2020
247
return ctx->fragUboBuffer->buffer;
Jul 1, 2020
Jul 1, 2020
248
249
} // get_uniform_buffer
Nov 24, 2021
Nov 24, 2021
250
251
252
253
static VkDeviceSize get_uniform_offset(
MOJOSHADER_vkContext *ctx,
MOJOSHADER_vkShader *shader
) {
Jul 1, 2020
Jul 1, 2020
254
255
256
257
if (shader == NULL || shader->parseData->uniform_count == 0)
return 0;
if (shader->parseData->shader_type == MOJOSHADER_TYPE_VERTEX)
Jul 6, 2020
Jul 6, 2020
258
return ctx->vertUboBuffer->dynamicOffset;
Jul 1, 2020
Jul 1, 2020
259
else
Jul 6, 2020
Jul 6, 2020
260
return ctx->fragUboBuffer->dynamicOffset;
Jul 1, 2020
Jul 1, 2020
261
262
} // get_uniform_offset
Nov 24, 2021
Nov 24, 2021
263
264
265
266
static VkDeviceSize get_uniform_size(
MOJOSHADER_vkContext *ctx,
MOJOSHADER_vkShader *shader
) {
Jul 1, 2020
Jul 1, 2020
267
268
269
270
if (shader == NULL || shader->parseData->uniform_count == 0)
return 0;
if (shader->parseData->shader_type == MOJOSHADER_TYPE_VERTEX)
Jul 6, 2020
Jul 6, 2020
271
return ctx->vertUboBuffer->currentBlockSize;
Jul 1, 2020
Jul 1, 2020
272
else
Jul 6, 2020
Jul 6, 2020
273
return ctx->fragUboBuffer->currentBlockSize;
Jul 1, 2020
Jul 1, 2020
274
275
} // get_uniform_size
Nov 24, 2021
Nov 24, 2021
276
277
278
279
static void update_uniform_buffer(
MOJOSHADER_vkContext *ctx,
MOJOSHADER_vkShader *shader
) {
Jul 6, 2020
Jul 6, 2020
280
int32_t i, j;
Jul 1, 2020
Jul 1, 2020
281
282
int32_t offset;
uint8_t *contents;
Jul 6, 2020
Jul 6, 2020
283
uint32_t *contentsI;
Jul 1, 2020
Jul 1, 2020
284
285
286
287
288
289
290
291
292
293
294
295
float *regF; int *regI; uint8_t *regB;
MOJOSHADER_vkUniformBuffer *ubo;
if (shader == NULL || shader->parseData->uniform_count == 0)
return;
if (shader->parseData->shader_type == MOJOSHADER_TYPE_VERTEX)
{
regF = ctx->vs_reg_file_f;
regI = ctx->vs_reg_file_i;
regB = ctx->vs_reg_file_b;
Jul 6, 2020
Jul 6, 2020
296
ubo = ctx->vertUboBuffer;
Jul 1, 2020
Jul 1, 2020
297
298
299
300
301
302
303
} // if
else
{
regF = ctx->ps_reg_file_f;
regI = ctx->ps_reg_file_i;
regB = ctx->ps_reg_file_b;
Jul 6, 2020
Jul 6, 2020
304
ubo = ctx->fragUboBuffer;
Jul 1, 2020
Jul 1, 2020
305
306
} // else
Oct 22, 2020
Oct 22, 2020
307
ubo->dynamicOffset += ubo->currentBlockIncrement;
Jul 1, 2020
Jul 1, 2020
308
Nov 24, 2021
Nov 24, 2021
309
ubo->currentBlockSize = next_highest_offset_alignment(ctx, uniform_data_size(shader));
Oct 22, 2020
Oct 22, 2020
310
ubo->currentBlockIncrement = ubo->currentBlockSize;
Jul 1, 2020
Jul 1, 2020
311
Jun 24, 2023
Jun 24, 2023
312
if (ubo->dynamicOffset + ubo->currentBlockSize >= ubo->bufferSize * (ctx->frameIndex + 1))
Jul 1, 2020
Jul 1, 2020
313
{
Jul 6, 2020
Jul 6, 2020
314
set_error("UBO overflow!!");
Jul 1, 2020
Jul 1, 2020
315
316
} // if
Jul 6, 2020
Jul 6, 2020
317
contents = ubo->mapPointer + ubo->dynamicOffset;
Jul 1, 2020
Jul 1, 2020
318
319
320
321
322
323
324
325
326
327
328
329
offset = 0;
for (i = 0; i < shader->parseData->uniform_count; i++)
{
const int32_t index = shader->parseData->uniforms[i].index;
const int32_t arrayCount = shader->parseData->uniforms[i].array_count;
const int32_t size = arrayCount ? arrayCount : 1;
switch (shader->parseData->uniforms[i].type)
{
case MOJOSHADER_UNIFORM_FLOAT:
memcpy(
Jul 6, 2020
Jul 6, 2020
330
contents + offset,
Jul 1, 2020
Jul 1, 2020
331
332
333
334
335
336
337
&regF[4 * index],
size * 16
);
break;
case MOJOSHADER_UNIFORM_INT:
memcpy(
Jul 6, 2020
Jul 6, 2020
338
contents + offset,
Jul 1, 2020
Jul 1, 2020
339
340
341
342
343
344
&regI[4 * index],
size * 16
);
break;
case MOJOSHADER_UNIFORM_BOOL:
Jul 6, 2020
Jul 6, 2020
345
346
347
contentsI = (uint32_t *) (contents + offset);
for (j = 0; j < size; j++)
contentsI[j * 4] = regB[index + j];
Jul 1, 2020
Jul 1, 2020
348
349
350
351
352
353
354
355
356
357
break;
default:
set_error(
"SOMETHING VERY WRONG HAPPENED WHEN UPDATING UNIFORMS"
);
assert(0);
break;
} // switch
Jul 6, 2020
Jul 6, 2020
358
offset += size * 16;
Jul 1, 2020
Jul 1, 2020
359
360
361
362
363
364
} // for
} // update_uniform_buffer
static void lookup_entry_points(MOJOSHADER_vkContext *ctx)
{
Mar 10, 2022
Mar 10, 2022
365
366
367
368
#define VULKAN_INSTANCE_FUNCTION(name) \
ctx->name = (PFN_##name) ctx->instance_proc_lookup(*ctx->instance, #name);
#define VULKAN_DEVICE_FUNCTION(name) \
ctx->name = (PFN_##name) ctx->device_proc_lookup(*ctx->logical_device, #name);
Jul 1, 2020
Jul 1, 2020
369
370
371
372
373
374
375
376
#include "mojoshader_vulkan_vkfuncs.h"
} // lookup_entry_points
static int shader_bytecode_len(MOJOSHADER_vkShader *shader)
{
return shader->parseData->output_len - sizeof(SpirvPatchTable);
} // shader_bytecode_len
Nov 24, 2021
Nov 24, 2021
377
378
379
380
static VkShaderModule compile_shader(
MOJOSHADER_vkContext *ctx,
MOJOSHADER_vkShader *shader
) {
Jul 7, 2020
Jul 7, 2020
381
382
383
384
385
386
387
388
389
390
391
392
VkResult result;
VkShaderModule module;
VkShaderModuleCreateInfo shaderModuleCreateInfo =
{
VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO
};
shaderModuleCreateInfo.flags = 0;
shaderModuleCreateInfo.codeSize = shader_bytecode_len(shader);
shaderModuleCreateInfo.pCode = (uint32_t*) shader->parseData->output;
result = ctx->vkCreateShaderModule(
Jul 1, 2020
Jul 1, 2020
393
*ctx->logical_device,
Jul 7, 2020
Jul 7, 2020
394
395
396
&shaderModuleCreateInfo,
NULL,
&module
Jul 1, 2020
Jul 1, 2020
397
);
Jul 7, 2020
Jul 7, 2020
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
if (result != VK_SUCCESS)
{
// FIXME: should display VK error code
set_error("Error when creating VkShaderModule");
ctx->vkDestroyShaderModule(
*ctx->logical_device,
module,
NULL
);
return VK_NULL_HANDLE;
} // if
return module;
} // compile_shader
typedef struct
{
MOJOSHADER_vkShader *vertex;
MOJOSHADER_vkShader *fragment;
} BoundShaders;
static uint32_t hash_shaders(const void *sym, void *data)
{
(void) data;
const BoundShaders *s = (const BoundShaders *) sym;
const uint16_t v = (s->vertex) ? s->vertex->tag : 0;
const uint16_t f = (s->fragment) ? s->fragment->tag : 0;
return ((uint32_t) v << 16) | (uint32_t) f;
} // hash_shaders
static int match_shaders(const void *_a, const void *_b, void *data)
{
(void) data;
const BoundShaders *a = (const BoundShaders *) _a;
const BoundShaders *b = (const BoundShaders *) _b;
const uint16_t av = (a->vertex) ? a->vertex->tag : 0;
const uint16_t bv = (b->vertex) ? b->vertex->tag : 0;
if (av != bv)
return 0;
const uint16_t af = (a->fragment) ? a->fragment->tag : 0;
const uint16_t bf = (b->fragment) ? b->fragment->tag : 0;
if (af != bf)
return 0;
return 1;
} // match_shaders
Nov 24, 2021
Nov 24, 2021
448
449
450
451
452
453
454
static void nuke_shaders(
const void *_ctx,
const void *key,
const void *value,
void *data
) {
MOJOSHADER_vkContext *ctx = (MOJOSHADER_vkContext *) _ctx;
Jul 7, 2020
Jul 7, 2020
455
456
(void) data;
ctx->free_fn((void *) key, ctx->malloc_data); // this was a BoundShaders struct.
Nov 24, 2021
Nov 24, 2021
457
MOJOSHADER_vkDeleteProgram(ctx, (MOJOSHADER_vkProgram *) value);
Jul 7, 2020
Jul 7, 2020
458
} // nuke_shaders
Jul 1, 2020
Jul 1, 2020
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
// Public API
MOJOSHADER_vkContext *MOJOSHADER_vkCreateContext(
VkInstance *instance,
VkPhysicalDevice *physical_device,
VkDevice *logical_device,
PFN_MOJOSHADER_vkGetInstanceProcAddr instance_lookup,
PFN_MOJOSHADER_vkGetDeviceProcAddr device_lookup,
unsigned int graphics_queue_family_index,
unsigned int max_uniform_buffer_range,
unsigned int min_uniform_buffer_offset_alignment,
MOJOSHADER_malloc m, MOJOSHADER_free f,
void *malloc_d
) {
MOJOSHADER_vkContext* resultCtx;
if (m == NULL) m = MOJOSHADER_internal_malloc;
if (f == NULL) f = MOJOSHADER_internal_free;
resultCtx = (MOJOSHADER_vkContext *) m(sizeof(MOJOSHADER_vkContext), malloc_d);
if (resultCtx == NULL)
{
out_of_memory();
goto init_fail;
Jul 6, 2020
Jul 6, 2020
484
} // if
Jul 1, 2020
Jul 1, 2020
485
486
487
488
489
490
491
492
493
494
495
memset(resultCtx, '\0', sizeof(MOJOSHADER_vkContext));
resultCtx->malloc_fn = m;
resultCtx->free_fn = f;
resultCtx->malloc_data = malloc_d;
resultCtx->instance = (VkInstance*) instance;
resultCtx->physical_device = (VkPhysicalDevice*) physical_device;
resultCtx->logical_device = (VkDevice*) logical_device;
resultCtx->instance_proc_lookup = (PFN_vkGetInstanceProcAddr) instance_lookup;
resultCtx->device_proc_lookup = (PFN_vkGetDeviceProcAddr) device_lookup;
Oct 1, 2020
Oct 1, 2020
496
resultCtx->frameIndex = 0;
Jul 1, 2020
Jul 1, 2020
497
498
499
500
501
502
resultCtx->graphics_queue_family_index = graphics_queue_family_index;
resultCtx->maxUniformBufferRange = max_uniform_buffer_range;
resultCtx->minUniformBufferOffsetAlignment = min_uniform_buffer_offset_alignment;
lookup_entry_points(resultCtx);
Jul 6, 2020
Jul 6, 2020
503
504
resultCtx->vertUboBuffer = create_ubo(resultCtx);
resultCtx->fragUboBuffer = create_ubo(resultCtx);
Jul 1, 2020
Jul 1, 2020
505
506
507
508
509
510
511
512
513
return resultCtx;
init_fail:
if (resultCtx != NULL)
f(resultCtx, malloc_d);
return NULL;
} // MOJOSHADER_vkCreateContext
Nov 24, 2021
Nov 24, 2021
514
void MOJOSHADER_vkDestroyContext(MOJOSHADER_vkContext *ctx)
Jul 1, 2020
Jul 1, 2020
515
{
Nov 24, 2021
Nov 24, 2021
516
MOJOSHADER_vkBindProgram(ctx, NULL);
Jul 7, 2020
Jul 7, 2020
517
if (ctx->linker_cache)
Nov 24, 2021
Nov 24, 2021
518
hash_destroy(ctx->linker_cache, ctx);
Jul 7, 2020
Jul 7, 2020
519
Jul 6, 2020
Jul 6, 2020
520
521
522
ctx->vkDestroyBuffer(*ctx->logical_device,
ctx->vertUboBuffer->buffer,
NULL);
Jul 1, 2020
Jul 1, 2020
523
Jul 6, 2020
Jul 6, 2020
524
525
526
ctx->vkDestroyBuffer(*ctx->logical_device,
ctx->fragUboBuffer->buffer,
NULL);
Jul 1, 2020
Jul 1, 2020
527
Jul 6, 2020
Jul 6, 2020
528
529
530
ctx->vkFreeMemory(*ctx->logical_device,
ctx->vertUboBuffer->deviceMemory,
NULL);
Jul 1, 2020
Jul 1, 2020
531
Jul 6, 2020
Jul 6, 2020
532
533
534
ctx->vkFreeMemory(*ctx->logical_device,
ctx->fragUboBuffer->deviceMemory,
NULL);
Jul 1, 2020
Jul 1, 2020
535
Jul 6, 2020
Jul 6, 2020
536
537
ctx->free_fn(ctx->vertUboBuffer, ctx->malloc_data);
ctx->free_fn(ctx->fragUboBuffer, ctx->malloc_data);
Jul 1, 2020
Jul 1, 2020
538
539
540
541
542
ctx->free_fn(ctx, ctx->malloc_data);
} // MOJOSHADER_vkDestroyContext
MOJOSHADER_vkShader *MOJOSHADER_vkCompileShader(
Nov 24, 2021
Nov 24, 2021
543
MOJOSHADER_vkContext *ctx,
Jul 1, 2020
Jul 1, 2020
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
const char *mainfn,
const unsigned char *tokenbuf,
const unsigned int bufsize,
const MOJOSHADER_swizzle *swiz,
const unsigned int swizcount,
const MOJOSHADER_samplerMap *smap,
const unsigned int smapcount
) {
MOJOSHADER_vkShader *shader;
const MOJOSHADER_parseData *pd = MOJOSHADER_parse(
"spirv", mainfn,
tokenbuf, bufsize,
swiz, swizcount,
smap, smapcount,
ctx->malloc_fn,
ctx->free_fn,
ctx->malloc_data
);
if (pd->error_count > 0)
{
set_error(pd->errors[0].error);
Jul 7, 2020
Jul 7, 2020
567
goto parse_shader_fail;
Jul 1, 2020
Jul 1, 2020
568
569
570
571
572
573
} // if
shader = (MOJOSHADER_vkShader *) ctx->malloc_fn(sizeof(MOJOSHADER_vkShader), ctx->malloc_data);
if (shader == NULL)
{
out_of_memory();
Jul 7, 2020
Jul 7, 2020
574
goto parse_shader_fail;
Jul 1, 2020
Jul 1, 2020
575
576
577
578
} // if
shader->parseData = pd;
shader->refcount = 1;
Jul 7, 2020
Jul 7, 2020
579
shader->tag = tagCounter++;
Jul 1, 2020
Jul 1, 2020
580
581
return shader;
Jul 7, 2020
Jul 7, 2020
582
parse_shader_fail:
Jul 1, 2020
Jul 1, 2020
583
584
585
586
MOJOSHADER_freeParseData(pd);
if (shader != NULL)
ctx->free_fn(shader, ctx->malloc_data);
return NULL;
Jul 7, 2020
Jul 7, 2020
587
} // MOJOSHADER_vkCompileShader
Jul 1, 2020
Jul 1, 2020
588
589
590
591
592
593
594
void MOJOSHADER_vkShaderAddRef(MOJOSHADER_vkShader *shader)
{
if (shader != NULL)
shader->refcount++;
} // MOJOShader_vkShaderAddRef
Nov 24, 2021
Nov 24, 2021
595
596
597
598
void MOJOSHADER_vkDeleteShader(
MOJOSHADER_vkContext *ctx,
MOJOSHADER_vkShader *shader
) {
Jul 1, 2020
Jul 1, 2020
599
600
601
602
603
604
if (shader != NULL)
{
if (shader->refcount > 1)
shader->refcount--;
else
{
Jul 7, 2020
Jul 7, 2020
605
606
607
608
609
610
611
612
613
614
615
616
617
618
// See if this was bound as an unlinked program anywhere...
if (ctx->linker_cache)
{
const void *key = NULL;
void *iter = NULL;
int morekeys = hash_iter_keys(ctx->linker_cache, &key, &iter);
while (morekeys)
{
const BoundShaders *shaders = (const BoundShaders *) key;
// Do this here so we don't confuse the iteration by removing...
morekeys = hash_iter_keys(ctx->linker_cache, &key, &iter);
if ((shaders->vertex == shader) || (shaders->fragment == shader))
{
// Deletes the linked program
Nov 24, 2021
Nov 24, 2021
619
hash_remove(ctx->linker_cache, shaders, ctx);
Jul 7, 2020
Jul 7, 2020
620
621
622
623
} // if
} // while
} // if
Jul 1, 2020
Jul 1, 2020
624
625
626
627
628
629
MOJOSHADER_freeParseData(shader->parseData);
ctx->free_fn(shader, ctx->malloc_data);
} // else
} // if
} // MOJOSHADER_vkDeleteShader
Jan 18, 2024
Jan 18, 2024
630
631
632
633
634
635
636
unsigned int MOJOSHADER_vkGetShaderRefCount(MOJOSHADER_vkShader *shader)
{
if (shader != NULL)
return shader->refcount;
return 0;
} // MOJOSHADER_vkGetShaderRefCount
Jul 1, 2020
Jul 1, 2020
637
638
639
640
641
642
const MOJOSHADER_parseData *MOJOSHADER_vkGetShaderParseData(
MOJOSHADER_vkShader *shader
) {
return (shader != NULL) ? shader->parseData : NULL;
} // MOJOSHADER_vkGetShaderParseData
Nov 24, 2021
Nov 24, 2021
643
644
645
646
void MOJOSHADER_vkDeleteProgram(
MOJOSHADER_vkContext *ctx,
MOJOSHADER_vkProgram *p
) {
Jul 7, 2020
Jul 7, 2020
647
648
649
650
651
652
653
if (p->vertexModule != VK_NULL_HANDLE)
ctx->vkDestroyShaderModule(*ctx->logical_device, p->vertexModule, NULL);
if (p->pixelModule != VK_NULL_HANDLE)
ctx->vkDestroyShaderModule(*ctx->logical_device, p->pixelModule, NULL);
ctx->free_fn(p, ctx->malloc_data);
} // MOJOSHADER_vkDeleteProgram
Nov 24, 2021
Nov 24, 2021
654
655
MOJOSHADER_vkProgram *MOJOSHADER_vkLinkProgram(MOJOSHADER_vkContext *ctx,
MOJOSHADER_vkShader *vshader,
Jul 7, 2020
Jul 7, 2020
656
657
658
659
MOJOSHADER_vkShader *pshader)
{
MOJOSHADER_vkProgram *result;
Aug 27, 2020
Aug 27, 2020
660
if ((vshader == NULL) || (pshader == NULL)) // Both shaders MUST exist!
Jul 7, 2020
Jul 7, 2020
661
662
return NULL;
Jul 8, 2020
Jul 8, 2020
663
664
result = (MOJOSHADER_vkProgram *) ctx->malloc_fn(sizeof (MOJOSHADER_vkProgram),
ctx->malloc_data);
Jul 7, 2020
Jul 7, 2020
665
666
667
668
669
670
if (result == NULL)
{
out_of_memory();
return NULL;
} // if
Apr 6, 2024
Apr 6, 2024
671
MOJOSHADER_spirv_link_attributes(vshader->parseData, pshader->parseData, 0);
Nov 24, 2021
Nov 24, 2021
672
673
result->vertexModule = compile_shader(ctx, vshader);
result->pixelModule = compile_shader(ctx, pshader);
Jul 7, 2020
Jul 7, 2020
674
675
676
677
678
679
result->vertexShader = vshader;
result->pixelShader = pshader;
if (result->vertexModule == VK_NULL_HANDLE
|| result->pixelModule == VK_NULL_HANDLE)
{
Nov 24, 2021
Nov 24, 2021
680
MOJOSHADER_vkDeleteProgram(ctx, result);
Jul 7, 2020
Jul 7, 2020
681
682
683
684
685
return NULL;
}
return result;
} // MOJOSHADER_vkLinkProgram
Nov 24, 2021
Nov 24, 2021
686
687
688
689
void MOJOSHADER_vkBindProgram(
MOJOSHADER_vkContext *ctx,
MOJOSHADER_vkProgram *p
) {
Jul 7, 2020
Jul 7, 2020
690
691
692
ctx->bound_program = p;
} // MOJOSHADER_vkBindProgram
Nov 24, 2021
Nov 24, 2021
693
694
695
696
697
void MOJOSHADER_vkBindShaders(
MOJOSHADER_vkContext *ctx,
MOJOSHADER_vkShader *vshader,
MOJOSHADER_vkShader *pshader
) {
Jul 7, 2020
Jul 7, 2020
698
699
700
701
702
if (ctx->linker_cache == NULL)
{
ctx->linker_cache = hash_create(NULL, hash_shaders, match_shaders,
nuke_shaders, 0, ctx->malloc_fn,
ctx->free_fn, ctx->malloc_data);
Jul 1, 2020
Jul 1, 2020
703
Jul 7, 2020
Jul 7, 2020
704
705
706
707
708
709
710
711
712
713
714
715
if (ctx->linker_cache == NULL)
{
out_of_memory();
return;
} // if
} // if
MOJOSHADER_vkProgram *program = NULL;
BoundShaders shaders;
shaders.vertex = vshader;
shaders.fragment = pshader;
Aug 27, 2020
Aug 27, 2020
716
717
718
ctx->bound_vshader = vshader;
ctx->bound_pshader = pshader;
Jul 7, 2020
Jul 7, 2020
719
720
721
722
723
const void *val = NULL;
if (hash_find(ctx->linker_cache, &shaders, &val))
program = (MOJOSHADER_vkProgram *) val;
else
{
Nov 24, 2021
Nov 24, 2021
724
program = MOJOSHADER_vkLinkProgram(ctx, vshader, pshader);
Jul 7, 2020
Jul 7, 2020
725
726
727
728
729
730
731
if (program == NULL)
return;
BoundShaders *item = (BoundShaders *) ctx->malloc_fn(sizeof (BoundShaders),
ctx->malloc_data);
if (item == NULL)
{
Nov 24, 2021
Nov 24, 2021
732
MOJOSHADER_vkDeleteProgram(ctx, program);
Jul 7, 2020
Jul 7, 2020
733
734
735
736
737
738
739
return;
} // if
memcpy(item, &shaders, sizeof (BoundShaders));
if (hash_insert(ctx->linker_cache, item, program) != 1)
{
ctx->free_fn(item, ctx->malloc_data);
Nov 24, 2021
Nov 24, 2021
740
MOJOSHADER_vkDeleteProgram(ctx, program);
Jul 7, 2020
Jul 7, 2020
741
742
743
744
745
746
747
out_of_memory();
return;
} // if
} // else
assert(program != NULL);
ctx->bound_program = program;
Jul 1, 2020
Jul 1, 2020
748
749
} // MOJOSHADER_vkBindShaders
Nov 24, 2021
Nov 24, 2021
750
751
752
753
754
void MOJOSHADER_vkGetBoundShaders(
MOJOSHADER_vkContext *ctx,
MOJOSHADER_vkShader **vshader,
MOJOSHADER_vkShader **pshader
) {
Jul 7, 2020
Jul 7, 2020
755
756
757
758
759
if (vshader != NULL)
{
if (ctx->bound_program != NULL)
*vshader = ctx->bound_program->vertexShader;
else
Aug 27, 2020
Aug 27, 2020
760
*vshader = ctx->bound_vshader; // In case a pshader isn't set yet
Jul 7, 2020
Jul 7, 2020
761
762
763
764
765
766
} // if
if (pshader != NULL)
{
if (ctx->bound_program != NULL)
*pshader = ctx->bound_program->pixelShader;
else
Aug 27, 2020
Aug 27, 2020
767
*pshader = ctx->bound_pshader; // In case a vshader isn't set yet
Jul 7, 2020
Jul 7, 2020
768
} // if
Jul 1, 2020
Jul 1, 2020
769
770
} // MOJOSHADER_vkGetBoundShaders
Nov 24, 2021
Nov 24, 2021
771
772
773
774
775
void MOJOSHADER_vkMapUniformBufferMemory(
MOJOSHADER_vkContext *ctx,
float **vsf, int **vsi, unsigned char **vsb,
float **psf, int **psi, unsigned char **psb
) {
Jul 1, 2020
Jul 1, 2020
776
777
778
779
780
781
782
783
*vsf = ctx->vs_reg_file_f;
*vsi = ctx->vs_reg_file_i;
*vsb = ctx->vs_reg_file_b;
*psf = ctx->ps_reg_file_f;
*psi = ctx->ps_reg_file_i;
*psb = ctx->ps_reg_file_b;
} // MOJOSHADER_vkMapUniformBufferMemory
Nov 24, 2021
Nov 24, 2021
784
void MOJOSHADER_vkUnmapUniformBufferMemory(MOJOSHADER_vkContext *ctx)
Jul 1, 2020
Jul 1, 2020
785
{
Aug 27, 2020
Aug 27, 2020
786
787
if (ctx->bound_program == NULL)
return; // Ignore buffer updates until we have a real program linked
Nov 24, 2021
Nov 24, 2021
788
789
update_uniform_buffer(ctx, ctx->bound_program->vertexShader);
update_uniform_buffer(ctx, ctx->bound_program->pixelShader);
Jul 1, 2020
Jul 1, 2020
790
791
} // MOJOSHADER_vkUnmapUniformBufferMemory
Nov 24, 2021
Nov 24, 2021
792
793
794
795
796
void MOJOSHADER_vkGetUniformBuffers(
MOJOSHADER_vkContext *ctx,
VkBuffer *vbuf, unsigned long long *voff, unsigned long long *vsize,
VkBuffer *pbuf, unsigned long long *poff, unsigned long long *psize
) {
Jul 7, 2020
Jul 7, 2020
797
assert(ctx->bound_program != NULL);
Nov 24, 2021
Nov 24, 2021
798
799
800
801
802
803
*vbuf = get_uniform_buffer(ctx, ctx->bound_program->vertexShader);
*voff = get_uniform_offset(ctx, ctx->bound_program->vertexShader);
*vsize = get_uniform_size(ctx, ctx->bound_program->vertexShader);
*pbuf = get_uniform_buffer(ctx, ctx->bound_program->pixelShader);
*poff = get_uniform_offset(ctx, ctx->bound_program->pixelShader);
*psize = get_uniform_size(ctx, ctx->bound_program->pixelShader);
Jul 1, 2020
Jul 1, 2020
804
805
} // MOJOSHADER_vkGetUniformBuffers
Nov 24, 2021
Nov 24, 2021
806
void MOJOSHADER_vkEndFrame(MOJOSHADER_vkContext *ctx)
Jul 1, 2020
Jul 1, 2020
807
{
Oct 1, 2020
Oct 1, 2020
808
809
810
811
812
ctx->frameIndex = (ctx->frameIndex + 1) % 2;
// Reset counters
// Offset by size of buffer to simulate "rotating" the buffers
ctx->vertUboBuffer->dynamicOffset = UBO_BUFFER_SIZE * ctx->frameIndex;
Oct 22, 2020
Oct 22, 2020
813
ctx->vertUboBuffer->currentBlockIncrement = 0;
Oct 1, 2020
Oct 1, 2020
814
ctx->fragUboBuffer->dynamicOffset = UBO_BUFFER_SIZE * ctx->frameIndex;
Oct 22, 2020
Oct 22, 2020
815
ctx->fragUboBuffer->currentBlockIncrement = 0;
Jul 1, 2020
Jul 1, 2020
816
817
} // MOJOSHADER_VkEndFrame
Nov 24, 2021
Nov 24, 2021
818
819
820
821
int MOJOSHADER_vkGetVertexAttribLocation(
MOJOSHADER_vkShader *vert,
MOJOSHADER_usage usage, int index
) {
Jul 1, 2020
Jul 1, 2020
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
int32_t i;
if (vert == NULL)
return -1;
for (i = 0; i < vert->parseData->attribute_count; i++)
{
if (vert->parseData->attributes[i].usage == usage &&
vert->parseData->attributes[i].index == index)
{
return i;
} // if
} // for
// failure
return -1;
} //MOJOSHADER_vkGetVertexAttribLocation
Nov 24, 2021
Nov 24, 2021
839
840
841
842
843
void MOJOSHADER_vkGetShaderModules(
MOJOSHADER_vkContext *ctx,
VkShaderModule *vmodule,
VkShaderModule *pmodule
) {
Jul 7, 2020
Jul 7, 2020
844
845
846
847
848
849
assert(ctx->bound_program != NULL);
if (vmodule != NULL)
*vmodule = ctx->bound_program->vertexModule;
if (pmodule != NULL)
*pmodule = ctx->bound_program->pixelModule;
} //MOJOSHADER_vkGetShaderModules
Jul 1, 2020
Jul 1, 2020
850
Nov 24, 2021
Nov 24, 2021
851
const char *MOJOSHADER_vkGetError(MOJOSHADER_vkContext *ctx)
Jul 1, 2020
Jul 1, 2020
852
853
854
855
856
857
858
{
return error_buffer;
} // MOJOSHADER_vkGetError
#endif /* SUPPORT_PROFILE_SPIRV */
// end of mojoshader_vulkan.c ...