wined3d: Recognize SM5+ patch input primitive types.

In D3D11 geometry shaders accept patches as input primitives. This is
forbidden in OpenGL as specified in the ARB_tessellation_shaders spec:
  "we will not allow geometry shaders to receive patches in this
  extension. That limitation may be relaxed in a future extension."

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2017-05-15 12:05:47 +02:00 committed by Alexandre Julliard
parent c8b2452e35
commit 7b01569e44
6 changed files with 79 additions and 21 deletions

View file

@ -89,6 +89,9 @@ GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type)
case WINED3D_PT_TRIANGLESTRIP_ADJ:
return GL_TRIANGLE_STRIP_ADJACENCY_ARB;
case WINED3D_PT_PATCH:
return GL_PATCHES;
default:
FIXME("Unhandled primitive type %s.\n", debug_d3dprimitivetype(primitive_type));
case WINED3D_PT_UNDEFINED:
@ -130,6 +133,9 @@ static enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_t
case GL_TRIANGLE_STRIP_ADJACENCY_ARB:
return WINED3D_PT_TRIANGLESTRIP_ADJ;
case GL_PATCHES:
return WINED3D_PT_PATCH;
default:
FIXME("Unhandled primitive type %s.\n", debug_d3dprimitivetype(primitive_type));
case ~0u:

View file

