vkd3d-shader: Implement 64-bit immediate constants

Signed-off-by: Joshua Ashton <joshua@froggi.es>
This commit is contained in:
Joshua Ashton 2020-10-21 12:09:31 +01:00
parent ab03abe419
commit 837ef2edc6
4 changed files with 117 additions and 4 deletions

View File

@ -363,6 +363,7 @@ enum vkd3d_sm4_register_type
VKD3D_SM4_RT_OUTPUT = 0x02,
VKD3D_SM4_RT_INDEXABLE_TEMP = 0x03,
VKD3D_SM4_RT_IMMCONST = 0x04,
VKD3D_SM4_RT_IMMCONST64 = 0x05,
VKD3D_SM4_RT_SAMPLER = 0x06,
VKD3D_SM4_RT_RESOURCE = 0x07,
VKD3D_SM4_RT_CONSTBUFFER = 0x08,
@ -454,6 +455,7 @@ enum vkd3d_sm4_immconst_type
{
VKD3D_SM4_IMMCONST_SCALAR = 0x1,
VKD3D_SM4_IMMCONST_VEC4 = 0x2,
VKD3D_SM4_IMMCONST_DVEC2 = VKD3D_SM4_IMMCONST_VEC4,
};
enum vkd3d_sm4_resource_type
@ -1307,7 +1309,7 @@ static const enum vkd3d_shader_register_type register_type_table[] =
/* VKD3D_SM4_RT_OUTPUT */ VKD3DSPR_OUTPUT,
/* VKD3D_SM4_RT_INDEXABLE_TEMP */ VKD3DSPR_IDXTEMP,
/* VKD3D_SM4_RT_IMMCONST */ VKD3DSPR_IMMCONST,
/* UNKNOWN */ ~0u,
/* VKD3D_SM4_RT_IMMCONST64 */ VKD3DSPR_IMMCONST64,
/* VKD3D_SM4_RT_SAMPLER */ VKD3DSPR_SAMPLER,
/* VKD3D_SM4_RT_RESOURCE */ VKD3DSPR_RESOURCE,
/* VKD3D_SM4_RT_CONSTBUFFER */ VKD3DSPR_CONSTBUFFER,
@ -1710,6 +1712,40 @@ static bool shader_sm4_read_param(struct vkd3d_sm4_data *priv, const DWORD **ptr
break;
}
}
else if (register_type == VKD3D_SM4_RT_IMMCONST64)
{
enum vkd3d_sm4_immconst_type immconst_type =
(token & VKD3D_SM4_IMMCONST_TYPE_MASK) >> VKD3D_SM4_IMMCONST_TYPE_SHIFT;
switch (immconst_type)
{
case VKD3D_SM4_IMMCONST_SCALAR:
param->immconst_type = VKD3D_IMMCONST_SCALAR;
if (end - *ptr < VKD3D_DOUBLE_DWORD_SIZE)
{
WARN("Invalid ptr %p, end %p.\n", *ptr, end);
return false;
}
memcpy(param->immconst_uint64, *ptr, VKD3D_DOUBLE_DWORD_SIZE * sizeof(DWORD));
*ptr += VKD3D_DOUBLE_DWORD_SIZE;
break;
case VKD3D_SM4_IMMCONST_DVEC2:
param->immconst_type = VKD3D_IMMCONST_VEC4;
if (end - *ptr < VKD3D_DVEC2_DWORD_SIZE)
{
WARN("Invalid ptr %p, end %p.\n", *ptr, end);
return false;
}
memcpy(param->immconst_uint64, *ptr, VKD3D_DVEC2_DWORD_SIZE * sizeof(DWORD));
*ptr += VKD3D_DVEC2_DWORD_SIZE;
break;
default:
FIXME("Unhandled immediate constant type %#x.\n", immconst_type);
break;
}
}
map_register(priv, param);

View File

