123 lines
4.7 KiB
C
123 lines
4.7 KiB
C
#include "assetmeta.h"
|
|
#include "processing.h"
|
|
#include "processing_flags.h"
|
|
#include "utils.h"
|
|
|
|
#include "runtime/buffer_manager.h"
|
|
|
|
#include <shaderc/shaderc.h>
|
|
#include <string.h>
|
|
|
|
static shaderc_include_result *ResolveInclude(void *user_data,
|
|
const char *requested_source,
|
|
int type,
|
|
const char *requesting_source,
|
|
size_t include_depth) {
|
|
shaderc_include_result *result = NULL;
|
|
|
|
return result;
|
|
}
|
|
|
|
static void ReleaseIncludeResult(void *user_data, shaderc_include_result *result) {
|
|
}
|
|
|
|
rt_result rtProcessShaderFile(rt_file_id file,
|
|
void *buffer,
|
|
size_t size,
|
|
uint32_t flags,
|
|
rt_processor_output *output) {
|
|
/* If we determine that shader compilation takes too long, we can instead
|
|
* keep the compiler around */
|
|
|
|
shaderc_compiler_t compiler = shaderc_compiler_initialize();
|
|
if (!compiler) {
|
|
rtLog("ASSETC", "Failed to initialize the shaderc compiler.");
|
|
return RT_PROCESSING_FAILED;
|
|
}
|
|
|
|
const char *path = rtGetFilePath(file);
|
|
|
|
shaderc_compile_options_t options = shaderc_compile_options_initialize();
|
|
if (!options) {
|
|
rtLog("ASSETC", "Failed to initialize shader compile options.");
|
|
shaderc_compiler_release(compiler);
|
|
return RT_PROCESSING_FAILED;
|
|
}
|
|
|
|
shaderc_compile_options_set_include_callbacks(options,
|
|
ResolveInclude,
|
|
ReleaseIncludeResult,
|
|
NULL);
|
|
|
|
uint32_t optimize_from_flags = flags & RT_SHADER_FLAG_OPTIMIZE_MASK;
|
|
if (optimize_from_flags == RT_SHADER_FLAG_OPTIMIZE_SPEED)
|
|
shaderc_compile_options_set_optimization_level(options,
|
|
shaderc_optimization_level_performance);
|
|
else if (optimize_from_flags == RT_SHADER_FLAG_OPTIMIZE_SIZE)
|
|
shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_size);
|
|
else
|
|
shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_zero);
|
|
|
|
uint32_t type_from_flags = flags & RT_SHADER_FLAG_TYPE_MASK;
|
|
shaderc_shader_kind shaderc_kind;
|
|
switch (type_from_flags) {
|
|
case RT_SHADER_FLAG_VERTEX:
|
|
shaderc_kind = shaderc_glsl_vertex_shader;
|
|
break;
|
|
case RT_SHADER_FLAG_FRAGMENT:
|
|
shaderc_kind = shaderc_glsl_fragment_shader;
|
|
break;
|
|
case RT_SHADER_FLAG_COMPUTE:
|
|
shaderc_kind = shaderc_glsl_compute_shader;
|
|
break;
|
|
default:
|
|
rtLog("ASSETC", "Invalid shader stage flag %u", type_from_flags);
|
|
shaderc_compile_options_release(options);
|
|
shaderc_compiler_release(compiler);
|
|
return RT_PROCESSING_FAILED;
|
|
}
|
|
|
|
shaderc_compilation_result_t result = shaderc_compile_into_spv(compiler,
|
|
(const char *)buffer,
|
|
size,
|
|
shaderc_kind,
|
|
path,
|
|
"main",
|
|
options);
|
|
|
|
|
|
shaderc_compilation_status status = shaderc_result_get_compilation_status(result);
|
|
if (status != shaderc_compilation_status_success || shaderc_result_get_num_errors(result) > 0) {
|
|
|
|
rtLog("ASSETC",
|
|
"Compilation of %s failed: %s",
|
|
path,
|
|
shaderc_result_get_error_message(result));
|
|
|
|
shaderc_result_release(result);
|
|
shaderc_compile_options_release(options);
|
|
shaderc_compiler_release(compiler);
|
|
return RT_PROCESSING_FAILED;
|
|
}
|
|
|
|
size_t output_size = shaderc_result_get_length(result);
|
|
output->data = rtAllocBuffer(output_size);
|
|
if (!output->data) {
|
|
shaderc_result_release(result);
|
|
shaderc_compile_options_release(options);
|
|
shaderc_compiler_release(compiler);
|
|
rtLog("ASSETC", "Failed to allocate %zu bytes for shader compilation output.", output_size);
|
|
return RT_PROCESSING_FAILED;
|
|
}
|
|
const uint32_t *spv_bytes = (uint32_t *)shaderc_result_get_bytes(result);
|
|
memcpy(output->data, spv_bytes, output_size);
|
|
output->size = output_size;
|
|
|
|
shaderc_result_release(result);
|
|
shaderc_compile_options_release(options);
|
|
shaderc_compiler_release(compiler);
|
|
|
|
output->asset_uid = rtCalculateUID(path);
|
|
|
|
return RT_SUCCESS;
|
|
} |