mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/hlsl: Move CTAB generation to hlsl_codegen.c.
This commit is contained in:
parent
c681673993
commit
e8cc288426
Notes:
Henri Verbeet
2024-12-17 16:53:24 +01:00
Approved-by: Francisco Casas (@fcasas) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1321
@ -25,7 +25,7 @@
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "hlsl.h"
|
||||
#include "vkd3d_shader_private.h"
|
||||
|
||||
#define VKD3D_SM1_VS 0xfffeu
|
||||
#define VKD3D_SM1_PS 0xffffu
|
||||
@ -1552,407 +1552,6 @@ static uint32_t sm1_version(enum vkd3d_shader_type type, unsigned int major, uns
|
||||
type == VKD3D_SHADER_TYPE_VERTEX ? VKD3D_SM1_VS : VKD3D_SM1_PS);
|
||||
}
|
||||
|
||||
D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type)
|
||||
{
|
||||
switch (type->class)
|
||||
{
|
||||
case HLSL_CLASS_ARRAY:
|
||||
return hlsl_sm1_class(type->e.array.type);
|
||||
case HLSL_CLASS_MATRIX:
|
||||
VKD3D_ASSERT(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
|
||||
if (type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR)
|
||||
return D3DXPC_MATRIX_COLUMNS;
|
||||
else
|
||||
return D3DXPC_MATRIX_ROWS;
|
||||
case HLSL_CLASS_SCALAR:
|
||||
return D3DXPC_SCALAR;
|
||||
case HLSL_CLASS_STRUCT:
|
||||
return D3DXPC_STRUCT;
|
||||
case HLSL_CLASS_VECTOR:
|
||||
return D3DXPC_VECTOR;
|
||||
case HLSL_CLASS_PIXEL_SHADER:
|
||||
case HLSL_CLASS_SAMPLER:
|
||||
case HLSL_CLASS_STRING:
|
||||
case HLSL_CLASS_TEXTURE:
|
||||
case HLSL_CLASS_VERTEX_SHADER:
|
||||
return D3DXPC_OBJECT;
|
||||
case HLSL_CLASS_DEPTH_STENCIL_STATE:
|
||||
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
|
||||
case HLSL_CLASS_EFFECT_GROUP:
|
||||
case HLSL_CLASS_ERROR:
|
||||
case HLSL_CLASS_PASS:
|
||||
case HLSL_CLASS_RASTERIZER_STATE:
|
||||
case HLSL_CLASS_RENDER_TARGET_VIEW:
|
||||
case HLSL_CLASS_TECHNIQUE:
|
||||
case HLSL_CLASS_UAV:
|
||||
case HLSL_CLASS_VOID:
|
||||
case HLSL_CLASS_CONSTANT_BUFFER:
|
||||
case HLSL_CLASS_COMPUTE_SHADER:
|
||||
case HLSL_CLASS_DOMAIN_SHADER:
|
||||
case HLSL_CLASS_HULL_SHADER:
|
||||
case HLSL_CLASS_GEOMETRY_SHADER:
|
||||
case HLSL_CLASS_BLEND_STATE:
|
||||
case HLSL_CLASS_STREAM_OUTPUT:
|
||||
case HLSL_CLASS_NULL:
|
||||
break;
|
||||
}
|
||||
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type, bool is_combined_sampler)
|
||||
{
|
||||
enum hlsl_type_class class = type->class;
|
||||
|
||||
if (is_combined_sampler)
|
||||
class = HLSL_CLASS_TEXTURE;
|
||||
|
||||
switch (class)
|
||||
{
|
||||
case HLSL_CLASS_SCALAR:
|
||||
case HLSL_CLASS_VECTOR:
|
||||
case HLSL_CLASS_MATRIX:
|
||||
switch (type->e.numeric.type)
|
||||
{
|
||||
case HLSL_TYPE_BOOL:
|
||||
return D3DXPT_BOOL;
|
||||
/* Actually double behaves differently depending on DLL version:
|
||||
* For <= 36, it maps to D3DXPT_FLOAT.
|
||||
* For 37-40, it maps to zero (D3DXPT_VOID).
|
||||
* For >= 41, it maps to 39, which is D3D_SVT_DOUBLE (note D3D_SVT_*
|
||||
* values are mostly compatible with D3DXPT_*).
|
||||
* However, the latter two cases look like bugs, and a reasonable
|
||||
* application certainly wouldn't know what to do with them.
|
||||
* For fx_2_0 it's always D3DXPT_FLOAT regardless of DLL version. */
|
||||
case HLSL_TYPE_DOUBLE:
|
||||
case HLSL_TYPE_FLOAT:
|
||||
case HLSL_TYPE_HALF:
|
||||
return D3DXPT_FLOAT;
|
||||
case HLSL_TYPE_INT:
|
||||
case HLSL_TYPE_UINT:
|
||||
return D3DXPT_INT;
|
||||
default:
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
case HLSL_CLASS_SAMPLER:
|
||||
switch (type->sampler_dim)
|
||||
{
|
||||
case HLSL_SAMPLER_DIM_1D:
|
||||
return D3DXPT_SAMPLER1D;
|
||||
case HLSL_SAMPLER_DIM_2D:
|
||||
return D3DXPT_SAMPLER2D;
|
||||
case HLSL_SAMPLER_DIM_3D:
|
||||
return D3DXPT_SAMPLER3D;
|
||||
case HLSL_SAMPLER_DIM_CUBE:
|
||||
return D3DXPT_SAMPLERCUBE;
|
||||
case HLSL_SAMPLER_DIM_GENERIC:
|
||||
return D3DXPT_SAMPLER;
|
||||
default:
|
||||
ERR("Invalid dimension %#x.\n", type->sampler_dim);
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
break;
|
||||
|
||||
case HLSL_CLASS_TEXTURE:
|
||||
switch (type->sampler_dim)
|
||||
{
|
||||
case HLSL_SAMPLER_DIM_1D:
|
||||
return D3DXPT_TEXTURE1D;
|
||||
case HLSL_SAMPLER_DIM_2D:
|
||||
return D3DXPT_TEXTURE2D;
|
||||
case HLSL_SAMPLER_DIM_3D:
|
||||
return D3DXPT_TEXTURE3D;
|
||||
case HLSL_SAMPLER_DIM_CUBE:
|
||||
return D3DXPT_TEXTURECUBE;
|
||||
case HLSL_SAMPLER_DIM_GENERIC:
|
||||
return D3DXPT_TEXTURE;
|
||||
default:
|
||||
ERR("Invalid dimension %#x.\n", type->sampler_dim);
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
break;
|
||||
|
||||
case HLSL_CLASS_ARRAY:
|
||||
return hlsl_sm1_base_type(type->e.array.type, is_combined_sampler);
|
||||
|
||||
case HLSL_CLASS_STRUCT:
|
||||
return D3DXPT_VOID;
|
||||
|
||||
case HLSL_CLASS_STRING:
|
||||
return D3DXPT_STRING;
|
||||
|
||||
case HLSL_CLASS_PIXEL_SHADER:
|
||||
return D3DXPT_PIXELSHADER;
|
||||
|
||||
case HLSL_CLASS_VERTEX_SHADER:
|
||||
return D3DXPT_VERTEXSHADER;
|
||||
|
||||
case HLSL_CLASS_DEPTH_STENCIL_STATE:
|
||||
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
|
||||
case HLSL_CLASS_EFFECT_GROUP:
|
||||
case HLSL_CLASS_ERROR:
|
||||
case HLSL_CLASS_PASS:
|
||||
case HLSL_CLASS_RASTERIZER_STATE:
|
||||
case HLSL_CLASS_RENDER_TARGET_VIEW:
|
||||
case HLSL_CLASS_TECHNIQUE:
|
||||
case HLSL_CLASS_UAV:
|
||||
case HLSL_CLASS_VOID:
|
||||
case HLSL_CLASS_CONSTANT_BUFFER:
|
||||
case HLSL_CLASS_COMPUTE_SHADER:
|
||||
case HLSL_CLASS_DOMAIN_SHADER:
|
||||
case HLSL_CLASS_HULL_SHADER:
|
||||
case HLSL_CLASS_GEOMETRY_SHADER:
|
||||
case HLSL_CLASS_BLEND_STATE:
|
||||
case HLSL_CLASS_STREAM_OUTPUT:
|
||||
case HLSL_CLASS_NULL:
|
||||
break;
|
||||
}
|
||||
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer,
|
||||
struct hlsl_type *type, bool is_combined_sampler, unsigned int ctab_start)
|
||||
{
|
||||
const struct hlsl_type *array_type = hlsl_get_multiarray_element_type(type);
|
||||
unsigned int array_size = hlsl_get_multiarray_size(type);
|
||||
unsigned int field_count = 0;
|
||||
size_t fields_offset = 0;
|
||||
size_t i;
|
||||
|
||||
if (type->bytecode_offset)
|
||||
return;
|
||||
|
||||
if (array_type->class == HLSL_CLASS_STRUCT)
|
||||
{
|
||||
field_count = array_type->e.record.field_count;
|
||||
|
||||
for (i = 0; i < field_count; ++i)
|
||||
{
|
||||
struct hlsl_struct_field *field = &array_type->e.record.fields[i];
|
||||
|
||||
field->name_bytecode_offset = put_string(buffer, field->name);
|
||||
write_sm1_type(buffer, field->type, false, ctab_start);
|
||||
}
|
||||
|
||||
fields_offset = bytecode_align(buffer) - ctab_start;
|
||||
|
||||
for (i = 0; i < field_count; ++i)
|
||||
{
|
||||
struct hlsl_struct_field *field = &array_type->e.record.fields[i];
|
||||
|
||||
put_u32(buffer, field->name_bytecode_offset - ctab_start);
|
||||
put_u32(buffer, field->type->bytecode_offset - ctab_start);
|
||||
}
|
||||
}
|
||||
|
||||
type->bytecode_offset = put_u32(buffer,
|
||||
vkd3d_make_u32(hlsl_sm1_class(type), hlsl_sm1_base_type(array_type, is_combined_sampler)));
|
||||
put_u32(buffer, vkd3d_make_u32(type->dimy, type->dimx));
|
||||
put_u32(buffer, vkd3d_make_u32(array_size, field_count));
|
||||
put_u32(buffer, fields_offset);
|
||||
}
|
||||
|
||||
static void sm1_sort_extern(struct list *sorted, struct hlsl_ir_var *to_sort)
|
||||
{
|
||||
struct hlsl_ir_var *var;
|
||||
|
||||
list_remove(&to_sort->extern_entry);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, sorted, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if (strcmp(to_sort->name, var->name) < 0)
|
||||
{
|
||||
list_add_before(&var->extern_entry, &to_sort->extern_entry);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
list_add_tail(sorted, &to_sort->extern_entry);
|
||||
}
|
||||
|
||||
static void sm1_sort_externs(struct hlsl_ctx *ctx)
|
||||
{
|
||||
struct list sorted = LIST_INIT(sorted);
|
||||
struct hlsl_ir_var *var, *next;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(var, next, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if (var->is_uniform)
|
||||
sm1_sort_extern(&sorted, var);
|
||||
}
|
||||
list_move_tail(&ctx->extern_vars, &sorted);
|
||||
}
|
||||
|
||||
static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer)
|
||||
{
|
||||
size_t ctab_start, vars_offset, vars_start, creator_offset, offset;
|
||||
unsigned int uniform_count = 0;
|
||||
struct hlsl_ir_var *var;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
unsigned int r;
|
||||
|
||||
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
|
||||
{
|
||||
if (var->semantic.name || !var->regs[r].allocated || !var->last_read)
|
||||
continue;
|
||||
|
||||
++uniform_count;
|
||||
|
||||
if (var->is_param && var->is_uniform)
|
||||
{
|
||||
char *new_name;
|
||||
|
||||
if (!(new_name = hlsl_sprintf_alloc(ctx, "$%s", var->name)))
|
||||
return;
|
||||
vkd3d_free((char *)var->name);
|
||||
var->name = new_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sm1_sort_externs(ctx);
|
||||
|
||||
ctab_start = put_u32(buffer, 7 * sizeof(uint32_t)); /* CTAB header size. */
|
||||
creator_offset = put_u32(buffer, 0);
|
||||
put_u32(buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version));
|
||||
put_u32(buffer, uniform_count);
|
||||
vars_offset = put_u32(buffer, 0);
|
||||
put_u32(buffer, 0); /* FIXME: flags */
|
||||
put_u32(buffer, 0); /* FIXME: target string */
|
||||
|
||||
vars_start = bytecode_align(buffer);
|
||||
set_u32(buffer, vars_offset, vars_start - ctab_start);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
unsigned int r;
|
||||
|
||||
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
|
||||
{
|
||||
if (var->semantic.name || !var->regs[r].allocated || !var->last_read)
|
||||
continue;
|
||||
|
||||
put_u32(buffer, 0); /* name */
|
||||
if (r == HLSL_REGSET_NUMERIC)
|
||||
{
|
||||
put_u32(buffer, vkd3d_make_u32(D3DXRS_FLOAT4, var->regs[r].id));
|
||||
put_u32(buffer, var->bind_count[r]);
|
||||
}
|
||||
else
|
||||
{
|
||||
put_u32(buffer, vkd3d_make_u32(D3DXRS_SAMPLER, var->regs[r].index));
|
||||
put_u32(buffer, var->bind_count[r]);
|
||||
}
|
||||
put_u32(buffer, 0); /* type */
|
||||
put_u32(buffer, 0); /* default value */
|
||||
}
|
||||
}
|
||||
|
||||
uniform_count = 0;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
unsigned int r;
|
||||
|
||||
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
|
||||
{
|
||||
size_t var_offset, name_offset;
|
||||
|
||||
if (var->semantic.name || !var->regs[r].allocated || !var->last_read)
|
||||
continue;
|
||||
|
||||
var_offset = vars_start + (uniform_count * 5 * sizeof(uint32_t));
|
||||
|
||||
name_offset = put_string(buffer, var->name);
|
||||
set_u32(buffer, var_offset, name_offset - ctab_start);
|
||||
|
||||
write_sm1_type(buffer, var->data_type, var->is_combined_sampler, ctab_start);
|
||||
set_u32(buffer, var_offset + 3 * sizeof(uint32_t), var->data_type->bytecode_offset - ctab_start);
|
||||
|
||||
if (var->default_values)
|
||||
{
|
||||
unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC];
|
||||
unsigned int comp_count = hlsl_type_component_count(var->data_type);
|
||||
unsigned int default_value_offset;
|
||||
unsigned int k;
|
||||
|
||||
default_value_offset = bytecode_reserve_bytes(buffer, reg_size * sizeof(uint32_t));
|
||||
set_u32(buffer, var_offset + 4 * sizeof(uint32_t), default_value_offset - ctab_start);
|
||||
|
||||
for (k = 0; k < comp_count; ++k)
|
||||
{
|
||||
struct hlsl_type *comp_type = hlsl_type_get_component_type(ctx, var->data_type, k);
|
||||
unsigned int comp_offset;
|
||||
enum hlsl_regset regset;
|
||||
|
||||
comp_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, ®set);
|
||||
if (regset == HLSL_REGSET_NUMERIC)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t u;
|
||||
float f;
|
||||
} uni;
|
||||
|
||||
switch (comp_type->e.numeric.type)
|
||||
{
|
||||
case HLSL_TYPE_DOUBLE:
|
||||
if (ctx->double_as_float_alias)
|
||||
uni.u = var->default_values[k].number.u;
|
||||
else
|
||||
uni.u = 0;
|
||||
break;
|
||||
|
||||
case HLSL_TYPE_INT:
|
||||
uni.f = var->default_values[k].number.i;
|
||||
break;
|
||||
|
||||
case HLSL_TYPE_UINT:
|
||||
case HLSL_TYPE_BOOL:
|
||||
uni.f = var->default_values[k].number.u;
|
||||
break;
|
||||
|
||||
case HLSL_TYPE_HALF:
|
||||
case HLSL_TYPE_FLOAT:
|
||||
uni.u = var->default_values[k].number.u;
|
||||
break;
|
||||
|
||||
default:
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
set_u32(buffer, default_value_offset + comp_offset * sizeof(uint32_t), uni.u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++uniform_count;
|
||||
}
|
||||
}
|
||||
|
||||
offset = put_string(buffer, vkd3d_shader_get_version(NULL, NULL));
|
||||
set_u32(buffer, creator_offset, offset - ctab_start);
|
||||
}
|
||||
|
||||
void sm1_generate_ctab(struct hlsl_ctx *ctx, struct vkd3d_shader_code *ctab)
|
||||
{
|
||||
struct vkd3d_bytecode_buffer buffer = {0};
|
||||
|
||||
write_sm1_uniforms(ctx, &buffer);
|
||||
if (buffer.status)
|
||||
{
|
||||
vkd3d_free(buffer.data);
|
||||
ctx->result = buffer.status;
|
||||
return;
|
||||
}
|
||||
ctab->code = buffer.data;
|
||||
ctab->size = buffer.size;
|
||||
}
|
||||
|
||||
static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir(
|
||||
struct d3dbc_compiler *d3dbc, enum vkd3d_shader_opcode vkd3d_opcode)
|
||||
{
|
||||
|
@ -1658,8 +1658,6 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx,
|
||||
D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type);
|
||||
D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type, bool is_combined_sampler);
|
||||
|
||||
void sm1_generate_ctab(struct hlsl_ctx *ctx, struct vkd3d_shader_code *ctab);
|
||||
|
||||
struct extern_resource
|
||||
{
|
||||
/* "var" is only not NULL if this resource is a whole variable, so it may
|
||||
|
@ -8067,6 +8067,403 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
|
||||
sm1_generate_vsir_block(ctx, &entry_func->body, program);
|
||||
}
|
||||
|
||||
D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type)
|
||||
{
|
||||
switch (type->class)
|
||||
{
|
||||
case HLSL_CLASS_ARRAY:
|
||||
return hlsl_sm1_class(type->e.array.type);
|
||||
case HLSL_CLASS_MATRIX:
|
||||
VKD3D_ASSERT(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
|
||||
if (type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR)
|
||||
return D3DXPC_MATRIX_COLUMNS;
|
||||
else
|
||||
return D3DXPC_MATRIX_ROWS;
|
||||
case HLSL_CLASS_SCALAR:
|
||||
return D3DXPC_SCALAR;
|
||||
case HLSL_CLASS_STRUCT:
|
||||
return D3DXPC_STRUCT;
|
||||
case HLSL_CLASS_VECTOR:
|
||||
return D3DXPC_VECTOR;
|
||||
case HLSL_CLASS_PIXEL_SHADER:
|
||||
case HLSL_CLASS_SAMPLER:
|
||||
case HLSL_CLASS_STRING:
|
||||
case HLSL_CLASS_TEXTURE:
|
||||
case HLSL_CLASS_VERTEX_SHADER:
|
||||
return D3DXPC_OBJECT;
|
||||
case HLSL_CLASS_DEPTH_STENCIL_STATE:
|
||||
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
|
||||
case HLSL_CLASS_EFFECT_GROUP:
|
||||
case HLSL_CLASS_ERROR:
|
||||
case HLSL_CLASS_PASS:
|
||||
case HLSL_CLASS_RASTERIZER_STATE:
|
||||
case HLSL_CLASS_RENDER_TARGET_VIEW:
|
||||
case HLSL_CLASS_TECHNIQUE:
|
||||
case HLSL_CLASS_UAV:
|
||||
case HLSL_CLASS_VOID:
|
||||
case HLSL_CLASS_CONSTANT_BUFFER:
|
||||
case HLSL_CLASS_COMPUTE_SHADER:
|
||||
case HLSL_CLASS_DOMAIN_SHADER:
|
||||
case HLSL_CLASS_HULL_SHADER:
|
||||
case HLSL_CLASS_GEOMETRY_SHADER:
|
||||
case HLSL_CLASS_BLEND_STATE:
|
||||
case HLSL_CLASS_STREAM_OUTPUT:
|
||||
case HLSL_CLASS_NULL:
|
||||
break;
|
||||
}
|
||||
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type, bool is_combined_sampler)
|
||||
{
|
||||
enum hlsl_type_class class = type->class;
|
||||
|
||||
if (is_combined_sampler)
|
||||
class = HLSL_CLASS_TEXTURE;
|
||||
|
||||
switch (class)
|
||||
{
|
||||
case HLSL_CLASS_SCALAR:
|
||||
case HLSL_CLASS_VECTOR:
|
||||
case HLSL_CLASS_MATRIX:
|
||||
switch (type->e.numeric.type)
|
||||
{
|
||||
case HLSL_TYPE_BOOL:
|
||||
return D3DXPT_BOOL;
|
||||
/* Actually double behaves differently depending on DLL version:
|
||||
* For <= 36, it maps to D3DXPT_FLOAT.
|
||||
* For 37-40, it maps to zero (D3DXPT_VOID).
|
||||
* For >= 41, it maps to 39, which is D3D_SVT_DOUBLE (note D3D_SVT_*
|
||||
* values are mostly compatible with D3DXPT_*).
|
||||
* However, the latter two cases look like bugs, and a reasonable
|
||||
* application certainly wouldn't know what to do with them.
|
||||
* For fx_2_0 it's always D3DXPT_FLOAT regardless of DLL version. */
|
||||
case HLSL_TYPE_DOUBLE:
|
||||
case HLSL_TYPE_FLOAT:
|
||||
case HLSL_TYPE_HALF:
|
||||
return D3DXPT_FLOAT;
|
||||
case HLSL_TYPE_INT:
|
||||
case HLSL_TYPE_UINT:
|
||||
return D3DXPT_INT;
|
||||
default:
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
case HLSL_CLASS_SAMPLER:
|
||||
switch (type->sampler_dim)
|
||||
{
|
||||
case HLSL_SAMPLER_DIM_1D:
|
||||
return D3DXPT_SAMPLER1D;
|
||||
case HLSL_SAMPLER_DIM_2D:
|
||||
return D3DXPT_SAMPLER2D;
|
||||
case HLSL_SAMPLER_DIM_3D:
|
||||
return D3DXPT_SAMPLER3D;
|
||||
case HLSL_SAMPLER_DIM_CUBE:
|
||||
return D3DXPT_SAMPLERCUBE;
|
||||
case HLSL_SAMPLER_DIM_GENERIC:
|
||||
return D3DXPT_SAMPLER;
|
||||
default:
|
||||
ERR("Invalid dimension %#x.\n", type->sampler_dim);
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
break;
|
||||
|
||||
case HLSL_CLASS_TEXTURE:
|
||||
switch (type->sampler_dim)
|
||||
{
|
||||
case HLSL_SAMPLER_DIM_1D:
|
||||
return D3DXPT_TEXTURE1D;
|
||||
case HLSL_SAMPLER_DIM_2D:
|
||||
return D3DXPT_TEXTURE2D;
|
||||
case HLSL_SAMPLER_DIM_3D:
|
||||
return D3DXPT_TEXTURE3D;
|
||||
case HLSL_SAMPLER_DIM_CUBE:
|
||||
return D3DXPT_TEXTURECUBE;
|
||||
case HLSL_SAMPLER_DIM_GENERIC:
|
||||
return D3DXPT_TEXTURE;
|
||||
default:
|
||||
ERR("Invalid dimension %#x.\n", type->sampler_dim);
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
break;
|
||||
|
||||
case HLSL_CLASS_ARRAY:
|
||||
return hlsl_sm1_base_type(type->e.array.type, is_combined_sampler);
|
||||
|
||||
case HLSL_CLASS_STRUCT:
|
||||
return D3DXPT_VOID;
|
||||
|
||||
case HLSL_CLASS_STRING:
|
||||
return D3DXPT_STRING;
|
||||
|
||||
case HLSL_CLASS_PIXEL_SHADER:
|
||||
return D3DXPT_PIXELSHADER;
|
||||
|
||||
case HLSL_CLASS_VERTEX_SHADER:
|
||||
return D3DXPT_VERTEXSHADER;
|
||||
|
||||
case HLSL_CLASS_DEPTH_STENCIL_STATE:
|
||||
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
|
||||
case HLSL_CLASS_EFFECT_GROUP:
|
||||
case HLSL_CLASS_ERROR:
|
||||
case HLSL_CLASS_PASS:
|
||||
case HLSL_CLASS_RASTERIZER_STATE:
|
||||
case HLSL_CLASS_RENDER_TARGET_VIEW:
|
||||
case HLSL_CLASS_TECHNIQUE:
|
||||
case HLSL_CLASS_UAV:
|
||||
case HLSL_CLASS_VOID:
|
||||
case HLSL_CLASS_CONSTANT_BUFFER:
|
||||
case HLSL_CLASS_COMPUTE_SHADER:
|
||||
case HLSL_CLASS_DOMAIN_SHADER:
|
||||
case HLSL_CLASS_HULL_SHADER:
|
||||
case HLSL_CLASS_GEOMETRY_SHADER:
|
||||
case HLSL_CLASS_BLEND_STATE:
|
||||
case HLSL_CLASS_STREAM_OUTPUT:
|
||||
case HLSL_CLASS_NULL:
|
||||
break;
|
||||
}
|
||||
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer,
|
||||
struct hlsl_type *type, bool is_combined_sampler, unsigned int ctab_start)
|
||||
{
|
||||
const struct hlsl_type *array_type = hlsl_get_multiarray_element_type(type);
|
||||
unsigned int array_size = hlsl_get_multiarray_size(type);
|
||||
struct hlsl_struct_field *field;
|
||||
unsigned int field_count = 0;
|
||||
size_t fields_offset = 0;
|
||||
size_t i;
|
||||
|
||||
if (type->bytecode_offset)
|
||||
return;
|
||||
|
||||
if (array_type->class == HLSL_CLASS_STRUCT)
|
||||
{
|
||||
field_count = array_type->e.record.field_count;
|
||||
|
||||
for (i = 0; i < field_count; ++i)
|
||||
{
|
||||
field = &array_type->e.record.fields[i];
|
||||
field->name_bytecode_offset = put_string(buffer, field->name);
|
||||
write_sm1_type(buffer, field->type, false, ctab_start);
|
||||
}
|
||||
|
||||
fields_offset = bytecode_align(buffer) - ctab_start;
|
||||
|
||||
for (i = 0; i < field_count; ++i)
|
||||
{
|
||||
field = &array_type->e.record.fields[i];
|
||||
put_u32(buffer, field->name_bytecode_offset - ctab_start);
|
||||
put_u32(buffer, field->type->bytecode_offset - ctab_start);
|
||||
}
|
||||
}
|
||||
|
||||
type->bytecode_offset = put_u32(buffer,
|
||||
vkd3d_make_u32(hlsl_sm1_class(type), hlsl_sm1_base_type(array_type, is_combined_sampler)));
|
||||
put_u32(buffer, vkd3d_make_u32(type->dimy, type->dimx));
|
||||
put_u32(buffer, vkd3d_make_u32(array_size, field_count));
|
||||
put_u32(buffer, fields_offset);
|
||||
}
|
||||
|
||||
static void sm1_sort_extern(struct list *sorted, struct hlsl_ir_var *to_sort)
|
||||
{
|
||||
struct hlsl_ir_var *var;
|
||||
|
||||
list_remove(&to_sort->extern_entry);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, sorted, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if (strcmp(to_sort->name, var->name) < 0)
|
||||
{
|
||||
list_add_before(&var->extern_entry, &to_sort->extern_entry);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
list_add_tail(sorted, &to_sort->extern_entry);
|
||||
}
|
||||
|
||||
static void sm1_sort_externs(struct hlsl_ctx *ctx)
|
||||
{
|
||||
struct list sorted = LIST_INIT(sorted);
|
||||
struct hlsl_ir_var *var, *next;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(var, next, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if (var->is_uniform)
|
||||
sm1_sort_extern(&sorted, var);
|
||||
}
|
||||
list_move_tail(&ctx->extern_vars, &sorted);
|
||||
}
|
||||
|
||||
static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer)
|
||||
{
|
||||
size_t ctab_start, vars_offset, vars_start, creator_offset, offset;
|
||||
unsigned int uniform_count = 0, r;
|
||||
struct hlsl_ir_var *var;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
|
||||
{
|
||||
if (var->semantic.name || !var->regs[r].allocated || !var->last_read)
|
||||
continue;
|
||||
|
||||
++uniform_count;
|
||||
|
||||
if (var->is_param && var->is_uniform)
|
||||
{
|
||||
char *new_name;
|
||||
|
||||
if (!(new_name = hlsl_sprintf_alloc(ctx, "$%s", var->name)))
|
||||
return;
|
||||
vkd3d_free((char *)var->name);
|
||||
var->name = new_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sm1_sort_externs(ctx);
|
||||
|
||||
ctab_start = put_u32(buffer, 7 * sizeof(uint32_t)); /* CTAB header size. */
|
||||
creator_offset = put_u32(buffer, 0);
|
||||
if (ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX)
|
||||
put_u32(buffer, D3DVS_VERSION(ctx->profile->major_version, ctx->profile->minor_version));
|
||||
else
|
||||
put_u32(buffer, D3DPS_VERSION(ctx->profile->major_version, ctx->profile->minor_version));
|
||||
put_u32(buffer, uniform_count);
|
||||
vars_offset = put_u32(buffer, 0);
|
||||
put_u32(buffer, 0); /* FIXME: flags */
|
||||
put_u32(buffer, 0); /* FIXME: target string */
|
||||
|
||||
vars_start = bytecode_align(buffer);
|
||||
set_u32(buffer, vars_offset, vars_start - ctab_start);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
|
||||
{
|
||||
if (var->semantic.name || !var->regs[r].allocated || !var->last_read)
|
||||
continue;
|
||||
|
||||
put_u32(buffer, 0); /* name */
|
||||
if (r == HLSL_REGSET_NUMERIC)
|
||||
{
|
||||
put_u32(buffer, vkd3d_make_u32(D3DXRS_FLOAT4, var->regs[r].id));
|
||||
put_u32(buffer, var->bind_count[r]);
|
||||
}
|
||||
else
|
||||
{
|
||||
put_u32(buffer, vkd3d_make_u32(D3DXRS_SAMPLER, var->regs[r].index));
|
||||
put_u32(buffer, var->bind_count[r]);
|
||||
}
|
||||
put_u32(buffer, 0); /* type */
|
||||
put_u32(buffer, 0); /* default value */
|
||||
}
|
||||
}
|
||||
|
||||
uniform_count = 0;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
|
||||
{
|
||||
size_t var_offset, name_offset;
|
||||
|
||||
if (var->semantic.name || !var->regs[r].allocated || !var->last_read)
|
||||
continue;
|
||||
|
||||
var_offset = vars_start + (uniform_count * 5 * sizeof(uint32_t));
|
||||
|
||||
name_offset = put_string(buffer, var->name);
|
||||
set_u32(buffer, var_offset, name_offset - ctab_start);
|
||||
|
||||
write_sm1_type(buffer, var->data_type, var->is_combined_sampler, ctab_start);
|
||||
set_u32(buffer, var_offset + 3 * sizeof(uint32_t), var->data_type->bytecode_offset - ctab_start);
|
||||
|
||||
if (var->default_values)
|
||||
{
|
||||
unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC];
|
||||
unsigned int comp_count = hlsl_type_component_count(var->data_type);
|
||||
unsigned int default_value_offset;
|
||||
unsigned int k;
|
||||
|
||||
default_value_offset = bytecode_reserve_bytes(buffer, reg_size * sizeof(uint32_t));
|
||||
set_u32(buffer, var_offset + 4 * sizeof(uint32_t), default_value_offset - ctab_start);
|
||||
|
||||
for (k = 0; k < comp_count; ++k)
|
||||
{
|
||||
struct hlsl_type *comp_type = hlsl_type_get_component_type(ctx, var->data_type, k);
|
||||
unsigned int comp_offset;
|
||||
enum hlsl_regset regset;
|
||||
|
||||
comp_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, ®set);
|
||||
if (regset == HLSL_REGSET_NUMERIC)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t u;
|
||||
float f;
|
||||
} uni;
|
||||
|
||||
switch (comp_type->e.numeric.type)
|
||||
{
|
||||
case HLSL_TYPE_DOUBLE:
|
||||
if (ctx->double_as_float_alias)
|
||||
uni.u = var->default_values[k].number.u;
|
||||
else
|
||||
uni.u = 0;
|
||||
break;
|
||||
|
||||
case HLSL_TYPE_INT:
|
||||
uni.f = var->default_values[k].number.i;
|
||||
break;
|
||||
|
||||
case HLSL_TYPE_UINT:
|
||||
case HLSL_TYPE_BOOL:
|
||||
uni.f = var->default_values[k].number.u;
|
||||
break;
|
||||
|
||||
case HLSL_TYPE_HALF:
|
||||
case HLSL_TYPE_FLOAT:
|
||||
uni.u = var->default_values[k].number.u;
|
||||
break;
|
||||
|
||||
default:
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
set_u32(buffer, default_value_offset + comp_offset * sizeof(uint32_t), uni.u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++uniform_count;
|
||||
}
|
||||
}
|
||||
|
||||
offset = put_string(buffer, vkd3d_shader_get_version(NULL, NULL));
|
||||
set_u32(buffer, creator_offset, offset - ctab_start);
|
||||
}
|
||||
|
||||
static void sm1_generate_ctab(struct hlsl_ctx *ctx, struct vkd3d_shader_code *ctab)
|
||||
{
|
||||
struct vkd3d_bytecode_buffer buffer = {0};
|
||||
|
||||
write_sm1_uniforms(ctx, &buffer);
|
||||
if (buffer.status)
|
||||
{
|
||||
vkd3d_free(buffer.data);
|
||||
ctx->result = buffer.status;
|
||||
return;
|
||||
}
|
||||
ctab->code = buffer.data;
|
||||
ctab->size = buffer.size;
|
||||
}
|
||||
|
||||
static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vsir_program *program,
|
||||
const struct hlsl_ir_var *var, bool is_patch_constant_func, struct hlsl_block *block,
|
||||
const struct vkd3d_shader_location *loc)
|
||||
|
Loading…
x
Reference in New Issue
Block a user