mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader: Synthesize signatures for d3dbc shaders.
This commit is contained in:
parent
20190a1388
commit
7e1fcdca89
Notes:
Alexandre Julliard
2023-06-27 23:33:23 +02:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/200
@ -1559,10 +1559,13 @@ static inline uint32_t vkd3d_shader_create_swizzle(enum vkd3d_shader_swizzle_com
|
||||
/**
|
||||
* A chained structure containing descriptions of shader inputs and outputs.
|
||||
*
|
||||
* This structure is currently implemented only for DXBC source types. For DXBC
|
||||
* shaders, the returned information is parsed directly from the signatures
|
||||
* embedded in the DXBC shader. For all other shader types, the structure is
|
||||
* zeroed.
|
||||
* This structure is currently implemented only for DXBC and legacy D3D bytecode
|
||||
* source types.
|
||||
* For DXBC shaders, the returned information is parsed directly from the
|
||||
* signatures embedded in the DXBC shader.
|
||||
* For legacy D3D shaders, the returned information is synthesized based on
|
||||
* registers declared or used by shader instructions.
|
||||
* For all other shader types, the structure is zeroed.
|
||||
*
|
||||
* All members (except for \ref type and \ref next) are output-only.
|
||||
*
|
||||
@ -1575,6 +1578,23 @@ static inline uint32_t vkd3d_shader_create_swizzle(enum vkd3d_shader_swizzle_com
|
||||
* All signatures may contain pointers into the input shader, and should only
|
||||
* be accessed while the input shader remains valid.
|
||||
*
|
||||
* Signature elements are synthesized from legacy Direct3D bytecode as follows:
|
||||
* - The \ref vkd3d_shader_signature_element.semantic_name field is set to an
|
||||
* uppercase string corresponding to the HLSL name for the usage, e.g.
|
||||
* "POSITION", "BLENDWEIGHT", "COLOR", "PSIZE", etc.
|
||||
* - The \ref vkd3d_shader_signature_element.semantic_index field is set to the
|
||||
* usage index.
|
||||
* - The \ref vkd3d_shader_signature_element.stream_index is always 0.
|
||||
*
|
||||
* Signature elements are synthesized for any input or output register declared
|
||||
* or used in a legacy Direct3D bytecode shader, including the following:
|
||||
* - Shader model 1 and 2 colour and texture coordinate registers.
|
||||
* - The shader model 1 pixel shader output register.
|
||||
* - Shader model 1 and 2 vertex shader output registers (position, fog, and
|
||||
* point size).
|
||||
* - Shader model 3 pixel shader system value input registers (pixel position
|
||||
* and face).
|
||||
*
|
||||
* \since 1.9
|
||||
*/
|
||||
struct vkd3d_shader_scan_signature_info
|
||||
|
@ -490,6 +490,245 @@ static void shader_sm1_parse_dst_param(uint32_t param, const struct vkd3d_shader
|
||||
dst->shift = (param & VKD3D_SM1_DSTSHIFT_MASK) >> VKD3D_SM1_DSTSHIFT_SHIFT;
|
||||
}
|
||||
|
||||
static struct signature_element *find_signature_element(const struct shader_signature *signature,
|
||||
const char *semantic_name, unsigned int semantic_index)
|
||||
{
|
||||
struct signature_element *e = signature->elements;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < signature->element_count; ++i)
|
||||
{
|
||||
if (!ascii_strcasecmp(e[i].semantic_name, semantic_name)
|
||||
&& e[i].semantic_index == semantic_index)
|
||||
return &e[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct signature_element *find_signature_element_by_register_index(
|
||||
const struct shader_signature *signature, unsigned int register_index)
|
||||
{
|
||||
struct signature_element *e = signature->elements;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < signature->element_count; ++i)
|
||||
{
|
||||
if (e[i].register_index == register_index)
|
||||
return &e[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool output,
|
||||
const char *name, unsigned int index, enum vkd3d_shader_sysval_semantic sysval,
|
||||
unsigned int register_index, bool is_dcl, unsigned int mask)
|
||||
{
|
||||
struct shader_signature *signature;
|
||||
struct signature_element *element;
|
||||
|
||||
if (output)
|
||||
signature = &sm1->p.shader_desc.output_signature;
|
||||
else
|
||||
signature = &sm1->p.shader_desc.input_signature;
|
||||
|
||||
if ((element = find_signature_element(signature, name, index)))
|
||||
{
|
||||
element->mask |= mask;
|
||||
if (!is_dcl)
|
||||
element->used_mask |= mask;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!vkd3d_array_reserve((void **)&signature->elements, &signature->elements_capacity,
|
||||
signature->element_count + 1, sizeof(*signature->elements)))
|
||||
return false;
|
||||
element = &signature->elements[signature->element_count++];
|
||||
|
||||
element->semantic_name = name;
|
||||
element->semantic_index = index;
|
||||
element->stream_index = 0;
|
||||
element->sysval_semantic = sysval;
|
||||
element->component_type = VKD3D_SHADER_COMPONENT_FLOAT;
|
||||
element->register_index = register_index;
|
||||
element->register_count = 1;
|
||||
element->mask = mask;
|
||||
element->used_mask = is_dcl ? 0 : mask;
|
||||
element->min_precision = VKD3D_SHADER_MINIMUM_PRECISION_NONE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output,
|
||||
unsigned int register_index, unsigned int mask)
|
||||
{
|
||||
struct shader_signature *signature;
|
||||
struct signature_element *element;
|
||||
|
||||
if (output)
|
||||
signature = &sm1->p.shader_desc.output_signature;
|
||||
else
|
||||
signature = &sm1->p.shader_desc.input_signature;
|
||||
|
||||
if (!(element = find_signature_element_by_register_index(signature, register_index)))
|
||||
{
|
||||
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNDECLARED_SEMANTIC,
|
||||
"%s register %u was used without being declared.", output ? "Output" : "Input", register_index);
|
||||
return;
|
||||
}
|
||||
|
||||
element->used_mask |= mask;
|
||||
}
|
||||
|
||||
static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *sm1,
|
||||
const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask)
|
||||
{
|
||||
unsigned int register_index = reg->idx[0].offset;
|
||||
|
||||
switch (reg->type)
|
||||
{
|
||||
case VKD3DSPR_TEMP:
|
||||
if (sm1->p.shader_version.type == VKD3D_SHADER_TYPE_PIXEL
|
||||
&& sm1->p.shader_version.major == 1 && !register_index)
|
||||
return add_signature_element(sm1, true, "COLOR", 0, VKD3D_SHADER_SV_NONE, 0, is_dcl, mask);
|
||||
return true;
|
||||
|
||||
case VKD3DSPR_INPUT:
|
||||
/* For vertex shaders or sm3 pixel shaders, we should have already
|
||||
* had a DCL instruction. Otherwise, this is a colour input. */
|
||||
if (sm1->p.shader_version.type == VKD3D_SHADER_TYPE_VERTEX || sm1->p.shader_version.major == 3)
|
||||
{
|
||||
add_signature_mask(sm1, false, register_index, mask);
|
||||
return true;
|
||||
}
|
||||
return add_signature_element(sm1, false, "COLOR", register_index,
|
||||
VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask);
|
||||
|
||||
case VKD3DSPR_TEXTURE:
|
||||
/* For vertex shaders, this is ADDR. */
|
||||
if (sm1->p.shader_version.type == VKD3D_SHADER_TYPE_VERTEX)
|
||||
return true;
|
||||
return add_signature_element(sm1, false, "TEXCOORD", register_index,
|
||||
VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask);
|
||||
|
||||
case VKD3DSPR_OUTPUT:
|
||||
if (sm1->p.shader_version.type == VKD3D_SHADER_TYPE_VERTEX)
|
||||
{
|
||||
/* For sm < 2 vertex shaders, this is TEXCRDOUT.
|
||||
*
|
||||
* For sm3 vertex shaders, this is OUTPUT, but we already
|
||||
* should have had a DCL instruction. */
|
||||
if (sm1->p.shader_version.major == 3)
|
||||
{
|
||||
add_signature_mask(sm1, true, register_index, mask);
|
||||
return true;
|
||||
}
|
||||
return add_signature_element(sm1, true, "TEXCOORD", register_index,
|
||||
VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask);
|
||||
}
|
||||
/* fall through */
|
||||
|
||||
case VKD3DSPR_ATTROUT:
|
||||
case VKD3DSPR_COLOROUT:
|
||||
return add_signature_element(sm1, true, "COLOR", register_index,
|
||||
VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask);
|
||||
|
||||
case VKD3DSPR_DEPTHOUT:
|
||||
return add_signature_element(sm1, true, "DEPTH", 0,
|
||||
VKD3D_SHADER_SV_NONE, register_index, is_dcl, 0x1);
|
||||
|
||||
case VKD3DSPR_RASTOUT:
|
||||
switch (register_index)
|
||||
{
|
||||
case 0:
|
||||
return add_signature_element(sm1, true, "POSITION", 0,
|
||||
VKD3D_SHADER_SV_POSITION, register_index, is_dcl, mask);
|
||||
|
||||
case 1:
|
||||
return add_signature_element(sm1, true, "FOG", 0,
|
||||
VKD3D_SHADER_SV_NONE, register_index, is_dcl, 0x1);
|
||||
|
||||
case 2:
|
||||
return add_signature_element(sm1, true, "PSIZE", 0,
|
||||
VKD3D_SHADER_SV_NONE, register_index, is_dcl, 0x1);
|
||||
|
||||
default:
|
||||
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_INDEX,
|
||||
"Invalid rasterizer output index %u.", register_index);
|
||||
return true;
|
||||
}
|
||||
|
||||
case VKD3DSPR_MISCTYPE:
|
||||
switch (register_index)
|
||||
{
|
||||
case 0:
|
||||
return add_signature_element(sm1, false, "VPOS", 0,
|
||||
VKD3D_SHADER_SV_POSITION, register_index, is_dcl, mask);
|
||||
|
||||
case 1:
|
||||
return add_signature_element(sm1, false, "VFACE", 0,
|
||||
VKD3D_SHADER_SV_IS_FRONT_FACE, register_index, is_dcl, 0x1);
|
||||
|
||||
default:
|
||||
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_INDEX,
|
||||
"Invalid miscellaneous fragment input index %u.", register_index);
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser *sm1,
|
||||
const struct vkd3d_shader_semantic *semantic)
|
||||
{
|
||||
const struct vkd3d_shader_register *reg = &semantic->resource.reg.reg;
|
||||
enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE;
|
||||
unsigned int mask = semantic->resource.reg.write_mask;
|
||||
bool output;
|
||||
|
||||
static const char sm1_semantic_names[][13] =
|
||||
{
|
||||
[VKD3D_DECL_USAGE_POSITION ] = "POSITION",
|
||||
[VKD3D_DECL_USAGE_BLEND_WEIGHT ] = "BLENDWEIGHT",
|
||||
[VKD3D_DECL_USAGE_BLEND_INDICES] = "BLENDINDICES",
|
||||
[VKD3D_DECL_USAGE_NORMAL ] = "NORMAL",
|
||||
[VKD3D_DECL_USAGE_PSIZE ] = "PSIZE",
|
||||
[VKD3D_DECL_USAGE_TEXCOORD ] = "TEXCOORD",
|
||||
[VKD3D_DECL_USAGE_TANGENT ] = "TANGENT",
|
||||
[VKD3D_DECL_USAGE_BINORMAL ] = "BINORMAL",
|
||||
[VKD3D_DECL_USAGE_TESS_FACTOR ] = "TESSFACTOR",
|
||||
[VKD3D_DECL_USAGE_POSITIONT ] = "POSITIONT",
|
||||
[VKD3D_DECL_USAGE_COLOR ] = "COLOR",
|
||||
[VKD3D_DECL_USAGE_FOG ] = "FOG",
|
||||
[VKD3D_DECL_USAGE_DEPTH ] = "DEPTH",
|
||||
[VKD3D_DECL_USAGE_SAMPLE ] = "SAMPLE",
|
||||
};
|
||||
|
||||
if (reg->type == VKD3DSPR_OUTPUT)
|
||||
output = true;
|
||||
else if (reg->type == VKD3DSPR_INPUT || reg->type == VKD3DSPR_TEXTURE)
|
||||
output = false;
|
||||
else /* vpos and vface don't have a semantic. */
|
||||
return add_signature_element_from_register(sm1, reg, true, mask);
|
||||
|
||||
/* sm2 pixel shaders use DCL but don't provide a semantic. */
|
||||
if (sm1->p.shader_version.type == VKD3D_SHADER_TYPE_PIXEL && sm1->p.shader_version.major == 2)
|
||||
return add_signature_element_from_register(sm1, reg, true, mask);
|
||||
|
||||
/* With the exception of vertex POSITION output, none of these are system
|
||||
* values. Pixel POSITION input is not equivalent to SV_Position; the closer
|
||||
* equivalent is VPOS, which is not declared as a semantic. */
|
||||
if (sm1->p.shader_version.type == VKD3D_SHADER_TYPE_VERTEX
|
||||
&& output && semantic->usage == VKD3D_DECL_USAGE_POSITION)
|
||||
sysval = VKD3D_SHADER_SV_POSITION;
|
||||
|
||||
return add_signature_element(sm1, output, sm1_semantic_names[semantic->usage],
|
||||
semantic->usage_idx, sysval, reg->idx[0].offset, true, mask);
|
||||
}
|
||||
|
||||
/* Read a parameter token from the input stream, and possibly a relative
|
||||
* addressing token. */
|
||||
static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1,
|
||||
@ -640,6 +879,8 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1,
|
||||
range = &semantic->resource.range;
|
||||
range->space = 0;
|
||||
range->first = range->last = semantic->resource.reg.reg.idx[0].offset;
|
||||
|
||||
add_signature_element_from_semantic(sm1, semantic);
|
||||
}
|
||||
|
||||
static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
|
||||
@ -744,6 +985,14 @@ static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1,
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int mask_from_swizzle(unsigned int swizzle)
|
||||
{
|
||||
return (1u << vkd3d_swizzle_get_component(swizzle, 0))
|
||||
| (1u << vkd3d_swizzle_get_component(swizzle, 1))
|
||||
| (1u << vkd3d_swizzle_get_component(swizzle, 2))
|
||||
| (1u << vkd3d_swizzle_get_component(swizzle, 3));
|
||||
}
|
||||
|
||||
static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins)
|
||||
{
|
||||
struct vkd3d_shader_src_param *src_params, *predicate;
|
||||
@ -832,7 +1081,10 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
|
||||
{
|
||||
/* Destination token */
|
||||
if (ins->dst_count)
|
||||
{
|
||||
shader_sm1_read_dst_param(sm1, &p, dst_param);
|
||||
add_signature_element_from_register(sm1, &dst_param->reg, false, dst_param->write_mask);
|
||||
}
|
||||
|
||||
/* Predication token */
|
||||
if (ins->predicate)
|
||||
@ -840,7 +1092,11 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
|
||||
|
||||
/* Other source tokens */
|
||||
for (i = 0; i < ins->src_count; ++i)
|
||||
{
|
||||
shader_sm1_read_src_param(sm1, &p, &src_params[i]);
|
||||
add_signature_element_from_register(sm1, &src_params[i].reg,
|
||||
false, mask_from_swizzle(src_params[i].swizzle));
|
||||
}
|
||||
}
|
||||
|
||||
if (sm1->abort)
|
||||
|
@ -145,6 +145,8 @@ enum vkd3d_shader_error
|
||||
VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE = 7002,
|
||||
VKD3D_SHADER_ERROR_D3DBC_INVALID_RESOURCE_TYPE = 7003,
|
||||
VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY = 7004,
|
||||
VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_INDEX = 7005,
|
||||
VKD3D_SHADER_ERROR_D3DBC_UNDECLARED_SEMANTIC = 7006,
|
||||
|
||||
VKD3D_SHADER_WARNING_D3DBC_IGNORED_INSTRUCTION_FLAGS= 7300,
|
||||
};
|
||||
@ -802,6 +804,7 @@ struct signature_element
|
||||
struct shader_signature
|
||||
{
|
||||
struct signature_element *elements;
|
||||
size_t elements_capacity;
|
||||
unsigned int element_count;
|
||||
};
|
||||
|
||||
|
@ -476,6 +476,75 @@ static void test_scan_signatures(void)
|
||||
{"position", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
|
||||
};
|
||||
|
||||
static const char vs3_source[] =
|
||||
"void main(\n"
|
||||
" in float4 c : position,\n"
|
||||
" out float4 b : position,\n"
|
||||
" in float4 a : binormal,\n"
|
||||
" in float4 d : blendindices,\n"
|
||||
" inout float4 e : texcoord2,\n"
|
||||
" inout float4 f : color,\n"
|
||||
" inout float g : fog,\n"
|
||||
" inout float h : psize)\n"
|
||||
"{\n"
|
||||
" b = a + c + d;\n"
|
||||
"}";
|
||||
|
||||
static const struct vkd3d_shader_signature_element vs3_inputs[] =
|
||||
{
|
||||
{"POSITION", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
|
||||
{"BINORMAL", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
|
||||
{"BLENDINDICES", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
|
||||
{"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 3, 0xf, 0xf},
|
||||
{"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 4, 0xf, 0xf},
|
||||
{"FOG", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 5, 0xf, 0xf},
|
||||
{"PSIZE", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 6, 0xf, 0xf},
|
||||
};
|
||||
|
||||
static const struct vkd3d_shader_signature_element vs3_outputs[] =
|
||||
{
|
||||
{"POSITION", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
|
||||
{"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
|
||||
{"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
|
||||
{"FOG", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0x1, 0x1},
|
||||
{"PSIZE", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0x1, 0x1},
|
||||
};
|
||||
|
||||
static const char vs4_source[] =
|
||||
"void main(\n"
|
||||
" inout float4 c : position,\n"
|
||||
" inout float4 a : binormal,\n"
|
||||
" inout float4 d : blendindices,\n"
|
||||
" inout float4 e : texcoord2,\n"
|
||||
" inout float4 f : color,\n"
|
||||
" inout float4 g : fog,\n"
|
||||
" inout float h : psize)\n"
|
||||
"{\n"
|
||||
"}";
|
||||
|
||||
static const struct vkd3d_shader_signature_element vs4_inputs[] =
|
||||
{
|
||||
{"POSITION", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
|
||||
{"BINORMAL", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
|
||||
{"BLENDINDICES", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
|
||||
{"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 3, 0xf, 0xf},
|
||||
{"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 4, 0xf, 0xf},
|
||||
{"FOG", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 5, 0xf, 0xf},
|
||||
{"PSIZE", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 6, 0xf, 0xf},
|
||||
};
|
||||
|
||||
static const struct vkd3d_shader_signature_element vs4_outputs[] =
|
||||
{
|
||||
{"POSITION", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
|
||||
{"BINORMAL", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
|
||||
{"BLENDINDICES", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
|
||||
{"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 3, 0xf, 0xf},
|
||||
{"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 4, 0xf, 0xf},
|
||||
{"FOG", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 5, 0xf, 0xf},
|
||||
/* FIXME: This doesn't match native, which always declares and writes all 4 components. */
|
||||
{"PSIZE", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 6, 0x1, 0x1},
|
||||
};
|
||||
|
||||
static const char ps1_source[] =
|
||||
"void main(\n"
|
||||
" in float2 a : apple,\n"
|
||||
@ -501,6 +570,72 @@ static void test_scan_signatures(void)
|
||||
{"sv_depth", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, ~0u, 0x1, 0x1},
|
||||
};
|
||||
|
||||
static const char ps2_source[] =
|
||||
"void main(\n"
|
||||
"in float4 c : color,\n"
|
||||
"in float4 a : texcoord2,\n"
|
||||
"out float4 b : color)\n"
|
||||
"{\n"
|
||||
"b = a.x + c;\n"
|
||||
"}";
|
||||
|
||||
static const struct vkd3d_shader_signature_element ps2_inputs[] =
|
||||
{
|
||||
{"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
|
||||
{"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
|
||||
};
|
||||
|
||||
static const struct vkd3d_shader_signature_element ps2_outputs[] =
|
||||
{
|
||||
{"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
|
||||
};
|
||||
|
||||
static const char ps3_source[] =
|
||||
"void main(\n"
|
||||
"in float4 c : color,\n"
|
||||
"in float4 a : texcoord2,\n"
|
||||
"out float4 b : color,\n"
|
||||
"out float d : depth)\n"
|
||||
"{\n"
|
||||
"b = c;\n"
|
||||
"d = a;\n"
|
||||
"}";
|
||||
|
||||
static const struct vkd3d_shader_signature_element ps3_inputs[] =
|
||||
{
|
||||
{"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
|
||||
{"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
|
||||
};
|
||||
|
||||
static const struct vkd3d_shader_signature_element ps3_outputs[] =
|
||||
{
|
||||
{"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
|
||||
{"DEPTH", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0x1, 0x1},
|
||||
};
|
||||
|
||||
static const char ps4_source[] =
|
||||
"void main(\n"
|
||||
" in float4 c : color,\n"
|
||||
" in float4 a : texcoord2,\n"
|
||||
" out float4 b : color,\n"
|
||||
" inout float d : depth,\n"
|
||||
" in float4 e : blendindices,\n"
|
||||
" in float4 f : vpos,\n"
|
||||
" in float g : vface)\n"
|
||||
"{\n"
|
||||
" b = c + a + e + f + g;\n"
|
||||
"}";
|
||||
|
||||
static const struct vkd3d_shader_signature_element ps4_inputs[] =
|
||||
{
|
||||
{"COLOR", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
|
||||
{"TEXCOORD", 2, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0xf, 0xf},
|
||||
{"DEPTH", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 2, 0xf, 0xf},
|
||||
{"BLENDINDICES", 0, 0, VKD3D_SHADER_SV_NONE, VKD3D_SHADER_COMPONENT_FLOAT, 3, 0xf, 0xf},
|
||||
{"VPOS", 0, 0, VKD3D_SHADER_SV_POSITION, VKD3D_SHADER_COMPONENT_FLOAT, 0, 0xf, 0xf},
|
||||
{"VFACE", 0, 0, VKD3D_SHADER_SV_IS_FRONT_FACE, VKD3D_SHADER_COMPONENT_FLOAT, 1, 0x1, 0x1},
|
||||
};
|
||||
|
||||
static const char cs1_source[] =
|
||||
"[numthreads(1, 1, 1)]\n"
|
||||
"void main(\n"
|
||||
@ -513,6 +648,7 @@ static void test_scan_signatures(void)
|
||||
static const struct
|
||||
{
|
||||
const char *source;
|
||||
bool sm4;
|
||||
const char *profile;
|
||||
const struct vkd3d_shader_signature_element *inputs;
|
||||
size_t input_count;
|
||||
@ -523,10 +659,16 @@ static void test_scan_signatures(void)
|
||||
}
|
||||
tests[] =
|
||||
{
|
||||
{vs1_source, "vs_4_0", vs1_inputs, ARRAY_SIZE(vs1_inputs), vs1_outputs, ARRAY_SIZE(vs1_outputs)},
|
||||
{vs2_source, "vs_4_0", vs2_inputs, ARRAY_SIZE(vs2_inputs), vs2_outputs, ARRAY_SIZE(vs2_outputs)},
|
||||
{ps1_source, "ps_4_0", ps1_inputs, ARRAY_SIZE(ps1_inputs), ps1_outputs, ARRAY_SIZE(ps1_outputs)},
|
||||
{cs1_source, "cs_5_0", NULL, 0, NULL, 0},
|
||||
{vs1_source, true, "vs_4_0", vs1_inputs, ARRAY_SIZE(vs1_inputs), vs1_outputs, ARRAY_SIZE(vs1_outputs)},
|
||||
{vs2_source, true, "vs_4_0", vs2_inputs, ARRAY_SIZE(vs2_inputs), vs2_outputs, ARRAY_SIZE(vs2_outputs)},
|
||||
{vs3_source, false, "vs_1_1", vs3_inputs, ARRAY_SIZE(vs3_inputs), vs3_outputs, ARRAY_SIZE(vs3_outputs)},
|
||||
{vs3_source, false, "vs_2_0", vs3_inputs, ARRAY_SIZE(vs3_inputs), vs3_outputs, ARRAY_SIZE(vs3_outputs)},
|
||||
{vs4_source, false, "vs_3_0", vs4_inputs, ARRAY_SIZE(vs4_inputs), vs4_outputs, ARRAY_SIZE(vs4_outputs)},
|
||||
{ps1_source, true, "ps_4_0", ps1_inputs, ARRAY_SIZE(ps1_inputs), ps1_outputs, ARRAY_SIZE(ps1_outputs)},
|
||||
{ps2_source, false, "ps_1_1", ps2_inputs, ARRAY_SIZE(ps2_inputs), ps2_outputs, ARRAY_SIZE(ps2_outputs)},
|
||||
{ps3_source, false, "ps_2_0", ps3_inputs, ARRAY_SIZE(ps3_inputs), ps3_outputs, ARRAY_SIZE(ps3_outputs)},
|
||||
{ps4_source, false, "ps_3_0", ps4_inputs, ARRAY_SIZE(ps4_inputs), ps3_outputs, ARRAY_SIZE(ps3_outputs)},
|
||||
{cs1_source, true, "cs_5_0", NULL, 0, NULL, 0},
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tests); ++i)
|
||||
@ -536,7 +678,7 @@ static void test_scan_signatures(void)
|
||||
compile_info.source.code = tests[i].source;
|
||||
compile_info.source.size = strlen(tests[i].source);
|
||||
compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL;
|
||||
compile_info.target_type = VKD3D_SHADER_TARGET_DXBC_TPF;
|
||||
compile_info.target_type = tests[i].sm4 ? VKD3D_SHADER_TARGET_DXBC_TPF : VKD3D_SHADER_TARGET_D3D_BYTECODE;
|
||||
compile_info.log_level = VKD3D_SHADER_LOG_INFO;
|
||||
|
||||
compile_info.next = &hlsl_info;
|
||||
@ -545,7 +687,7 @@ static void test_scan_signatures(void)
|
||||
rc = vkd3d_shader_compile(&compile_info, &dxbc, NULL);
|
||||
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
|
||||
|
||||
compile_info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
|
||||
compile_info.source_type = tests[i].sm4 ? VKD3D_SHADER_SOURCE_DXBC_TPF : VKD3D_SHADER_SOURCE_D3D_BYTECODE;
|
||||
compile_info.source = dxbc;
|
||||
|
||||
compile_info.next = &signature_info;
|
||||
|
Loading…
Reference in New Issue
Block a user