Commit 34d271ba authored by Jason Green's avatar Jason Green Committed by Alexandre Julliard

wined3d: Add preliminary support for constant boolean and integer registers in GLSL.

- Separate the declaration phase of the shader string generator into the arb and glsl specific files. - Add declarations and recognition for application-sent constant integers and booleans (locally defined ones will follow). - Standardize capitilization of pixel/vertex specific variable names.
parent 2d8e05f8
......@@ -108,4 +108,40 @@ void shader_arb_load_constants(
}
}
/* Generate the variable & register declarations for the ARB_vertex_program output target */
void shader_generate_arb_declarations(
IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps,
SHADER_BUFFER* buffer) {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
DWORD i;
for(i = 0; i < This->baseShader.limits.temporary; i++) {
if (reg_maps->temporary[i])
shader_addline(buffer, "TEMP R%lu;\n", i);
}
for (i = 0; i < This->baseShader.limits.address; i++) {
if (reg_maps->address[i])
shader_addline(buffer, "ADDRESS A%ld;\n", i);
}
for(i = 0; i < This->baseShader.limits.texcoord; i++) {
if (reg_maps->texcoord[i])
shader_addline(buffer,"TEMP T%lu;\n", i);
}
/* Texture coordinate registers must be pre-loaded */
for (i = 0; i < This->baseShader.limits.texcoord; i++) {
if (reg_maps->texcoord[i])
shader_addline(buffer, "MOV T%lu, fragment.texcoord[%lu];\n", i, i);
}
/* Need to PARAM the environment parameters (constants) so we can use relative addressing */
shader_addline(buffer, "PARAM C[%d] = { program.env[0..%d] };\n",
This->baseShader.limits.constant_float,
This->baseShader.limits.constant_float - 1);
}
/* TODO: Add more ARB_[vertex/fragment]_program specific code here */
......@@ -679,134 +679,6 @@ void shader_dump_param(
}
}
/* Generate the variable & register declarations for the ARB_vertex_program output target */
void shader_generate_arb_declarations(
IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps,
SHADER_BUFFER* buffer) {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
DWORD i;
for(i = 0; i < This->baseShader.limits.temporary; i++) {
if (reg_maps->temporary[i])
shader_addline(buffer, "TEMP R%lu;\n", i);
}
for (i = 0; i < This->baseShader.limits.address; i++) {
if (reg_maps->address[i])
shader_addline(buffer, "ADDRESS A%ld;\n", i);
}
for(i = 0; i < This->baseShader.limits.texcoord; i++) {
if (reg_maps->texcoord[i])
shader_addline(buffer,"TEMP T%lu;\n", i);
}
/* Texture coordinate registers must be pre-loaded */
for (i = 0; i < This->baseShader.limits.texcoord; i++) {
if (reg_maps->texcoord[i])
shader_addline(buffer, "MOV T%lu, fragment.texcoord[%lu];\n", i, i);
}
/* Need to PARAM the environment parameters (constants) so we can use relative addressing */
shader_addline(buffer, "PARAM C[%d] = { program.env[0..%d] };\n",
This->baseShader.limits.constant_float,
This->baseShader.limits.constant_float - 1);
}
/** Generate the variable & register declarations for the GLSL output target */
void shader_generate_glsl_declarations(
IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps,
SHADER_BUFFER* buffer) {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
int i;
/* There are some minor differences between pixel and vertex shaders */
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
/* Declare the constants (aka uniforms) */
if (pshader)
shader_addline(buffer, "uniform vec4 PC[%u];\n", This->baseShader.limits.constant_float);
else
shader_addline(buffer, "uniform vec4 VC[%u];\n", This->baseShader.limits.constant_float);
/* Declare texture samplers */
for (i = 0; i < This->baseShader.limits.sampler; i++) {
if (reg_maps->samplers[i]) {
const char* prefix = pshader? "psampler": "vsampler";
DWORD stype = reg_maps->samplers[i] & D3DSP_TEXTURETYPE_MASK;
switch (stype) {
case D3DSTT_2D:
shader_addline(buffer, "uniform sampler2D %s%lu;\n", prefix, i);
break;
case D3DSTT_CUBE:
shader_addline(buffer, "uniform samplerCube %s%lu;\n", prefix, i);
break;
case D3DSTT_VOLUME:
shader_addline(buffer, "uniform sampler3D %s%lu;\n", prefix, i);
break;
default:
shader_addline(buffer, "uniform unsupported_sampler %s%lu;\n", prefix, i);
FIXME("Unrecognized sampler type: %#lx\n", stype);
break;
}
}
}
/* Declare address variables */
for (i = 0; i < This->baseShader.limits.address; i++) {
if (reg_maps->address[i])
shader_addline(buffer, "ivec4 A%ld;\n", i);
}
/* Declare texture coordinate temporaries and initialize them */
for (i = 0; i < This->baseShader.limits.texcoord; i++) {
if (reg_maps->texcoord[i])
shader_addline(buffer, "vec4 T%lu = gl_TexCoord[%lu];\n", i, i);
}
/* Declare input register temporaries */
for (i=0; i < This->baseShader.limits.packed_input; i++) {
if (reg_maps->packed_input[i])
shader_addline(buffer, "vec4 IN%lu;\n", i);
}
/* Declare output register temporaries */
for (i = 0; i < This->baseShader.limits.packed_output; i++) {
if (reg_maps->packed_output[i])
shader_addline(buffer, "vec4 OUT%lu;\n", i);
}
/* Declare temporary variables */
for(i = 0; i < This->baseShader.limits.temporary; i++) {
if (reg_maps->temporary[i])
shader_addline(buffer, "vec4 R%lu;\n", i);
}
/* Declare attributes */
for (i = 0; i < This->baseShader.limits.attributes; i++) {
if (reg_maps->attributes[i])
shader_addline(buffer, "attribute vec4 attrib%i;\n", i);
}
/* Declare loop register aL */
if (reg_maps->loop)
shader_addline(buffer, "int aL;\n");
/* Temporary variables for matrix operations */
shader_addline(buffer, "vec4 tmp0;\n");
shader_addline(buffer, "vec4 tmp1;\n");
/* Start the main program */
shader_addline(buffer, "void main() {\n");
}
/** Shared code in order to generate the bulk of the shader string.
Use the shader_header_fct & shader_footer_fct to add strings
that are specific to pixel or vertex functions
......
......@@ -62,7 +62,7 @@ void shader_glsl_load_psamplers(
for (i=0; i< GL_LIMITS(textures); ++i) {
if (stateBlock->textures[i] != NULL) {
snprintf(sampler_name, sizeof(sampler_name), "psampler%d", i);
snprintf(sampler_name, sizeof(sampler_name), "Psampler%d", i);
name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name));
if (name_loc != -1) {
TRACE_(d3d_shader)("Loading %s for texture %d\n", sampler_name, i);
......@@ -160,6 +160,101 @@ void shader_glsl_load_constants(
}
}
/** Generate the variable & register declarations for the GLSL output target */
void shader_generate_glsl_declarations(
IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps,
SHADER_BUFFER* buffer) {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
int i;
/* There are some minor differences between pixel and vertex shaders */
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
char prefix = pshader ? 'P' : 'V';
/* Declare the constants (aka uniforms) */
if (This->baseShader.limits.constant_float > 0)
shader_addline(buffer, "uniform vec4 %cC[%u];\n", prefix, This->baseShader.limits.constant_float);
if (This->baseShader.limits.constant_int > 0)
shader_addline(buffer, "uniform ivec4 %cI[%u];\n", prefix, This->baseShader.limits.constant_int);
if (This->baseShader.limits.constant_bool > 0)
shader_addline(buffer, "uniform bool %cB[%u];\n", prefix, This->baseShader.limits.constant_bool);
/* Declare texture samplers */
for (i = 0; i < This->baseShader.limits.sampler; i++) {
if (reg_maps->samplers[i]) {
DWORD stype = reg_maps->samplers[i] & D3DSP_TEXTURETYPE_MASK;
switch (stype) {
case D3DSTT_2D:
shader_addline(buffer, "uniform sampler2D %csampler%lu;\n", prefix, i);
break;
case D3DSTT_CUBE:
shader_addline(buffer, "uniform samplerCube %csampler%lu;\n", prefix, i);
break;
case D3DSTT_VOLUME:
shader_addline(buffer, "uniform sampler3D %csampler%lu;\n", prefix, i);
break;
default:
shader_addline(buffer, "uniform unsupported_sampler %csampler%lu;\n", prefix, i);
FIXME("Unrecognized sampler type: %#lx\n", stype);
break;
}
}
}
/* Declare address variables */
for (i = 0; i < This->baseShader.limits.address; i++) {
if (reg_maps->address[i])
shader_addline(buffer, "ivec4 A%ld;\n", i);
}
/* Declare texture coordinate temporaries and initialize them */
for (i = 0; i < This->baseShader.limits.texcoord; i++) {
if (reg_maps->texcoord[i])
shader_addline(buffer, "vec4 T%lu = gl_TexCoord[%lu];\n", i, i);
}
/* Declare input register temporaries */
for (i=0; i < This->baseShader.limits.packed_input; i++) {
if (reg_maps->packed_input[i])
shader_addline(buffer, "vec4 IN%lu;\n", i);
}
/* Declare output register temporaries */
for (i = 0; i < This->baseShader.limits.packed_output; i++) {
if (reg_maps->packed_output[i])
shader_addline(buffer, "vec4 OUT%lu;\n", i);
}
/* Declare temporary variables */
for(i = 0; i < This->baseShader.limits.temporary; i++) {
if (reg_maps->temporary[i])
shader_addline(buffer, "vec4 R%lu;\n", i);
}
/* Declare attributes */
for (i = 0; i < This->baseShader.limits.attributes; i++) {
if (reg_maps->attributes[i])
shader_addline(buffer, "attribute vec4 attrib%i;\n", i);
}
/* Declare loop register aL */
if (reg_maps->loop)
shader_addline(buffer, "int aL;\n");
/* Temporary variables for matrix operations */
shader_addline(buffer, "vec4 tmp0;\n");
shader_addline(buffer, "vec4 tmp1;\n");
/* Start the main program */
shader_addline(buffer, "void main() {\n");
}
/*****************************************************************************
* Functions to generate GLSL strings from DirectX Shader bytecode begin here.
*
......@@ -322,7 +417,7 @@ static void shader_glsl_get_register_name(
const char* prefix = pshader? "PC":"VC";
if (arg->reg_maps->constantsF[reg]) {
/* Use a local constant declared by "dcl" */
/* Use a local constant declared by "def" */
if (param & D3DVS_ADDRMODE_RELATIVE) {
/* FIXME: Copy all constants (local & global) into a single array
......@@ -351,6 +446,32 @@ static void shader_glsl_get_register_name(
}
break;
}
case D3DSPR_CONSTINT:
if (arg->reg_maps->constantsI[reg]) {
/* Integer vector was defined locally using "defi" */
sprintf(tmpStr, "I%lu", reg);
} else {
/* Uniform integer value - pixel or vertex specific */
if (pshader) {
sprintf(tmpStr, "PI[%lu]", reg);
} else {
sprintf(tmpStr, "VI[%lu]", reg);
}
}
break;
case D3DSPR_CONSTBOOL:
if (arg->reg_maps->constantsB[reg]) {
/* Boolean was defined locally using "defb" */
sprintf(tmpStr, "B%lu", reg);
} else {
/* Uniform boolean value - pixel or vertex specific */
if (pshader) {
sprintf(tmpStr, "PB[%lu]", reg);
} else {
sprintf(tmpStr, "VB[%lu]", reg);
}
}
break;
case D3DSPR_TEXTURE: /* case D3DSPR_ADDR: */
if (pshader) {
sprintf(tmpStr, "T%lu", reg);
......@@ -363,9 +484,9 @@ static void shader_glsl_get_register_name(
break;
case D3DSPR_SAMPLER:
if (pshader)
sprintf(tmpStr, "psampler%lu", reg);
sprintf(tmpStr, "Psampler%lu", reg);
else
sprintf(tmpStr, "vsampler%lu", reg);
sprintf(tmpStr, "Vsampler%lu", reg);
break;
case D3DSPR_COLOROUT:
if (reg == 0)
......@@ -963,7 +1084,7 @@ void pshader_glsl_tex(SHADER_OPCODE_ARG* arg) {
/* 1.0-1.4: Use destination register as coordinate source.
* 2.0+: Use provided coordinate source register. */
if (hex_version < D3DPS_VERSION(2,0)) {
sprintf(sampler_str, "psampler%lu", reg_dest_code);
sprintf(sampler_str, "Psampler%lu", reg_dest_code);
sampler_code = reg_dest_code;
}
else {
......@@ -1040,7 +1161,7 @@ void pshader_glsl_texm3x2tex(SHADER_OPCODE_ARG* arg) {
shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_name, src0_mask, src0_str);
shader_addline(buffer, "tmp0.y = dot(vec3(T%lu), vec3(%s));\n", reg, src0_str);
shader_addline(buffer, "T%lu = texture2D(psampler%lu, tmp0.st);\n", reg, reg);
shader_addline(buffer, "T%lu = texture2D(Psampler%lu, tmp0.st);\n", reg, reg);
}
void pshader_glsl_input_pack(
......
......@@ -1255,6 +1255,8 @@ struct glsl_shader_prog_link {
#define MAX_REG_OUTPUT 12
#define MAX_ATTRIBS 16
#define MAX_CONST_F 256
#define MAX_CONST_I 16
#define MAX_CONST_B 16
typedef struct shader_reg_maps {
......@@ -1266,8 +1268,9 @@ typedef struct shader_reg_maps {
char attributes[MAX_ATTRIBS]; /* vertex */
char constantsF[MAX_CONST_F]; /* pixel, vertex */
/* TODO: Integer and bool constants */
char constantsI[MAX_CONST_I]; /* pixel & vertex >= 2.0 */
char constantsB[MAX_CONST_B]; /* pixel & vertex >= 2.0 */
/* Semantics maps (semantic -> reg_token)
* Use 0 as default (bit 31 is always 1 on a valid token) */
DWORD* semantics_in; /* vertex, pixel */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment