diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index 1275dd55ad82bd821ce4fa6fc1b086315ef95807..b3823c2ec5292d33407e0ac180032994137c10b0 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -277,7 +277,14 @@ HRESULT shader_get_registers_used( D3DSIO_REP == curOpcode->opcode) { reg_maps->loop = 1; pToken += curOpcode->num_params; - + + /* For subroutine prototypes */ + } else if (D3DSIO_LABEL == curOpcode->opcode) { + + DWORD snum = *pToken & D3DSP_REGNUM_MASK; + reg_maps->labels[snum] = 1; + pToken += curOpcode->num_params; + /* Set texture, address, temporary registers */ } else { int i, limit; @@ -683,7 +690,8 @@ void shader_generate_main( D3DSIO_NOP == curOpcode->opcode || D3DSIO_DEF == curOpcode->opcode || D3DSIO_DEFI == curOpcode->opcode || - D3DSIO_DEFB == curOpcode->opcode) { + D3DSIO_DEFB == curOpcode->opcode || + D3DSIO_RET == curOpcode->opcode) { pToken += shader_skip_opcode(This, curOpcode, hw_arg.opcode_token); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index bd91f10547562284288fd90914e45f181d6fb6d9..223a8e01376280de0c1b2615c77156f99b46e7ad 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -331,6 +331,12 @@ void shader_generate_glsl_declarations( char pshader = shader_is_pshader_version(This->baseShader.hex_version); char prefix = pshader ? 'P' : 'V'; + /* Prototype the subroutines */ + for (i = 0; i < This->baseShader.limits.label; i++) { + if (reg_maps->labels[i]) + shader_addline(buffer, "void subroutine%lu();\n", i); + } + /* 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); @@ -495,6 +501,9 @@ static void shader_glsl_gen_modifier ( case D3DSPSM_NEG: sprintf(out_str, "-%s%s", in_reg, in_regswizzle); break; + case D3DSPSM_NOT: + sprintf(out_str, "!%s%s", in_reg, in_regswizzle); + break; case D3DSPSM_BIAS: sprintf(out_str, "(%s%s - vec4(0.5)%s)", in_reg, in_regswizzle, in_regswizzle); break; @@ -1238,6 +1247,29 @@ void shader_glsl_breakc(SHADER_OPCODE_ARG* arg) { src0_str, shader_get_comp_op(arg->opcode_token), src1_str); } +void shader_glsl_label(SHADER_OPCODE_ARG* arg) { + + DWORD snum = (arg->src[0]) & D3DSP_REGNUM_MASK; + shader_addline(arg->buffer, "}\n"); + shader_addline(arg->buffer, "void subroutine%lu () {\n", snum); +} + +void shader_glsl_call(SHADER_OPCODE_ARG* arg) { + DWORD snum = (arg->src[0]) & D3DSP_REGNUM_MASK; + shader_addline(arg->buffer, "subroutine%lu();\n", snum); +} + +void shader_glsl_callnz(SHADER_OPCODE_ARG* arg) { + + char src1_str[100]; + char src1_reg[50]; + char src1_mask[6]; + + DWORD snum = (arg->src[0]) & D3DSP_REGNUM_MASK; + shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str); + shader_addline(arg->buffer, "if (%s) subroutine%lu();\n", src1_str, snum); +} + /********************************************* * Pixel Shader Specific Code begins here ********************************************/ diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index 977cb4e7e2818d896536a1539815d671b20188d0..498380bf6921d26a6047d62697f6273f4ef64da8 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -685,12 +685,12 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = { {D3DSIO_BREAK, "break", NULL, 0, 0, pshader_break, NULL, shader_glsl_break, D3DPS_VERSION(2,1), -1}, {D3DSIO_BREAKC, "breakc", NULL, 0, 2, pshader_breakc, NULL, shader_glsl_breakc, D3DPS_VERSION(2,1), -1}, {D3DSIO_BREAKP, "breakp", GLNAME_REQUIRE_GLSL, 0, 1, pshader_breakp, NULL, NULL, 0, 0}, - {D3DSIO_CALL, "call", GLNAME_REQUIRE_GLSL, 0, 1, pshader_call, NULL, NULL, 0, 0}, - {D3DSIO_CALLNZ, "callnz", GLNAME_REQUIRE_GLSL, 0, 2, pshader_callnz, NULL, NULL, 0, 0}, + {D3DSIO_CALL, "call", NULL, 0, 1, pshader_call, NULL, shader_glsl_call, D3DPS_VERSION(2,1), -1}, + {D3DSIO_CALLNZ, "callnz", NULL, 0, 2, pshader_callnz, NULL, shader_glsl_callnz, D3DPS_VERSION(2,1), -1}, {D3DSIO_LOOP, "loop", NULL, 0, 2, pshader_loop, NULL, shader_glsl_loop, D3DPS_VERSION(3,0), -1}, - {D3DSIO_RET, "ret", GLNAME_REQUIRE_GLSL, 0, 0, pshader_ret, NULL, NULL, 0, 0}, + {D3DSIO_RET, "ret", NULL, 0, 0, pshader_ret, NULL, NULL, D3DPS_VERSION(2,1), -1}, {D3DSIO_ENDLOOP, "endloop", NULL, 0, 0, pshader_endloop, NULL, shader_glsl_end, D3DPS_VERSION(3,0), -1}, - {D3DSIO_LABEL, "label", GLNAME_REQUIRE_GLSL, 0, 1, pshader_label, NULL, NULL, 0, 0}, + {D3DSIO_LABEL, "label", NULL, 0, 1, pshader_label, NULL, shader_glsl_label, D3DPS_VERSION(2,1), -1}, /* Constant definitions */ {D3DSIO_DEF, "def", "undefined", 1, 5, pshader_def, NULL, NULL, 0, 0}, @@ -751,6 +751,7 @@ static void pshader_set_limits( This->baseShader.limits.texcoord = 4; This->baseShader.limits.sampler = 4; This->baseShader.limits.packed_input = 0; + This->baseShader.limits.label = 0; break; case D3DPS_VERSION(1,4): @@ -761,10 +762,20 @@ static void pshader_set_limits( This->baseShader.limits.texcoord = 6; This->baseShader.limits.sampler = 6; This->baseShader.limits.packed_input = 0; + This->baseShader.limits.label = 0; break; /* FIXME: temporaries must match D3DPSHADERCAPS2_0.NumTemps */ case D3DPS_VERSION(2,0): + This->baseShader.limits.temporary = 32; + This->baseShader.limits.constant_float = 32; + This->baseShader.limits.constant_int = 16; + This->baseShader.limits.constant_bool = 16; + This->baseShader.limits.texcoord = 8; + This->baseShader.limits.sampler = 16; + This->baseShader.limits.packed_input = 0; + break; + case D3DPS_VERSION(2,1): This->baseShader.limits.temporary = 32; This->baseShader.limits.constant_float = 32; @@ -773,6 +784,7 @@ static void pshader_set_limits( This->baseShader.limits.texcoord = 8; This->baseShader.limits.sampler = 16; This->baseShader.limits.packed_input = 0; + This->baseShader.limits.label = 16; break; case D3DPS_VERSION(3,0): @@ -783,6 +795,7 @@ static void pshader_set_limits( This->baseShader.limits.texcoord = 0; This->baseShader.limits.sampler = 16; This->baseShader.limits.packed_input = 12; + This->baseShader.limits.label = 16; /* FIXME: 2048 */ break; default: This->baseShader.limits.temporary = 32; @@ -792,6 +805,7 @@ static void pshader_set_limits( This->baseShader.limits.texcoord = 8; This->baseShader.limits.sampler = 16; This->baseShader.limits.packed_input = 0; + This->baseShader.limits.label = 0; FIXME("Unrecognized pixel shader version %#lx\n", This->baseShader.hex_version); } diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index 20d1d4097eab6bad6c4298f781efb8a82199d666..026207997de7d969971e1562ebcbde3269be0d56 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -545,12 +545,12 @@ CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = { {D3DSIO_BREAK, "break", NULL, 0, 0, vshader_break, NULL, shader_glsl_break, D3DVS_VERSION(2,1), -1}, {D3DSIO_BREAKC, "breakc", NULL, 0, 2, vshader_breakc, NULL, shader_glsl_breakc, D3DVS_VERSION(2,1), -1}, {D3DSIO_BREAKP, "breakp", GLNAME_REQUIRE_GLSL, 0, 1, vshader_breakp, NULL, NULL, 0, 0}, - {D3DSIO_CALL, "call", GLNAME_REQUIRE_GLSL, 0, 1, vshader_call, NULL, NULL, 0, 0}, - {D3DSIO_CALLNZ, "callnz", GLNAME_REQUIRE_GLSL, 0, 2, vshader_callnz, NULL, NULL, 0, 0}, + {D3DSIO_CALL, "call", NULL, 0, 1, vshader_call, NULL, shader_glsl_call, D3DVS_VERSION(2,0), -1}, + {D3DSIO_CALLNZ, "callnz", NULL, 0, 2, vshader_callnz, NULL, shader_glsl_callnz, D3DVS_VERSION(2,0), -1}, {D3DSIO_LOOP, "loop", NULL, 0, 2, vshader_loop, NULL, shader_glsl_loop, D3DVS_VERSION(2,0), -1}, - {D3DSIO_RET, "ret", GLNAME_REQUIRE_GLSL, 0, 0, vshader_ret, NULL, NULL, 0, 0}, + {D3DSIO_RET, "ret", NULL, 0, 0, vshader_ret, NULL, NULL, D3DVS_VERSION(2,0), -1}, {D3DSIO_ENDLOOP, "endloop", NULL, 0, 0, vshader_endloop, NULL, shader_glsl_end, D3DVS_VERSION(2,0), -1}, - {D3DSIO_LABEL, "label", GLNAME_REQUIRE_GLSL, 0, 1, vshader_label, NULL, NULL, 0, 0}, + {D3DSIO_LABEL, "label", NULL, 0, 1, vshader_label, NULL, shader_glsl_label, D3DVS_VERSION(2,0), -1}, {D3DSIO_MOVA, "mova", GLNAME_REQUIRE_GLSL, 1, 2, vshader_mova, NULL, shader_glsl_mov, 0, 0}, {D3DSIO_SETP, "setp", GLNAME_REQUIRE_GLSL, 1, 3, vshader_setp, NULL, NULL, 0, 0}, @@ -577,6 +577,7 @@ static void vshader_set_limits( This->baseShader.limits.address = 1; This->baseShader.limits.packed_output = 0; This->baseShader.limits.sampler = 0; + This->baseShader.limits.label = 0; break; case D3DVS_VERSION(2,0): @@ -587,6 +588,7 @@ static void vshader_set_limits( This->baseShader.limits.address = 1; This->baseShader.limits.packed_output = 0; This->baseShader.limits.sampler = 0; + This->baseShader.limits.label = 16; break; case D3DVS_VERSION(3,0): @@ -596,6 +598,7 @@ static void vshader_set_limits( This->baseShader.limits.address = 1; This->baseShader.limits.packed_output = 12; This->baseShader.limits.sampler = 4; + This->baseShader.limits.label = 16; /* FIXME: 2048 */ break; default: This->baseShader.limits.temporary = 12; @@ -604,6 +607,7 @@ static void vshader_set_limits( This->baseShader.limits.address = 1; This->baseShader.limits.packed_output = 0; This->baseShader.limits.sampler = 0; + This->baseShader.limits.label = 16; FIXME("Unrecognized vertex shader version %#lx\n", This->baseShader.hex_version); } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 5102e7caa2aeb5b4eecc8f6ddc49cea0669b1d46..c1ce7634bb5d2a0c84b59af82741a796998f114a 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1282,6 +1282,10 @@ struct glsl_shader_prog_link { #define MAX_CONST_I 16 #define MAX_CONST_B 16 +/* FIXME: This needs to go up to 2048 for + * Shader model 3 according to msdn (and for software shaders) */ +#define MAX_LABELS 16 + typedef struct semantic { DWORD usage; DWORD reg; @@ -1301,6 +1305,7 @@ typedef struct shader_reg_maps { char packed_input[MAX_REG_INPUT]; /* pshader >= 3.0 */ char packed_output[MAX_REG_OUTPUT]; /* vertex >= 3.0 */ char attributes[MAX_ATTRIBS]; /* vertex */ + char labels[MAX_LABELS]; /* pixel, vertex */ /* Sampler usage tokens * Use 0 as default (bit 31 is always 1 on a valid token) */ @@ -1368,6 +1373,7 @@ typedef struct SHADER_LIMITS { unsigned int packed_output; unsigned int packed_input; unsigned int attributes; + unsigned int label; } SHADER_LIMITS; /** Keeps track of details for TEX_M#x# shader opcodes which need to @@ -1463,6 +1469,9 @@ extern void shader_glsl_else(SHADER_OPCODE_ARG* arg); extern void shader_glsl_break(SHADER_OPCODE_ARG* arg); extern void shader_glsl_breakc(SHADER_OPCODE_ARG* arg); extern void shader_glsl_rep(SHADER_OPCODE_ARG* arg); +extern void shader_glsl_call(SHADER_OPCODE_ARG* arg); +extern void shader_glsl_callnz(SHADER_OPCODE_ARG* arg); +extern void shader_glsl_label(SHADER_OPCODE_ARG* arg); /** GLSL Pixel Shader Prototypes */ extern void pshader_glsl_tex(SHADER_OPCODE_ARG* arg);