wined3d: Implement more GLSL instructions.
- Implemented: D3DSIO_SGN, LOOP, ENDLOOP, LOGP, LIT, DST, SINCOS - Process instruction-based modifiers (function existed, it just wasn't being called) - Add loop checking to register maps. - Renamed "sng" to "sgn" for D3DSIO_SGN - it's not handled anywhere except for GLSL, so won't matter.
This commit is contained in:
parent
da5cc56378
commit
cc06ed3d53
|
@ -411,6 +411,9 @@ void shader_get_registers_used(
|
|||
|
||||
else if (D3DSPR_INPUT == regtype && !pshader)
|
||||
reg_maps->attributes[reg] = 1;
|
||||
|
||||
else if (D3DSPR_LOOP == regtype)
|
||||
reg_maps->loop = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -792,6 +795,10 @@ void shader_generate_glsl_declarations(
|
|||
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");
|
||||
|
@ -901,6 +908,10 @@ void shader_generate_main(
|
|||
/* Call appropriate function for output target */
|
||||
hw_fct(&hw_arg);
|
||||
|
||||
/* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
|
||||
if (wined3d_settings.shader_mode == SHADER_GLSL)
|
||||
shader_glsl_add_instruction_modifiers(&hw_arg);
|
||||
|
||||
/* Unhandled opcode */
|
||||
} else {
|
||||
|
||||
|
|
|
@ -245,6 +245,9 @@ static void shader_glsl_get_register_name(
|
|||
sprintf(tmpStr, "A%lu", reg);
|
||||
}
|
||||
break;
|
||||
case D3DSPR_LOOP:
|
||||
sprintf(tmpStr, "aL");
|
||||
break;
|
||||
case D3DSPR_SAMPLER:
|
||||
if (pshader)
|
||||
sprintf(tmpStr, "psampler%lu", reg);
|
||||
|
@ -508,11 +511,13 @@ void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg) {
|
|||
case D3DSIO_POW: strcat(tmpLine, "pow"); break;
|
||||
case D3DSIO_CRS: strcat(tmpLine, "cross"); break;
|
||||
case D3DSIO_NRM: strcat(tmpLine, "normalize"); break;
|
||||
case D3DSIO_LOGP:
|
||||
case D3DSIO_LOG: strcat(tmpLine, "log2"); break;
|
||||
case D3DSIO_EXPP:
|
||||
case D3DSIO_EXP: strcat(tmpLine, "exp2"); break;
|
||||
case D3DSIO_SGE: strcat(tmpLine, "greaterThanEqual"); break;
|
||||
case D3DSIO_SLT: strcat(tmpLine, "lessThan"); break;
|
||||
case D3DSIO_SGN: strcat(tmpLine, "sign"); break;
|
||||
default:
|
||||
FIXME("Opcode %s not yet handled in GLSL\n", curOpcode->name);
|
||||
break;
|
||||
|
@ -728,6 +733,93 @@ void shader_glsl_def(SHADER_OPCODE_ARG* arg) {
|
|||
arg->reg_maps->constantsF[reg] = 1;
|
||||
}
|
||||
|
||||
/** Process the D3DSIO_LIT instruction in GLSL:
|
||||
* dst.x = dst.w = 1.0
|
||||
* dst.y = (src0.x > 0) ? src0.x
|
||||
* dst.z = (src0.x > 0) ? ((src0.y > 0) ? pow(src0.y, src.w) : 0) : 0
|
||||
* where src.w is clamped at +- 128
|
||||
*/
|
||||
void shader_glsl_lit(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
char dst_str[100], src0_str[100];
|
||||
char dst_reg[50], src0_reg[50];
|
||||
char dst_mask[6], src0_mask[6];
|
||||
|
||||
shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
|
||||
shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
|
||||
|
||||
shader_addline(arg->buffer,
|
||||
"%s = vec4(1.0, (%s.x > 0.0 ? %s.x : 0.0), (%s.x > 0.0 ? ((%s.y > 0.0) ? pow(%s.y, clamp(%s.w, -128.0, 128.0)) : 0.0) : 0.0), 1.0)%s;\n",
|
||||
dst_str, src0_reg, src0_reg, src0_reg, src0_reg, src0_reg, src0_reg, dst_mask);
|
||||
}
|
||||
|
||||
/** Process the D3DSIO_DST instruction in GLSL:
|
||||
* dst.x = 1.0
|
||||
* dst.y = src0.x * src0.y
|
||||
* dst.z = src0.z
|
||||
* dst.w = src1.w
|
||||
*/
|
||||
void shader_glsl_dst(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
char dst_str[100], src0_str[100], src1_str[100];
|
||||
char dst_reg[50], src0_reg[50], src1_reg[50];
|
||||
char dst_mask[6], src0_mask[6], src1_mask[6];
|
||||
|
||||
shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
|
||||
shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
|
||||
shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
|
||||
|
||||
shader_addline(arg->buffer, "%s = vec4(1.0, %s.x * %s.y, %s.z, %s.w)%s;\n",
|
||||
dst_str, src0_reg, src1_reg, src0_reg, src1_reg, dst_mask);
|
||||
}
|
||||
|
||||
/** Process the D3DSIO_SINCOS instruction in GLSL:
|
||||
* VS 2.0 requires that specific cosine and sine constants be passed to this instruction so the hardware
|
||||
* can handle it. But, these functions are built-in for GLSL, so we can just ignore the last 2 params.
|
||||
*
|
||||
* dst.x = cos(src0.?)
|
||||
* dst.y = sin(src0.?)
|
||||
* dst.z = dst.z
|
||||
* dst.w = dst.w
|
||||
*/
|
||||
void shader_glsl_sincos(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
char dst_str[100], src0_str[100];
|
||||
char dst_reg[50], src0_reg[50];
|
||||
char dst_mask[6], src0_mask[6];
|
||||
|
||||
shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
|
||||
shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
|
||||
|
||||
shader_addline(arg->buffer, "%s = vec4(cos(%s), sin(%s), %s.z, %s.w)%s;\n",
|
||||
dst_str, src0_str, src0_str, dst_reg, dst_reg, dst_mask);
|
||||
}
|
||||
|
||||
/** Process the D3DSIO_LOOP instruction in GLSL:
|
||||
* Start a for() loop where src0.y is the initial value of aL,
|
||||
* increment aL by src0.z while (aL < src0.x).
|
||||
*/
|
||||
void shader_glsl_loop(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
char src0_str[100];
|
||||
char src0_reg[50];
|
||||
char src0_mask[6];
|
||||
|
||||
shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
|
||||
|
||||
shader_addline(arg->buffer, "for (aL = %s.y; aL < %s.x; aL += %s.z) {\n",
|
||||
src0_reg, src0_reg, src0_reg);
|
||||
}
|
||||
|
||||
/** Process the D3DSIO_ENDLOOP instruction in GLSL:
|
||||
* End the for() loop
|
||||
*/
|
||||
void shader_glsl_endloop(SHADER_OPCODE_ARG* arg) {
|
||||
|
||||
shader_addline(arg->buffer, "}\n");
|
||||
}
|
||||
|
||||
|
||||
/*********************************************
|
||||
* Pixel Shader Specific Code begins here
|
||||
********************************************/
|
||||
|
|
|
@ -654,8 +654,8 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
|
|||
{D3DSIO_EXP, "exp", "EX2", 1, 2, pshader_exp, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{D3DSIO_LOG, "log", "LG2", 1, 2, pshader_log, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{D3DSIO_EXPP, "expp", "EXP", 1, 2, pshader_expp, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{D3DSIO_LOGP, "logp", "LOG", 1, 2, pshader_logp, pshader_hw_map2gl, NULL, 0, 0},
|
||||
{D3DSIO_DST, "dst", "DST", 1, 3, pshader_dst, pshader_hw_map2gl, NULL, 0, 0},
|
||||
{D3DSIO_LOGP, "logp", "LOG", 1, 2, pshader_logp, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{D3DSIO_DST, "dst", "DST", 1, 3, pshader_dst, pshader_hw_map2gl, shader_glsl_dst, 0, 0},
|
||||
{D3DSIO_LRP, "lrp", "LRP", 1, 4, pshader_lrp, pshader_hw_map2gl, shader_glsl_lrp, 0, 0},
|
||||
{D3DSIO_FRC, "frc", "FRC", 1, 2, pshader_frc, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{D3DSIO_CND, "cnd", NULL, 1, 4, pshader_cnd, pshader_hw_cnd, shader_glsl_cnd, D3DPS_VERSION(1,1), D3DPS_VERSION(1,4)},
|
||||
|
@ -673,8 +673,8 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
|
|||
|
||||
*/
|
||||
{D3DSIO_NRM, "nrm", NULL, 1, 2, pshader_nrm, NULL, shader_glsl_map2gl, 0, 0},
|
||||
{D3DSIO_SINCOS, "sincos", NULL, 1, 4, pshader_sincos2, NULL, NULL, D3DPS_VERSION(2,0), D3DPS_VERSION(2,0)},
|
||||
{D3DSIO_SINCOS, "sincos", NULL, 1, 2, pshader_sincos3, NULL, NULL, D3DPS_VERSION(3,0), -1},
|
||||
{D3DSIO_SINCOS, "sincos", NULL, 1, 4, pshader_sincos2, NULL, shader_glsl_sincos, D3DPS_VERSION(2,0), D3DPS_VERSION(2,0)},
|
||||
{D3DSIO_SINCOS, "sincos", NULL, 1, 2, pshader_sincos3, NULL, shader_glsl_sincos, D3DPS_VERSION(3,0), -1},
|
||||
/* TODO: dp2add can be made out of multiple instuctions */
|
||||
{D3DSIO_DP2ADD, "dp2add", GLNAME_REQUIRE_GLSL, 1, 4, pshader_dp2add, NULL, NULL, D3DPS_VERSION(2,0), -1},
|
||||
|
||||
|
@ -700,9 +700,9 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
|
|||
{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_LOOP, "loop", GLNAME_REQUIRE_GLSL, 0, 2, pshader_loop, NULL, NULL, 0, 0},
|
||||
{D3DSIO_LOOP, "loop", GLNAME_REQUIRE_GLSL, 0, 2, pshader_loop, NULL, shader_glsl_loop, 0, 0},
|
||||
{D3DSIO_RET, "ret", GLNAME_REQUIRE_GLSL, 0, 0, pshader_ret, NULL, NULL, 0, 0},
|
||||
{D3DSIO_ENDLOOP, "endloop", GLNAME_REQUIRE_GLSL, 0, 0, pshader_endloop, NULL, NULL, 0, 0},
|
||||
{D3DSIO_ENDLOOP, "endloop", GLNAME_REQUIRE_GLSL, 0, 0, pshader_endloop, NULL, shader_glsl_endloop, 0, 0},
|
||||
{D3DSIO_LABEL, "label", GLNAME_REQUIRE_GLSL, 0, 1, pshader_label, NULL, NULL, 0, 0},
|
||||
|
||||
/* Constant definitions */
|
||||
|
|
|
@ -397,7 +397,7 @@ static void vshader_pow(WINED3DSHADERVECTOR* d, WINED3DSHADERVECTOR* s0, WINED3D
|
|||
FIXME(" : Stub\n");
|
||||
}
|
||||
|
||||
static void vshader_sng(WINED3DSHADERVECTOR* d, WINED3DSHADERVECTOR* s0) {
|
||||
static void vshader_sgn(WINED3DSHADERVECTOR* d, WINED3DSHADERVECTOR* s0) {
|
||||
FIXME(" : Stub\n");
|
||||
}
|
||||
|
||||
|
@ -501,9 +501,9 @@ CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
|
|||
{D3DSIO_EXP, "exp", "EX2", 1, 2, vshader_exp, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{D3DSIO_LOG, "log", "LG2", 1, 2, vshader_log, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{D3DSIO_EXPP, "expp", "EXP", 1, 2, vshader_expp, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{D3DSIO_LOGP, "logp", "LOG", 1, 2, vshader_logp, vshader_hw_map2gl, NULL, 0, 0},
|
||||
{D3DSIO_LIT, "lit", "LIT", 1, 2, vshader_lit, vshader_hw_map2gl, NULL, 0, 0},
|
||||
{D3DSIO_DST, "dst", "DST", 1, 3, vshader_dst, vshader_hw_map2gl, NULL, 0, 0},
|
||||
{D3DSIO_LOGP, "logp", "LOG", 1, 2, vshader_logp, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{D3DSIO_LIT, "lit", "LIT", 1, 2, vshader_lit, vshader_hw_map2gl, shader_glsl_lit, 0, 0},
|
||||
{D3DSIO_DST, "dst", "DST", 1, 3, vshader_dst, vshader_hw_map2gl, shader_glsl_dst, 0, 0},
|
||||
{D3DSIO_LRP, "lrp", "LRP", 1, 4, vshader_lrp, NULL, shader_glsl_lrp, 0, 0},
|
||||
{D3DSIO_FRC, "frc", "FRC", 1, 2, vshader_frc, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{D3DSIO_POW, "pow", "POW", 1, 3, vshader_pow, NULL, shader_glsl_map2gl, 0, 0},
|
||||
|
@ -511,7 +511,7 @@ CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
|
|||
/* TODO: sng can possibly be performed a s
|
||||
RCP tmp, vec
|
||||
MUL out, tmp, vec*/
|
||||
{D3DSIO_SGN, "sng", NULL, 1, 2, vshader_sng, NULL, NULL, 0, 0},
|
||||
{D3DSIO_SGN, "sgn", NULL, 1, 2, vshader_sgn, NULL, shader_glsl_map2gl, 0, 0},
|
||||
/* TODO: xyz normalise can be performed as VS_ARB using one temporary register,
|
||||
DP3 tmp , vec, vec;
|
||||
RSQ tmp, tmp.x;
|
||||
|
@ -523,8 +523,8 @@ CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
|
|||
|
||||
*/
|
||||
{D3DSIO_NRM, "nrm", NULL, 1, 2, vshader_nrm, NULL, shader_glsl_map2gl, 0, 0},
|
||||
{D3DSIO_SINCOS, "sincos", NULL, 1, 4, vshader_sincos2, NULL, NULL, D3DVS_VERSION(2,0), D3DVS_VERSION(2,0)},
|
||||
{D3DSIO_SINCOS, "sincos", NULL, 1, 2, vshader_sincos3, NULL, NULL, D3DVS_VERSION(3,0), -1},
|
||||
{D3DSIO_SINCOS, "sincos", NULL, 1, 4, vshader_sincos2, NULL, shader_glsl_sincos, D3DVS_VERSION(2,0), D3DVS_VERSION(2,0)},
|
||||
{D3DSIO_SINCOS, "sincos", NULL, 1, 2, vshader_sincos3, NULL, shader_glsl_sincos, D3DVS_VERSION(3,0), -1},
|
||||
|
||||
/* Matrix */
|
||||
{D3DSIO_M4x4, "m4x4", "undefined", 1, 3, vshader_m4x4, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0},
|
||||
|
@ -553,9 +553,9 @@ CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
|
|||
{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_LOOP, "loop", GLNAME_REQUIRE_GLSL, 0, 2, vshader_loop, NULL, NULL, 0, 0},
|
||||
{D3DSIO_LOOP, "loop", GLNAME_REQUIRE_GLSL, 0, 2, vshader_loop, NULL, shader_glsl_loop, 0, 0},
|
||||
{D3DSIO_RET, "ret", GLNAME_REQUIRE_GLSL, 0, 0, vshader_ret, NULL, NULL, 0, 0},
|
||||
{D3DSIO_ENDLOOP, "endloop", GLNAME_REQUIRE_GLSL, 0, 0, vshader_endloop, NULL, NULL, 0, 0},
|
||||
{D3DSIO_ENDLOOP, "endloop", GLNAME_REQUIRE_GLSL, 0, 0, vshader_endloop, NULL, shader_glsl_endloop, 0, 0},
|
||||
{D3DSIO_LABEL, "label", GLNAME_REQUIRE_GLSL, 0, 1, vshader_label, NULL, NULL, 0, 0},
|
||||
|
||||
{D3DSIO_MOVA, "mova", GLNAME_REQUIRE_GLSL, 1, 2, vshader_mova, NULL, shader_glsl_mov, 0, 0},
|
||||
|
|
|
@ -1277,6 +1277,9 @@ typedef struct shader_reg_maps {
|
|||
* Use 0 as default (bit 31 is always 1 on a valid token) */
|
||||
DWORD samplers[MAX_SAMPLERS];
|
||||
|
||||
/* Whether or not a loop is used in this shader */
|
||||
char loop;
|
||||
|
||||
} shader_reg_maps;
|
||||
|
||||
#define SHADER_PGMSIZE 65535
|
||||
|
@ -1344,8 +1347,9 @@ extern const SHADER_OPCODE* shader_get_opcode(
|
|||
/* ARB shader program Prototypes */
|
||||
extern void shader_hw_def(SHADER_OPCODE_ARG *arg);
|
||||
|
||||
/* GLSL helper programs */
|
||||
/* GLSL helper functions */
|
||||
extern void set_glsl_shader_program(IWineD3DDevice *iface);
|
||||
extern void shader_glsl_add_instruction_modifiers(SHADER_OPCODE_ARG *arg);
|
||||
|
||||
/** The following translate DirectX pixel/vertex shader opcodes to GLSL lines */
|
||||
extern void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg);
|
||||
|
@ -1360,6 +1364,11 @@ extern void shader_glsl_cnd(SHADER_OPCODE_ARG* arg);
|
|||
extern void shader_glsl_compare(SHADER_OPCODE_ARG* arg);
|
||||
extern void shader_glsl_def(SHADER_OPCODE_ARG* arg);
|
||||
extern void shader_glsl_cmp(SHADER_OPCODE_ARG* arg);
|
||||
extern void shader_glsl_lit(SHADER_OPCODE_ARG* arg);
|
||||
extern void shader_glsl_dst(SHADER_OPCODE_ARG* arg);
|
||||
extern void shader_glsl_sincos(SHADER_OPCODE_ARG* arg);
|
||||
extern void shader_glsl_loop(SHADER_OPCODE_ARG* arg);
|
||||
extern void shader_glsl_endloop(SHADER_OPCODE_ARG* arg);
|
||||
|
||||
/** GLSL Pixel Shader Prototypes */
|
||||
extern void pshader_glsl_tex(SHADER_OPCODE_ARG* arg);
|
||||
|
|
Loading…
Reference in New Issue