d3dx9: Shader assembler ps_1_4 support.
This commit is contained in:
parent
7c834e30d7
commit
bfa3999284
|
@ -161,6 +161,12 @@ static void asmparser_dcl_input_ps_2(struct asm_parser *This, DWORD usage, DWORD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void asmparser_dcl_input_unsupported(struct asm_parser *This, DWORD usage, DWORD num,
|
||||||
|
DWORD mod, const struct shader_reg *reg) {
|
||||||
|
asmparser_message(This, "Line %u: Input declaration unsupported in this shader version\n", This->line_no);
|
||||||
|
set_parse_status(This, PARSE_ERR);
|
||||||
|
}
|
||||||
|
|
||||||
static void asmparser_dcl_sampler(struct asm_parser *This, DWORD samptype,
|
static void asmparser_dcl_sampler(struct asm_parser *This, DWORD samptype,
|
||||||
DWORD mod, DWORD regnum,
|
DWORD mod, DWORD regnum,
|
||||||
unsigned int line_no) {
|
unsigned int line_no) {
|
||||||
|
@ -220,6 +226,84 @@ static void asmparser_sincos(struct asm_parser *This, DWORD mod, DWORD shift,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void asmparser_texcrd(struct asm_parser *This, DWORD mod, DWORD shift,
|
||||||
|
const struct shader_reg *dst,
|
||||||
|
const struct src_regs *srcs) {
|
||||||
|
struct instruction *instr;
|
||||||
|
|
||||||
|
if(!srcs || srcs->count != 1) {
|
||||||
|
asmparser_message(This, "Line %u: Wrong number of source registers in texcrd instruction\n", This->line_no);
|
||||||
|
set_parse_status(This, PARSE_ERR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
instr = alloc_instr(1);
|
||||||
|
if(!instr) {
|
||||||
|
ERR("Error allocating memory for the instruction\n");
|
||||||
|
set_parse_status(This, PARSE_ERR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The job of texcrd is done by mov in later shader versions */
|
||||||
|
instr->opcode = BWRITERSIO_MOV;
|
||||||
|
instr->dstmod = mod;
|
||||||
|
instr->shift = shift;
|
||||||
|
instr->comptype = 0;
|
||||||
|
|
||||||
|
This->funcs->dstreg(This, instr, dst);
|
||||||
|
This->funcs->srcreg(This, instr, 0, &srcs->reg[0]);
|
||||||
|
|
||||||
|
if(!add_instruction(This->shader, instr)) {
|
||||||
|
ERR("Out of memory\n");
|
||||||
|
set_parse_status(This, PARSE_ERR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void asmparser_texld14(struct asm_parser *This, DWORD mod, DWORD shift,
|
||||||
|
const struct shader_reg *dst,
|
||||||
|
const struct src_regs *srcs) {
|
||||||
|
struct instruction *instr;
|
||||||
|
|
||||||
|
if(!srcs || srcs->count != 1) {
|
||||||
|
asmparser_message(This, "Line %u: texld (PS 1.4) has a wrong number of source registers\n", This->line_no);
|
||||||
|
set_parse_status(This, PARSE_ERR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
instr = alloc_instr(2);
|
||||||
|
if(!instr) {
|
||||||
|
ERR("Error allocating memory for the instruction\n");
|
||||||
|
set_parse_status(This, PARSE_ERR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This code is recording a texld instruction, not tex. However,
|
||||||
|
* texld borrows the opcode of tex
|
||||||
|
*/
|
||||||
|
instr->opcode = BWRITERSIO_TEX;
|
||||||
|
instr->dstmod = mod;
|
||||||
|
instr->shift = shift;
|
||||||
|
instr->comptype = 0;
|
||||||
|
|
||||||
|
This->funcs->dstreg(This, instr, dst);
|
||||||
|
This->funcs->srcreg(This, instr, 0, &srcs->reg[0]);
|
||||||
|
|
||||||
|
/* The 2nd source register is the sampler register with the
|
||||||
|
* destination's regnum
|
||||||
|
*/
|
||||||
|
ZeroMemory(&instr->src[1], sizeof(instr->src[1]));
|
||||||
|
instr->src[1].type = BWRITERSPR_SAMPLER;
|
||||||
|
instr->src[1].regnum = dst->regnum;
|
||||||
|
instr->src[1].swizzle = BWRITERVS_NOSWIZZLE;
|
||||||
|
instr->src[1].srcmod = BWRITERSPSM_NONE;
|
||||||
|
instr->src[1].rel_reg = NULL;
|
||||||
|
|
||||||
|
if(!add_instruction(This->shader, instr)) {
|
||||||
|
ERR("Out of memory\n");
|
||||||
|
set_parse_status(This, PARSE_ERR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void asmparser_instr(struct asm_parser *This, DWORD opcode,
|
static void asmparser_instr(struct asm_parser *This, DWORD opcode,
|
||||||
DWORD mod, DWORD shift,
|
DWORD mod, DWORD shift,
|
||||||
BWRITER_COMPARISON_TYPE comp,
|
BWRITER_COMPARISON_TYPE comp,
|
||||||
|
@ -258,6 +342,19 @@ ns */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Use the default handling */
|
/* Use the default handling */
|
||||||
|
break;
|
||||||
|
case BWRITERSIO_TEXCOORD:
|
||||||
|
/* texcoord/texcrd are two instructions present only in PS <= 1.3 and PS 1.4 respectively */
|
||||||
|
asmparser_texcrd(This, mod, shift, dst, srcs);
|
||||||
|
return;
|
||||||
|
case BWRITERSIO_TEX:
|
||||||
|
/* this encodes both the tex PS 1.x instruction and the
|
||||||
|
texld 1.4/2.0+ instruction */
|
||||||
|
if(This->shader->version == BWRITERPS_VERSION(1, 4)) {
|
||||||
|
asmparser_texld14(This, mod, shift, dst, srcs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* else fallback to the standard behavior */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,6 +660,30 @@ static void asmparser_srcreg_vs_3(struct asm_parser *This,
|
||||||
memcpy(&instr->src[num], src, sizeof(*src));
|
memcpy(&instr->src[num], src, sizeof(*src));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct allowed_reg_type ps_1_4_reg_allowed[] = {
|
||||||
|
{ BWRITERSPR_CONST, 8, FALSE },
|
||||||
|
{ BWRITERSPR_TEMP, 6, FALSE },
|
||||||
|
{ BWRITERSPR_TEXTURE, 6, FALSE },
|
||||||
|
{ BWRITERSPR_INPUT, 2, FALSE },
|
||||||
|
{ ~0U, 0 } /* End tag */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void asmparser_srcreg_ps_1_4(struct asm_parser *This,
|
||||||
|
struct instruction *instr, int num,
|
||||||
|
const struct shader_reg *src) {
|
||||||
|
struct shader_reg reg;
|
||||||
|
|
||||||
|
if(!check_reg_type(src, ps_1_4_reg_allowed)) {
|
||||||
|
asmparser_message(This, "Line %u: Source register %s not supported in PS 1.4\n",
|
||||||
|
This->line_no,
|
||||||
|
debug_print_srcreg(src));
|
||||||
|
set_parse_status(This, PARSE_ERR);
|
||||||
|
}
|
||||||
|
check_abs_srcmod(This, src->srcmod);
|
||||||
|
reg = map_oldps_register(src, TRUE);
|
||||||
|
memcpy(&instr->src[num], ®, sizeof(reg));
|
||||||
|
}
|
||||||
|
|
||||||
static const struct allowed_reg_type ps_2_0_reg_allowed[] = {
|
static const struct allowed_reg_type ps_2_0_reg_allowed[] = {
|
||||||
{ BWRITERSPR_INPUT, 2, FALSE },
|
{ BWRITERSPR_INPUT, 2, FALSE },
|
||||||
{ BWRITERSPR_TEMP, 32, FALSE },
|
{ BWRITERSPR_TEMP, 32, FALSE },
|
||||||
|
@ -706,6 +827,22 @@ static void asmparser_dstreg_vs_3(struct asm_parser *This,
|
||||||
instr->has_dst = TRUE;
|
instr->has_dst = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void asmparser_dstreg_ps_1_4(struct asm_parser *This,
|
||||||
|
struct instruction *instr,
|
||||||
|
const struct shader_reg *dst) {
|
||||||
|
struct shader_reg reg;
|
||||||
|
|
||||||
|
if(!check_reg_type(dst, ps_1_4_reg_allowed)) {
|
||||||
|
asmparser_message(This, "Line %u: Destination register %s not supported in PS 1\n",
|
||||||
|
This->line_no,
|
||||||
|
debug_print_dstreg(dst));
|
||||||
|
set_parse_status(This, PARSE_ERR);
|
||||||
|
}
|
||||||
|
reg = map_oldps_register(dst, FALSE);
|
||||||
|
memcpy(&instr->dst, ®, sizeof(reg));
|
||||||
|
instr->has_dst = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void asmparser_dstreg_ps_2(struct asm_parser *This,
|
static void asmparser_dstreg_ps_2(struct asm_parser *This,
|
||||||
struct instruction *instr,
|
struct instruction *instr,
|
||||||
const struct shader_reg *dst) {
|
const struct shader_reg *dst) {
|
||||||
|
@ -769,6 +906,16 @@ static void asmparser_predicate_unsupported(struct asm_parser *This,
|
||||||
set_parse_status(This, PARSE_ERR);
|
set_parse_status(This, PARSE_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void asmparser_coissue_supported(struct asm_parser *This) {
|
||||||
|
/* this sets the coissue flag of the last instruction added to the shader */
|
||||||
|
if(!This->shader) return;
|
||||||
|
if(This->shader->num_instrs == 0){
|
||||||
|
asmparser_message(This, "Line %u: Coissue flag on the first shader instruction\n", This->line_no);
|
||||||
|
set_parse_status(This, PARSE_ERR);
|
||||||
|
}
|
||||||
|
This->shader->instr[This->shader->num_instrs-1]->coissue = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void asmparser_coissue_unsupported(struct asm_parser *This) {
|
static void asmparser_coissue_unsupported(struct asm_parser *This) {
|
||||||
asmparser_message(This, "Line %u: Coissue is only supported in pixel shaders versions <= 1.4\n", This->line_no);
|
asmparser_message(This, "Line %u: Coissue is only supported in pixel shaders versions <= 1.4\n", This->line_no);
|
||||||
set_parse_status(This, PARSE_ERR);
|
set_parse_status(This, PARSE_ERR);
|
||||||
|
@ -834,6 +981,26 @@ static const struct asmparser_backend parser_vs_3 = {
|
||||||
asmparser_instr,
|
asmparser_instr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct asmparser_backend parser_ps_1_4 = {
|
||||||
|
asmparser_constF,
|
||||||
|
asmparser_constI,
|
||||||
|
asmparser_constB,
|
||||||
|
|
||||||
|
asmparser_dstreg_ps_1_4,
|
||||||
|
asmparser_srcreg_ps_1_4,
|
||||||
|
|
||||||
|
asmparser_predicate_unsupported,
|
||||||
|
asmparser_coissue_supported,
|
||||||
|
|
||||||
|
asmparser_dcl_output_unsupported,
|
||||||
|
asmparser_dcl_input_unsupported,
|
||||||
|
asmparser_dcl_sampler_unsupported,
|
||||||
|
|
||||||
|
asmparser_end,
|
||||||
|
|
||||||
|
asmparser_instr,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct asmparser_backend parser_ps_2 = {
|
static const struct asmparser_backend parser_ps_2 = {
|
||||||
asmparser_constF,
|
asmparser_constF,
|
||||||
asmparser_constI,
|
asmparser_constI,
|
||||||
|
@ -1004,6 +1171,22 @@ void create_vs30_parser(struct asm_parser *ret) {
|
||||||
ret->funcs = &parser_vs_3;
|
ret->funcs = &parser_vs_3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void create_ps14_parser(struct asm_parser *ret) {
|
||||||
|
TRACE_(parsed_shader)("ps_1_4\n");
|
||||||
|
|
||||||
|
ret->shader = asm_alloc(sizeof(*ret->shader));
|
||||||
|
if(!ret->shader) {
|
||||||
|
ERR("Failed to allocate memory for the shader\n");
|
||||||
|
set_parse_status(ret, PARSE_ERR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->shader->type = ST_PIXEL;
|
||||||
|
ret->shader->version = BWRITERPS_VERSION(1, 4);
|
||||||
|
ret->funcs = &parser_ps_1_4;
|
||||||
|
gen_oldps_input(ret->shader, 6);
|
||||||
|
}
|
||||||
|
|
||||||
void create_ps20_parser(struct asm_parser *ret) {
|
void create_ps20_parser(struct asm_parser *ret) {
|
||||||
TRACE_(parsed_shader)("ps_2_0\n");
|
TRACE_(parsed_shader)("ps_2_0\n");
|
||||||
|
|
||||||
|
|
|
@ -336,8 +336,7 @@ version_marker: VER_VS10
|
||||||
| VER_PS14
|
| VER_PS14
|
||||||
{
|
{
|
||||||
TRACE("Pixel shader 1.4\n");
|
TRACE("Pixel shader 1.4\n");
|
||||||
set_parse_status(&asm_ctx, PARSE_ERR);
|
create_ps14_parser(&asm_ctx);
|
||||||
YYABORT;
|
|
||||||
}
|
}
|
||||||
| VER_PS20
|
| VER_PS20
|
||||||
{
|
{
|
||||||
|
@ -370,6 +369,11 @@ complexinstr: instruction
|
||||||
TRACE("predicate\n");
|
TRACE("predicate\n");
|
||||||
asm_ctx.funcs->predicate(&asm_ctx, &$1);
|
asm_ctx.funcs->predicate(&asm_ctx, &$1);
|
||||||
}
|
}
|
||||||
|
| '+' instruction
|
||||||
|
{
|
||||||
|
TRACE("coissue\n");
|
||||||
|
asm_ctx.funcs->coissue(&asm_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
instruction: INSTR_ADD omods dreg ',' sregs
|
instruction: INSTR_ADD omods dreg ',' sregs
|
||||||
{
|
{
|
||||||
|
|
|
@ -578,6 +578,28 @@ static HRESULT find_ps_builtin_semantics(struct bc_writer *This,
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ps_1_4_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
/* First check the constants and varyings, and complain if unsupported things are used */
|
||||||
|
if(shader->num_ci || shader->num_cb) {
|
||||||
|
WARN("Int and bool constants are not supported in shader model 1 shaders\n");
|
||||||
|
WARN("Got %u int and %u boolean constants\n", shader->num_ci, shader->num_cb);
|
||||||
|
This->state = E_INVALIDARG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = find_ps_builtin_semantics(This, shader, 6);
|
||||||
|
if(FAILED(hr)) {
|
||||||
|
This->state = hr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Declare the shader type and version */
|
||||||
|
put_dword(buffer, This->version);
|
||||||
|
write_constF(shader, buffer, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
static void end(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
|
static void end(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
|
||||||
put_dword(buffer, D3DSIO_END);
|
put_dword(buffer, D3DSIO_END);
|
||||||
}
|
}
|
||||||
|
@ -888,6 +910,168 @@ static const struct bytecode_backend vs_1_x_backend = {
|
||||||
vs_1_x_handlers
|
vs_1_x_handlers
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void ps_1_4_srcreg(struct bc_writer *This, const struct shader_reg *reg,
|
||||||
|
struct bytecode_buffer *buffer) {
|
||||||
|
DWORD token = (1 << 31); /* Bit 31 of registers is 1 */
|
||||||
|
if(reg->rel_reg) {
|
||||||
|
WARN("Relative addressing not supported in <= ps_3_0\n");
|
||||||
|
This->state = E_INVALIDARG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(reg->type) {
|
||||||
|
case BWRITERSPR_INPUT:
|
||||||
|
token |= map_ps_input(This, reg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Can be mapped 1:1 */
|
||||||
|
case BWRITERSPR_TEMP:
|
||||||
|
case BWRITERSPR_CONST:
|
||||||
|
token |= (reg->type << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK;
|
||||||
|
token |= reg->regnum & D3DSP_REGNUM_MASK; /* No shift */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
WARN("Invalid register type for ps_1_4 shader\n");
|
||||||
|
This->state = E_INVALIDARG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
token |= d3d9_swizzle(reg->swizzle) & D3DVS_SWIZZLE_MASK; /* already shifted */
|
||||||
|
|
||||||
|
if(reg->srcmod == BWRITERSPSM_ABS || reg->srcmod == BWRITERSPSM_ABSNEG ||
|
||||||
|
reg->srcmod == BWRITERSPSM_NOT) {
|
||||||
|
WARN("Invalid source modifier %u for ps_1_4\n", reg->srcmod);
|
||||||
|
This->state = E_INVALIDARG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
token |= d3d9_srcmod(reg->srcmod);
|
||||||
|
put_dword(buffer, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ps_1_4_dstreg(struct bc_writer *This, const struct shader_reg *reg,
|
||||||
|
struct bytecode_buffer *buffer,
|
||||||
|
DWORD shift, DWORD mod) {
|
||||||
|
DWORD token = (1 << 31); /* Bit 31 of registers is 1 */
|
||||||
|
|
||||||
|
if(reg->rel_reg) {
|
||||||
|
WARN("Relative addressing not supported for destination registers\n");
|
||||||
|
This->state = E_INVALIDARG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(reg->type) {
|
||||||
|
case BWRITERSPR_TEMP: /* 1:1 mapping */
|
||||||
|
token |= (reg->type << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK;
|
||||||
|
token |= reg->regnum & D3DSP_REGNUM_MASK; /* No shift */
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* For texkill */
|
||||||
|
case BWRITERSPR_INPUT:
|
||||||
|
token |= map_ps_input(This, reg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
WARN("Invalid dest register type for 1.x pshader\n");
|
||||||
|
This->state = E_INVALIDARG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
token |= (shift << D3DSP_DSTSHIFT_SHIFT) & D3DSP_DSTSHIFT_MASK;
|
||||||
|
token |= d3d9_dstmod(mod);
|
||||||
|
|
||||||
|
token |= d3d9_writemask(reg->writemask);
|
||||||
|
put_dword(buffer, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void instr_ps_1_4_mov(struct bc_writer *This,
|
||||||
|
const struct instruction *instr,
|
||||||
|
struct bytecode_buffer *buffer) {
|
||||||
|
DWORD token = D3DSIO_MOV & D3DSI_OPCODE_MASK;
|
||||||
|
|
||||||
|
if(instr->dst.type == BWRITERSPR_TEMP && instr->src[0].type == BWRITERSPR_INPUT) {
|
||||||
|
if(instr->src[0].regnum == This->t_regnum[0] ||
|
||||||
|
instr->src[0].regnum == This->t_regnum[1] ||
|
||||||
|
instr->src[0].regnum == This->t_regnum[2] ||
|
||||||
|
instr->src[0].regnum == This->t_regnum[3] ||
|
||||||
|
instr->src[0].regnum == This->t_regnum[4] ||
|
||||||
|
instr->src[0].regnum == This->t_regnum[5]) {
|
||||||
|
/* Similar to a regular mov, but a different opcode */
|
||||||
|
token = D3DSIO_TEXCOORD & D3DSI_OPCODE_MASK;
|
||||||
|
} else if(instr->src[0].regnum == This->v_regnum[0] ||
|
||||||
|
instr->src[0].regnum == This->v_regnum[1]) {
|
||||||
|
/* Handled by the normal mov below. Just drop out of the if condition */
|
||||||
|
} else {
|
||||||
|
WARN("Unsupported varying -> temp mov in ps_1_4\n");
|
||||||
|
This->state = E_INVALIDARG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
This->funcs->opcode(This, instr, token, buffer);
|
||||||
|
This->funcs->dstreg(This, &instr->dst, buffer, instr->shift, instr->dstmod);
|
||||||
|
This->funcs->srcreg(This, &instr->src[0], buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void instr_ps_1_4_texld(struct bc_writer *This,
|
||||||
|
const struct instruction *instr,
|
||||||
|
struct bytecode_buffer *buffer) {
|
||||||
|
if(instr->src[1].type != BWRITERSPR_SAMPLER ||
|
||||||
|
instr->src[1].regnum > 5) {
|
||||||
|
WARN("Unsupported sampler type %u regnum %u\n",
|
||||||
|
instr->src[1].type, instr->src[1].regnum);
|
||||||
|
This->state = E_INVALIDARG;
|
||||||
|
return;
|
||||||
|
} else if(instr->dst.type != BWRITERSPR_TEMP) {
|
||||||
|
WARN("Can only sample into a temp register\n");
|
||||||
|
This->state = E_INVALIDARG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(instr->src[1].regnum != instr->dst.regnum) {
|
||||||
|
WARN("Sampling from sampler s%u to register r%u is not possible in ps_1_4\n",
|
||||||
|
instr->src[1].regnum, instr->dst.regnum);
|
||||||
|
This->state = E_INVALIDARG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
This->funcs->opcode(This, instr, D3DSIO_TEX & D3DSI_OPCODE_MASK, buffer);
|
||||||
|
This->funcs->dstreg(This, &instr->dst, buffer, instr->shift, instr->dstmod);
|
||||||
|
This->funcs->srcreg(This, &instr->src[0], buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct instr_handler_table ps_1_4_handlers[] = {
|
||||||
|
{BWRITERSIO_ADD, instr_handler},
|
||||||
|
{BWRITERSIO_NOP, instr_handler},
|
||||||
|
{BWRITERSIO_MOV, instr_ps_1_4_mov},
|
||||||
|
{BWRITERSIO_SUB, instr_handler},
|
||||||
|
{BWRITERSIO_MAD, instr_handler},
|
||||||
|
{BWRITERSIO_MUL, instr_handler},
|
||||||
|
{BWRITERSIO_DP3, instr_handler},
|
||||||
|
{BWRITERSIO_DP4, instr_handler},
|
||||||
|
{BWRITERSIO_LRP, instr_handler},
|
||||||
|
|
||||||
|
/* pshader instructions */
|
||||||
|
{BWRITERSIO_CND, instr_handler},
|
||||||
|
{BWRITERSIO_CMP, instr_handler},
|
||||||
|
{BWRITERSIO_TEXKILL, instr_handler},
|
||||||
|
{BWRITERSIO_TEX, instr_ps_1_4_texld},
|
||||||
|
{BWRITERSIO_TEXDEPTH, instr_handler},
|
||||||
|
{BWRITERSIO_BEM, instr_handler},
|
||||||
|
|
||||||
|
{BWRITERSIO_PHASE, instr_handler},
|
||||||
|
{BWRITERSIO_END, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct bytecode_backend ps_1_4_backend = {
|
||||||
|
ps_1_4_header,
|
||||||
|
end,
|
||||||
|
ps_1_4_srcreg,
|
||||||
|
ps_1_4_dstreg,
|
||||||
|
sm_1_x_opcode,
|
||||||
|
ps_1_4_handlers
|
||||||
|
};
|
||||||
|
|
||||||
static void write_constB(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len) {
|
static void write_constB(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len) {
|
||||||
write_const(shader->constB, shader->num_cb, D3DSIO_DEFB, D3DSPR_CONSTBOOL, buffer, len);
|
write_const(shader->constB, shader->num_cb, D3DSIO_DEFB, D3DSPR_CONSTBOOL, buffer, len);
|
||||||
}
|
}
|
||||||
|
@ -1676,6 +1860,11 @@ static void init_vs30_dx9_writer(struct bc_writer *writer) {
|
||||||
writer->funcs = &vs_3_backend;
|
writer->funcs = &vs_3_backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void init_ps14_dx9_writer(struct bc_writer *writer) {
|
||||||
|
TRACE("Creating DirectX9 pixel shader 1.4 writer\n");
|
||||||
|
writer->funcs = &ps_1_4_backend;
|
||||||
|
}
|
||||||
|
|
||||||
static void init_ps20_dx9_writer(struct bc_writer *writer) {
|
static void init_ps20_dx9_writer(struct bc_writer *writer) {
|
||||||
TRACE("Creating DirectX9 pixel shader 2.0 writer\n");
|
TRACE("Creating DirectX9 pixel shader 2.0 writer\n");
|
||||||
writer->funcs = &ps_2_0_backend;
|
writer->funcs = &ps_2_0_backend;
|
||||||
|
@ -1769,7 +1958,7 @@ static struct bc_writer *create_writer(DWORD version, DWORD dxversion) {
|
||||||
WARN("Unsupported dxversion for pixel shader 1.4 requested: %u\n", dxversion);
|
WARN("Unsupported dxversion for pixel shader 1.4 requested: %u\n", dxversion);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
/* TODO: Set the appropriate writer backend */
|
init_ps14_dx9_writer(ret);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BWRITERPS_VERSION(2, 0):
|
case BWRITERPS_VERSION(2, 0):
|
||||||
|
|
|
@ -323,6 +323,7 @@ void create_vs11_parser(struct asm_parser *ret);
|
||||||
void create_vs20_parser(struct asm_parser *ret);
|
void create_vs20_parser(struct asm_parser *ret);
|
||||||
void create_vs2x_parser(struct asm_parser *ret);
|
void create_vs2x_parser(struct asm_parser *ret);
|
||||||
void create_vs30_parser(struct asm_parser *ret);
|
void create_vs30_parser(struct asm_parser *ret);
|
||||||
|
void create_ps14_parser(struct asm_parser *ret);
|
||||||
void create_ps20_parser(struct asm_parser *ret);
|
void create_ps20_parser(struct asm_parser *ret);
|
||||||
void create_ps2x_parser(struct asm_parser *ret);
|
void create_ps2x_parser(struct asm_parser *ret);
|
||||||
void create_ps30_parser(struct asm_parser *ret);
|
void create_ps30_parser(struct asm_parser *ret);
|
||||||
|
|
|
@ -561,6 +561,33 @@ static void ps_1_4_test(void) {
|
||||||
"texdepth r5\n",
|
"texdepth r5\n",
|
||||||
{0xffff0104, 0x00000057, 0x800f0005, 0x0000ffff}
|
{0xffff0104, 0x00000057, 0x800f0005, 0x0000ffff}
|
||||||
},
|
},
|
||||||
|
{ /* shader 15 */
|
||||||
|
"ps_1_4\n"
|
||||||
|
"add r0, r1, r2_bx2\n",
|
||||||
|
{0xffff0104, 0x00000002, 0x800f0000, 0x80e40001, 0x84e40002, 0x0000ffff}
|
||||||
|
},
|
||||||
|
{ /* shader 16 */
|
||||||
|
"ps_1_4\n"
|
||||||
|
"add_x4 r0, r1, r2\n",
|
||||||
|
{0xffff0104, 0x00000002, 0x820f0000, 0x80e40001, 0x80e40002, 0x0000ffff}
|
||||||
|
},
|
||||||
|
{ /* shader 17 */
|
||||||
|
"ps_1_4\n"
|
||||||
|
"add r0.rgb, r1, r2\n"
|
||||||
|
"+add r0.a, r1, r2\n",
|
||||||
|
{0xffff0104, 0x00000002, 0x80070000, 0x80e40001, 0x80e40002, 0x40000002,
|
||||||
|
0x80080000, 0x80e40001, 0x80e40002, 0x0000ffff}
|
||||||
|
},
|
||||||
|
{ /* shader 18 */
|
||||||
|
"ps_1_4\n"
|
||||||
|
"texdepth_x2 r5\n",
|
||||||
|
{0xffff0104, 0x00000057, 0x810f0005, 0x0000ffff}
|
||||||
|
},
|
||||||
|
{ /* shader 18 */
|
||||||
|
"ps_1_4\n"
|
||||||
|
"bem_d2 r1, c0, r0\n",
|
||||||
|
{0xffff0104, 0x00000059, 0x8f0f0001, 0xa0e40000, 0x80e40000, 0x0000ffff}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
exec_tests("ps_1_4", tests, sizeof(tests) / sizeof(tests[0]));
|
exec_tests("ps_1_4", tests, sizeof(tests) / sizeof(tests[0]));
|
||||||
|
@ -1627,7 +1654,7 @@ START_TEST(asm)
|
||||||
todo_wine ps_1_1_test();
|
todo_wine ps_1_1_test();
|
||||||
vs_1_1_test();
|
vs_1_1_test();
|
||||||
todo_wine ps_1_3_test();
|
todo_wine ps_1_3_test();
|
||||||
todo_wine ps_1_4_test();
|
ps_1_4_test();
|
||||||
vs_2_0_test();
|
vs_2_0_test();
|
||||||
vs_2_x_test();
|
vs_2_x_test();
|
||||||
ps_2_0_test();
|
ps_2_0_test();
|
||||||
|
|
Loading…
Reference in New Issue