Commit 33293df1 authored by Ivan Gyurdiev's avatar Ivan Gyurdiev Committed by Alexandre Julliard

wined3d: More flow control instructions.

- Implement call, callnz, label, and ret - Implement support for NOT modifier
parent 6ede5649
......@@ -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);
......
......@@ -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
********************************************/
......
......@@ -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);
}
......
......@@ -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);
}
......
......@@ -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);
......
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