mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/dxil: Load geometry shader properties.
This commit is contained in:
parent
00b0b8d65c
commit
4fd2d5aa77
Notes:
Alexandre Julliard
2024-05-08 22:50:56 +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/805
@ -37,6 +37,9 @@ static const size_t MAX_IR_INSTRUCTIONS_PER_DXIL_INSTRUCTION = 11;
|
|||||||
|
|
||||||
static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64};
|
static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64};
|
||||||
|
|
||||||
|
static const unsigned int MAX_GS_INSTANCE_COUNT = 32; /* kMaxGSInstanceCount */
|
||||||
|
static const unsigned int MAX_GS_OUTPUT_TOTAL_SCALARS = 1024; /* kMaxGSOutputTotalScalars */
|
||||||
|
|
||||||
#define VKD3D_SHADER_SWIZZLE_64_MASK \
|
#define VKD3D_SHADER_SWIZZLE_64_MASK \
|
||||||
(VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(0) \
|
(VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(0) \
|
||||||
| VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(1))
|
| VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(1))
|
||||||
@ -283,6 +286,18 @@ enum dxil_element_additional_tag
|
|||||||
ADDITIONAL_TAG_USED_MASK = 3,
|
ADDITIONAL_TAG_USED_MASK = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum dxil_input_primitive
|
||||||
|
{
|
||||||
|
INPUT_PRIMITIVE_UNDEFINED = 0,
|
||||||
|
INPUT_PRIMITIVE_POINT = 1,
|
||||||
|
INPUT_PRIMITIVE_LINE = 2,
|
||||||
|
INPUT_PRIMITIVE_TRIANGLE = 3,
|
||||||
|
INPUT_PRIMITIVE_LINEWITHADJACENCY = 6,
|
||||||
|
INPUT_PRIMITIVE_TRIANGLEWITHADJACENY = 7,
|
||||||
|
INPUT_PRIMITIVE_PATCH1 = 8,
|
||||||
|
INPUT_PRIMITIVE_PATCH32 = 39,
|
||||||
|
};
|
||||||
|
|
||||||
enum dxil_shader_properties_tag
|
enum dxil_shader_properties_tag
|
||||||
{
|
{
|
||||||
SHADER_PROPERTIES_FLAGS = 0,
|
SHADER_PROPERTIES_FLAGS = 0,
|
||||||
@ -9467,6 +9482,17 @@ static void sm6_parser_emit_dcl_count(struct sm6_parser *sm6, enum vkd3d_shader_
|
|||||||
ins->declaration.count = count;
|
ins->declaration.count = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sm6_parser_emit_dcl_primitive_topology(struct sm6_parser *sm6,
|
||||||
|
enum vkd3d_shader_opcode handler_idx, enum vkd3d_primitive_type primitive_type,
|
||||||
|
unsigned int patch_vertex_count)
|
||||||
|
{
|
||||||
|
struct vkd3d_shader_instruction *ins;
|
||||||
|
|
||||||
|
ins = sm6_parser_add_instruction(sm6, handler_idx);
|
||||||
|
ins->declaration.primitive_type.type = primitive_type;
|
||||||
|
ins->declaration.primitive_type.patch_vertex_count = patch_vertex_count;
|
||||||
|
}
|
||||||
|
|
||||||
static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6,
|
static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6,
|
||||||
enum vkd3d_tessellator_domain tessellator_domain)
|
enum vkd3d_tessellator_domain tessellator_domain)
|
||||||
{
|
{
|
||||||
@ -9551,6 +9577,128 @@ static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6,
|
|||||||
ins->declaration.max_tessellation_factor = max_tessellation_factor;
|
ins->declaration.max_tessellation_factor = max_tessellation_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m)
|
||||||
|
{
|
||||||
|
enum vkd3d_primitive_type input_primitive = VKD3D_PT_TRIANGLELIST, output_primitive;
|
||||||
|
unsigned int i, input_control_point_count = 1, patch_vertex_count = 0;
|
||||||
|
const struct sm6_metadata_node *node;
|
||||||
|
unsigned int operands[5] = {0};
|
||||||
|
|
||||||
|
if (!m || !sm6_metadata_value_is_node(m))
|
||||||
|
{
|
||||||
|
WARN("Missing or invalid GS properties.\n");
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
|
||||||
|
"Geometry shader properties node is missing or invalid.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = m->u.node;
|
||||||
|
if (node->operand_count < ARRAY_SIZE(operands))
|
||||||
|
{
|
||||||
|
WARN("Invalid operand count %u.\n", node->operand_count);
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT,
|
||||||
|
"Geometry shader properties operand count %u is invalid.", node->operand_count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (node->operand_count > ARRAY_SIZE(operands))
|
||||||
|
{
|
||||||
|
WARN("Ignoring %zu extra operands.\n", node->operand_count - ARRAY_SIZE(operands));
|
||||||
|
vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS,
|
||||||
|
"Ignoring %zu extra operands for geometry shader properties.",
|
||||||
|
node->operand_count - ARRAY_SIZE(operands));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < node->operand_count; ++i)
|
||||||
|
{
|
||||||
|
if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &operands[i]))
|
||||||
|
{
|
||||||
|
WARN("GS property at index %u is not a uint value.\n", i);
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
|
||||||
|
"Geometry shader properties operand at index %u is not an integer.", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (i = operands[0])
|
||||||
|
{
|
||||||
|
case INPUT_PRIMITIVE_POINT:
|
||||||
|
input_primitive = VKD3D_PT_POINTLIST;
|
||||||
|
input_control_point_count = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INPUT_PRIMITIVE_LINE:
|
||||||
|
input_primitive = VKD3D_PT_LINELIST;
|
||||||
|
input_control_point_count = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INPUT_PRIMITIVE_TRIANGLE:
|
||||||
|
input_primitive = VKD3D_PT_TRIANGLELIST;
|
||||||
|
input_control_point_count = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INPUT_PRIMITIVE_LINEWITHADJACENCY:
|
||||||
|
input_primitive = VKD3D_PT_LINELIST_ADJ;
|
||||||
|
input_control_point_count = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INPUT_PRIMITIVE_TRIANGLEWITHADJACENY:
|
||||||
|
input_primitive = VKD3D_PT_TRIANGLELIST_ADJ;
|
||||||
|
input_control_point_count = 6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (i >= INPUT_PRIMITIVE_PATCH1 && i <= INPUT_PRIMITIVE_PATCH32)
|
||||||
|
{
|
||||||
|
input_primitive = VKD3D_PT_PATCH;
|
||||||
|
patch_vertex_count = i - INPUT_PRIMITIVE_PATCH1 + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN("Unhandled input primitive %u.\n", i);
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
|
||||||
|
"Geometry shader input primitive %u is unhandled.", i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count);
|
||||||
|
sm6->p.program.input_control_point_count = input_control_point_count;
|
||||||
|
|
||||||
|
i = operands[1];
|
||||||
|
/* Max total scalar count sets an upper limit. We would need to scan outputs to be more precise. */
|
||||||
|
if (i > MAX_GS_OUTPUT_TOTAL_SCALARS)
|
||||||
|
{
|
||||||
|
WARN("GS output vertex count %u invalid.\n", i);
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
|
||||||
|
"Geometry shader output vertex count %u is invalid.", i);
|
||||||
|
}
|
||||||
|
sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_VERTICES_OUT, i);
|
||||||
|
|
||||||
|
if (operands[2] > 1)
|
||||||
|
{
|
||||||
|
FIXME("Unhandled stream mask %#x.\n", operands[2]);
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
|
||||||
|
"Geometry shader stream mask %#x is unhandled.", operands[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
output_primitive = operands[3];
|
||||||
|
if (output_primitive == VKD3D_PT_UNDEFINED || output_primitive >= VKD3D_PT_COUNT)
|
||||||
|
{
|
||||||
|
WARN("Unhandled output primitive %u.\n", output_primitive);
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
|
||||||
|
"Geometry shader output primitive %u is unhandled.", output_primitive);
|
||||||
|
output_primitive = VKD3D_PT_TRIANGLELIST;
|
||||||
|
}
|
||||||
|
sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_OUTPUT_TOPOLOGY, output_primitive, 0);
|
||||||
|
|
||||||
|
i = operands[4];
|
||||||
|
if (!i || i > MAX_GS_INSTANCE_COUNT)
|
||||||
|
{
|
||||||
|
WARN("GS instance count %u invalid.\n", i);
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
|
||||||
|
"Geometry shader instance count %u is invalid.", i);
|
||||||
|
}
|
||||||
|
sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_GS_INSTANCES, i);
|
||||||
|
}
|
||||||
|
|
||||||
static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_parser *sm6,
|
static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_parser *sm6,
|
||||||
const struct sm6_metadata_value *m)
|
const struct sm6_metadata_value *m)
|
||||||
{
|
{
|
||||||
@ -9741,6 +9889,9 @@ static enum vkd3d_result sm6_parser_entry_point_init(struct sm6_parser *sm6)
|
|||||||
case SHADER_PROPERTIES_FLAGS:
|
case SHADER_PROPERTIES_FLAGS:
|
||||||
sm6_parser_emit_global_flags(sm6, node->operands[i + 1]);
|
sm6_parser_emit_global_flags(sm6, node->operands[i + 1]);
|
||||||
break;
|
break;
|
||||||
|
case SHADER_PROPERTIES_GEOMETRY:
|
||||||
|
sm6_parser_gs_properties_init(sm6, node->operands[i + 1]);
|
||||||
|
break;
|
||||||
case SHADER_PROPERTIES_DOMAIN:
|
case SHADER_PROPERTIES_DOMAIN:
|
||||||
tessellator_domain = sm6_parser_ds_properties_init(sm6, node->operands[i + 1]);
|
tessellator_domain = sm6_parser_ds_properties_init(sm6, node->operands[i + 1]);
|
||||||
break;
|
break;
|
||||||
|
@ -1164,6 +1164,8 @@ enum vkd3d_primitive_type
|
|||||||
VKD3D_PT_TRIANGLELIST_ADJ = 12,
|
VKD3D_PT_TRIANGLELIST_ADJ = 12,
|
||||||
VKD3D_PT_TRIANGLESTRIP_ADJ = 13,
|
VKD3D_PT_TRIANGLESTRIP_ADJ = 13,
|
||||||
VKD3D_PT_PATCH = 14,
|
VKD3D_PT_PATCH = 14,
|
||||||
|
|
||||||
|
VKD3D_PT_COUNT = 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vkd3d_shader_primitive_type
|
struct vkd3d_shader_primitive_type
|
||||||
|
Loading…
Reference in New Issue
Block a user