intel: Support GLSL compiling in less intrusive way
Removed all the extension semantics. Support for compiling GLSL in the
driver is intended to be a tempory feature and these changes minimize
the impact on the driver and make it easier to remove in the future.
diff --git a/icd/intel/compiler/shader/compiler_interface.cpp b/icd/intel/compiler/shader/compiler_interface.cpp
index e8070a1..3e1ea99 100644
--- a/icd/intel/compiler/shader/compiler_interface.cpp
+++ b/icd/intel/compiler/shader/compiler_interface.cpp
@@ -242,13 +242,18 @@
// invoke front end compiler to generate an independently linked
// program object that contains Mesa HIR
-struct gl_shader_program *shader_create_program_bil(struct intel_shader *sh,
- const icd_bil_header *bil,
+struct gl_shader_program *shader_create_program(struct intel_shader *sh,
+ const void *code,
XGL_SIZE size)
{
+ struct icd_bil_header header;
struct gl_context local_ctx;
struct gl_context *ctx = &local_ctx;
+ memcpy(&header, code, sizeof(header));
+ if (header.magic != ICD_BIL_MAGIC)
+ return NULL;
+
_mesa_create_shader_compiler();
initialize_mesa_context_to_defaults(ctx);
@@ -266,116 +271,55 @@
shader_program->Shaders[shader_program->NumShaders] = shader;
shader_program->NumShaders++;
- shader->Source = (const GLchar*)bil;
- shader->Size = size / sizeof(unsigned); // size in BIL words
+ if (header.version == 0) {
+ // version 0 means we really have GLSL Source
+ shader->Source = (const char *) code + sizeof(header);
- glbil::ExecutionModel executionModel = glbil::ModelVertex;
-
- unsigned bilWord = 5;
-
- while (bilWord < size) {
- const unsigned opWord = ((unsigned int*)bil)[bilWord];
- const glbil::OpCode op = glbil::OpCode((opWord & 0xffff));
-
- if (op == glbil::OpEntryPoint) {
- executionModel = glbil::ExecutionModel(((unsigned int*)bil)[bilWord+1]);
+ switch(header.gen_magic) {
+ case XGL_SHADER_STAGE_VERTEX:
+ shader->Type = GL_VERTEX_SHADER;
+ break;
+ case XGL_SHADER_STAGE_FRAGMENT:
+ shader->Type = GL_FRAGMENT_SHADER;
+ break;
+ default:
+ assert(0);
break;
}
+ } else {
- bilWord += (opWord & 0xffff0000) >> 16;
- }
+ shader->Source = (const GLchar*)code;
+ shader->Size = size / sizeof(unsigned); // size in BIL words
- // We should parse the glsl text out of bil right now, but
- // instead we are just plopping down our glsl
- switch(executionModel) {
- case glbil::ModelVertex:
- shader->Type = GL_VERTEX_SHADER;
- break;
- case glbil::ModelFragment:
- shader->Type = GL_FRAGMENT_SHADER;
- break;
- default:
- assert(0);
- break;
- }
+ glbil::ExecutionModel executionModel = glbil::ModelVertex;
- shader->Stage = _mesa_shader_enum_to_shader_stage(shader->Type);
+ unsigned bilWord = 5;
- struct _mesa_glsl_parse_state *state =
- new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader);
+ while (bilWord < size) {
+ const unsigned opWord = ((unsigned int*)code)[bilWord];
+ const glbil::OpCode op = glbil::OpCode((opWord & 0xffff));
- shader_program->Type = shader->Stage;
+ if (op == glbil::OpEntryPoint) {
+ executionModel = glbil::ExecutionModel(((unsigned int*)code)[bilWord+1]);
+ break;
+ }
- bool dump_ast = false;
- bool dump_hir = true;
- bool do_link = true;
+ bilWord += (opWord & 0xffff0000) >> 16;
+ }
- _mesa_glsl_compile_shader(ctx, shader, dump_ast, dump_hir);
-
- if (strlen(shader->InfoLog) > 0)
- printf("Info log:\n%s\n", shader->InfoLog);
-
- if (!shader->CompileStatus)
- return NULL;
-
- assert(shader_program->NumShaders == 1);
-
- // for XGL, we are independently compiling and linking individual
- // shaders, which matches this frontend's concept of SSO
- shader_program->SeparateShader = true;
-
- link_shaders(ctx, shader_program);
- if (!shader_program->LinkStatus)
- return NULL;
-
- if (strlen(shader_program->InfoLog) > 0)
- printf("Info log for linking:\n%s\n", shader_program->InfoLog);
-
- _mesa_destroy_shader_compiler();
-
- return shader_program;
-}
-
-
-// invoke front end compiler to generate an independently linked
-// program object that contains Mesa HIR
-struct gl_shader_program *shader_create_program_glsl(struct intel_shader *sh,
- const XGL_INTEL_COMPILE_GLSL *glsl_header)
-{
- struct gl_context local_ctx;
- struct gl_context *ctx = &local_ctx;
-
- _mesa_create_shader_compiler();
- initialize_mesa_context_to_defaults(ctx);
-
- struct gl_shader_program *shader_program = brw_new_shader_program(ctx, 0);
- assert(shader_program != NULL);
-
- shader_program->InfoLog = ralloc_strdup(shader_program, "");
- shader_program->Shaders =
- reralloc(shader_program, shader_program->Shaders,
- struct gl_shader *, shader_program->NumShaders + 1);
- assert(shader_program->Shaders != NULL);
-
- struct gl_shader *shader = rzalloc(shader_program, struct gl_shader);
-
- shader_program->Shaders[shader_program->NumShaders] = shader;
- shader_program->NumShaders++;
-
- shader->Source = glsl_header->pCode;
-
- // We should parse the glsl text out of bil right now, but
- // instead we are just plopping down our glsl
- switch(glsl_header->stage) {
- case XGL_SHADER_STAGE_VERTEX:
- shader->Type = GL_VERTEX_SHADER;
- break;
- case XGL_SHADER_STAGE_FRAGMENT:
- shader->Type = GL_FRAGMENT_SHADER;
- break;
- default:
- assert(0);
- break;
+ // We should parse the glsl text out of bil right now, but
+ // instead we are just plopping down our glsl
+ switch(executionModel) {
+ case glbil::ModelVertex:
+ shader->Type = GL_VERTEX_SHADER;
+ break;
+ case glbil::ModelFragment:
+ shader->Type = GL_FRAGMENT_SHADER;
+ break;
+ default:
+ assert(0);
+ break;
+ }
}
shader->Stage = _mesa_shader_enum_to_shader_stage(shader->Type);
diff --git a/icd/intel/compiler/shader/compiler_interface.h b/icd/intel/compiler/shader/compiler_interface.h
index 986daf9..4205d1c 100644
--- a/icd/intel/compiler/shader/compiler_interface.h
+++ b/icd/intel/compiler/shader/compiler_interface.h
@@ -40,11 +40,8 @@
void initialize_mesa_context_to_defaults(struct gl_context *ctx);
-struct gl_shader_program *shader_create_program_glsl(struct intel_shader *sh,
- const XGL_INTEL_COMPILE_GLSL *glsl_header);
-
-struct gl_shader_program *shader_create_program_bil(struct intel_shader *sh,
- const struct icd_bil_header *bil,
+struct gl_shader_program *shader_create_program(struct intel_shader *sh,
+ const void *code,
XGL_SIZE size);
void shader_destroy_program(struct gl_shader_program *shader_program);
diff --git a/icd/intel/intel.h b/icd/intel/intel.h
index dd2b064..4515b91 100644
--- a/icd/intel/intel.h
+++ b/icd/intel/intel.h
@@ -37,7 +37,6 @@
#include <xgl.h>
#include <xglDbg.h>
#include <xglWsiX11Ext.h>
-#include <xglIntelExt.h>
#include "icd.h"
#include "icd-bil.h"
diff --git a/icd/intel/obj.c b/icd/intel/obj.c
index 149553f..d5d3250 100644
--- a/icd/intel/obj.c
+++ b/icd/intel/obj.c
@@ -153,9 +153,7 @@
assert(info.header->struct_type == XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
break;
case XGL_DBG_OBJECT_SHADER:
- assert(info.header->struct_type == XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO ||
- (dbg->dev->exts[INTEL_EXT_COMPILE_GLSL] &&
- ((XGL_INTEL_STRUCTURE_TYPE)info.header->struct_type == XGL_INTEL_STRUCTURE_TYPE_SHADER_CREATE_INFO)));
+ assert(info.header->struct_type == XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO);
shallow_copy = sizeof(XGL_SHADER_CREATE_INFO);
break;
default:
diff --git a/icd/intel/shader.c b/icd/intel/shader.c
index 9e4a312..0f94002 100644
--- a/icd/intel/shader.c
+++ b/icd/intel/shader.c
@@ -30,32 +30,7 @@
#include "shader.h"
#include "compiler/shader/compiler_interface.h"
-static XGL_RESULT shader_parse_glsl(struct intel_shader *sh,
- const struct intel_gpu *gpu,
- const XGL_INTEL_COMPILE_GLSL *glsl_header,
- XGL_SIZE size)
-{
- struct intel_ir *ir;
-
- ir = icd_alloc(sizeof(*ir), 0, XGL_SYSTEM_ALLOC_INTERNAL_SHADER);
- if (!ir)
- return XGL_ERROR_OUT_OF_MEMORY;
-
- ir->size = size;
-
- // invoke our program creation as well
- ir->shader_program = shader_create_program_glsl(sh, glsl_header);
- if (!ir->shader_program)
- return XGL_ERROR_BAD_SHADER_CODE;
-
- // TODO: set necessary shader information. This should really
- // happen as result of create_program call.
- sh->ir = ir;
-
- return XGL_SUCCESS;
-}
-
-static XGL_RESULT shader_parse_bil(struct intel_shader *sh,
+static XGL_RESULT shader_parse(struct intel_shader *sh,
const struct intel_gpu *gpu,
const struct icd_bil_header *bil,
XGL_SIZE size)
@@ -69,7 +44,7 @@
ir->size = size - sizeof(*bil);
// invoke our program creation as well
- ir->shader_program = shader_create_program_bil(sh, bil, size);
+ ir->shader_program = shader_create_program(sh, bil, size);
if (!ir->shader_program)
return XGL_ERROR_BAD_SHADER_CODE;
@@ -105,28 +80,19 @@
if (!sh)
return XGL_ERROR_OUT_OF_MEMORY;
- if (dev->exts[INTEL_EXT_COMPILE_GLSL] &&
- info->sType == (XGL_STRUCTURE_TYPE) XGL_INTEL_STRUCTURE_TYPE_SHADER_CREATE_INFO) {
- // use GLSL compiler extension
- ret = shader_parse_glsl(sh, dev->gpu, info->pCode, info->codeSize);
- if (ret != XGL_SUCCESS) {
- shader_destroy(&sh->obj);
- return ret;
- }
- } else {
- if (info->codeSize < sizeof(*bil))
- return XGL_ERROR_INVALID_MEMORY_SIZE;
- if (bil->magic != ICD_BIL_MAGIC)
- return XGL_ERROR_BAD_SHADER_CODE;
+ if (info->codeSize < sizeof(*bil))
+ return XGL_ERROR_INVALID_MEMORY_SIZE;
+ if (bil->magic != ICD_BIL_MAGIC)
+ return XGL_ERROR_BAD_SHADER_CODE;
- ret = shader_parse_bil(sh, dev->gpu, bil, info->codeSize);
- if (ret != XGL_SUCCESS) {
- shader_destroy(&sh->obj);
- return ret;
- }
+ ret = shader_parse(sh, dev->gpu, bil, info->codeSize);
+ if (ret != XGL_SUCCESS) {
+ shader_destroy(&sh->obj);
+ return ret;
}
+
sh->obj.destroy = shader_destroy;
*sh_ret = sh;
diff --git a/include/xglIntelExt.h b/include/xglIntelExt.h
deleted file mode 100644
index 15c7f52..0000000
--- a/include/xglIntelExt.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* IN DEVELOPMENT. DO NOT SHIP. */
-
-#ifndef __XGLINTELEXT_H__
-#define __XGLINTELEXT_H__
-
-#include <xcb/xcb.h>
-#include <xcb/randr.h>
-#include "xgl.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif // __cplusplus
-
-typedef enum _XGL_INTEL_STRUCTURE_TYPE
-{
- XGL_INTEL_STRUCTURE_TYPE_SHADER_CREATE_INFO = 1000,
-} XGL_INTEL_STRUCTURE_TYPE;
-
-typedef struct _XGL_INTEL_COMPILE_GLSL
-{
- XGL_PIPELINE_SHADER_STAGE stage;
- const char *pCode;
-} XGL_INTEL_COMPILE_GLSL;
-
-#ifdef __cplusplus
-} // extern "C"
-#endif // __cplusplus
-
-#endif // __XGLINTELEXT_H__
diff --git a/tests/base_render_test.cpp b/tests/base_render_test.cpp
index 7bf9055..c40c38b 100644
--- a/tests/base_render_test.cpp
+++ b/tests/base_render_test.cpp
@@ -64,7 +64,6 @@
using namespace std;
#include <xgl.h>
-#include <xglIntelExt.h>
#include "gtest-1.7.0/include/gtest/gtest.h"
#include "xgldevice.h"
@@ -440,6 +439,7 @@
std::vector<unsigned int> bil;
XGL_SHADER_CREATE_INFO createInfo;
XGL_SHADER shader;
+ size_t shader_len;
XGL_IMAGE m_image;
XGL_COLOR_ATTACHMENT_VIEW m_targetView;
XGL_IMAGE_VIEW_ATTACH_INFO m_imageInfo;
@@ -563,46 +563,32 @@
" vertices[2] = vec2( 0.0, 1.0);\n"
" gl_Position = vec4(vertices[gl_VertexID % 3], 0.0, 1.0);\n"
"}\n";
- static const char *vertShader2 =
- "#version 330\n"
- "out vec4 color;\n"
- "out vec4 scale;\n"
- "void main() {\n"
- " vec2 vertices[3];"
- " vertices[0] = vec2(-0.5, -0.5);\n"
- " vertices[1] = vec2( 0.5, -0.5);\n"
- " vertices[2] = vec2( 0.5, 0.5);\n"
- " vec4 colors[3];\n"
- " colors[0] = vec4(1.0, 0.0, 0.0, 1.0);\n"
- " colors[1] = vec4(0.0, 1.0, 0.0, 1.0);\n"
- " colors[2] = vec4(0.0, 0.0, 1.0, 1.0);\n"
- " color = colors[int(mod(gl_VertexID, 3))];\n"
- " scale = vec4(1.0, 1.0, 1.0, 1.0);\n"
- " gl_Position = vec4(vertices[int(mod(gl_VertexID, 3))], 0.0, 1.0);\n"
- "}\n";
createInfo.sType = XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO;
createInfo.pNext = NULL;
- if (this->m_device->extension_exist("XGL_COMPILE_GLSL")) {
- XGL_INTEL_COMPILE_GLSL glsl_header;
+ shader_len = strlen(vertShaderText);
+ createInfo.codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
+ createInfo.pCode = malloc(createInfo.codeSize);
+ createInfo.flags = 0;
- glsl_header.stage = XGL_SHADER_STAGE_VERTEX;
- glsl_header.pCode = vertShader2;
- // Driver has extended CreateShader to process GLSL
- createInfo.sType = (XGL_STRUCTURE_TYPE) XGL_INTEL_STRUCTURE_TYPE_SHADER_CREATE_INFO;
- createInfo.pCode = &glsl_header;
- createInfo.codeSize = strlen(vertShader2);
- createInfo.flags = 0;
- } else {
+ /* try version 0 first: XGL_PIPELINE_SHADER_STAGE followed by GLSL */
+ ((uint32_t *) createInfo.pCode)[0] = ICD_BIL_MAGIC;
+ ((uint32_t *) createInfo.pCode)[1] = 0;
+ ((uint32_t *) createInfo.pCode)[2] = XGL_SHADER_STAGE_VERTEX;
+ memcpy(((uint32_t *) createInfo.pCode + 3), vertShaderText, shader_len + 1);
+
+ err = xglCreateShader(device(), &createInfo, &shader);
+ if (err) {
+ free((void *) createInfo.pCode);
+
// Use Reference GLSL to BIL compiler
- GLSLtoBIL(XGL_SHADER_STAGE_VERTEX, vertShader2, bil);
+ GLSLtoBIL(XGL_SHADER_STAGE_VERTEX, vertShaderText, bil);
createInfo.pCode = bil.data();
createInfo.codeSize = bil.size() * sizeof(unsigned int);
createInfo.flags = 0;
+ err = xglCreateShader(device(), &createInfo, &shader);
}
-
- err = xglCreateShader(device(), &createInfo, &vs);
ASSERT_XGL_SUCCESS(err);
vs_stage.sType = XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@@ -621,37 +607,32 @@
"void main() {\n"
" gl_FragColor = foo;\n"
"}\n";
- static const char *fragShader2 =
- "#version 430\n"
- "in vec4 color;\n"
- "in vec4 scale;\n"
- "layout(location = 0) uniform vec4 foo;\n"
- "void main() {\n"
- " gl_FragColor = color * scale + foo;\n"
- "}\n";
createInfo.sType = XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO;
createInfo.pNext = NULL;
- if (this->m_device->extension_exist("XGL_COMPILE_GLSL")) {
- XGL_INTEL_COMPILE_GLSL glsl_header;
+ shader_len = strlen(fragShaderText);
+ createInfo.codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
+ createInfo.pCode = malloc(createInfo.codeSize);
+ createInfo.flags = 0;
- glsl_header.stage = XGL_SHADER_STAGE_FRAGMENT;
- glsl_header.pCode = fragShader2;
- // Driver has extended CreateShader to process GLSL
- createInfo.sType = (XGL_STRUCTURE_TYPE) XGL_INTEL_STRUCTURE_TYPE_SHADER_CREATE_INFO;
- createInfo.pCode = &glsl_header;
- createInfo.codeSize = strlen(fragShader2);
- createInfo.flags = 0;
- } else {
+ /* try version 0 first: XGL_PIPELINE_SHADER_STAGE followed by GLSL */
+ ((uint32_t *) createInfo.pCode)[0] = ICD_BIL_MAGIC;
+ ((uint32_t *) createInfo.pCode)[1] = 0;
+ ((uint32_t *) createInfo.pCode)[2] = XGL_SHADER_STAGE_VERTEX;
+ memcpy(((uint32_t *) createInfo.pCode + 3), fragShaderText, shader_len + 1);
+
+ err = xglCreateShader(device(), &createInfo, &ps);
+ if (err) {
+ free((void *) createInfo.pCode);
+
// Use Reference GLSL to BIL compiler
- GLSLtoBIL(XGL_SHADER_STAGE_FRAGMENT, fragShader2, bil);
+ GLSLtoBIL(XGL_SHADER_STAGE_VERTEX, fragShaderText, bil);
createInfo.pCode = bil.data();
createInfo.codeSize = bil.size() * sizeof(unsigned int);
createInfo.flags = 0;
+ err = xglCreateShader(device(), &createInfo, &ps);
}
-
- err = xglCreateShader(device(), &createInfo, &ps);
ASSERT_XGL_SUCCESS(err);
ps_stage.sType = XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
diff --git a/tests/render_tests.cpp b/tests/render_tests.cpp
index 3b61d0b..d82951e 100644
--- a/tests/render_tests.cpp
+++ b/tests/render_tests.cpp
@@ -61,7 +61,6 @@
using namespace std;
#include <xgl.h>
-#include <xglIntelExt.h>
#include "gtest-1.7.0/include/gtest/gtest.h"
#include "xgldevice.h"
diff --git a/tests/xglrenderframework.cpp b/tests/xglrenderframework.cpp
index dcfb04f..547b580 100644
--- a/tests/xglrenderframework.cpp
+++ b/tests/xglrenderframework.cpp
@@ -26,7 +26,6 @@
*/
#include "xglrenderframework.h"
-#include "xglIntelExt.h"
XglRenderFramework::XglRenderFramework() :
m_colorBlend( XGL_NULL_HANDLE ),
@@ -234,33 +233,43 @@
const char *shader_code,
XGL_SHADER *pshader)
{
- XGL_RESULT err;
+ XGL_RESULT err = XGL_SUCCESS;
std::vector<unsigned int> bil;
XGL_SHADER_CREATE_INFO createInfo;
+ size_t shader_len;
XGL_SHADER shader;
createInfo.sType = XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO;
createInfo.pNext = NULL;
- if (!this->m_use_bil && this->m_device->extension_exist("XGL_COMPILE_GLSL")) {
- XGL_INTEL_COMPILE_GLSL glsl_header;
-
- glsl_header.stage = stage;
- glsl_header.pCode = shader_code;
- // Driver has extended CreateShader to process GLSL
- createInfo.sType = (XGL_STRUCTURE_TYPE) XGL_INTEL_STRUCTURE_TYPE_SHADER_CREATE_INFO;
- createInfo.pCode = &glsl_header;
- createInfo.codeSize = strlen(shader_code);
+ if (!this->m_use_bil) {
+ shader_len = strlen(shader_code);
+ createInfo.codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
+ createInfo.pCode = malloc(createInfo.codeSize);
createInfo.flags = 0;
- } else {
+
+ /* try version 0 first: XGL_PIPELINE_SHADER_STAGE followed by GLSL */
+ ((uint32_t *) createInfo.pCode)[0] = ICD_BIL_MAGIC;
+ ((uint32_t *) createInfo.pCode)[1] = 0;
+ ((uint32_t *) createInfo.pCode)[2] = stage;
+ memcpy(((uint32_t *) createInfo.pCode + 3), shader_code, shader_len + 1);
+
+ err = xglCreateShader(device(), &createInfo, &shader);
+ if (err) {
+ free((void *) createInfo.pCode);
+ }
+ }
+
+ // Only use BIL if GLSL compile fails or it's requested via m_use_bil
+ if (this->m_use_bil || err) {
// Use Reference GLSL to BIL compiler
GLSLtoBIL(stage, shader_code, bil);
createInfo.pCode = bil.data();
createInfo.codeSize = bil.size() * sizeof(unsigned int);
createInfo.flags = 0;
+ err = xglCreateShader(device(), &createInfo, &shader);
}
- err = xglCreateShader(device(), &createInfo, &shader);
ASSERT_XGL_SUCCESS(err);
*pshader = shader;
diff --git a/tests/xgltestframework.h b/tests/xgltestframework.h
index fe9cfd2..becf085 100644
--- a/tests/xgltestframework.h
+++ b/tests/xgltestframework.h
@@ -27,6 +27,7 @@
#include "xglimage.h"
#include "ShaderLang.h"
#include "GLSL450Lib.h"
+#include "icd-bil.h"
#include <stdlib.h>
#include <stdio.h>