[PATCH 5/5] wined3d: Recognize SM5+ patch input primitive types.
Józef Kucia
jkucia at codeweavers.com
Mon May 15 05:05:47 CDT 2017
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 at codeweavers.com>
---
dlls/wined3d/device.c | 6 ++++
dlls/wined3d/shader.c | 15 ++++++----
dlls/wined3d/shader_sm4.c | 67 ++++++++++++++++++++++++++++++++++--------
dlls/wined3d/utils.c | 3 +-
dlls/wined3d/wined3d_private.h | 8 ++++-
include/wine/wined3d.h | 1 +
6 files changed, 79 insertions(+), 21 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 61be30e..26a1911 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -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:
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 5717767..8fb6d0f 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -1047,7 +1047,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);
@@ -1055,7 +1055,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);
@@ -2394,9 +2394,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");
@@ -2431,8 +2431,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;
}
}
@@ -2630,7 +2633,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)
{
diff --git a/dlls/wined3d/shader_sm4.c b/dlls/wined3d/shader_sm4.c
index 3c975f3f..0c2ab52 100644
--- a/dlls/wined3d/shader_sm4.c
+++ b/dlls/wined3d/shader_sm4.c
@@ -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)
@@ -341,11 +341,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
@@ -593,11 +625,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);
}
@@ -608,12 +640,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);
}
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index fb4a849..78ada57 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -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";
}
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 38e5a45..308b709 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1147,6 +1147,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;
@@ -1163,7 +1169,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;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index d58c4b4..7ab0c68 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -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
--
2.10.2
More information about the wine-patches
mailing list