summaryrefslogtreecommitdiffstats
path: root/src/vulkan
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2015-05-20 17:05:38 -0700
committerJason Ekstrand <[email protected]>2015-05-20 17:05:41 -0700
commit14929046ba3a2d328d274522e34bcde6a19a47e5 (patch)
tree077b40715d59f8ccb97ffdad00706e02491fc38e /src/vulkan
parent47c1cf5ce68d0f76e749883627983f330c2c8d76 (diff)
vk/compiler: Add shader language detection
This commit adds support for the LunarG GLSL back-door as well as detecting regular GLSL and SPIR-V. The SPIR-V path doesn't exist yet, so that will cause an assert-fail.
Diffstat (limited to 'src/vulkan')
-rw-r--r--src/vulkan/compiler.cpp86
1 files changed, 73 insertions, 13 deletions
diff --git a/src/vulkan/compiler.cpp b/src/vulkan/compiler.cpp
index 7743fba2c9d..1907bd52cc8 100644
--- a/src/vulkan/compiler.cpp
+++ b/src/vulkan/compiler.cpp
@@ -38,6 +38,8 @@
#include <mesa/program/program.h>
#include <glsl/program.h>
+#define SPIR_V_MAGIC_NUMBER 0x07230203
+
static void
fail_if(int cond, const char *format, ...)
{
@@ -796,8 +798,35 @@ static const struct {
{ GL_COMPUTE_SHADER, "compute" },
};
+struct spirv_header{
+ uint32_t magic;
+ uint32_t version;
+ uint32_t gen_magic;
+};
+
+static const char *
+src_as_glsl(const char *data)
+{
+ const struct spirv_header *as_spirv = (const struct spirv_header *)data;
+
+ /* Check alignment */
+ if ((intptr_t)data & 0x3) {
+ return data;
+ }
+
+ if (as_spirv->magic == SPIR_V_MAGIC_NUMBER) {
+ /* LunarG back-door */
+ if (as_spirv->version == 0)
+ return data + 12;
+ else
+ return NULL;
+ } else {
+ return data;
+ }
+}
+
static void
-anv_compile_shader(struct anv_compiler *compiler,
+anv_compile_shader_glsl(struct anv_compiler *compiler,
struct gl_shader_program *program,
struct anv_pipeline *pipeline, uint32_t stage)
{
@@ -807,7 +836,8 @@ anv_compile_shader(struct anv_compiler *compiler,
shader = brw_new_shader(&brw->ctx, name, stage_info[stage].token);
fail_if(shader == NULL, "failed to create %s shader\n", stage_info[stage].name);
- shader->Source = strdup(pipeline->shaders[stage]->data);
+
+ shader->Source = strdup(src_as_glsl(pipeline->shaders[stage]->data));
_mesa_glsl_compile_shader(&brw->ctx, shader, false, false);
fail_on_compile_error(shader->CompileStatus, shader->InfoLog);
@@ -815,13 +845,20 @@ anv_compile_shader(struct anv_compiler *compiler,
program->NumShaders++;
}
+static void
+anv_compile_shader_spirv(struct anv_compiler *compiler,
+ struct gl_shader_program *program,
+ struct anv_pipeline *pipeline, uint32_t stage)
+{
+ unreachable("SPIR-V is not supported yet!");
+}
+
int
anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipeline)
{
struct gl_shader_program *program;
int name = 0;
struct brw_context *brw = compiler->brw;
- struct anv_device *device = pipeline->device;
/* When we free the pipeline, we detect stages based on the NULL status
* of various prog_data pointers. Make them NULL by default.
@@ -837,18 +874,41 @@ anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipeline)
fail_if(program == NULL || program->Shaders == NULL,
"failed to create program\n");
- if (pipeline->shaders[VK_SHADER_STAGE_VERTEX])
- anv_compile_shader(compiler, program, pipeline, VK_SHADER_STAGE_VERTEX);
- anv_compile_shader(compiler, program, pipeline, VK_SHADER_STAGE_FRAGMENT);
- if (pipeline->shaders[VK_SHADER_STAGE_GEOMETRY])
- anv_compile_shader(compiler, program, pipeline, VK_SHADER_STAGE_GEOMETRY);
+ bool all_spirv = true;
+ for (unsigned i = 0; i < VK_NUM_SHADER_STAGE; i++) {
+ if (pipeline->shaders[i] == NULL)
+ continue;
+
+ /* You need at least this much for "void main() { }" anyway */
+ assert(pipeline->shaders[i]->size >= 12);
+
+ if (src_as_glsl(pipeline->shaders[i]->data)) {
+ all_spirv = false;
+ break;
+ }
+
+ assert(pipeline->shaders[i]->size % 4 == 0);
+ }
+
+ assert(pipeline->shaders[VK_SHADER_STAGE_FRAGMENT] != NULL);
- _mesa_glsl_link_shader(&brw->ctx, program);
- fail_on_compile_error(program->LinkStatus,
- program->InfoLog);
+ if (all_spirv) {
+ for (unsigned i = 0; i < VK_NUM_SHADER_STAGE; i++) {
+ if (pipeline->shaders[i])
+ anv_compile_shader_spirv(compiler, program, pipeline, i);
+ }
- anv_state_stream_init(&pipeline->program_stream,
- &device->instruction_block_pool);
+ /* TODO: nir_link_shader? */
+ } else {
+ for (unsigned i = 0; i < VK_NUM_SHADER_STAGE; i++) {
+ if (pipeline->shaders[i])
+ anv_compile_shader_glsl(compiler, program, pipeline, i);
+ }
+
+ _mesa_glsl_link_shader(&brw->ctx, program);
+ fail_on_compile_error(program->LinkStatus,
+ program->InfoLog);
+ }
bool success;
struct brw_wm_prog_key wm_key;