@ -1048,7 +1048,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PRIMITIVE)
{
if (shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY)
shader->u.gs.input_type = ins.declaration.primitive_type;
shader->u.gs.input_type = ins.declaration.primitive_type.type;
else
FIXME("Invalid instruction %#x for shader type %#x.\n",
ins.handler_idx, shader_version.type);
@ -1056,7 +1056,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
else if (ins.handler_idx == WINED3DSIH_DCL_OUTPUT_TOPOLOGY)
{
if (shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY)
shader->u.gs.output_type = ins.declaration.primitive_type;
shader->u.gs.output_type = ins.declaration.primitive_type.type;
else
FIXME("Invalid instruction %#x for shader type %#x.\n",
ins.handler_idx, shader_version.type);
@ -2395,9 +2395,9 @@ static void shader_dump_ins_modifiers(struct wined3d_string_buffer *buffer,
}
static void shader_dump_primitive_type(struct wined3d_string_buffer *buffer,
enum wined3d_primitive_type primitive_type)
const struct wined3d_shader_primitive_type *primitive_type)
{
switch (primitive_type)
switch (primitive_type->type)
{
case WINED3D_PT_UNDEFINED:
shader_addline(buffer, "undefined");
@ -2432,8 +2432,11 @@ static void shader_dump_primitive_type(struct wined3d_string_buffer *buffer,
case WINED3D_PT_TRIANGLESTRIP_ADJ:
shader_addline(buffer, "trianglestrip_adj");
break;
case WINED3D_PT_PATCH:
shader_addline(buffer, "patch%u", primitive_type->patch_vertex_count);
break;
default:
shader_addline(buffer, "<unrecognized_primitive_type %#x>", primitive_type);
shader_addline(buffer, "<unrecognized_primitive_type %#x>", primitive_type->type);
break;
}
}
@ -2631,7 +2634,7 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe
|| ins.handler_idx == WINED3DSIH_DCL_OUTPUT_TOPOLOGY)
{
shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
shader_dump_primitive_type(&buffer, ins.declaration.primitive_type);
shader_dump_primitive_type(&buffer, &ins.declaration.primitive_type);
}
else if (ins.handler_idx == WINED3DSIH_DCL_INTERFACE)
{

View file

@ -44,7 +44,7 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_bytecode);
#define WINED3D_SM4_RESOURCE_TYPE_MASK (0xfu << WINED3D_SM4_RESOURCE_TYPE_SHIFT)
#define WINED3D_SM4_PRIMITIVE_TYPE_SHIFT 11
#define WINED3D_SM4_PRIMITIVE_TYPE_MASK (0x7u << WINED3D_SM4_PRIMITIVE_TYPE_SHIFT)
#define WINED3D_SM4_PRIMITIVE_TYPE_MASK (0x3fu << WINED3D_SM4_PRIMITIVE_TYPE_SHIFT)
#define WINED3D_SM4_INDEX_TYPE_SHIFT 11
#define WINED3D_SM4_INDEX_TYPE_MASK (0x1u << WINED3D_SM4_INDEX_TYPE_SHIFT)
@ -342,11 +342,43 @@ enum wined3d_sm4_output_primitive_type
enum wined3d_sm4_input_primitive_type
{
WINED3D_SM4_INPUT_PT_POINT = 0x1,
WINED3D_SM4_INPUT_PT_LINE = 0x2,
WINED3D_SM4_INPUT_PT_TRIANGLE = 0x3,
WINED3D_SM4_INPUT_PT_LINEADJ = 0x6,
WINED3D_SM4_INPUT_PT_TRIANGLEADJ = 0x7,
WINED3D_SM4_INPUT_PT_POINT = 0x01,
WINED3D_SM4_INPUT_PT_LINE = 0x02,
WINED3D_SM4_INPUT_PT_TRIANGLE = 0x03,
WINED3D_SM4_INPUT_PT_LINEADJ = 0x06,
WINED3D_SM4_INPUT_PT_TRIANGLEADJ = 0x07,
WINED3D_SM5_INPUT_PT_PATCH1 = 0x08,
WINED3D_SM5_INPUT_PT_PATCH2 = 0x09,
WINED3D_SM5_INPUT_PT_PATCH3 = 0x0a,
WINED3D_SM5_INPUT_PT_PATCH4 = 0x0b,
WINED3D_SM5_INPUT_PT_PATCH5 = 0x0c,
WINED3D_SM5_INPUT_PT_PATCH6 = 0x0d,
WINED3D_SM5_INPUT_PT_PATCH7 = 0x0e,
WINED3D_SM5_INPUT_PT_PATCH8 = 0x0f,
WINED3D_SM5_INPUT_PT_PATCH9 = 0x10,
WINED3D_SM5_INPUT_PT_PATCH10 = 0x11,
WINED3D_SM5_INPUT_PT_PATCH11 = 0x12,
WINED3D_SM5_INPUT_PT_PATCH12 = 0x13,
WINED3D_SM5_INPUT_PT_PATCH13 = 0x14,
WINED3D_SM5_INPUT_PT_PATCH14 = 0x15,
WINED3D_SM5_INPUT_PT_PATCH15 = 0x16,
WINED3D_SM5_INPUT_PT_PATCH16 = 0x17,
WINED3D_SM5_INPUT_PT_PATCH17 = 0x18,
WINED3D_SM5_INPUT_PT_PATCH18 = 0x19,
WINED3D_SM5_INPUT_PT_PATCH19 = 0x1a,
WINED3D_SM5_INPUT_PT_PATCH20 = 0x1b,
WINED3D_SM5_INPUT_PT_PATCH21 = 0x1c,
WINED3D_SM5_INPUT_PT_PATCH22 = 0x1d,
WINED3D_SM5_INPUT_PT_PATCH23 = 0x1e,
WINED3D_SM5_INPUT_PT_PATCH24 = 0x1f,
WINED3D_SM5_INPUT_PT_PATCH25 = 0x20,
WINED3D_SM5_INPUT_PT_PATCH26 = 0x21,
WINED3D_SM5_INPUT_PT_PATCH27 = 0x22,
WINED3D_SM5_INPUT_PT_PATCH28 = 0x23,
WINED3D_SM5_INPUT_PT_PATCH29 = 0x24,
WINED3D_SM5_INPUT_PT_PATCH30 = 0x25,
WINED3D_SM5_INPUT_PT_PATCH31 = 0x26,
WINED3D_SM5_INPUT_PT_PATCH32 = 0x27,
};
enum wined3d_sm4_swizzle_type
@ -594,11 +626,11 @@ static void shader_sm4_read_dcl_output_topology(struct wined3d_shader_instructio
primitive_type = (opcode_token & WINED3D_SM4_PRIMITIVE_TYPE_MASK) >> WINED3D_SM4_PRIMITIVE_TYPE_SHIFT;
if (primitive_type >= ARRAY_SIZE(output_primitive_type_table))
ins->declaration.primitive_type = WINED3D_PT_UNDEFINED;
ins->declaration.primitive_type.type = WINED3D_PT_UNDEFINED;
else
ins->declaration.primitive_type = output_primitive_type_table[primitive_type];
ins->declaration.primitive_type.type = output_primitive_type_table[primitive_type];
if (ins->declaration.primitive_type == WINED3D_PT_UNDEFINED)
if (ins->declaration.primitive_type.type == WINED3D_PT_UNDEFINED)
FIXME("Unhandled output primitive type %#x.\n", primitive_type);
}
@ -609,12 +641,21 @@ static void shader_sm4_read_dcl_input_primitive(struct wined3d_shader_instructio
enum wined3d_sm4_input_primitive_type primitive_type;
primitive_type = (opcode_token & WINED3D_SM4_PRIMITIVE_TYPE_MASK) >> WINED3D_SM4_PRIMITIVE_TYPE_SHIFT;
if (primitive_type >= ARRAY_SIZE(input_primitive_type_table))
ins->declaration.primitive_type = WINED3D_PT_UNDEFINED;
if (WINED3D_SM5_INPUT_PT_PATCH1 <= primitive_type && primitive_type <= WINED3D_SM5_INPUT_PT_PATCH32)
{
ins->declaration.primitive_type.type = WINED3D_PT_PATCH;
ins->declaration.primitive_type.patch_vertex_count = primitive_type - WINED3D_SM5_INPUT_PT_PATCH1 + 1;
}
else if (primitive_type >= ARRAY_SIZE(input_primitive_type_table))
{
ins->declaration.primitive_type.type = WINED3D_PT_UNDEFINED;
}
else
ins->declaration.primitive_type = input_primitive_type_table[primitive_type];
{
ins->declaration.primitive_type.type = input_primitive_type_table[primitive_type];
}
if (ins->declaration.primitive_type == WINED3D_PT_UNDEFINED)
if (ins->declaration.primitive_type.type == WINED3D_PT_UNDEFINED)
FIXME("Unhandled input primitive type %#x.\n", primitive_type);
}

View file

@ -4102,9 +4102,10 @@ const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type)
PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ);
PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ);
PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ);
PRIM_TO_STR(WINED3D_PT_PATCH);
#undef PRIM_TO_STR
default:
FIXME("Unrecognized %u primitive type!\n", primitive_type);
FIXME("Unrecognized primitive type %#x.\n", primitive_type);
return "unrecognized";
}
}

View file

@ -1148,6 +1148,12 @@ struct wined3d_shader_texel_offset
signed char u, v, w;
};
struct wined3d_shader_primitive_type
{
enum wined3d_primitive_type type;
unsigned int patch_vertex_count;
};
struct wined3d_shader_instruction
{
const struct wined3d_shader_context *ctx;
@ -1164,7 +1170,7 @@ struct wined3d_shader_instruction
{
struct wined3d_shader_semantic semantic;
struct wined3d_shader_register_semantic register_semantic;
enum wined3d_primitive_type primitive_type;
struct wined3d_shader_primitive_type primitive_type;
struct wined3d_shader_dst_param dst;
struct wined3d_shader_src_param src;
unsigned int count;

View file

@ -72,6 +72,7 @@ enum wined3d_primitive_type
WINED3D_PT_LINESTRIP_ADJ = 11,
WINED3D_PT_TRIANGLELIST_ADJ = 12,
WINED3D_PT_TRIANGLESTRIP_ADJ = 13,
WINED3D_PT_PATCH = 14,
};
enum wined3d_device_type