nir/spirv: Add basic support for Op[Group]MemberDecorate
This commit is contained in:
@@ -180,15 +180,21 @@ vtn_handle_extension(struct vtn_builder *b, SpvOp opcode,
|
|||||||
static void
|
static void
|
||||||
_foreach_decoration_helper(struct vtn_builder *b,
|
_foreach_decoration_helper(struct vtn_builder *b,
|
||||||
struct vtn_value *base_value,
|
struct vtn_value *base_value,
|
||||||
|
int member,
|
||||||
struct vtn_value *value,
|
struct vtn_value *value,
|
||||||
vtn_decoration_foreach_cb cb, void *data)
|
vtn_decoration_foreach_cb cb, void *data)
|
||||||
{
|
{
|
||||||
for (struct vtn_decoration *dec = value->decoration; dec; dec = dec->next) {
|
for (struct vtn_decoration *dec = value->decoration; dec; dec = dec->next) {
|
||||||
|
if (dec->member >= 0) {
|
||||||
|
assert(member == -1);
|
||||||
|
member = dec->member;
|
||||||
|
}
|
||||||
|
|
||||||
if (dec->group) {
|
if (dec->group) {
|
||||||
assert(dec->group->value_type == vtn_value_type_decoration_group);
|
assert(dec->group->value_type == vtn_value_type_decoration_group);
|
||||||
_foreach_decoration_helper(b, base_value, dec->group, cb, data);
|
_foreach_decoration_helper(b, base_value, member, dec->group, cb, data);
|
||||||
} else {
|
} else {
|
||||||
cb(b, base_value, dec, data);
|
cb(b, base_value, member, dec, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -203,24 +209,33 @@ void
|
|||||||
vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
|
vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
|
||||||
vtn_decoration_foreach_cb cb, void *data)
|
vtn_decoration_foreach_cb cb, void *data)
|
||||||
{
|
{
|
||||||
_foreach_decoration_helper(b, value, value, cb, data);
|
_foreach_decoration_helper(b, value, -1, value, cb, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
|
vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
|
||||||
const uint32_t *w, unsigned count)
|
const uint32_t *w, unsigned count)
|
||||||
{
|
{
|
||||||
|
const uint32_t *w_end = w + count;
|
||||||
|
const uint32_t target = w[1];
|
||||||
|
w += 2;
|
||||||
|
|
||||||
|
int member = -1;
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case SpvOpDecorationGroup:
|
case SpvOpDecorationGroup:
|
||||||
vtn_push_value(b, w[1], vtn_value_type_undef);
|
vtn_push_value(b, target, vtn_value_type_undef);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SpvOpMemberDecorate:
|
||||||
|
member = *(w++);
|
||||||
|
/* fallthrough */
|
||||||
case SpvOpDecorate: {
|
case SpvOpDecorate: {
|
||||||
struct vtn_value *val = &b->values[w[1]];
|
struct vtn_value *val = &b->values[target];
|
||||||
|
|
||||||
struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
|
struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
|
||||||
dec->decoration = w[2];
|
dec->member = member;
|
||||||
dec->literals = &w[3];
|
dec->decoration = *(w++);
|
||||||
|
dec->literals = w;
|
||||||
|
|
||||||
/* Link into the list */
|
/* Link into the list */
|
||||||
dec->next = val->decoration;
|
dec->next = val->decoration;
|
||||||
@@ -228,13 +243,17 @@ vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SpvOpGroupMemberDecorate:
|
||||||
|
member = *(w++);
|
||||||
|
/* fallthrough */
|
||||||
case SpvOpGroupDecorate: {
|
case SpvOpGroupDecorate: {
|
||||||
struct vtn_value *group = &b->values[w[1]];
|
struct vtn_value *group = &b->values[target];
|
||||||
assert(group->value_type == vtn_value_type_decoration_group);
|
assert(group->value_type == vtn_value_type_decoration_group);
|
||||||
|
|
||||||
for (unsigned i = 2; i < count; i++) {
|
for (; w < w_end; w++) {
|
||||||
struct vtn_value *val = &b->values[w[i]];
|
struct vtn_value *val = &b->values[*w];
|
||||||
struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
|
struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
|
||||||
|
dec->member = member;
|
||||||
dec->group = group;
|
dec->group = group;
|
||||||
|
|
||||||
/* Link into the list */
|
/* Link into the list */
|
||||||
@@ -244,10 +263,6 @@ vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SpvOpGroupMemberDecorate:
|
|
||||||
assert(!"Bad instruction. Khronos Bug #13513");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
unreachable("Unhandled opcode");
|
unreachable("Unhandled opcode");
|
||||||
}
|
}
|
||||||
@@ -432,7 +447,7 @@ vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
var_decoration_cb(struct vtn_builder *b, struct vtn_value *val,
|
var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
|
||||||
const struct vtn_decoration *dec, void *void_var)
|
const struct vtn_decoration *dec, void *void_var)
|
||||||
{
|
{
|
||||||
assert(val->value_type == vtn_value_type_deref);
|
assert(val->value_type == vtn_value_type_deref);
|
||||||
|
@@ -100,6 +100,7 @@ struct vtn_value {
|
|||||||
|
|
||||||
struct vtn_decoration {
|
struct vtn_decoration {
|
||||||
struct vtn_decoration *next;
|
struct vtn_decoration *next;
|
||||||
|
int member; /* -1 if not a member decoration */
|
||||||
const uint32_t *literals;
|
const uint32_t *literals;
|
||||||
struct vtn_value *group;
|
struct vtn_value *group;
|
||||||
SpvDecoration decoration;
|
SpvDecoration decoration;
|
||||||
@@ -168,6 +169,7 @@ struct vtn_ssa_value *vtn_ssa_value(struct vtn_builder *b, uint32_t value_id);
|
|||||||
|
|
||||||
typedef void (*vtn_decoration_foreach_cb)(struct vtn_builder *,
|
typedef void (*vtn_decoration_foreach_cb)(struct vtn_builder *,
|
||||||
struct vtn_value *,
|
struct vtn_value *,
|
||||||
|
int member,
|
||||||
const struct vtn_decoration *,
|
const struct vtn_decoration *,
|
||||||
void *);
|
void *);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user