libs/vkd3d-shader: Translate mov instruction.

This commit is contained in:
Józef Kucia 2017-06-20 13:34:44 +02:00
parent 18e952aaf4
commit 2b1396e7e4
2 changed files with 524 additions and 0 deletions

View File

@ -282,6 +282,12 @@ static void vkd3d_spirv_build_op2(struct vkd3d_spirv_stream *stream,
return vkd3d_spirv_build_op2v(stream, op, operand0, operand1, NULL, 0);
}
static void vkd3d_spirv_build_op3(struct vkd3d_spirv_stream *stream,
SpvOp op, uint32_t operand0, uint32_t operand1, uint32_t operand2)
{
return vkd3d_spirv_build_op2v(stream, op, operand0, operand1, &operand2, 1);
}
static uint32_t vkd3d_spirv_build_op_rv(struct vkd3d_spirv_builder *builder,
struct vkd3d_spirv_stream *stream, SpvOp op,
const uint32_t *operands, unsigned int operand_count)
@ -328,6 +334,12 @@ static uint32_t vkd3d_spirv_build_op_trv(struct vkd3d_spirv_builder *builder,
return result_id;
}
static uint32_t vkd3d_spirv_build_op_tr(struct vkd3d_spirv_builder *builder,
struct vkd3d_spirv_stream *stream, SpvOp op, uint32_t result_type)
{
return vkd3d_spirv_build_op_trv(builder, stream, op, result_type, NULL, 0);
}
static uint32_t vkd3d_spirv_build_op_tr1(struct vkd3d_spirv_builder *builder,
struct vkd3d_spirv_stream *stream, SpvOp op, uint32_t result_type,
uint32_t operand0)
@ -344,6 +356,37 @@ static uint32_t vkd3d_spirv_build_op_tr2(struct vkd3d_spirv_builder *builder,
operands, ARRAY_SIZE(operands));
}
static uint32_t vkd3d_spirv_build_op_tr1v(struct vkd3d_spirv_builder *builder,
struct vkd3d_spirv_stream *stream, SpvOp op, uint32_t result_type,
uint32_t operand0, const uint32_t *operands, unsigned int operand_count)
{
uint32_t result_id = builder->current_id++;
unsigned int i;
vkd3d_spirv_build_word(stream, vkd3d_spirv_opcode_word(op, 4 + operand_count));
vkd3d_spirv_build_word(stream, result_type);
vkd3d_spirv_build_word(stream, result_id);
vkd3d_spirv_build_word(stream, operand0);
for (i = 0; i < operand_count; ++i)
vkd3d_spirv_build_word(stream, operands[i]);
return result_id;
}
static uint32_t vkd3d_spirv_build_op_tr2v(struct vkd3d_spirv_builder *builder,
struct vkd3d_spirv_stream *stream, SpvOp op, uint32_t result_type,
uint32_t operand0, uint32_t operand1, const uint32_t *operands, unsigned int operand_count)
{
uint32_t result_id = builder->current_id++;
unsigned int i;
vkd3d_spirv_build_word(stream, vkd3d_spirv_opcode_word(op, 5 + operand_count));
vkd3d_spirv_build_word(stream, result_type);
vkd3d_spirv_build_word(stream, result_id);
vkd3d_spirv_build_word(stream, operand0);
vkd3d_spirv_build_word(stream, operand1);
for (i = 0; i < operand_count; ++i)
vkd3d_spirv_build_word(stream, operands[i]);
return result_id;
}
static void vkd3d_spirv_build_op_capability(struct vkd3d_spirv_stream *stream,
SpvCapability cap)
{
@ -437,6 +480,21 @@ static uint32_t vkd3d_spirv_build_op_type_pointer(struct vkd3d_spirv_builder *bu
SpvOpTypePointer, storage_class, type_id);
}
/* Types larger than 32-bits are not supported. */
static uint32_t vkd3d_spirv_build_op_constant(struct vkd3d_spirv_builder *builder,
uint32_t result_type, const uint32_t value)
{
return vkd3d_spirv_build_op_tr1(builder, &builder->global_stream,
SpvOpConstant, result_type, value);
}
static uint32_t vkd3d_spirv_build_op_constant_composite(struct vkd3d_spirv_builder *builder,
uint32_t result_type, const uint32_t* constituents, unsigned int constituent_count)
{
return vkd3d_spirv_build_op_trv(builder, &builder->global_stream,
SpvOpConstantComposite, result_type, constituents, constituent_count);
}
/* Initializers are not supported. */
static uint32_t vkd3d_spirv_build_op_variable(struct vkd3d_spirv_builder *builder,
struct vkd3d_spirv_stream *stream, uint32_t type_id, uint32_t storage_class)
@ -461,11 +519,68 @@ static uint32_t vkd3d_spirv_build_op_label(struct vkd3d_spirv_builder *builder)
return vkd3d_spirv_build_op_r(builder, &builder->function_stream, SpvOpLabel);
}
static uint32_t vkd3d_spirv_build_op_undef(struct vkd3d_spirv_builder *builder,
struct vkd3d_spirv_stream *stream, uint32_t type_id)
{
return vkd3d_spirv_build_op_tr(builder, stream, SpvOpUndef, type_id);
}
static uint32_t vkd3d_spirv_build_op_access_chain(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t base_id, uint32_t *indexes, uint32_t index_count)
{
return vkd3d_spirv_build_op_tr1v(builder, &builder->function_stream,
SpvOpAccessChain, result_type, base_id, indexes, index_count);
}
static uint32_t vkd3d_spirv_build_op_in_bounds_access_chain(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t base_id, uint32_t *indexes, uint32_t index_count)
{
return vkd3d_spirv_build_op_tr1v(builder, &builder->function_stream,
SpvOpInBoundsAccessChain, result_type, base_id, indexes, index_count);
}
static uint32_t vkd3d_spirv_build_op_vector_shuffle(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t vector1_id, uint32_t vector2_id,
uint32_t *components, uint32_t component_count)
{
return vkd3d_spirv_build_op_tr2v(builder, &builder->function_stream, SpvOpVectorShuffle,
result_type, vector1_id, vector2_id, components, component_count);
}
static uint32_t vkd3d_spirv_build_op_load(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t pointer_id, uint32_t memory_access)
{
if (!memory_access)
return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpLoad,
result_type, pointer_id);
else
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpLoad,
result_type, pointer_id, memory_access);
}
static void vkd3d_spirv_build_op_store(struct vkd3d_spirv_builder *builder,
uint32_t pointer_id, uint32_t object_id, uint32_t memory_access)
{
if (!memory_access)
return vkd3d_spirv_build_op2(&builder->function_stream, SpvOpStore,
pointer_id, object_id);
else
return vkd3d_spirv_build_op3(&builder->function_stream, SpvOpStore,
pointer_id, object_id, memory_access);
}
static void vkd3d_spirv_build_op_return(struct vkd3d_spirv_builder *builder)
{
vkd3d_spirv_build_op(&builder->function_stream, SpvOpReturn);
}
static uint32_t vkd3d_spirv_build_op_bitcast(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand)
{
return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream,
SpvOpBitcast, result_type, operand);
}
static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder,
enum vkd3d_component_type component_type, unsigned int component_count)
{
@ -604,6 +719,17 @@ struct vkd3d_symbol_pointer_type
SpvStorageClass storage_class;
};
struct vkd3d_symbol_constant
{
unsigned int component_count;
enum vkd3d_component_type component_type;
union
{
float f[VKD3D_VEC4_SIZE];
uint32_t u[VKD3D_VEC4_SIZE];
} value;
};
struct vkd3d_symbol_register
{
enum vkd3d_shader_register_type type;
@ -617,12 +743,14 @@ struct vkd3d_symbol
enum
{
VKD3D_SYMBOL_POINTER_TYPE,
VKD3D_SYMBOL_CONSTANT,
VKD3D_SYMBOL_REGISTER,
} type;
union
{
struct vkd3d_symbol_pointer_type pointer_type;
struct vkd3d_symbol_constant constant;
struct vkd3d_symbol_register reg;
} key;
@ -659,6 +787,16 @@ static void vkd3d_symbol_make_pointer_type(struct vkd3d_symbol *symbol,
symbol->key.pointer_type.storage_class = storage_class;
}
static void vkd3d_symbol_make_constant(struct vkd3d_symbol *symbol,
enum vkd3d_component_type component_type, unsigned int component_count, const uint32_t *values)
{
symbol->type = VKD3D_SYMBOL_CONSTANT;
memset(&symbol->key, 0, sizeof(symbol->key));
symbol->key.constant.component_type = component_type;
symbol->key.constant.component_count = component_count;
memcpy(symbol->key.constant.value.u, values, sizeof(*values) * component_count);
}
static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol,
const struct vkd3d_shader_register *reg)
{
@ -758,6 +896,55 @@ static uint32_t vkd3d_dxbc_compiler_get_pointer_type(struct vkd3d_dxbc_compiler
return pointer_type.id;
}
static uint32_t vkd3d_dxbc_compiler_get_constant(struct vkd3d_dxbc_compiler *compiler,
enum vkd3d_component_type component_type, unsigned int component_count, const uint32_t *values)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
uint32_t component_ids[VKD3D_VEC4_SIZE];
struct vkd3d_symbol constant;
struct rb_entry *entry;
unsigned int i;
assert(0 < component_count && component_count <= VKD3D_VEC4_SIZE);
vkd3d_symbol_make_constant(&constant, component_type, component_count, values);
if ((entry = rb_get(&compiler->symbol_table, &constant)))
return RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry)->id;
switch (component_type)
{
case VKD3D_TYPE_UINT:
case VKD3D_TYPE_INT:
case VKD3D_TYPE_FLOAT:
break;
default:
FIXME("Unhandled component_type %#x.\n", component_type);
return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id);
}
if (component_count == 1)
{
constant.id = vkd3d_spirv_build_op_constant(builder, type_id, *values);
}
else
{
for (i = 0; i < component_count; ++i)
component_ids[i] = vkd3d_dxbc_compiler_get_constant(compiler, component_type, 1, &values[i]);
constant.id = vkd3d_spirv_build_op_constant_composite(builder, type_id, component_ids, component_count);
}
vkd3d_dxbc_compiler_put_symbol(compiler, &constant);
return constant.id;
}
static uint32_t vkd3d_dxbc_compiler_get_constant_uint(struct vkd3d_dxbc_compiler *compiler,
uint32_t value)
{
return vkd3d_dxbc_compiler_get_constant(compiler, VKD3D_TYPE_UINT, 1, &value);
}
static bool vkd3d_dxbc_compiler_get_register_name(char *buffer,const struct vkd3d_shader_register *reg)
{
switch (reg->type)
@ -801,6 +988,278 @@ static uint32_t vkd3d_dxbc_compiler_emit_variable(struct vkd3d_dxbc_compiler *co
return vkd3d_spirv_build_op_variable(builder, stream, ptr_type_id, storage_class);
}
static uint32_t vkd3d_dxbc_compiler_emit_undef(struct vkd3d_dxbc_compiler *compiler,
struct vkd3d_spirv_stream *stream, const struct vkd3d_shader_register *reg)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t type_id, ptr_type_id;
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, VKD3D_VEC4_SIZE);
ptr_type_id = vkd3d_dxbc_compiler_get_pointer_type(compiler, type_id, SpvStorageClassPrivate);
return vkd3d_spirv_build_op_undef(builder, stream, ptr_type_id);
}
struct vkd3d_dxbc_register_info
{
uint32_t id;
SpvStorageClass storage_class;
};
static void vkd3d_dxbc_compiler_get_register_info(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, struct vkd3d_dxbc_register_info *register_info)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
struct vkd3d_symbol reg_symbol, *symbol;
struct rb_entry *entry;
assert(reg->type != VKD3DSPR_IMMCONST);
if (reg->idx[0].rel_addr || reg->idx[1].rel_addr)
FIXME("Relative indexing not implemented.\n");
if (reg->type == VKD3DSPR_TEMP)
{
assert(reg->idx[0].offset < compiler->temp_count);
register_info->id = compiler->temp_id + reg->idx[0].offset;
register_info->storage_class = SpvStorageClassFunction;
return;
}
vkd3d_symbol_make_register(&reg_symbol, reg);
entry = rb_get(&compiler->symbol_table, &reg_symbol);
assert(entry);
symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry);
register_info->id = symbol->id;
register_info->storage_class = symbol->info.storage_class;
if (reg->type == VKD3DSPR_CONSTBUFFER)
{
uint32_t type_id, ptr_type_id;
uint32_t indexes[] =
{
vkd3d_dxbc_compiler_get_constant_uint(compiler, 0),
vkd3d_dxbc_compiler_get_constant_uint(compiler, reg->idx[1].offset),
};
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, VKD3D_VEC4_SIZE);
ptr_type_id = vkd3d_dxbc_compiler_get_pointer_type(compiler,
type_id, register_info->storage_class);
register_info->id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id,
register_info->id, indexes, ARRAY_SIZE(indexes));
}
}
static uint32_t vkd3d_dxbc_compiler_get_register_id(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
struct vkd3d_dxbc_register_info register_info;
unsigned int component_count;
switch (reg->type)
{
case VKD3DSPR_TEMP:
case VKD3DSPR_INPUT:
case VKD3DSPR_OUTPUT:
case VKD3DSPR_COLOROUT:
case VKD3DSPR_CONSTBUFFER:
vkd3d_dxbc_compiler_get_register_info(compiler, reg, &register_info);
return register_info.id;
case VKD3DSPR_IMMCONST:
if (reg->immconst_type == VKD3D_IMMCONST_SCALAR)
{
component_count = 1;
}
else if (reg->immconst_type == VKD3D_IMMCONST_VEC4)
{
component_count = VKD3D_VEC4_SIZE;
}
else
{
FIXME("Unhandled immconst type %#x.\n", reg->immconst_type);
component_count = 1;
}
return vkd3d_dxbc_compiler_get_constant(compiler,
vkd3d_component_type_from_data_type(reg->data_type),
component_count, reg->u.immconst_data);
default:
FIXME("Unhandled register type %#x.\n", reg->type);
return vkd3d_dxbc_compiler_emit_undef(compiler, &builder->global_stream, reg);
}
}
static uint32_t vkd3d_dxbc_compiler_emit_load_constant(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
{
unsigned int component_count = vkd3d_write_mask_component_count(write_mask);
uint32_t values[VKD3D_VEC4_SIZE];
unsigned int i, j;
assert(reg->type == VKD3DSPR_IMMCONST);
if (component_count == 1 || component_count == VKD3D_VEC4_SIZE)
{
assert(component_count != 1 || reg->immconst_type == VKD3D_IMMCONST_SCALAR);
return vkd3d_dxbc_compiler_get_register_id(compiler, reg);
}
assert(reg->immconst_type == VKD3D_IMMCONST_VEC4);
for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
values[j++] = reg->u.immconst_data[vkd3d_swizzle_get_component(swizzle, i)];
}
return vkd3d_dxbc_compiler_get_constant(compiler,
vkd3d_component_type_from_data_type(reg->data_type), component_count, values);
}
static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t type_id, ptr_type_id, indexes[1], chain_id, val_id;
struct vkd3d_dxbc_register_info reg_info;
unsigned int component_idx;
assert(reg->type != VKD3DSPR_IMMCONST);
assert(vkd3d_write_mask_component_count(write_mask) == 1);
component_idx = vkd3d_write_mask_get_component_idx(write_mask);
component_idx = vkd3d_swizzle_get_component(swizzle, component_idx);
vkd3d_dxbc_compiler_get_register_info(compiler, reg, &reg_info);
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, 1);
ptr_type_id = vkd3d_dxbc_compiler_get_pointer_type(compiler, type_id, reg_info.storage_class);
indexes[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx);
chain_id = vkd3d_spirv_build_op_in_bounds_access_chain(builder,
ptr_type_id, reg_info.id, indexes, ARRAY_SIZE(indexes));
val_id = vkd3d_spirv_build_op_load(builder, type_id, chain_id, SpvMemoryAccessMaskNone);
if (reg->data_type != VKD3D_DATA_FLOAT)
{
type_id = vkd3d_spirv_get_type_id(builder,
vkd3d_component_type_from_data_type(reg->data_type), 1);
val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
}
return val_id;
}
static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t src_id, type_id, val_id, components[VKD3D_VEC4_SIZE];
unsigned int i, component_idx, component_count;
if (reg->type == VKD3DSPR_IMMCONST)
return vkd3d_dxbc_compiler_emit_load_constant(compiler, reg, swizzle, write_mask);
component_count = vkd3d_write_mask_component_count(write_mask);
if (component_count == 1)
return vkd3d_dxbc_compiler_emit_load_scalar(compiler, reg, swizzle, write_mask);
src_id = vkd3d_dxbc_compiler_get_register_id(compiler, reg);
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, VKD3D_VEC4_SIZE);
val_id = vkd3d_spirv_build_op_load(builder, type_id, src_id, SpvMemoryAccessMaskNone);
if (component_count != VKD3D_VEC4_SIZE || swizzle != VKD3DSP_NOSWIZZLE)
{
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, component_count);
for (i = 0, component_idx = 0; i < ARRAY_SIZE(components); ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
components[component_idx++] = vkd3d_swizzle_get_component(swizzle, i);
}
val_id = vkd3d_spirv_build_op_vector_shuffle(builder,
type_id, val_id, val_id, components, component_count);
}
if (reg->data_type != VKD3D_DATA_FLOAT)
{
type_id = vkd3d_spirv_get_type_id(builder,
vkd3d_component_type_from_data_type(reg->data_type), component_count);
val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
}
return val_id;
}
static void vkd3d_dxbc_compiler_emit_store_scalar(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, DWORD write_mask, uint32_t val_id)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t type_id, ptr_type_id, chain_id, index[1];
struct vkd3d_dxbc_register_info reg_info;
unsigned int component_idx;
assert(reg->type != VKD3DSPR_IMMCONST);
vkd3d_dxbc_compiler_get_register_info(compiler, reg, &reg_info);
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, 1);
ptr_type_id = vkd3d_dxbc_compiler_get_pointer_type(compiler,
type_id, reg_info.storage_class);
component_idx = vkd3d_write_mask_get_component_idx(write_mask);
index[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx);
chain_id = vkd3d_spirv_build_op_in_bounds_access_chain(builder,
ptr_type_id, reg_info.id, index, ARRAY_SIZE(index));
vkd3d_spirv_build_op_store(builder, chain_id, val_id, SpvMemoryAccessMaskNone);
}
static void vkd3d_dxbc_compiler_emit_store_reg(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, DWORD write_mask, uint32_t val_id)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
unsigned int i, component_idx, component_count;
uint32_t components[VKD3D_VEC4_SIZE];
uint32_t reg_id;
assert(reg->type != VKD3DSPR_IMMCONST);
component_count = vkd3d_write_mask_component_count(write_mask);
if (reg->data_type != VKD3D_DATA_FLOAT)
{
uint32_t type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, component_count);
val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
}
if (component_count == 1)
return vkd3d_dxbc_compiler_emit_store_scalar(compiler, reg, write_mask, val_id);
if (component_count != VKD3D_VEC4_SIZE)
{
uint32_t type_id, reg_val_id;
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, VKD3D_VEC4_SIZE);
reg_val_id = vkd3d_dxbc_compiler_emit_load_reg(compiler,
reg, VKD3DSP_NOSWIZZLE, VKD3DSP_WRITEMASK_ALL);
for (i = 0, component_idx = 0; i < ARRAY_SIZE(components); ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
components[i] = VKD3D_VEC4_SIZE + component_idx++;
else
components[i] = i;
}
val_id = vkd3d_spirv_build_op_vector_shuffle(builder,
type_id, reg_val_id, val_id, components, ARRAY_SIZE(components));
}
reg_id = vkd3d_dxbc_compiler_get_register_id(compiler, reg);
vkd3d_spirv_build_op_store(builder, reg_id, val_id, SpvMemoryAccessMaskNone);
}
static void vkd3d_dxbc_compiler_decorate_sysval(struct vkd3d_spirv_builder *builder,
uint32_t target_id, enum vkd3d_shader_input_sysval_semantic sysval)
{
@ -899,6 +1358,17 @@ static void vkd3d_dxbc_compiler_emit_dcl_thread_group(struct vkd3d_dxbc_compiler
vkd3d_spirv_set_local_size(builder, group_size->x, group_size->y, group_size->z);
}
static void vkd3d_dxbc_compiler_emit_mov(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
const struct vkd3d_shader_dst_param *dst = &instruction->dst[0];
const struct vkd3d_shader_src_param *src = &instruction->src[0];
uint32_t val_id;
val_id = vkd3d_dxbc_compiler_emit_load_reg(compiler, &src->reg, src->swizzle, dst->write_mask);
vkd3d_dxbc_compiler_emit_store_reg(compiler, &dst->reg, dst->write_mask, val_id);
}
static void vkd3d_dxbc_compiler_emit_return(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
@ -922,6 +1392,9 @@ void vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler
case VKD3DSIH_DCL_THREAD_GROUP:
vkd3d_dxbc_compiler_emit_dcl_thread_group(compiler, instruction);
break;
case VKD3DSIH_MOV:
vkd3d_dxbc_compiler_emit_mov(compiler, instruction);
break;
case VKD3DSIH_RET:
vkd3d_dxbc_compiler_emit_return(compiler, instruction);
break;

View File

@ -827,4 +827,55 @@ bool vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler,
struct vkd3d_shader_code *spirv) DECLSPEC_HIDDEN;
void vkd3d_dxbc_compiler_destroy(struct vkd3d_dxbc_compiler *compiler) DECLSPEC_HIDDEN;
static inline enum vkd3d_component_type vkd3d_component_type_from_data_type(
enum vkd3d_data_type data_type)
{
switch (data_type)
{
case VKD3D_DATA_FLOAT:
return VKD3D_TYPE_FLOAT;
case VKD3D_DATA_UINT:
return VKD3D_TYPE_UINT;
case VKD3D_DATA_INT:
return VKD3D_TYPE_INT;
default:
FIXME("Unhandled data type %#x.\n", data_type);
return VKD3D_TYPE_UINT;
}
}
static inline unsigned int vkd3d_write_mask_get_component_idx(DWORD write_mask)
{
unsigned int i;
for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
return i;
}
FIXME("Invalid write mask %#x.\n", write_mask);
return 0;
}
static inline unsigned int vkd3d_write_mask_component_count(DWORD write_mask)
{
unsigned int i, count = 0;
for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
++count;
}
return count;
}
static inline unsigned int vkd3d_swizzle_get_component(DWORD swizzle,
unsigned int idx)
{
/* swizzle bits fields: wwzzyyxx */
return (swizzle >> (2 * idx)) & 0x3;
}
#endif /* __VKD3D_SHADER_PRIVATE_H */