wined3d: Add ability to generate GLSL shader objects for vertex and pixel shaders.
This commit is contained in:
parent
0161d6b636
commit
473ce80fa2
|
@ -549,8 +549,34 @@ void generate_glsl_declarations(
|
|||
shader_reg_maps* reg_maps,
|
||||
SHADER_BUFFER* buffer) {
|
||||
|
||||
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
|
||||
int i;
|
||||
|
||||
FIXME("GLSL not fully implemented yet.\n");
|
||||
|
||||
/* Declare the constants (aka uniforms) */
|
||||
shader_addline(buffer, "uniform vec4 C[%u];\n", This->baseShader.limits.constant_float);
|
||||
|
||||
/* Declare address variables */
|
||||
for (i = 0; i < This->baseShader.limits.address; i++) {
|
||||
if (reg_maps->address & (1 << i))
|
||||
shader_addline(buffer, "ivec4 A%ld;\n", i);
|
||||
}
|
||||
|
||||
/* Declare all named attributes (TODO: Add this to the reg_maps
|
||||
* and only declare those that are needed) */
|
||||
for (i = 0; i < This->baseShader.limits.attributes; i++) {
|
||||
shader_addline(buffer, "attribute vec4 attrib%i;\n", i);
|
||||
}
|
||||
|
||||
/* Declare temporary variables */
|
||||
for(i = 0; i < This->baseShader.limits.temporary; i++) {
|
||||
if (reg_maps->temporary & (1 << i))
|
||||
shader_addline(buffer, "vec4 R%lu;\n", i);
|
||||
}
|
||||
|
||||
/* Start the main program */
|
||||
shader_addline(buffer, "void main() {\n");
|
||||
}
|
||||
|
||||
/** Shared code in order to generate the bulk of the shader string.
|
||||
|
@ -585,7 +611,6 @@ void generate_base_shader(
|
|||
/* Pre-declare registers */
|
||||
if (wined3d_settings.shader_mode == SHADER_GLSL) {
|
||||
generate_glsl_declarations(iface, ®_maps, buffer);
|
||||
shader_addline(buffer, "void main() {\n");
|
||||
} else {
|
||||
generate_arb_declarations(iface, ®_maps, buffer);
|
||||
}
|
||||
|
@ -680,8 +705,7 @@ void generate_base_shader(
|
|||
/** Prints the GLSL info log which will contain error messages if they exist */
|
||||
void print_glsl_info_log(
|
||||
WineD3D_GL_Info *gl_info,
|
||||
GLhandleARB obj)
|
||||
{
|
||||
GLhandleARB obj) {
|
||||
int infologLength = 0;
|
||||
char *infoLog;
|
||||
|
||||
|
@ -689,11 +713,13 @@ void print_glsl_info_log(
|
|||
GL_OBJECT_INFO_LOG_LENGTH_ARB,
|
||||
&infologLength));
|
||||
|
||||
if (infologLength > 0)
|
||||
/* A size of 1 is just a null-terminated string, so the log should be bigger than
|
||||
* that if there are errors. */
|
||||
if (infologLength > 1)
|
||||
{
|
||||
infoLog = (char *)HeapAlloc(GetProcessHeap(), 0, infologLength);
|
||||
GL_EXTCALL(glGetInfoLogARB(obj, infologLength, NULL, infoLog));
|
||||
FIXME("Error received from GLSL shader #%u: %s", obj, debugstr_a(infoLog));
|
||||
FIXME("Error received from GLSL shader #%u: %s\n", obj, debugstr_a(infoLog));
|
||||
HeapFree(GetProcessHeap(), 0, infoLog);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -941,6 +941,7 @@ void pshader_set_version(
|
|||
This->baseShader.version = major * 10 + minor;
|
||||
TRACE("ps_%lu_%lu\n", major, minor);
|
||||
|
||||
This->baseShader.limits.attributes = 0;
|
||||
This->baseShader.limits.address = 0;
|
||||
|
||||
switch (This->baseShader.version) {
|
||||
|
@ -1298,8 +1299,28 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
|
|||
buffer.bsize = 0;
|
||||
buffer.lineNo = 0;
|
||||
|
||||
/* TODO: Optionally, generate the GLSL shader instead */
|
||||
if (GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
|
||||
if (wined3d_settings.shader_mode == SHADER_GLSL) {
|
||||
|
||||
/* Create the hw GLSL shader object and assign it as the baseShader.prgId */
|
||||
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
|
||||
|
||||
/* Generate the bulk of the shader code */
|
||||
generate_base_shader( (IWineD3DBaseShader*) This, &buffer, pFunction);
|
||||
|
||||
/* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
|
||||
if (This->baseShader.hex_version < D3DPS_VERSION(2,0))
|
||||
shader_addline(&buffer, "glFragColor = R0;\n");
|
||||
shader_addline(&buffer, "}\n\0");
|
||||
|
||||
TRACE("Compiling shader object %u\n", shader_obj);
|
||||
GL_EXTCALL(glShaderSourceARB(shader_obj, 1, (const char**)&buffer.buffer, NULL));
|
||||
GL_EXTCALL(glCompileShaderARB(shader_obj));
|
||||
print_glsl_info_log(&GLINFO_LOCATION, shader_obj);
|
||||
|
||||
/* Store the shader object */
|
||||
This->baseShader.prgId = shader_obj;
|
||||
|
||||
} else if (wined3d_settings.shader_mode == SHADER_ARB) {
|
||||
/* Create the hw ARB shader */
|
||||
shader_addline(&buffer, "!!ARBfp1.0\n");
|
||||
|
||||
|
|
|
@ -842,6 +842,7 @@ void vshader_set_version(
|
|||
TRACE("vs_%lu_%lu\n", major, minor);
|
||||
|
||||
This->baseShader.limits.texture = 0;
|
||||
This->baseShader.limits.attributes = 16;
|
||||
|
||||
/* Must match D3DCAPS9.MaxVertexShaderConst: at least 256 for vs_2_0 */
|
||||
This->baseShader.limits.constant_float = WINED3D_VSHADER_MAX_CONSTANTS;
|
||||
|
@ -1063,8 +1064,26 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
|
|||
buffer.bsize = 0;
|
||||
buffer.lineNo = 0;
|
||||
|
||||
/* TODO: Optionally, generate the GLSL shader instead */
|
||||
if (GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
|
||||
if (wined3d_settings.shader_mode == SHADER_GLSL) {
|
||||
|
||||
/* Create the hw GLSL shader program and assign it as the baseShader.prgId */
|
||||
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
|
||||
|
||||
/* Generate the bulk of the shader code */
|
||||
generate_base_shader( (IWineD3DBaseShader*) This, &buffer, pFunction);
|
||||
|
||||
shader_addline(&buffer, "}\n\0");
|
||||
|
||||
TRACE("Compiling shader object %u\n", shader_obj);
|
||||
GL_EXTCALL(glShaderSourceARB(shader_obj, 1, (const char**)&buffer.buffer, NULL));
|
||||
GL_EXTCALL(glCompileShaderARB(shader_obj));
|
||||
print_glsl_info_log(&GLINFO_LOCATION, shader_obj);
|
||||
|
||||
/* Store the shader object */
|
||||
This->baseShader.prgId = shader_obj;
|
||||
|
||||
} else if (wined3d_settings.shader_mode == SHADER_ARB) {
|
||||
|
||||
/* Create the hw ARB shader */
|
||||
shader_addline(&buffer, "!!ARBvp1.0\n");
|
||||
|
||||
|
|
|
@ -1282,6 +1282,7 @@ typedef struct SHADER_LIMITS {
|
|||
unsigned int constant_float;
|
||||
unsigned int constant_bool;
|
||||
unsigned int address;
|
||||
unsigned int attributes;
|
||||
} SHADER_LIMITS;
|
||||
|
||||
/** Keeps track of details for TEX_M#x# shader opcodes which need to
|
||||
|
|
Loading…
Reference in New Issue