@ -2921,7 +2921,7 @@ static bool vkd3d_dxbc_compiler_find_register_info(const struct vkd3d_dxbc_compi
struct vkd3d_symbol reg_symbol, *symbol;
struct rb_entry *entry;
assert(reg->type != VKD3DSPR_IMMCONST);
assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64);
if (reg->type == VKD3DSPR_TEMP)
{
@ -3161,6 +3161,33 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_constant(struct vkd3d_dxbc_compile
vkd3d_component_type_from_data_type(reg->data_type), component_count, values);
}
static uint32_t vkd3d_dxbc_compiler_emit_load_constant64(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_typed(write_mask, VKD3D_TYPE_DOUBLE);
uint64_t values[2] = {0};
unsigned int i, j;
assert(reg->type == VKD3DSPR_IMMCONST64);
if (reg->immconst_type == VKD3D_IMMCONST_SCALAR)
{
for (i = 0; i < component_count; ++i)
values[i] = reg->immconst_uint64[0];
}
else
{
for (i = 0, j = 0; i < VKD3D_DVEC2_SIZE; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << (i * 2)))
values[j++] = reg->immconst_uint64[vkd3d_swizzle_get_component(swizzle, i * 2) / 2];
}
}
return vkd3d_dxbc_compiler_get_constant(compiler,
vkd3d_component_type_from_data_type(reg->data_type), component_count, (const uint32_t*)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,
const struct vkd3d_shader_register_info *reg_info)
@ -3171,7 +3198,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler
enum vkd3d_component_type component_type;
unsigned int skipped_component_mask;
assert(reg->type != VKD3DSPR_IMMCONST);
assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64);
assert(vkd3d_write_mask_component_count(write_mask) == 1);
component_idx = vkd3d_write_mask_get_component_idx(write_mask);
@ -3301,6 +3328,8 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co
if (reg->type == VKD3DSPR_IMMCONST)
return vkd3d_dxbc_compiler_emit_load_constant(compiler, reg, swizzle, write_mask);
else if (reg->type == VKD3DSPR_IMMCONST64)
return vkd3d_dxbc_compiler_emit_load_constant64(compiler, reg, swizzle, write_mask);
component_count = vkd3d_write_mask_component_count(write_mask);
component_type = vkd3d_component_type_from_data_type(reg->data_type);
@ -3509,7 +3538,7 @@ static void vkd3d_dxbc_compiler_emit_store_reg(struct vkd3d_dxbc_compiler *compi
enum vkd3d_component_type component_type;
uint32_t type_id;
assert(reg->type != VKD3DSPR_IMMCONST);
assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64);
if (!vkd3d_dxbc_compiler_get_register_info(compiler, reg, &reg_info))
return;

View File

@ -667,6 +667,10 @@ static void shader_dump_register(struct vkd3d_string_buffer *buffer,
shader_addline(buffer, "l");
break;
case VKD3DSPR_IMMCONST64:
shader_addline(buffer, "d");
break;
case VKD3DSPR_CONSTBUFFER:
shader_addline(buffer, "cb");
break;
@ -833,6 +837,42 @@ static void shader_dump_register(struct vkd3d_string_buffer *buffer,
}
shader_addline(buffer, ")");
}
else if (reg->type == VKD3DSPR_IMMCONST64)
{
shader_addline(buffer, "(");
switch (reg->immconst_type)
{
case VKD3D_IMMCONST_SCALAR:
switch (reg->data_type)
{
case VKD3D_DATA_DOUBLE:
shader_addline(buffer, "%f", reg->immconst_double[0]);
break;
default:
shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
break;
}
break;
case VKD3D_IMMCONST_DVEC2:
switch (reg->data_type)
{
case VKD3D_DATA_DOUBLE:
shader_addline(buffer, "%f, %f",
reg->immconst_double[0], reg->immconst_double[1]);
break;
default:
shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
break;
}
break;
default:
shader_addline(buffer, "<unhandled immconst_type %#x>", reg->immconst_type);
break;
}
shader_addline(buffer, ")");
}
else if (reg->type != VKD3DSPR_NULL)
{
if (offset != ~0u)

View File

@ -58,6 +58,10 @@
#define VKD3D_VEC4_SIZE 4
#define VKD3D_DVEC2_SIZE 2
#define VKD3D_DOUBLE_DWORD_SIZE 2
#define VKD3D_DVEC2_DWORD_SIZE (VKD3D_DOUBLE_DWORD_SIZE * VKD3D_DVEC2_SIZE)
enum VKD3D_SHADER_INSTRUCTION_HANDLER
{
VKD3DSIH_ADD,
@ -308,6 +312,7 @@ enum vkd3d_shader_register_type
VKD3DSPR_DEPTHOUT,
VKD3DSPR_SAMPLER,
VKD3DSPR_IMMCONST,
VKD3DSPR_IMMCONST64,
VKD3DSPR_CONSTBUFFER,
VKD3DSPR_IMMCONSTBUFFER,
VKD3DSPR_PRIMID,
@ -374,6 +379,7 @@ enum vkd3d_immconst_type
{
VKD3D_IMMCONST_SCALAR,
VKD3D_IMMCONST_VEC4,
VKD3D_IMMCONST_DVEC2 = VKD3D_IMMCONST_VEC4,
};
enum vkd3d_shader_register_modifier
@ -535,6 +541,8 @@ struct vkd3d_shader_register
{
uint32_t immconst_uint[VKD3D_VEC4_SIZE];
float immconst_float[VKD3D_VEC4_SIZE];
double immconst_double[VKD3D_DVEC2_SIZE];
uint64_t immconst_uint64[VKD3D_DVEC2_SIZE];
unsigned fp_body_idx;
};
};