mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/hlsl: Move RDEF generation to hlsl_codegen.c.
This commit is contained in:
parent
9b3b47b1b8
commit
4227858cfe
Notes:
Henri Verbeet
2025-01-10 20:15:36 +01:00
Approved-by: Elizabeth Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1334
@ -1678,10 +1678,6 @@ struct extern_resource
|
||||
struct vkd3d_shader_location loc;
|
||||
};
|
||||
|
||||
struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count);
|
||||
void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count);
|
||||
void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rdef);
|
||||
|
||||
struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ctx, const char *name, const char *hlsl);
|
||||
|
||||
int hlsl_lexer_compile(struct hlsl_ctx *ctx, const struct vkd3d_shader_code *hlsl);
|
||||
|
@ -20,9 +20,13 @@
|
||||
|
||||
#include "hlsl.h"
|
||||
#include "vkd3d_shader_private.h"
|
||||
#include "vkd3d_d3dcommon.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
/* The shift that corresponds to the D3D_SIF_TEXTURE_COMPONENTS mask. */
|
||||
#define VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT 2
|
||||
|
||||
/* TODO: remove when no longer needed, only used for new_offset_instr_from_deref() */
|
||||
static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
||||
struct hlsl_type *type, struct hlsl_ir_node *base_offset, struct hlsl_ir_node *idx,
|
||||
@ -10106,7 +10110,7 @@ static const char *string_skip_tag(const char *string)
|
||||
return string;
|
||||
}
|
||||
|
||||
void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count)
|
||||
static void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@ -10117,7 +10121,7 @@ void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigne
|
||||
vkd3d_free(extern_resources);
|
||||
}
|
||||
|
||||
struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count)
|
||||
static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count)
|
||||
{
|
||||
bool separate_components = ctx->profile->major_version == 5 && ctx->profile->minor_version == 0;
|
||||
struct extern_resource *extern_resources = NULL;
|
||||
@ -10650,6 +10654,510 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
|
||||
generate_vsir_scan_global_flags(ctx, program, func);
|
||||
}
|
||||
|
||||
/* For some reason, for matrices, values from default value initializers end
|
||||
* up in different components than from regular initializers. Default value
|
||||
* initializers fill the matrix in vertical reading order
|
||||
* (left-to-right top-to-bottom) instead of regular reading order
|
||||
* (top-to-bottom left-to-right), so they have to be adjusted. An exception is
|
||||
* that the order of matrix initializers for function parameters are row-major
|
||||
* (top-to-bottom left-to-right). */
|
||||
static unsigned int get_component_index_from_default_initializer_index(struct hlsl_type *type, unsigned int index)
|
||||
{
|
||||
unsigned int element_comp_count, element, x, y, i;
|
||||
unsigned int base = 0;
|
||||
|
||||
switch (type->class)
|
||||
{
|
||||
case HLSL_CLASS_MATRIX:
|
||||
x = index / type->e.numeric.dimy;
|
||||
y = index % type->e.numeric.dimy;
|
||||
return y * type->e.numeric.dimx + x;
|
||||
|
||||
case HLSL_CLASS_ARRAY:
|
||||
element_comp_count = hlsl_type_component_count(type->e.array.type);
|
||||
element = index / element_comp_count;
|
||||
base = element * element_comp_count;
|
||||
return base + get_component_index_from_default_initializer_index(type->e.array.type, index - base);
|
||||
|
||||
case HLSL_CLASS_STRUCT:
|
||||
for (i = 0; i < type->e.record.field_count; ++i)
|
||||
{
|
||||
struct hlsl_type *field_type = type->e.record.fields[i].type;
|
||||
|
||||
element_comp_count = hlsl_type_component_count(field_type);
|
||||
if (index - base < element_comp_count)
|
||||
return base + get_component_index_from_default_initializer_index(field_type, index - base);
|
||||
base += element_comp_count;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return index;
|
||||
}
|
||||
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *type)
|
||||
{
|
||||
switch (type->sampler_dim)
|
||||
{
|
||||
case HLSL_SAMPLER_DIM_1D:
|
||||
return D3D_SRV_DIMENSION_TEXTURE1D;
|
||||
case HLSL_SAMPLER_DIM_2D:
|
||||
return D3D_SRV_DIMENSION_TEXTURE2D;
|
||||
case HLSL_SAMPLER_DIM_3D:
|
||||
return D3D_SRV_DIMENSION_TEXTURE3D;
|
||||
case HLSL_SAMPLER_DIM_CUBE:
|
||||
return D3D_SRV_DIMENSION_TEXTURECUBE;
|
||||
case HLSL_SAMPLER_DIM_1DARRAY:
|
||||
return D3D_SRV_DIMENSION_TEXTURE1DARRAY;
|
||||
case HLSL_SAMPLER_DIM_2DARRAY:
|
||||
return D3D_SRV_DIMENSION_TEXTURE2DARRAY;
|
||||
case HLSL_SAMPLER_DIM_2DMS:
|
||||
return D3D_SRV_DIMENSION_TEXTURE2DMS;
|
||||
case HLSL_SAMPLER_DIM_2DMSARRAY:
|
||||
return D3D_SRV_DIMENSION_TEXTURE2DMSARRAY;
|
||||
case HLSL_SAMPLER_DIM_CUBEARRAY:
|
||||
return D3D_SRV_DIMENSION_TEXTURECUBEARRAY;
|
||||
case HLSL_SAMPLER_DIM_BUFFER:
|
||||
case HLSL_SAMPLER_DIM_RAW_BUFFER:
|
||||
case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
|
||||
return D3D_SRV_DIMENSION_BUFFER;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type)
|
||||
{
|
||||
const struct hlsl_type *format = type->e.resource.format;
|
||||
|
||||
switch (format->e.numeric.type)
|
||||
{
|
||||
case HLSL_TYPE_DOUBLE:
|
||||
return D3D_RETURN_TYPE_DOUBLE;
|
||||
|
||||
case HLSL_TYPE_FLOAT:
|
||||
case HLSL_TYPE_HALF:
|
||||
if (format->modifiers & HLSL_MODIFIER_UNORM)
|
||||
return D3D_RETURN_TYPE_UNORM;
|
||||
if (format->modifiers & HLSL_MODIFIER_SNORM)
|
||||
return D3D_RETURN_TYPE_SNORM;
|
||||
return D3D_RETURN_TYPE_FLOAT;
|
||||
|
||||
case HLSL_TYPE_INT:
|
||||
return D3D_RETURN_TYPE_SINT;
|
||||
break;
|
||||
|
||||
case HLSL_TYPE_BOOL:
|
||||
case HLSL_TYPE_UINT:
|
||||
return D3D_RETURN_TYPE_UINT;
|
||||
}
|
||||
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type)
|
||||
{
|
||||
switch (type->class)
|
||||
{
|
||||
case HLSL_CLASS_SAMPLER:
|
||||
return D3D_SIT_SAMPLER;
|
||||
case HLSL_CLASS_TEXTURE:
|
||||
return D3D_SIT_TEXTURE;
|
||||
case HLSL_CLASS_UAV:
|
||||
return D3D_SIT_UAV_RWTYPED;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type)
|
||||
{
|
||||
switch (type->class)
|
||||
{
|
||||
case HLSL_CLASS_MATRIX:
|
||||
VKD3D_ASSERT(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
|
||||
if (type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR)
|
||||
return D3D_SVC_MATRIX_COLUMNS;
|
||||
else
|
||||
return D3D_SVC_MATRIX_ROWS;
|
||||
case HLSL_CLASS_SCALAR:
|
||||
return D3D_SVC_SCALAR;
|
||||
case HLSL_CLASS_VECTOR:
|
||||
return D3D_SVC_VECTOR;
|
||||
|
||||
case HLSL_CLASS_ARRAY:
|
||||
case HLSL_CLASS_DEPTH_STENCIL_STATE:
|
||||
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
|
||||
case HLSL_CLASS_EFFECT_GROUP:
|
||||
case HLSL_CLASS_ERROR:
|
||||
case HLSL_CLASS_STRUCT:
|
||||
case HLSL_CLASS_PASS:
|
||||
case HLSL_CLASS_PIXEL_SHADER:
|
||||
case HLSL_CLASS_RASTERIZER_STATE:
|
||||
case HLSL_CLASS_RENDER_TARGET_VIEW:
|
||||
case HLSL_CLASS_SAMPLER:
|
||||
case HLSL_CLASS_STRING:
|
||||
case HLSL_CLASS_TECHNIQUE:
|
||||
case HLSL_CLASS_TEXTURE:
|
||||
case HLSL_CLASS_UAV:
|
||||
case HLSL_CLASS_VERTEX_SHADER:
|
||||
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 D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type)
|
||||
{
|
||||
switch (type->e.numeric.type)
|
||||
{
|
||||
case HLSL_TYPE_BOOL:
|
||||
return D3D_SVT_BOOL;
|
||||
case HLSL_TYPE_DOUBLE:
|
||||
return D3D_SVT_DOUBLE;
|
||||
case HLSL_TYPE_FLOAT:
|
||||
case HLSL_TYPE_HALF:
|
||||
return D3D_SVT_FLOAT;
|
||||
case HLSL_TYPE_INT:
|
||||
return D3D_SVT_INT;
|
||||
case HLSL_TYPE_UINT:
|
||||
return D3D_SVT_UINT;
|
||||
}
|
||||
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, struct hlsl_type *type)
|
||||
{
|
||||
const struct hlsl_type *array_type = hlsl_get_multiarray_element_type(type);
|
||||
const char *name = array_type->name ? array_type->name : "<unnamed>";
|
||||
const struct hlsl_profile_info *profile = ctx->profile;
|
||||
unsigned int array_size = 0;
|
||||
size_t name_offset = 0;
|
||||
size_t i;
|
||||
|
||||
if (type->bytecode_offset)
|
||||
return;
|
||||
|
||||
if (profile->major_version >= 5)
|
||||
name_offset = put_string(buffer, name);
|
||||
|
||||
if (type->class == HLSL_CLASS_ARRAY)
|
||||
array_size = hlsl_get_multiarray_size(type);
|
||||
|
||||
if (array_type->class == HLSL_CLASS_STRUCT)
|
||||
{
|
||||
unsigned int field_count = 0;
|
||||
size_t fields_offset = 0;
|
||||
|
||||
for (i = 0; i < array_type->e.record.field_count; ++i)
|
||||
{
|
||||
struct hlsl_struct_field *field = &array_type->e.record.fields[i];
|
||||
|
||||
if (!field->type->reg_size[HLSL_REGSET_NUMERIC])
|
||||
continue;
|
||||
|
||||
field->name_bytecode_offset = put_string(buffer, field->name);
|
||||
write_sm4_type(ctx, buffer, field->type);
|
||||
++field_count;
|
||||
}
|
||||
|
||||
fields_offset = bytecode_align(buffer);
|
||||
|
||||
for (i = 0; i < array_type->e.record.field_count; ++i)
|
||||
{
|
||||
struct hlsl_struct_field *field = &array_type->e.record.fields[i];
|
||||
|
||||
if (!field->type->reg_size[HLSL_REGSET_NUMERIC])
|
||||
continue;
|
||||
|
||||
put_u32(buffer, field->name_bytecode_offset);
|
||||
put_u32(buffer, field->type->bytecode_offset);
|
||||
put_u32(buffer, field->reg_offset[HLSL_REGSET_NUMERIC] * sizeof(float));
|
||||
}
|
||||
type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID));
|
||||
put_u32(buffer, vkd3d_make_u32(1, hlsl_type_component_count(array_type)));
|
||||
put_u32(buffer, vkd3d_make_u32(array_size, field_count));
|
||||
put_u32(buffer, fields_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
VKD3D_ASSERT(array_type->class <= HLSL_CLASS_LAST_NUMERIC);
|
||||
type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type)));
|
||||
put_u32(buffer, vkd3d_make_u32(array_type->e.numeric.dimy, array_type->e.numeric.dimx));
|
||||
put_u32(buffer, vkd3d_make_u32(array_size, 0));
|
||||
put_u32(buffer, 1);
|
||||
}
|
||||
|
||||
if (profile->major_version >= 5)
|
||||
{
|
||||
put_u32(buffer, 0); /* FIXME: unknown */
|
||||
put_u32(buffer, 0); /* FIXME: unknown */
|
||||
put_u32(buffer, 0); /* FIXME: unknown */
|
||||
put_u32(buffer, 0); /* FIXME: unknown */
|
||||
put_u32(buffer, name_offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rdef)
|
||||
{
|
||||
uint32_t binding_desc_size = (hlsl_version_ge(ctx, 5, 1) ? 10 : 8) * sizeof(uint32_t);
|
||||
size_t cbuffers_offset, resources_offset, creator_offset, string_offset;
|
||||
unsigned int cbuffer_count = 0, extern_resources_count, i, j;
|
||||
size_t cbuffer_position, resource_position, creator_position;
|
||||
const struct hlsl_profile_info *profile = ctx->profile;
|
||||
struct vkd3d_bytecode_buffer buffer = {0};
|
||||
struct extern_resource *extern_resources;
|
||||
const struct hlsl_buffer *cbuffer;
|
||||
const struct hlsl_ir_var *var;
|
||||
|
||||
static const uint16_t target_types[] =
|
||||
{
|
||||
0xffff, /* PIXEL */
|
||||
0xfffe, /* VERTEX */
|
||||
0x4753, /* GEOMETRY */
|
||||
0x4853, /* HULL */
|
||||
0x4453, /* DOMAIN */
|
||||
0x4353, /* COMPUTE */
|
||||
};
|
||||
|
||||
extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
|
||||
{
|
||||
if (cbuffer->reg.allocated)
|
||||
++cbuffer_count;
|
||||
}
|
||||
|
||||
put_u32(&buffer, cbuffer_count);
|
||||
cbuffer_position = put_u32(&buffer, 0);
|
||||
put_u32(&buffer, extern_resources_count);
|
||||
resource_position = put_u32(&buffer, 0);
|
||||
put_u32(&buffer, vkd3d_make_u32(vkd3d_make_u16(profile->minor_version, profile->major_version),
|
||||
target_types[profile->type]));
|
||||
put_u32(&buffer, 0); /* FIXME: compilation flags */
|
||||
creator_position = put_u32(&buffer, 0);
|
||||
|
||||
if (profile->major_version >= 5)
|
||||
{
|
||||
put_u32(&buffer, hlsl_version_ge(ctx, 5, 1) ? TAG_RD11_REVERSE : TAG_RD11);
|
||||
put_u32(&buffer, 15 * sizeof(uint32_t)); /* size of RDEF header including this header */
|
||||
put_u32(&buffer, 6 * sizeof(uint32_t)); /* size of buffer desc */
|
||||
put_u32(&buffer, binding_desc_size); /* size of binding desc */
|
||||
put_u32(&buffer, 10 * sizeof(uint32_t)); /* size of variable desc */
|
||||
put_u32(&buffer, 9 * sizeof(uint32_t)); /* size of type desc */
|
||||
put_u32(&buffer, 3 * sizeof(uint32_t)); /* size of member desc */
|
||||
put_u32(&buffer, 0); /* unknown; possibly a null terminator */
|
||||
}
|
||||
|
||||
/* Bound resources. */
|
||||
|
||||
resources_offset = bytecode_align(&buffer);
|
||||
set_u32(&buffer, resource_position, resources_offset);
|
||||
|
||||
for (i = 0; i < extern_resources_count; ++i)
|
||||
{
|
||||
const struct extern_resource *resource = &extern_resources[i];
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (resource->is_user_packed)
|
||||
flags |= D3D_SIF_USERPACKED;
|
||||
|
||||
put_u32(&buffer, 0); /* name */
|
||||
if (resource->buffer)
|
||||
put_u32(&buffer, resource->buffer->type == HLSL_BUFFER_CONSTANT ? D3D_SIT_CBUFFER : D3D_SIT_TBUFFER);
|
||||
else
|
||||
put_u32(&buffer, sm4_resource_type(resource->component_type));
|
||||
if (resource->regset == HLSL_REGSET_TEXTURES || resource->regset == HLSL_REGSET_UAVS)
|
||||
{
|
||||
unsigned int dimx = resource->component_type->e.resource.format->e.numeric.dimx;
|
||||
|
||||
put_u32(&buffer, sm4_data_type(resource->component_type));
|
||||
put_u32(&buffer, sm4_rdef_resource_dimension(resource->component_type));
|
||||
put_u32(&buffer, ~0u); /* FIXME: multisample count */
|
||||
flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
put_u32(&buffer, 0);
|
||||
put_u32(&buffer, 0);
|
||||
put_u32(&buffer, 0);
|
||||
}
|
||||
put_u32(&buffer, resource->index);
|
||||
put_u32(&buffer, resource->bind_count);
|
||||
put_u32(&buffer, flags);
|
||||
|
||||
if (hlsl_version_ge(ctx, 5, 1))
|
||||
{
|
||||
put_u32(&buffer, resource->space);
|
||||
put_u32(&buffer, resource->id);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < extern_resources_count; ++i)
|
||||
{
|
||||
const struct extern_resource *resource = &extern_resources[i];
|
||||
|
||||
string_offset = put_string(&buffer, resource->name);
|
||||
set_u32(&buffer, resources_offset + i * binding_desc_size, string_offset);
|
||||
}
|
||||
|
||||
/* Buffers. */
|
||||
|
||||
cbuffers_offset = bytecode_align(&buffer);
|
||||
set_u32(&buffer, cbuffer_position, cbuffers_offset);
|
||||
LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
|
||||
{
|
||||
unsigned int var_count = 0;
|
||||
|
||||
if (!cbuffer->reg.allocated)
|
||||
continue;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if (var->is_uniform && var->buffer == cbuffer && var->data_type->reg_size[HLSL_REGSET_NUMERIC])
|
||||
++var_count;
|
||||
}
|
||||
|
||||
put_u32(&buffer, 0); /* name */
|
||||
put_u32(&buffer, var_count);
|
||||
put_u32(&buffer, 0); /* variable offset */
|
||||
put_u32(&buffer, align(cbuffer->size, 4) * sizeof(float));
|
||||
put_u32(&buffer, 0); /* FIXME: flags */
|
||||
put_u32(&buffer, cbuffer->type == HLSL_BUFFER_CONSTANT ? D3D_CT_CBUFFER : D3D_CT_TBUFFER);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
|
||||
{
|
||||
if (!cbuffer->reg.allocated)
|
||||
continue;
|
||||
|
||||
string_offset = put_string(&buffer, cbuffer->name);
|
||||
set_u32(&buffer, cbuffers_offset + i++ * 6 * sizeof(uint32_t), string_offset);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
|
||||
{
|
||||
size_t vars_start = bytecode_align(&buffer);
|
||||
|
||||
if (!cbuffer->reg.allocated)
|
||||
continue;
|
||||
|
||||
set_u32(&buffer, cbuffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (!var->is_uniform || var->buffer != cbuffer || !var->data_type->reg_size[HLSL_REGSET_NUMERIC])
|
||||
continue;
|
||||
|
||||
if (var->is_read)
|
||||
flags |= D3D_SVF_USED;
|
||||
|
||||
put_u32(&buffer, 0); /* name */
|
||||
put_u32(&buffer, var->buffer_offset * sizeof(float));
|
||||
put_u32(&buffer, var->data_type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float));
|
||||
put_u32(&buffer, flags);
|
||||
put_u32(&buffer, 0); /* type */
|
||||
put_u32(&buffer, 0); /* default value */
|
||||
|
||||
if (profile->major_version >= 5)
|
||||
{
|
||||
put_u32(&buffer, 0); /* texture start */
|
||||
put_u32(&buffer, 0); /* texture count */
|
||||
put_u32(&buffer, 0); /* sampler start */
|
||||
put_u32(&buffer, 0); /* sampler count */
|
||||
}
|
||||
}
|
||||
|
||||
j = 0;
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
const unsigned int var_size = (profile->major_version >= 5 ? 10 : 6);
|
||||
size_t var_offset = vars_start + j * var_size * sizeof(uint32_t);
|
||||
|
||||
if (!var->is_uniform || var->buffer != cbuffer || !var->data_type->reg_size[HLSL_REGSET_NUMERIC])
|
||||
continue;
|
||||
|
||||
string_offset = put_string(&buffer, var->name);
|
||||
set_u32(&buffer, var_offset, string_offset);
|
||||
write_sm4_type(ctx, &buffer, var->data_type);
|
||||
set_u32(&buffer, var_offset + 4 * sizeof(uint32_t), var->data_type->bytecode_offset);
|
||||
|
||||
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 + 5 * sizeof(uint32_t), default_value_offset);
|
||||
|
||||
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, comp_index;
|
||||
enum hlsl_regset regset;
|
||||
|
||||
if (comp_type->class == HLSL_CLASS_STRING)
|
||||
{
|
||||
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||
"Cannot write string default value.");
|
||||
continue;
|
||||
}
|
||||
|
||||
comp_index = get_component_index_from_default_initializer_index(var->data_type, k);
|
||||
comp_offset = hlsl_type_get_component_offset(ctx, var->data_type, comp_index, ®set);
|
||||
if (regset == HLSL_REGSET_NUMERIC)
|
||||
{
|
||||
if (comp_type->e.numeric.type == HLSL_TYPE_DOUBLE)
|
||||
hlsl_fixme(ctx, &var->loc, "Write double default values.");
|
||||
|
||||
set_u32(&buffer, default_value_offset + comp_offset * sizeof(uint32_t),
|
||||
var->default_values[k].number.u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
creator_offset = put_string(&buffer, vkd3d_shader_get_version(NULL, NULL));
|
||||
set_u32(&buffer, creator_position, creator_offset);
|
||||
|
||||
sm4_free_extern_resources(extern_resources, extern_resources_count);
|
||||
|
||||
if (buffer.status)
|
||||
{
|
||||
vkd3d_free(buffer.data);
|
||||
ctx->result = buffer.status;
|
||||
return;
|
||||
}
|
||||
rdef->code = buffer.data;
|
||||
rdef->size = buffer.size;
|
||||
}
|
||||
|
||||
static bool loop_unrolling_generate_const_bool_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *var,
|
||||
bool val, struct hlsl_block *block, struct vkd3d_shader_location *loc)
|
||||
{
|
||||
|
@ -21,9 +21,7 @@
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "hlsl.h"
|
||||
#include "vkd3d_shader_private.h"
|
||||
#include "vkd3d_d3dcommon.h"
|
||||
|
||||
#define SM4_MAX_SRC_COUNT 6
|
||||
#define SM4_MAX_DST_COUNT 2
|
||||
@ -163,9 +161,6 @@ STATIC_ASSERT(SM4_MAX_SRC_COUNT <= SPIRV_MAX_SRC_COUNT);
|
||||
|
||||
#define VKD3D_SM4_TYPE_COMPONENT(com, i) (((com) >> (4 * (i))) & 0xfu)
|
||||
|
||||
/* The shift that corresponds to the D3D_SIF_TEXTURE_COMPONENTS mask. */
|
||||
#define VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT 2
|
||||
|
||||
enum vkd3d_sm4_opcode
|
||||
{
|
||||
VKD3D_SM4_OP_ADD = 0x00,
|
||||
@ -3268,503 +3263,6 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si
|
||||
vkd3d_free(sorted_elements);
|
||||
}
|
||||
|
||||
static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type)
|
||||
{
|
||||
switch (type->class)
|
||||
{
|
||||
case HLSL_CLASS_MATRIX:
|
||||
VKD3D_ASSERT(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
|
||||
if (type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR)
|
||||
return D3D_SVC_MATRIX_COLUMNS;
|
||||
else
|
||||
return D3D_SVC_MATRIX_ROWS;
|
||||
case HLSL_CLASS_SCALAR:
|
||||
return D3D_SVC_SCALAR;
|
||||
case HLSL_CLASS_VECTOR:
|
||||
return D3D_SVC_VECTOR;
|
||||
|
||||
case HLSL_CLASS_ARRAY:
|
||||
case HLSL_CLASS_DEPTH_STENCIL_STATE:
|
||||
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
|
||||
case HLSL_CLASS_EFFECT_GROUP:
|
||||
case HLSL_CLASS_ERROR:
|
||||
case HLSL_CLASS_STRUCT:
|
||||
case HLSL_CLASS_PASS:
|
||||
case HLSL_CLASS_PIXEL_SHADER:
|
||||
case HLSL_CLASS_RASTERIZER_STATE:
|
||||
case HLSL_CLASS_RENDER_TARGET_VIEW:
|
||||
case HLSL_CLASS_SAMPLER:
|
||||
case HLSL_CLASS_STRING:
|
||||
case HLSL_CLASS_TECHNIQUE:
|
||||
case HLSL_CLASS_TEXTURE:
|
||||
case HLSL_CLASS_UAV:
|
||||
case HLSL_CLASS_VERTEX_SHADER:
|
||||
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 D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type)
|
||||
{
|
||||
switch (type->e.numeric.type)
|
||||
{
|
||||
case HLSL_TYPE_BOOL:
|
||||
return D3D_SVT_BOOL;
|
||||
case HLSL_TYPE_DOUBLE:
|
||||
return D3D_SVT_DOUBLE;
|
||||
case HLSL_TYPE_FLOAT:
|
||||
case HLSL_TYPE_HALF:
|
||||
return D3D_SVT_FLOAT;
|
||||
case HLSL_TYPE_INT:
|
||||
return D3D_SVT_INT;
|
||||
case HLSL_TYPE_UINT:
|
||||
return D3D_SVT_UINT;
|
||||
}
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, struct hlsl_type *type)
|
||||
{
|
||||
const struct hlsl_type *array_type = hlsl_get_multiarray_element_type(type);
|
||||
const char *name = array_type->name ? array_type->name : "<unnamed>";
|
||||
const struct hlsl_profile_info *profile = ctx->profile;
|
||||
unsigned int array_size = 0;
|
||||
size_t name_offset = 0;
|
||||
size_t i;
|
||||
|
||||
if (type->bytecode_offset)
|
||||
return;
|
||||
|
||||
if (profile->major_version >= 5)
|
||||
name_offset = put_string(buffer, name);
|
||||
|
||||
if (type->class == HLSL_CLASS_ARRAY)
|
||||
array_size = hlsl_get_multiarray_size(type);
|
||||
|
||||
if (array_type->class == HLSL_CLASS_STRUCT)
|
||||
{
|
||||
unsigned int field_count = 0;
|
||||
size_t fields_offset = 0;
|
||||
|
||||
for (i = 0; i < array_type->e.record.field_count; ++i)
|
||||
{
|
||||
struct hlsl_struct_field *field = &array_type->e.record.fields[i];
|
||||
|
||||
if (!field->type->reg_size[HLSL_REGSET_NUMERIC])
|
||||
continue;
|
||||
|
||||
field->name_bytecode_offset = put_string(buffer, field->name);
|
||||
write_sm4_type(ctx, buffer, field->type);
|
||||
++field_count;
|
||||
}
|
||||
|
||||
fields_offset = bytecode_align(buffer);
|
||||
|
||||
for (i = 0; i < array_type->e.record.field_count; ++i)
|
||||
{
|
||||
struct hlsl_struct_field *field = &array_type->e.record.fields[i];
|
||||
|
||||
if (!field->type->reg_size[HLSL_REGSET_NUMERIC])
|
||||
continue;
|
||||
|
||||
put_u32(buffer, field->name_bytecode_offset);
|
||||
put_u32(buffer, field->type->bytecode_offset);
|
||||
put_u32(buffer, field->reg_offset[HLSL_REGSET_NUMERIC] * sizeof(float));
|
||||
}
|
||||
type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID));
|
||||
put_u32(buffer, vkd3d_make_u32(1, hlsl_type_component_count(array_type)));
|
||||
put_u32(buffer, vkd3d_make_u32(array_size, field_count));
|
||||
put_u32(buffer, fields_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
VKD3D_ASSERT(array_type->class <= HLSL_CLASS_LAST_NUMERIC);
|
||||
type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type)));
|
||||
put_u32(buffer, vkd3d_make_u32(array_type->e.numeric.dimy, array_type->e.numeric.dimx));
|
||||
put_u32(buffer, vkd3d_make_u32(array_size, 0));
|
||||
put_u32(buffer, 1);
|
||||
}
|
||||
|
||||
if (profile->major_version >= 5)
|
||||
{
|
||||
put_u32(buffer, 0); /* FIXME: unknown */
|
||||
put_u32(buffer, 0); /* FIXME: unknown */
|
||||
put_u32(buffer, 0); /* FIXME: unknown */
|
||||
put_u32(buffer, 0); /* FIXME: unknown */
|
||||
put_u32(buffer, name_offset);
|
||||
}
|
||||
}
|
||||
|
||||
static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type)
|
||||
{
|
||||
switch (type->class)
|
||||
{
|
||||
case HLSL_CLASS_SAMPLER:
|
||||
return D3D_SIT_SAMPLER;
|
||||
case HLSL_CLASS_TEXTURE:
|
||||
return D3D_SIT_TEXTURE;
|
||||
case HLSL_CLASS_UAV:
|
||||
return D3D_SIT_UAV_RWTYPED;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
static enum vkd3d_sm4_data_type sm4_data_type(const struct hlsl_type *type)
|
||||
{
|
||||
const struct hlsl_type *format = type->e.resource.format;
|
||||
|
||||
switch (format->e.numeric.type)
|
||||
{
|
||||
case HLSL_TYPE_DOUBLE:
|
||||
return VKD3D_SM4_DATA_DOUBLE;
|
||||
|
||||
case HLSL_TYPE_FLOAT:
|
||||
case HLSL_TYPE_HALF:
|
||||
if (format->modifiers & HLSL_MODIFIER_UNORM)
|
||||
return VKD3D_SM4_DATA_UNORM;
|
||||
if (format->modifiers & HLSL_MODIFIER_SNORM)
|
||||
return VKD3D_SM4_DATA_SNORM;
|
||||
return VKD3D_SM4_DATA_FLOAT;
|
||||
|
||||
case HLSL_TYPE_INT:
|
||||
return VKD3D_SM4_DATA_INT;
|
||||
break;
|
||||
|
||||
case HLSL_TYPE_BOOL:
|
||||
case HLSL_TYPE_UINT:
|
||||
return VKD3D_SM4_DATA_UINT;
|
||||
}
|
||||
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *type)
|
||||
{
|
||||
switch (type->sampler_dim)
|
||||
{
|
||||
case HLSL_SAMPLER_DIM_1D:
|
||||
return D3D_SRV_DIMENSION_TEXTURE1D;
|
||||
case HLSL_SAMPLER_DIM_2D:
|
||||
return D3D_SRV_DIMENSION_TEXTURE2D;
|
||||
case HLSL_SAMPLER_DIM_3D:
|
||||
return D3D_SRV_DIMENSION_TEXTURE3D;
|
||||
case HLSL_SAMPLER_DIM_CUBE:
|
||||
return D3D_SRV_DIMENSION_TEXTURECUBE;
|
||||
case HLSL_SAMPLER_DIM_1DARRAY:
|
||||
return D3D_SRV_DIMENSION_TEXTURE1DARRAY;
|
||||
case HLSL_SAMPLER_DIM_2DARRAY:
|
||||
return D3D_SRV_DIMENSION_TEXTURE2DARRAY;
|
||||
case HLSL_SAMPLER_DIM_2DMS:
|
||||
return D3D_SRV_DIMENSION_TEXTURE2DMS;
|
||||
case HLSL_SAMPLER_DIM_2DMSARRAY:
|
||||
return D3D_SRV_DIMENSION_TEXTURE2DMSARRAY;
|
||||
case HLSL_SAMPLER_DIM_CUBEARRAY:
|
||||
return D3D_SRV_DIMENSION_TEXTURECUBEARRAY;
|
||||
case HLSL_SAMPLER_DIM_BUFFER:
|
||||
case HLSL_SAMPLER_DIM_RAW_BUFFER:
|
||||
case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
|
||||
return D3D_SRV_DIMENSION_BUFFER;
|
||||
default:
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
/* For some reason, for matrices, values from default value initializers end up in different
|
||||
* components than from regular initializers. Default value initializers fill the matrix in
|
||||
* vertical reading order (left-to-right top-to-bottom) instead of regular reading order
|
||||
* (top-to-bottom left-to-right), so they have to be adjusted.
|
||||
* An exception is that the order of matrix initializers for function parameters are row-major
|
||||
* (top-to-bottom left-to-right). */
|
||||
static unsigned int get_component_index_from_default_initializer_index(struct hlsl_type *type, unsigned int index)
|
||||
{
|
||||
unsigned int element_comp_count, element, x, y, i;
|
||||
unsigned int base = 0;
|
||||
|
||||
switch (type->class)
|
||||
{
|
||||
case HLSL_CLASS_MATRIX:
|
||||
x = index / type->e.numeric.dimy;
|
||||
y = index % type->e.numeric.dimy;
|
||||
return y * type->e.numeric.dimx + x;
|
||||
|
||||
case HLSL_CLASS_ARRAY:
|
||||
element_comp_count = hlsl_type_component_count(type->e.array.type);
|
||||
element = index / element_comp_count;
|
||||
base = element * element_comp_count;
|
||||
return base + get_component_index_from_default_initializer_index(type->e.array.type, index - base);
|
||||
|
||||
case HLSL_CLASS_STRUCT:
|
||||
for (i = 0; i < type->e.record.field_count; ++i)
|
||||
{
|
||||
struct hlsl_type *field_type = type->e.record.fields[i].type;
|
||||
|
||||
element_comp_count = hlsl_type_component_count(field_type);
|
||||
if (index - base < element_comp_count)
|
||||
return base + get_component_index_from_default_initializer_index(field_type, index - base);
|
||||
base += element_comp_count;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return index;
|
||||
}
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rdef)
|
||||
{
|
||||
uint32_t binding_desc_size = (hlsl_version_ge(ctx, 5, 1) ? 10 : 8) * sizeof(uint32_t);
|
||||
size_t cbuffers_offset, resources_offset, creator_offset, string_offset;
|
||||
unsigned int cbuffer_count = 0, extern_resources_count, i, j;
|
||||
size_t cbuffer_position, resource_position, creator_position;
|
||||
const struct hlsl_profile_info *profile = ctx->profile;
|
||||
struct vkd3d_bytecode_buffer buffer = {0};
|
||||
struct extern_resource *extern_resources;
|
||||
const struct hlsl_buffer *cbuffer;
|
||||
const struct hlsl_ir_var *var;
|
||||
|
||||
static const uint16_t target_types[] =
|
||||
{
|
||||
0xffff, /* PIXEL */
|
||||
0xfffe, /* VERTEX */
|
||||
0x4753, /* GEOMETRY */
|
||||
0x4853, /* HULL */
|
||||
0x4453, /* DOMAIN */
|
||||
0x4353, /* COMPUTE */
|
||||
};
|
||||
|
||||
extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
|
||||
{
|
||||
if (cbuffer->reg.allocated)
|
||||
++cbuffer_count;
|
||||
}
|
||||
|
||||
put_u32(&buffer, cbuffer_count);
|
||||
cbuffer_position = put_u32(&buffer, 0);
|
||||
put_u32(&buffer, extern_resources_count);
|
||||
resource_position = put_u32(&buffer, 0);
|
||||
put_u32(&buffer, vkd3d_make_u32(vkd3d_make_u16(profile->minor_version, profile->major_version),
|
||||
target_types[profile->type]));
|
||||
put_u32(&buffer, 0); /* FIXME: compilation flags */
|
||||
creator_position = put_u32(&buffer, 0);
|
||||
|
||||
if (profile->major_version >= 5)
|
||||
{
|
||||
put_u32(&buffer, hlsl_version_ge(ctx, 5, 1) ? TAG_RD11_REVERSE : TAG_RD11);
|
||||
put_u32(&buffer, 15 * sizeof(uint32_t)); /* size of RDEF header including this header */
|
||||
put_u32(&buffer, 6 * sizeof(uint32_t)); /* size of buffer desc */
|
||||
put_u32(&buffer, binding_desc_size); /* size of binding desc */
|
||||
put_u32(&buffer, 10 * sizeof(uint32_t)); /* size of variable desc */
|
||||
put_u32(&buffer, 9 * sizeof(uint32_t)); /* size of type desc */
|
||||
put_u32(&buffer, 3 * sizeof(uint32_t)); /* size of member desc */
|
||||
put_u32(&buffer, 0); /* unknown; possibly a null terminator */
|
||||
}
|
||||
|
||||
/* Bound resources. */
|
||||
|
||||
resources_offset = bytecode_align(&buffer);
|
||||
set_u32(&buffer, resource_position, resources_offset);
|
||||
|
||||
for (i = 0; i < extern_resources_count; ++i)
|
||||
{
|
||||
const struct extern_resource *resource = &extern_resources[i];
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (resource->is_user_packed)
|
||||
flags |= D3D_SIF_USERPACKED;
|
||||
|
||||
put_u32(&buffer, 0); /* name */
|
||||
if (resource->buffer)
|
||||
put_u32(&buffer, resource->buffer->type == HLSL_BUFFER_CONSTANT ? D3D_SIT_CBUFFER : D3D_SIT_TBUFFER);
|
||||
else
|
||||
put_u32(&buffer, sm4_resource_type(resource->component_type));
|
||||
if (resource->regset == HLSL_REGSET_TEXTURES || resource->regset == HLSL_REGSET_UAVS)
|
||||
{
|
||||
unsigned int dimx = resource->component_type->e.resource.format->e.numeric.dimx;
|
||||
|
||||
put_u32(&buffer, sm4_data_type(resource->component_type));
|
||||
put_u32(&buffer, sm4_rdef_resource_dimension(resource->component_type));
|
||||
put_u32(&buffer, ~0u); /* FIXME: multisample count */
|
||||
flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
put_u32(&buffer, 0);
|
||||
put_u32(&buffer, 0);
|
||||
put_u32(&buffer, 0);
|
||||
}
|
||||
put_u32(&buffer, resource->index);
|
||||
put_u32(&buffer, resource->bind_count);
|
||||
put_u32(&buffer, flags);
|
||||
|
||||
if (hlsl_version_ge(ctx, 5, 1))
|
||||
{
|
||||
put_u32(&buffer, resource->space);
|
||||
put_u32(&buffer, resource->id);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < extern_resources_count; ++i)
|
||||
{
|
||||
const struct extern_resource *resource = &extern_resources[i];
|
||||
|
||||
string_offset = put_string(&buffer, resource->name);
|
||||
set_u32(&buffer, resources_offset + i * binding_desc_size, string_offset);
|
||||
}
|
||||
|
||||
/* Buffers. */
|
||||
|
||||
cbuffers_offset = bytecode_align(&buffer);
|
||||
set_u32(&buffer, cbuffer_position, cbuffers_offset);
|
||||
LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
|
||||
{
|
||||
unsigned int var_count = 0;
|
||||
|
||||
if (!cbuffer->reg.allocated)
|
||||
continue;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if (var->is_uniform && var->buffer == cbuffer && var->data_type->reg_size[HLSL_REGSET_NUMERIC])
|
||||
++var_count;
|
||||
}
|
||||
|
||||
put_u32(&buffer, 0); /* name */
|
||||
put_u32(&buffer, var_count);
|
||||
put_u32(&buffer, 0); /* variable offset */
|
||||
put_u32(&buffer, align(cbuffer->size, 4) * sizeof(float));
|
||||
put_u32(&buffer, 0); /* FIXME: flags */
|
||||
put_u32(&buffer, cbuffer->type == HLSL_BUFFER_CONSTANT ? D3D_CT_CBUFFER : D3D_CT_TBUFFER);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
|
||||
{
|
||||
if (!cbuffer->reg.allocated)
|
||||
continue;
|
||||
|
||||
string_offset = put_string(&buffer, cbuffer->name);
|
||||
set_u32(&buffer, cbuffers_offset + i++ * 6 * sizeof(uint32_t), string_offset);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
|
||||
{
|
||||
size_t vars_start = bytecode_align(&buffer);
|
||||
|
||||
if (!cbuffer->reg.allocated)
|
||||
continue;
|
||||
|
||||
set_u32(&buffer, cbuffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if (var->is_uniform && var->buffer == cbuffer && var->data_type->reg_size[HLSL_REGSET_NUMERIC])
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (var->is_read)
|
||||
flags |= D3D_SVF_USED;
|
||||
|
||||
put_u32(&buffer, 0); /* name */
|
||||
put_u32(&buffer, var->buffer_offset * sizeof(float));
|
||||
put_u32(&buffer, var->data_type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float));
|
||||
put_u32(&buffer, flags);
|
||||
put_u32(&buffer, 0); /* type */
|
||||
put_u32(&buffer, 0); /* default value */
|
||||
|
||||
if (profile->major_version >= 5)
|
||||
{
|
||||
put_u32(&buffer, 0); /* texture start */
|
||||
put_u32(&buffer, 0); /* texture count */
|
||||
put_u32(&buffer, 0); /* sampler start */
|
||||
put_u32(&buffer, 0); /* sampler count */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
j = 0;
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if (var->is_uniform && var->buffer == cbuffer && var->data_type->reg_size[HLSL_REGSET_NUMERIC])
|
||||
{
|
||||
const unsigned int var_size = (profile->major_version >= 5 ? 10 : 6);
|
||||
size_t var_offset = vars_start + j * var_size * sizeof(uint32_t);
|
||||
|
||||
string_offset = put_string(&buffer, var->name);
|
||||
set_u32(&buffer, var_offset, string_offset);
|
||||
write_sm4_type(ctx, &buffer, var->data_type);
|
||||
set_u32(&buffer, var_offset + 4 * sizeof(uint32_t), var->data_type->bytecode_offset);
|
||||
|
||||
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 + 5 * sizeof(uint32_t), default_value_offset);
|
||||
|
||||
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, comp_index;
|
||||
enum hlsl_regset regset;
|
||||
|
||||
if (comp_type->class == HLSL_CLASS_STRING)
|
||||
{
|
||||
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||
"Cannot write string default value.");
|
||||
continue;
|
||||
}
|
||||
|
||||
comp_index = get_component_index_from_default_initializer_index(var->data_type, k);
|
||||
comp_offset = hlsl_type_get_component_offset(ctx, var->data_type, comp_index, ®set);
|
||||
if (regset == HLSL_REGSET_NUMERIC)
|
||||
{
|
||||
if (comp_type->e.numeric.type == HLSL_TYPE_DOUBLE)
|
||||
hlsl_fixme(ctx, &var->loc, "Write double default values.");
|
||||
|
||||
set_u32(&buffer, default_value_offset + comp_offset * sizeof(uint32_t),
|
||||
var->default_values[k].number.u);
|
||||
}
|
||||
}
|
||||
}
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
creator_offset = put_string(&buffer, vkd3d_shader_get_version(NULL, NULL));
|
||||
set_u32(&buffer, creator_position, creator_offset);
|
||||
|
||||
sm4_free_extern_resources(extern_resources, extern_resources_count);
|
||||
|
||||
if (buffer.status)
|
||||
{
|
||||
vkd3d_free(buffer.data);
|
||||
ctx->result = buffer.status;
|
||||
return;
|
||||
}
|
||||
rdef->code = buffer.data;
|
||||
rdef->size = buffer.size;
|
||||
}
|
||||
|
||||
static enum vkd3d_sm4_resource_type sm4_resource_dimension(enum vkd3d_shader_resource_type resource_type)
|
||||
{
|
||||
switch (resource_type)
|
||||
|
Loading…
x
Reference in New Issue
Block a user