Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
vkd3d
Manage
Activity
Members
Labels
Plan
Wiki
Bugzilla
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
wine
vkd3d
Commits
59730ecf
Commit
59730ecf
authored
1 year ago
by
Conor McCarthy
Committed by
Alexandre Julliard
1 year ago
Browse files
Options
Downloads
Patches
Plain Diff
vkd3d-shader/dxil: Implement the DXIL GEP instruction.
parent
a0f5d707
No related branches found
No related tags found
1 merge request
!471
vkd3d-shader/dxil: Implement the DXIL GEP and LOAD instructions.
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
libs/vkd3d-shader/dxil.c
+115
-0
115 additions, 0 deletions
libs/vkd3d-shader/dxil.c
libs/vkd3d-shader/ir.c
+3
-0
3 additions, 0 deletions
libs/vkd3d-shader/ir.c
libs/vkd3d-shader/vkd3d_shader_private.h
+2
-0
2 additions, 0 deletions
libs/vkd3d-shader/vkd3d_shader_private.h
with
120 additions
and
0 deletions
libs/vkd3d-shader/dxil.c
+
115
−
0
View file @
59730ecf
...
...
@@ -2195,6 +2195,18 @@ static bool sm6_value_validate_is_handle(const struct sm6_value *value, struct s
return
true
;
}
static
bool
sm6_value_validate_is_pointer
(
const
struct
sm6_value
*
value
,
struct
sm6_parser
*
sm6
)
{
if
(
!
sm6_type_is_pointer
(
value
->
type
))
{
WARN
(
"Operand result type class %u is not a pointer.
\n
"
,
value
->
type
->
class
);
vkd3d_shader_parser_error
(
&
sm6
->
p
,
VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND
,
"A pointer operand passed to a DXIL instruction is not a pointer."
);
return
false
;
}
return
true
;
}
static
bool
sm6_value_validate_is_bool
(
const
struct
sm6_value
*
value
,
struct
sm6_parser
*
sm6
)
{
const
struct
sm6_type
*
type
=
value
->
type
;
...
...
@@ -3877,6 +3889,106 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil
instruction_dst_param_init_ssa_scalar
(
ins
,
sm6
);
}
static
void
sm6_parser_emit_gep
(
struct
sm6_parser
*
sm6
,
const
struct
dxil_record
*
record
,
struct
vkd3d_shader_instruction
*
ins
,
struct
sm6_value
*
dst
)
{
const
struct
sm6_type
*
type
,
*
pointee_type
;
unsigned
int
elem_idx
,
operand_idx
=
2
;
enum
bitcode_address_space
addr_space
;
const
struct
sm6_value
*
elem_value
;
struct
vkd3d_shader_register
*
reg
;
const
struct
sm6_value
*
src
;
bool
is_in_bounds
;
if
(
!
dxil_record_validate_operand_min_count
(
record
,
5
,
sm6
)
||
!
(
type
=
sm6_parser_get_type
(
sm6
,
record
->
operands
[
1
]))
||
!
(
src
=
sm6_parser_get_value_by_ref
(
sm6
,
record
,
NULL
,
&
operand_idx
))
||
!
sm6_value_validate_is_register
(
src
,
sm6
)
||
!
sm6_value_validate_is_pointer
(
src
,
sm6
)
||
!
dxil_record_validate_operand_min_count
(
record
,
operand_idx
+
2
,
sm6
))
{
return
;
}
if
(
src
->
u
.
reg
.
idx_count
>
1
)
{
WARN
(
"Unsupported stacked GEP.
\n
"
);
vkd3d_shader_parser_error
(
&
sm6
->
p
,
VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND
,
"A GEP instruction on the result of a previous GEP is unsupported."
);
return
;
}
is_in_bounds
=
record
->
operands
[
0
];
if
((
pointee_type
=
src
->
type
->
u
.
pointer
.
type
)
!=
type
)
{
WARN
(
"Type mismatch, type %u width %u vs type %u width %u.
\n
"
,
type
->
class
,
type
->
u
.
width
,
pointee_type
->
class
,
pointee_type
->
u
.
width
);
vkd3d_shader_parser_warning
(
&
sm6
->
p
,
VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH
,
"Type mismatch in GEP operation arguments."
);
}
addr_space
=
src
->
type
->
u
.
pointer
.
addr_space
;
if
(
!
(
elem_value
=
sm6_parser_get_value_by_ref
(
sm6
,
record
,
NULL
,
&
operand_idx
)))
return
;
/* The first index is always zero, to form a simple pointer dereference. */
if
(
sm6_value_get_constant_uint
(
elem_value
))
{
WARN
(
"Expected constant zero.
\n
"
);
vkd3d_shader_parser_error
(
&
sm6
->
p
,
VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND
,
"The pointer dereference index for a GEP instruction is not constant zero."
);
return
;
}
if
(
!
sm6_type_is_array
(
pointee_type
))
{
WARN
(
"Invalid GEP on type class %u.
\n
"
,
pointee_type
->
class
);
vkd3d_shader_parser_error
(
&
sm6
->
p
,
VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND
,
"Source type for index 1 of a GEP instruction is not an array."
);
return
;
}
if
(
!
(
elem_value
=
sm6_parser_get_value_by_ref
(
sm6
,
record
,
NULL
,
&
operand_idx
)))
return
;
/* If indexing is dynamic, just get the type at offset zero. */
elem_idx
=
sm6_value_is_constant
(
elem_value
)
?
sm6_value_get_constant_uint
(
elem_value
)
:
0
;
type
=
sm6_type_get_element_type_at_index
(
pointee_type
,
elem_idx
);
if
(
!
type
)
{
WARN
(
"Invalid element index %u.
\n
"
,
elem_idx
);
vkd3d_shader_parser_error
(
&
sm6
->
p
,
VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND
,
"Element index %u for a GEP instruction is out of bounds."
,
elem_idx
);
return
;
}
if
(
operand_idx
<
record
->
operand_count
)
{
FIXME
(
"Multiple element indices are not implemented.
\n
"
);
vkd3d_shader_parser_error
(
&
sm6
->
p
,
VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND
,
"Multi-dimensional addressing in GEP instructions is not supported."
);
return
;
}
if
(
!
(
dst
->
type
=
sm6_type_get_pointer_to_type
(
type
,
addr_space
,
sm6
)))
{
WARN
(
"Failed to get pointer type for type %u.
\n
"
,
type
->
class
);
vkd3d_shader_parser_error
(
&
sm6
->
p
,
VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE
,
"Module does not define a pointer type for a GEP instruction."
);
return
;
}
reg
=
&
dst
->
u
.
reg
;
*
reg
=
src
->
u
.
reg
;
reg
->
idx
[
1
].
offset
=
0
;
register_index_address_init
(
&
reg
->
idx
[
1
],
elem_value
,
sm6
);
reg
->
idx
[
1
].
is_in_bounds
=
is_in_bounds
;
reg
->
idx_count
=
2
;
ins
->
handler_idx
=
VKD3DSIH_NOP
;
}
static
void
sm6_parser_emit_ret
(
struct
sm6_parser
*
sm6
,
const
struct
dxil_record
*
record
,
struct
sm6_block
*
code_block
,
struct
vkd3d_shader_instruction
*
ins
)
{
...
...
@@ -4079,6 +4191,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
case
FUNC_CODE_INST_EXTRACTVAL
:
sm6_parser_emit_extractval
(
sm6
,
record
,
ins
,
dst
);
break
;
case
FUNC_CODE_INST_GEP
:
sm6_parser_emit_gep
(
sm6
,
record
,
ins
,
dst
);
break
;
case
FUNC_CODE_INST_RET
:
sm6_parser_emit_ret
(
sm6
,
record
,
code_block
,
ins
);
is_terminator
=
true
;
...
...
This diff is collapsed.
Click to expand it.
libs/vkd3d-shader/ir.c
+
3
−
0
View file @
59730ecf
...
...
@@ -300,10 +300,13 @@ void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_reg
reg
->
data_type
=
data_type
;
reg
->
idx
[
0
].
offset
=
~
0u
;
reg
->
idx
[
0
].
rel_addr
=
NULL
;
reg
->
idx
[
0
].
is_in_bounds
=
false
;
reg
->
idx
[
1
].
offset
=
~
0u
;
reg
->
idx
[
1
].
rel_addr
=
NULL
;
reg
->
idx
[
1
].
is_in_bounds
=
false
;
reg
->
idx
[
2
].
offset
=
~
0u
;
reg
->
idx
[
2
].
rel_addr
=
NULL
;
reg
->
idx
[
2
].
is_in_bounds
=
false
;
reg
->
idx_count
=
idx_count
;
reg
->
dimension
=
VSIR_DIMENSION_SCALAR
;
}
...
...
This diff is collapsed.
Click to expand it.
libs/vkd3d-shader/vkd3d_shader_private.h
+
2
−
0
View file @
59730ecf
...
...
@@ -814,6 +814,8 @@ struct vkd3d_shader_register_index
{
const
struct
vkd3d_shader_src_param
*
rel_addr
;
unsigned
int
offset
;
/* address is known to fall within the object (for optimisation) */
bool
is_in_bounds
;
};
struct
vkd3d_shader_register
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment