223 lines
8.4 KiB
C
223 lines
8.4 KiB
C
#include <stdio.h>
|
|
#include <SpirvInterpreter.h>
|
|
|
|
#define CHECK_RESULT(expr) do { \
|
|
SpvResult check_result = (expr); \
|
|
if (check_result != SPV_RESULT_SUCCESS) \
|
|
{ \
|
|
fprintf(stderr, "%s failed with %d\n", #expr, check_result); \
|
|
return -1; \
|
|
} \
|
|
} while (0)
|
|
|
|
static SpvResult ReadImageFloat4(SpvReadImageInfo info, SpvVec4f* dst)
|
|
{
|
|
(void)info;
|
|
(void)dst;
|
|
return SPV_RESULT_UNSUPPORTED_SPIRV;
|
|
}
|
|
|
|
static SpvResult ReadImageInt4(SpvReadImageInfo info, SpvVec4u* dst)
|
|
{
|
|
(void)info;
|
|
(void)dst;
|
|
return SPV_RESULT_UNSUPPORTED_SPIRV;
|
|
}
|
|
|
|
static SpvResult WriteImageFloat4(SpvWriteImageInfo info, SpvVec4f src)
|
|
{
|
|
(void)info;
|
|
(void)src;
|
|
return SPV_RESULT_UNSUPPORTED_SPIRV;
|
|
}
|
|
|
|
static SpvResult WriteImageInt4(SpvWriteImageInfo info, SpvVec4u src)
|
|
{
|
|
(void)info;
|
|
(void)src;
|
|
return SPV_RESULT_UNSUPPORTED_SPIRV;
|
|
}
|
|
|
|
static SpvResult SampleImageFloat4(SpvSampleImageInfo info, SpvVec4f* dst)
|
|
{
|
|
(void)info;
|
|
(void)dst;
|
|
return SPV_RESULT_UNSUPPORTED_SPIRV;
|
|
}
|
|
|
|
static SpvResult SampleImageInt4(SpvSampleImageInfo info, SpvVec4u* dst)
|
|
{
|
|
(void)info;
|
|
(void)dst;
|
|
return SPV_RESULT_UNSUPPORTED_SPIRV;
|
|
}
|
|
|
|
static SpvResult SampleImageDref(SpvSampleImageInfo info, float dref, float* dst)
|
|
{
|
|
(void)info;
|
|
(void)dref;
|
|
(void)dst;
|
|
return SPV_RESULT_UNSUPPORTED_SPIRV;
|
|
}
|
|
|
|
static SpvResult QueryImageSize(SpvQueryImageInfo info, SpvVec4u* dst)
|
|
{
|
|
(void)info;
|
|
(void)dst;
|
|
return SPV_RESULT_UNSUPPORTED_SPIRV;
|
|
}
|
|
|
|
static SpvResult QueryImageLevels(void* driver_image, unsigned long* dst)
|
|
{
|
|
(void)driver_image;
|
|
(void)dst;
|
|
return SPV_RESULT_UNSUPPORTED_SPIRV;
|
|
}
|
|
|
|
static SpvResult QueryImageSamples(void* driver_image, unsigned long* dst)
|
|
{
|
|
(void)driver_image;
|
|
(void)dst;
|
|
return SPV_RESULT_UNSUPPORTED_SPIRV;
|
|
}
|
|
|
|
static SpvResult QueryImageLod(SpvQueryImageLodInfo info, SpvVec4f* dst)
|
|
{
|
|
(void)info;
|
|
(void)dst;
|
|
return SPV_RESULT_UNSUPPORTED_SPIRV;
|
|
}
|
|
|
|
static const unsigned char shader_source[] = {
|
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x82, 0x10, 0x27, 0x00, 0x17, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00,
|
|
0x0f, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
|
0x10, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
|
|
0x09, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x04, 0x00, 0x05, 0x00, 0x56, 0x65, 0x72, 0x73,
|
|
0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
|
|
0x07, 0x00, 0x00, 0x00, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00,
|
|
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00,
|
|
0x05, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00,
|
|
0x05, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
|
|
0x47, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x48, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,
|
|
0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
|
|
0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
|
0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
|
0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
|
0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
|
|
0x15, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x2b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x2b, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
|
|
0x2b, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
|
|
0x2b, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40,
|
|
0x2b, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
|
|
0x20, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
|
0x3b, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
|
0x36, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x02, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
|
|
0x08, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00,
|
|
0x04, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
|
0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00,
|
|
0x13, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
|
|
0x13, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
|
|
0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00,
|
|
0x16, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
|
|
0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00
|
|
};
|
|
|
|
int main(void)
|
|
{
|
|
SpvModule module;
|
|
SpvModuleOptions options;
|
|
options.use_simd_vectors_specializations = 1;
|
|
|
|
if(SpvInitModule(&module, (SpvWord*)shader_source, sizeof(shader_source) / 4, options) != SPV_RESULT_SUCCESS)
|
|
{
|
|
fprintf(stderr, "Module init failed\n");
|
|
return -1;
|
|
}
|
|
|
|
SpvWord binding_result = 0;
|
|
if (SpvModuleGetBindingResult(module, 0, 0, &binding_result) != SPV_RESULT_NOT_FOUND)
|
|
{
|
|
fprintf(stderr, "Unexpected binding lookup result\n");
|
|
return -1;
|
|
}
|
|
|
|
SpvImageAPI image_api = {
|
|
.SpvReadImageFloat4 = ReadImageFloat4,
|
|
.SpvReadImageInt4 = ReadImageInt4,
|
|
.SpvWriteImageFloat4 = WriteImageFloat4,
|
|
.SpvWriteImageInt4 = WriteImageInt4,
|
|
.SpvSampleImageFloat4 = SampleImageFloat4,
|
|
.SpvSampleImageInt4 = SampleImageInt4,
|
|
.SpvSampleImageDref = SampleImageDref,
|
|
.SpvQueryImageSize = QueryImageSize,
|
|
.SpvQueryImageLevels = QueryImageLevels,
|
|
.SpvQueryImageSamples = QueryImageSamples,
|
|
.SpvQueryImageLod = QueryImageLod
|
|
};
|
|
|
|
SpvRuntime runtime;
|
|
if(SpvInitRuntime(&runtime, module, image_api) != SPV_RESULT_SUCCESS)
|
|
{
|
|
fprintf(stderr, "Runtime init failed\n");
|
|
return -1;
|
|
}
|
|
|
|
SpvRuntime second_runtime;
|
|
if(SpvInitRuntime(&second_runtime, module, image_api) != SPV_RESULT_SUCCESS)
|
|
{
|
|
fprintf(stderr, "Second runtime init failed\n");
|
|
SpvDeinitRuntime(runtime);
|
|
return -1;
|
|
}
|
|
|
|
unsigned int spec_value = 64;
|
|
SpvRuntimeSpecializationEntry spec_entry = {
|
|
.id = 0,
|
|
.offset = 0,
|
|
.size = sizeof(spec_value)
|
|
};
|
|
CHECK_RESULT(SpvAddSpecializationInfo(runtime, spec_entry, (const SpvByte*)&spec_value, sizeof(spec_value)));
|
|
CHECK_RESULT(SpvCopySpecializationConstantsFrom(second_runtime, runtime));
|
|
|
|
SpvWord main_entry_index;
|
|
CHECK_RESULT(SpvGetEntryPointByName(runtime, "main", &main_entry_index));
|
|
CHECK_RESULT(SpvCallEntryPoint(runtime, main_entry_index));
|
|
|
|
float output[4];
|
|
SpvWord output_result;
|
|
CHECK_RESULT(SpvGetResultByName(runtime, "color", &output_result));
|
|
CHECK_RESULT(SpvReadOutput(runtime, (SpvByte*)output, sizeof(output), output_result));
|
|
|
|
SpvSize output_size = 0;
|
|
SpvPrimitiveType primitive_type;
|
|
CHECK_RESULT(SpvGetResultMemorySize(runtime, output_result, &output_size));
|
|
CHECK_RESULT(SpvGetResultPrimitiveType(runtime, output_result, &primitive_type));
|
|
if (output_size != sizeof(output) || primitive_type != SPV_PRIMITIVE_FLOAT || primitive_type == SPV_PRIMITIVE_SINT || primitive_type == SPV_PRIMITIVE_UINT)
|
|
{
|
|
fprintf(stderr, "Unexpected output metadata\n");
|
|
SpvDeinitRuntime(second_runtime);
|
|
SpvDeinitRuntime(runtime);
|
|
SpvDeinitModule(module);
|
|
return -1;
|
|
}
|
|
|
|
float dx[4] = { 1.0f, 2.0f, 3.0f, 4.0f };
|
|
float dy[4] = { 5.0f, 6.0f, 7.0f, 8.0f };
|
|
CHECK_RESULT(SpvSetDerivativeFromMemory(runtime, output_result, (const SpvByte*)dx, sizeof(dx), (const SpvByte*)dy, sizeof(dy)));
|
|
CHECK_RESULT(SpvCopyDerivative(runtime, output_result, output_result));
|
|
SpvClearDerivative(runtime, output_result);
|
|
|
|
printf("Output: Vec4[%f, %f, %f, %f]\n", output[0], output[1], output[2], output[3]);
|
|
|
|
SpvDeinitRuntime(second_runtime);
|
|
SpvDeinitRuntime(runtime);
|
|
SpvDeinitModule(module);
|
|
return 0;
|
|
}
|