Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
5786d3a0
Commit
5786d3a0
authored
May 20, 2010
by
Matteo Bruni
Committed by
Alexandre Julliard
May 21, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
d3dx9: Shader assembler ps_2_x support.
parent
ce3e846f
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
579 additions
and
10 deletions
+579
-10
asmparser.c
dlls/d3dx9_36/asmparser.c
+227
-2
asmshader.y
dlls/d3dx9_36/asmshader.y
+2
-4
bytecodewriter.c
dlls/d3dx9_36/bytecodewriter.c
+333
-2
d3dx9_36_private.h
dlls/d3dx9_36/d3dx9_36_private.h
+6
-0
asm.c
dlls/d3dx9_36/tests/asm.c
+11
-2
No files found.
dlls/d3dx9_36/asmparser.c
View file @
5786d3a0
...
...
@@ -53,6 +53,17 @@ WINE_DECLARE_DEBUG_CHANNEL(parsed_shader);
#define OD0_REG 10
#define OD1_REG 11
/* Input color registers 0-1 are identically mapped */
#define C0_VARYING 0
#define C1_VARYING 1
#define T0_VARYING 2
#define T1_VARYING 3
#define T2_VARYING 4
#define T3_VARYING 5
#define T4_VARYING 6
#define T5_VARYING 7
#define T6_VARYING 8
#define T7_VARYING 9
/****************************************************************
* Common(non-version specific) shader parser control code *
...
...
@@ -283,6 +294,39 @@ static struct shader_reg map_oldvs_register(const struct shader_reg *reg) {
}
}
static
struct
shader_reg
map_oldps_register
(
const
struct
shader_reg
*
reg
,
BOOL
tex_varying
)
{
struct
shader_reg
ret
;
switch
(
reg
->
type
)
{
case
BWRITERSPR_TEXTURE
:
if
(
tex_varying
)
{
ret
=
*
reg
;
ret
.
type
=
BWRITERSPR_INPUT
;
switch
(
reg
->
regnum
)
{
case
0
:
ret
.
regnum
=
T0_VARYING
;
break
;
case
1
:
ret
.
regnum
=
T1_VARYING
;
break
;
case
2
:
ret
.
regnum
=
T2_VARYING
;
break
;
case
3
:
ret
.
regnum
=
T3_VARYING
;
break
;
case
4
:
ret
.
regnum
=
T4_VARYING
;
break
;
case
5
:
ret
.
regnum
=
T5_VARYING
;
break
;
case
6
:
ret
.
regnum
=
T6_VARYING
;
break
;
case
7
:
ret
.
regnum
=
T7_VARYING
;
break
;
default:
FIXME
(
"Unexpected TEXTURE register t%u
\n
"
,
reg
->
regnum
);
return
*
reg
;
}
return
ret
;
}
else
{
FIXME
(
"TODO: ps_1_x texture register mapping
\n
"
);
return
*
reg
;
}
/* case BWRITERSPR_INPUT - Identical mapping of 1.x/2.0 color varyings
to 3.0 ones */
default:
return
*
reg
;
}
}
/* Checks for unsupported source modifiers in VS (all versions) or
PS 2.0 and newer */
static
void
check_legacy_srcmod
(
struct
asm_parser
*
This
,
DWORD
srcmod
)
{
...
...
@@ -421,6 +465,68 @@ static void asmparser_srcreg_vs_3(struct asm_parser *This,
memcpy
(
&
instr
->
src
[
num
],
src
,
sizeof
(
*
src
));
}
static
const
struct
allowed_reg_type
ps_2_0_reg_allowed
[]
=
{
{
BWRITERSPR_INPUT
,
2
},
{
BWRITERSPR_TEMP
,
32
},
{
BWRITERSPR_CONST
,
32
},
{
BWRITERSPR_CONSTINT
,
16
},
{
BWRITERSPR_CONSTBOOL
,
16
},
{
BWRITERSPR_SAMPLER
,
16
},
{
BWRITERSPR_TEXTURE
,
8
},
{
BWRITERSPR_COLOROUT
,
4
},
{
BWRITERSPR_DEPTHOUT
,
1
},
{
~
0U
,
0
}
/* End tag */
};
static
void
asmparser_srcreg_ps_2
(
struct
asm_parser
*
This
,
struct
instruction
*
instr
,
int
num
,
const
struct
shader_reg
*
src
)
{
struct
shader_reg
reg
;
if
(
!
check_reg_type
(
src
,
ps_2_0_reg_allowed
))
{
asmparser_message
(
This
,
"Line %u: Source register %s not supported in PS 2.0
\n
"
,
This
->
line_no
,
debug_print_srcreg
(
src
,
ST_PIXEL
));
set_parse_status
(
This
,
PARSE_ERR
);
}
check_legacy_srcmod
(
This
,
src
->
srcmod
);
check_abs_srcmod
(
This
,
src
->
srcmod
);
reg
=
map_oldps_register
(
src
,
TRUE
);
memcpy
(
&
instr
->
src
[
num
],
&
reg
,
sizeof
(
reg
));
}
static
const
struct
allowed_reg_type
ps_2_x_reg_allowed
[]
=
{
{
BWRITERSPR_INPUT
,
2
},
{
BWRITERSPR_TEMP
,
32
},
{
BWRITERSPR_CONST
,
32
},
{
BWRITERSPR_CONSTINT
,
16
},
{
BWRITERSPR_CONSTBOOL
,
16
},
{
BWRITERSPR_PREDICATE
,
1
},
{
BWRITERSPR_SAMPLER
,
16
},
{
BWRITERSPR_TEXTURE
,
8
},
{
BWRITERSPR_LABEL
,
2048
},
{
BWRITERSPR_COLOROUT
,
4
},
{
BWRITERSPR_DEPTHOUT
,
1
},
{
~
0U
,
0
}
/* End tag */
};
static
void
asmparser_srcreg_ps_2_x
(
struct
asm_parser
*
This
,
struct
instruction
*
instr
,
int
num
,
const
struct
shader_reg
*
src
)
{
struct
shader_reg
reg
;
if
(
!
check_reg_type
(
src
,
ps_2_x_reg_allowed
))
{
asmparser_message
(
This
,
"Line %u: Source register %s not supported in PS 2.x
\n
"
,
This
->
line_no
,
debug_print_srcreg
(
src
,
ST_PIXEL
));
set_parse_status
(
This
,
PARSE_ERR
);
}
check_legacy_srcmod
(
This
,
src
->
srcmod
);
check_abs_srcmod
(
This
,
src
->
srcmod
);
reg
=
map_oldps_register
(
src
,
TRUE
);
memcpy
(
&
instr
->
src
[
num
],
&
reg
,
sizeof
(
reg
));
}
static
const
struct
allowed_reg_type
ps_3_reg_allowed
[]
=
{
{
BWRITERSPR_INPUT
,
10
},
{
BWRITERSPR_TEMP
,
32
},
...
...
@@ -484,6 +590,40 @@ static void asmparser_dstreg_vs_3(struct asm_parser *This,
instr
->
has_dst
=
TRUE
;
}
static
void
asmparser_dstreg_ps_2
(
struct
asm_parser
*
This
,
struct
instruction
*
instr
,
const
struct
shader_reg
*
dst
)
{
struct
shader_reg
reg
;
if
(
!
check_reg_type
(
dst
,
ps_2_0_reg_allowed
))
{
asmparser_message
(
This
,
"Line %u: Destination register %s not supported in PS 2.0
\n
"
,
This
->
line_no
,
debug_print_dstreg
(
dst
,
ST_PIXEL
));
set_parse_status
(
This
,
PARSE_ERR
);
}
check_shift_dstmod
(
This
,
instr
->
shift
);
reg
=
map_oldps_register
(
dst
,
TRUE
);
memcpy
(
&
instr
->
dst
,
&
reg
,
sizeof
(
reg
));
instr
->
has_dst
=
TRUE
;
}
static
void
asmparser_dstreg_ps_2_x
(
struct
asm_parser
*
This
,
struct
instruction
*
instr
,
const
struct
shader_reg
*
dst
)
{
struct
shader_reg
reg
;
if
(
!
check_reg_type
(
dst
,
ps_2_x_reg_allowed
))
{
asmparser_message
(
This
,
"Line %u: Destination register %s not supported in PS 2.x
\n
"
,
This
->
line_no
,
debug_print_dstreg
(
dst
,
ST_PIXEL
));
set_parse_status
(
This
,
PARSE_ERR
);
}
check_shift_dstmod
(
This
,
instr
->
shift
);
reg
=
map_oldps_register
(
dst
,
TRUE
);
memcpy
(
&
instr
->
dst
,
&
reg
,
sizeof
(
reg
));
instr
->
has_dst
=
TRUE
;
}
static
void
asmparser_dstreg_ps_3
(
struct
asm_parser
*
This
,
struct
instruction
*
instr
,
const
struct
shader_reg
*
dst
)
{
...
...
@@ -507,13 +647,11 @@ static void asmparser_predicate_supported(struct asm_parser *This,
memcpy
(
&
This
->
shader
->
instr
[
This
->
shader
->
num_instrs
-
1
]
->
predicate
,
predicate
,
sizeof
(
*
predicate
));
}
#if 0
static
void
asmparser_predicate_unsupported
(
struct
asm_parser
*
This
,
const
struct
shader_reg
*
predicate
)
{
asmparser_message
(
This
,
"Line %u: Predicate not supported in < VS 2.0 or PS 2.x
\n
"
,
This
->
line_no
);
set_parse_status
(
This
,
PARSE_ERR
);
}
#endif
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
);
...
...
@@ -560,6 +698,46 @@ static const struct asmparser_backend parser_vs_3 = {
asmparser_instr
,
};
static
const
struct
asmparser_backend
parser_ps_2
=
{
asmparser_constF
,
asmparser_constI
,
asmparser_constB
,
asmparser_dstreg_ps_2
,
asmparser_srcreg_ps_2
,
asmparser_predicate_unsupported
,
asmparser_coissue_unsupported
,
asmparser_dcl_output
,
asmparser_dcl_input
,
asmparser_dcl_sampler
,
asmparser_end
,
asmparser_instr
,
};
static
const
struct
asmparser_backend
parser_ps_2_x
=
{
asmparser_constF
,
asmparser_constI
,
asmparser_constB
,
asmparser_dstreg_ps_2_x
,
asmparser_srcreg_ps_2_x
,
asmparser_predicate_supported
,
asmparser_coissue_unsupported
,
asmparser_dcl_output
,
asmparser_dcl_input
,
asmparser_dcl_sampler
,
asmparser_end
,
asmparser_instr
,
};
static
const
struct
asmparser_backend
parser_ps_3
=
{
asmparser_constF
,
asmparser_constI
,
...
...
@@ -596,6 +774,21 @@ static void gen_oldvs_output(struct bwriter_shader *shader) {
record_declaration
(
shader
,
BWRITERDECLUSAGE_COLOR
,
1
,
TRUE
,
OD1_REG
,
BWRITERSP_WRITEMASK_ALL
);
}
static
void
gen_oldps_input
(
struct
bwriter_shader
*
shader
,
DWORD
texcoords
)
{
switch
(
texcoords
)
{
case
8
:
record_declaration
(
shader
,
BWRITERDECLUSAGE_TEXCOORD
,
7
,
FALSE
,
T7_VARYING
,
BWRITERSP_WRITEMASK_ALL
);
case
7
:
record_declaration
(
shader
,
BWRITERDECLUSAGE_TEXCOORD
,
6
,
FALSE
,
T6_VARYING
,
BWRITERSP_WRITEMASK_ALL
);
case
6
:
record_declaration
(
shader
,
BWRITERDECLUSAGE_TEXCOORD
,
5
,
FALSE
,
T5_VARYING
,
BWRITERSP_WRITEMASK_ALL
);
case
5
:
record_declaration
(
shader
,
BWRITERDECLUSAGE_TEXCOORD
,
4
,
FALSE
,
T4_VARYING
,
BWRITERSP_WRITEMASK_ALL
);
case
4
:
record_declaration
(
shader
,
BWRITERDECLUSAGE_TEXCOORD
,
3
,
FALSE
,
T3_VARYING
,
BWRITERSP_WRITEMASK_ALL
);
case
3
:
record_declaration
(
shader
,
BWRITERDECLUSAGE_TEXCOORD
,
2
,
FALSE
,
T2_VARYING
,
BWRITERSP_WRITEMASK_ALL
);
case
2
:
record_declaration
(
shader
,
BWRITERDECLUSAGE_TEXCOORD
,
1
,
FALSE
,
T1_VARYING
,
BWRITERSP_WRITEMASK_ALL
);
case
1
:
record_declaration
(
shader
,
BWRITERDECLUSAGE_TEXCOORD
,
0
,
FALSE
,
T0_VARYING
,
BWRITERSP_WRITEMASK_ALL
);
};
record_declaration
(
shader
,
BWRITERDECLUSAGE_COLOR
,
0
,
FALSE
,
C0_VARYING
,
BWRITERSP_WRITEMASK_ALL
);
record_declaration
(
shader
,
BWRITERDECLUSAGE_COLOR
,
1
,
FALSE
,
C1_VARYING
,
BWRITERSP_WRITEMASK_ALL
);
}
void
create_vs20_parser
(
struct
asm_parser
*
ret
)
{
TRACE_
(
parsed_shader
)(
"vs_2_0
\n
"
);
...
...
@@ -643,6 +836,38 @@ void create_vs30_parser(struct asm_parser *ret) {
ret
->
funcs
=
&
parser_vs_3
;
}
void
create_ps20_parser
(
struct
asm_parser
*
ret
)
{
TRACE_
(
parsed_shader
)(
"ps_2_0
\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
(
2
,
0
);
ret
->
funcs
=
&
parser_ps_2
;
gen_oldps_input
(
ret
->
shader
,
8
);
}
void
create_ps2x_parser
(
struct
asm_parser
*
ret
)
{
TRACE_
(
parsed_shader
)(
"ps_2_x
\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
(
2
,
1
);
ret
->
funcs
=
&
parser_ps_2_x
;
gen_oldps_input
(
ret
->
shader
,
8
);
}
void
create_ps30_parser
(
struct
asm_parser
*
ret
)
{
TRACE_
(
parsed_shader
)(
"ps_3_0
\n
"
);
...
...
dlls/d3dx9_36/asmshader.y
View file @
5786d3a0
...
...
@@ -328,14 +328,12 @@ version_marker: VER_VS10
| VER_PS20
{
TRACE("Pixel shader 2.0\n");
set_parse_status(&asm_ctx, PARSE_ERR);
YYABORT;
create_ps20_parser(&asm_ctx);
}
| VER_PS2X
{
TRACE("Pixel shader 2.x\n");
set_parse_status(&asm_ctx, PARSE_ERR);
YYABORT;
create_ps2x_parser(&asm_ctx);
}
| VER_PS30
{
...
...
dlls/d3dx9_36/bytecodewriter.c
View file @
5786d3a0
...
...
@@ -484,6 +484,61 @@ static HRESULT vs_find_builtin_varyings(struct bc_writer *This, const struct bwr
return
S_OK
;
}
static
HRESULT
find_ps_builtin_semantics
(
struct
bc_writer
*
This
,
const
struct
bwriter_shader
*
shader
,
DWORD
texcoords
)
{
DWORD
i
;
DWORD
usage
,
usage_idx
,
writemask
,
regnum
;
This
->
v_regnum
[
0
]
=
-
1
;
This
->
v_regnum
[
1
]
=
-
1
;
for
(
i
=
0
;
i
<
8
;
i
++
)
This
->
t_regnum
[
i
]
=
-
1
;
for
(
i
=
0
;
i
<
shader
->
num_inputs
;
i
++
)
{
usage
=
shader
->
inputs
[
i
].
usage
;
usage_idx
=
shader
->
inputs
[
i
].
usage_idx
;
writemask
=
shader
->
inputs
[
i
].
writemask
;
regnum
=
shader
->
inputs
[
i
].
regnum
;
switch
(
usage
)
{
case
BWRITERDECLUSAGE_COLOR
:
if
(
usage_idx
>
1
)
{
WARN
(
"dcl_color%u not supported in sm 1 shaders
\n
"
,
usage_idx
);
return
E_INVALIDARG
;
}
if
(
writemask
!=
BWRITERSP_WRITEMASK_ALL
)
{
WARN
(
"Only WRITEMASK_ALL is supported on color in sm 1
\n
"
);
return
E_INVALIDARG
;
}
TRACE
(
"v%u is v%u
\n
"
,
regnum
,
usage_idx
);
This
->
v_regnum
[
usage_idx
]
=
regnum
;
break
;
case
BWRITERDECLUSAGE_TEXCOORD
:
if
(
usage_idx
>
texcoords
)
{
WARN
(
"dcl_texcoord%u not supported in this shader version
\n
"
,
usage_idx
);
return
E_INVALIDARG
;
}
if
(
writemask
!=
(
BWRITERSP_WRITEMASK_0
)
&&
writemask
!=
(
BWRITERSP_WRITEMASK_0
|
BWRITERSP_WRITEMASK_1
)
&&
writemask
!=
(
BWRITERSP_WRITEMASK_0
|
BWRITERSP_WRITEMASK_1
|
BWRITERSP_WRITEMASK_2
)
&&
writemask
!=
(
BWRITERSP_WRITEMASK_ALL
))
{
WARN
(
"Partial writemasks not supported on texture coordinates in sm 1 and 2
\n
"
);
}
else
{
writemask
=
BWRITERSP_WRITEMASK_ALL
;
}
TRACE
(
"v%u is t%u
\n
"
,
regnum
,
usage_idx
);
This
->
t_regnum
[
usage_idx
]
=
regnum
;
break
;
default:
WARN
(
"Varying type %u is not supported in shader model 1.x
\n
"
,
usage
);
return
E_INVALIDARG
;
}
}
return
S_OK
;
}
static
void
end
(
struct
bc_writer
*
This
,
const
struct
bwriter_shader
*
shader
,
struct
bytecode_buffer
*
buffer
)
{
put_dword
(
buffer
,
D3DSIO_END
);
}
...
...
@@ -625,6 +680,30 @@ static void write_srcregs(struct bc_writer *This, const struct instruction *inst
}
}
static
DWORD
map_ps_input
(
struct
bc_writer
*
This
,
const
struct
shader_reg
*
reg
)
{
DWORD
i
,
token
=
0
;
/* Map color interpolators */
for
(
i
=
0
;
i
<
2
;
i
++
)
{
if
(
reg
->
regnum
==
This
->
v_regnum
[
i
])
{
token
|=
(
D3DSPR_INPUT
<<
D3DSP_REGTYPE_SHIFT
)
&
D3DSP_REGTYPE_MASK
;
token
|=
i
&
D3DSP_REGNUM_MASK
;
/* No shift */
return
token
;
}
}
for
(
i
=
0
;
i
<
8
;
i
++
)
{
if
(
reg
->
regnum
==
This
->
t_regnum
[
i
])
{
token
|=
(
D3DSPR_TEXTURE
<<
D3DSP_REGTYPE_SHIFT
)
&
D3DSP_REGTYPE_MASK
;
token
|=
i
&
D3DSP_REGNUM_MASK
;
/* No shift */
return
token
;
}
}
WARN
(
"Invalid ps 1/2 varying
\n
"
);
This
->
state
=
E_INVALIDARG
;
return
token
;
}
/* The length of an instruction consists of the destination register (if any),
* the number of source registers, the number of address registers used for
* indirect addressing, and optionally the predicate register
...
...
@@ -943,6 +1022,248 @@ static void write_samplers(const struct bwriter_shader *shader, struct bytecode_
}
}
static
void
ps_2_header
(
struct
bc_writer
*
This
,
const
struct
bwriter_shader
*
shader
,
struct
bytecode_buffer
*
buffer
)
{
HRESULT
hr
=
find_ps_builtin_semantics
(
This
,
shader
,
8
);
if
(
FAILED
(
hr
))
{
This
->
state
=
hr
;
return
;
}
/* Declare the shader type and version */
put_dword
(
buffer
,
This
->
version
);
write_samplers
(
shader
,
buffer
);
write_constF
(
shader
,
buffer
,
TRUE
);
write_constB
(
shader
,
buffer
,
TRUE
);
write_constI
(
shader
,
buffer
,
TRUE
);
}
static
void
ps_2_srcreg
(
struct
bc_writer
*
This
,
const
struct
shader_reg
*
reg
,
struct
bytecode_buffer
*
buffer
)
{
DWORD
token
=
(
1
<<
31
);
/* Bit 31 of registers is 1 */
DWORD
d3d9reg
;
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
:
case
BWRITERSPR_COLOROUT
:
case
BWRITERSPR_CONSTBOOL
:
case
BWRITERSPR_CONSTINT
:
case
BWRITERSPR_SAMPLER
:
case
BWRITERSPR_LABEL
:
case
BWRITERSPR_DEPTHOUT
:
d3d9reg
=
d3d9_register
(
reg
->
type
);
token
|=
(
d3d9reg
<<
D3DSP_REGTYPE_SHIFT
)
&
D3DSP_REGTYPE_MASK
;
token
|=
(
d3d9reg
<<
D3DSP_REGTYPE_SHIFT2
)
&
D3DSP_REGTYPE_MASK2
;
token
|=
reg
->
regnum
&
D3DSP_REGNUM_MASK
;
/* No shift */
break
;
case
BWRITERSPR_PREDICATE
:
if
(
This
->
version
!=
BWRITERPS_VERSION
(
2
,
1
)){
WARN
(
"Predicate register not supported in ps_2_0
\n
"
);
This
->
state
=
E_INVALIDARG
;
}
if
(
reg
->
regnum
)
{
WARN
(
"Predicate register with regnum %u not supported
\n
"
,
reg
->
regnum
);
This
->
state
=
E_INVALIDARG
;
}
token
|=
(
D3DSPR_PREDICATE
<<
D3DSP_REGTYPE_SHIFT
)
&
D3DSP_REGTYPE_MASK
;
token
|=
(
D3DSPR_PREDICATE
<<
D3DSP_REGTYPE_SHIFT2
)
&
D3DSP_REGTYPE_MASK2
;
token
|=
0
&
D3DSP_REGNUM_MASK
;
/* No shift */
break
;
default:
WARN
(
"Invalid register type for ps_2_0 shader
\n
"
);
This
->
state
=
E_INVALIDARG
;
return
;
}
token
|=
d3d9_swizzle
(
reg
->
swizzle
)
&
D3DVS_SWIZZLE_MASK
;
/* already shifted */
token
|=
d3d9_srcmod
(
reg
->
srcmod
);
put_dword
(
buffer
,
token
);
}
static
void
ps_2_0_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 */
DWORD
d3d9reg
;
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 */
case
BWRITERSPR_COLOROUT
:
case
BWRITERSPR_DEPTHOUT
:
d3d9reg
=
d3d9_register
(
reg
->
type
);
token
|=
(
d3d9reg
<<
D3DSP_REGTYPE_SHIFT
)
&
D3DSP_REGTYPE_MASK
;
token
|=
(
d3d9reg
<<
D3DSP_REGTYPE_SHIFT2
)
&
D3DSP_REGTYPE_MASK2
;
token
|=
reg
->
regnum
&
D3DSP_REGNUM_MASK
;
/* No shift */
break
;
case
BWRITERSPR_PREDICATE
:
if
(
This
->
version
!=
BWRITERPS_VERSION
(
2
,
1
)){
WARN
(
"Predicate register not supported in ps_2_0
\n
"
);
This
->
state
=
E_INVALIDARG
;
}
token
|=
(
D3DSPR_PREDICATE
<<
D3DSP_REGTYPE_SHIFT
)
&
D3DSP_REGTYPE_MASK
;
token
|=
(
D3DSPR_PREDICATE
<<
D3DSP_REGTYPE_SHIFT2
)
&
D3DSP_REGTYPE_MASK2
;
token
|=
reg
->
regnum
&
D3DSP_REGNUM_MASK
;
/* No shift */
break
;
/* texkill uses the input register as a destination parameter */
case
BWRITERSPR_INPUT
:
token
|=
map_ps_input
(
This
,
reg
);
break
;
default:
WARN
(
"Invalid dest register type for 2.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
const
struct
instr_handler_table
ps_2_0_handlers
[]
=
{
{
BWRITERSIO_ADD
,
instr_handler
},
{
BWRITERSIO_NOP
,
instr_handler
},
{
BWRITERSIO_MOV
,
instr_handler
},
{
BWRITERSIO_SUB
,
instr_handler
},
{
BWRITERSIO_MAD
,
instr_handler
},
{
BWRITERSIO_MUL
,
instr_handler
},
{
BWRITERSIO_RCP
,
instr_handler
},
{
BWRITERSIO_RSQ
,
instr_handler
},
{
BWRITERSIO_DP3
,
instr_handler
},
{
BWRITERSIO_DP4
,
instr_handler
},
{
BWRITERSIO_MIN
,
instr_handler
},
{
BWRITERSIO_MAX
,
instr_handler
},
{
BWRITERSIO_ABS
,
instr_handler
},
{
BWRITERSIO_EXP
,
instr_handler
},
{
BWRITERSIO_LOG
,
instr_handler
},
{
BWRITERSIO_EXPP
,
instr_handler
},
{
BWRITERSIO_LOGP
,
instr_handler
},
{
BWRITERSIO_LRP
,
instr_handler
},
{
BWRITERSIO_FRC
,
instr_handler
},
{
BWRITERSIO_CRS
,
instr_handler
},
{
BWRITERSIO_NRM
,
instr_handler
},
{
BWRITERSIO_SINCOS
,
instr_handler
},
{
BWRITERSIO_M4x4
,
instr_handler
},
{
BWRITERSIO_M4x3
,
instr_handler
},
{
BWRITERSIO_M3x4
,
instr_handler
},
{
BWRITERSIO_M3x3
,
instr_handler
},
{
BWRITERSIO_M3x2
,
instr_handler
},
{
BWRITERSIO_POW
,
instr_handler
},
{
BWRITERSIO_DP2ADD
,
instr_handler
},
{
BWRITERSIO_CMP
,
instr_handler
},
{
BWRITERSIO_TEX
,
instr_handler
},
{
BWRITERSIO_TEXLDP
,
instr_handler
},
{
BWRITERSIO_TEXLDB
,
instr_handler
},
{
BWRITERSIO_TEXKILL
,
instr_handler
},
{
BWRITERSIO_END
,
NULL
},
};
static
const
struct
bytecode_backend
ps_2_0_backend
=
{
ps_2_header
,
end
,
ps_2_srcreg
,
ps_2_0_dstreg
,
sm_2_opcode
,
ps_2_0_handlers
};
static
const
struct
instr_handler_table
ps_2_x_handlers
[]
=
{
{
BWRITERSIO_ADD
,
instr_handler
},
{
BWRITERSIO_NOP
,
instr_handler
},
{
BWRITERSIO_MOV
,
instr_handler
},
{
BWRITERSIO_SUB
,
instr_handler
},
{
BWRITERSIO_MAD
,
instr_handler
},
{
BWRITERSIO_MUL
,
instr_handler
},
{
BWRITERSIO_RCP
,
instr_handler
},
{
BWRITERSIO_RSQ
,
instr_handler
},
{
BWRITERSIO_DP3
,
instr_handler
},
{
BWRITERSIO_DP4
,
instr_handler
},
{
BWRITERSIO_MIN
,
instr_handler
},
{
BWRITERSIO_MAX
,
instr_handler
},
{
BWRITERSIO_ABS
,
instr_handler
},
{
BWRITERSIO_EXP
,
instr_handler
},
{
BWRITERSIO_LOG
,
instr_handler
},
{
BWRITERSIO_EXPP
,
instr_handler
},
{
BWRITERSIO_LOGP
,
instr_handler
},
{
BWRITERSIO_LRP
,
instr_handler
},
{
BWRITERSIO_FRC
,
instr_handler
},
{
BWRITERSIO_CRS
,
instr_handler
},
{
BWRITERSIO_NRM
,
instr_handler
},
{
BWRITERSIO_SINCOS
,
instr_handler
},
{
BWRITERSIO_M4x4
,
instr_handler
},
{
BWRITERSIO_M4x3
,
instr_handler
},
{
BWRITERSIO_M3x4
,
instr_handler
},
{
BWRITERSIO_M3x3
,
instr_handler
},
{
BWRITERSIO_M3x2
,
instr_handler
},
{
BWRITERSIO_POW
,
instr_handler
},
{
BWRITERSIO_DP2ADD
,
instr_handler
},
{
BWRITERSIO_CMP
,
instr_handler
},
{
BWRITERSIO_CALL
,
instr_handler
},
{
BWRITERSIO_CALLNZ
,
instr_handler
},
{
BWRITERSIO_REP
,
instr_handler
},
{
BWRITERSIO_ENDREP
,
instr_handler
},
{
BWRITERSIO_IF
,
instr_handler
},
{
BWRITERSIO_LABEL
,
instr_handler
},
{
BWRITERSIO_IFC
,
instr_handler
},
{
BWRITERSIO_ELSE
,
instr_handler
},
{
BWRITERSIO_ENDIF
,
instr_handler
},
{
BWRITERSIO_BREAK
,
instr_handler
},
{
BWRITERSIO_BREAKC
,
instr_handler
},
{
BWRITERSIO_RET
,
instr_handler
},
{
BWRITERSIO_TEX
,
instr_handler
},
{
BWRITERSIO_TEXLDP
,
instr_handler
},
{
BWRITERSIO_TEXLDB
,
instr_handler
},
{
BWRITERSIO_TEXKILL
,
instr_handler
},
{
BWRITERSIO_DSX
,
instr_handler
},
{
BWRITERSIO_DSY
,
instr_handler
},
{
BWRITERSIO_SETP
,
instr_handler
},
{
BWRITERSIO_BREAKP
,
instr_handler
},
{
BWRITERSIO_TEXLDD
,
instr_handler
},
{
BWRITERSIO_END
,
NULL
},
};
static
const
struct
bytecode_backend
ps_2_x_backend
=
{
ps_2_header
,
end
,
ps_2_srcreg
,
ps_2_0_dstreg
,
sm_2_opcode
,
ps_2_x_handlers
};
static
void
sm_3_header
(
struct
bc_writer
*
This
,
const
struct
bwriter_shader
*
shader
,
struct
bytecode_buffer
*
buffer
)
{
/* Declare the shader type and version */
put_dword
(
buffer
,
This
->
version
);
...
...
@@ -1186,6 +1507,16 @@ static void init_vs30_dx9_writer(struct bc_writer *writer) {
writer
->
funcs
=
&
vs_3_backend
;
}
static
void
init_ps20_dx9_writer
(
struct
bc_writer
*
writer
)
{
TRACE
(
"Creating DirectX9 pixel shader 2.0 writer
\n
"
);
writer
->
funcs
=
&
ps_2_0_backend
;
}
static
void
init_ps2x_dx9_writer
(
struct
bc_writer
*
writer
)
{
TRACE
(
"Creating DirectX9 pixel shader 2.x writer
\n
"
);
writer
->
funcs
=
&
ps_2_x_backend
;
}
static
void
init_ps30_dx9_writer
(
struct
bc_writer
*
writer
)
{
TRACE
(
"Creating DirectX9 pixel shader 3.0 writer
\n
"
);
writer
->
funcs
=
&
ps_3_backend
;
...
...
@@ -1277,7 +1608,7 @@ static struct bc_writer *create_writer(DWORD version, DWORD dxversion) {
WARN
(
"Unsupported dxversion for pixel shader 2.0 requested: %u
\n
"
,
dxversion
);
goto
fail
;
}
/* TODO: Set the appropriate writer backend */
init_ps20_dx9_writer
(
ret
);
break
;
case
BWRITERPS_VERSION
(
2
,
1
):
...
...
@@ -1285,7 +1616,7 @@ static struct bc_writer *create_writer(DWORD version, DWORD dxversion) {
WARN
(
"Unsupported dxversion for pixel shader 2.x requested: %u
\n
"
,
dxversion
);
goto
fail
;
}
/* TODO: Set the appropriate writer backend */
init_ps2x_dx9_writer
(
ret
);
break
;
case
BWRITERPS_VERSION
(
3
,
0
):
...
...
dlls/d3dx9_36/d3dx9_36_private.h
View file @
5786d3a0
...
...
@@ -314,6 +314,8 @@ extern struct asm_parser asm_ctx;
void
create_vs20_parser
(
struct
asm_parser
*
ret
);
void
create_vs2x_parser
(
struct
asm_parser
*
ret
);
void
create_vs30_parser
(
struct
asm_parser
*
ret
);
void
create_ps20_parser
(
struct
asm_parser
*
ret
);
void
create_ps2x_parser
(
struct
asm_parser
*
ret
);
void
create_ps30_parser
(
struct
asm_parser
*
ret
);
struct
bwriter_shader
*
parse_asm_shader
(
char
**
messages
);
...
...
@@ -380,6 +382,10 @@ struct bc_writer {
DWORD
oFog_mask
;
DWORD
oPts_regnum
;
DWORD
oPts_mask
;
/* Pixel shader specific members */
DWORD
t_regnum
[
8
];
DWORD
v_regnum
[
2
];
};
/* Debug utility routines */
...
...
dlls/d3dx9_36/tests/asm.c
View file @
5786d3a0
...
...
@@ -1015,6 +1015,15 @@ static void ps_2_x_test(void) {
{
0xffff0201
,
0x01000026
,
0xf0e40000
,
0x01000060
,
0xb0ff1000
,
0x00000027
,
0x0000ffff
}
},
{
/* shader 16 */
"ps_2_x
\n
"
"call l2047
\n
"
"ret
\n
"
"label l2047
\n
"
"ret
\n
"
,
{
0xffff0201
,
0x01000019
,
0xa0e417ff
,
0x0000001c
,
0x0100001e
,
0xa0e417ff
,
0x0000001c
,
0x0000ffff
}
},
};
exec_tests
(
"ps_2_x"
,
tests
,
sizeof
(
tests
)
/
sizeof
(
tests
[
0
]));
...
...
@@ -1504,8 +1513,8 @@ START_TEST(asm)
todo_wine
ps_1_4_test
();
vs_2_0_test
();
vs_2_x_test
();
todo_wine
ps_2_0_test
();
todo_wine
ps_2_x_test
();
ps_2_0_test
();
ps_2_x_test
();
vs_3_0_test
();
ps_3_0_test
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment