Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • wine/vkd3d
  • stefan/vkd3d
  • cmccarthy/vkd3d
  • giomasce/vkd3d
  • fcasas/vkd3d
  • jactry/vkd3d
  • ReDress/vkd3d
  • mstorsjo/vkd3d
  • huw/vkd3d
  • julliard/vkd3d
  • bshanks/vkd3d
  • zfigura/vkd3d
  • hverbeet/vkd3d
  • DarkShadow44/vkd3d
  • nsivov/vkd3d
  • dhary686/vkd3d
  • Mystral/vkd3d
  • maljaf/vkd3d
  • smcv/vkd3d
  • flibitijibibo/vkd3d
  • q4a/vkd3d
  • jsikorski/vkd3d
  • alesliehughes/vkd3d-alesliehughes
  • vitorhnn/vkd3d
  • agusev/vkd3d
  • etang-cw/vkd3d
  • petrathekat/vkd3d
  • simon.mr995/vkd3d
  • sgwaki/vkd3d
  • jacek/vkd3d
  • fweimer/vkd3d
  • Clara/vkd3d
  • disini/vkd3d
  • antenabr2/vkd3d
  • gilvbp/vkd3d
  • yshui/vkd3d
  • shaunren/vkd3d
  • jennetsaryyewa96/vkd3d
  • Jamesattay/vkd3d
  • zacemmneeto77/vkd3d
  • GermanAizek/vkd3d
  • opespinach/vkd3d
  • ruslanboyka201/vkd3d
  • navi/vkd3d
  • Feifan/vkd3d
  • yashmhmdly172/vkd3d
  • Sec32fun32/vkd3d
  • ritalat/vkd3d
  • ivyl/vkd3d
  • baikaishiuc/vkd3d
  • austin987/vkd3d
  • TornadoCookie/vkd3d
52 results
Show changes
...@@ -197,6 +197,7 @@ vkd3d_shader_tests = \ ...@@ -197,6 +197,7 @@ vkd3d_shader_tests = \
tests/hlsl/object-field-offsets.shader_test \ tests/hlsl/object-field-offsets.shader_test \
tests/hlsl/object-parameters.shader_test \ tests/hlsl/object-parameters.shader_test \
tests/hlsl/object-references.shader_test \ tests/hlsl/object-references.shader_test \
tests/hlsl/patch-syntax.shader_test \
tests/hlsl/point-sprite.shader_test \ tests/hlsl/point-sprite.shader_test \
tests/hlsl/pointer-cast.shader_test \ tests/hlsl/pointer-cast.shader_test \
tests/hlsl/pow.shader_test \ tests/hlsl/pow.shader_test \
......
...@@ -297,6 +297,12 @@ bool hlsl_type_is_shader(const struct hlsl_type *type) ...@@ -297,6 +297,12 @@ bool hlsl_type_is_shader(const struct hlsl_type *type)
return false; return false;
} }
bool hlsl_type_is_patch_array(const struct hlsl_type *type)
{
return type->class == HLSL_CLASS_ARRAY && (type->e.array.array_type == HLSL_ARRAY_PATCH_INPUT
|| type->e.array.array_type == HLSL_ARRAY_PATCH_OUTPUT);
}
/* Only intended to be used for derefs (after copies have been lowered to components or vectors) or /* Only intended to be used for derefs (after copies have been lowered to components or vectors) or
* resources, since for both their data types span across a single regset. */ * resources, since for both their data types span across a single regset. */
static enum hlsl_regset type_get_regset(const struct hlsl_type *type) static enum hlsl_regset type_get_regset(const struct hlsl_type *type)
...@@ -891,7 +897,8 @@ struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, co ...@@ -891,7 +897,8 @@ struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, co
} }
} }
struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size) struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type,
unsigned int array_size, enum hlsl_array_type array_type)
{ {
struct hlsl_type *type; struct hlsl_type *type;
...@@ -902,6 +909,7 @@ struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *ba ...@@ -902,6 +909,7 @@ struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *ba
type->modifiers = basic_type->modifiers; type->modifiers = basic_type->modifiers;
type->e.array.elements_count = array_size; type->e.array.elements_count = array_size;
type->e.array.type = basic_type; type->e.array.type = basic_type;
type->e.array.array_type = array_type;
type->sampler_dim = basic_type->sampler_dim; type->sampler_dim = basic_type->sampler_dim;
hlsl_type_calculate_reg_size(ctx, type); hlsl_type_calculate_reg_size(ctx, type);
...@@ -1172,6 +1180,7 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2 ...@@ -1172,6 +1180,7 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2
case HLSL_CLASS_ARRAY: case HLSL_CLASS_ARRAY:
return t1->e.array.elements_count == t2->e.array.elements_count return t1->e.array.elements_count == t2->e.array.elements_count
&& t1->e.array.array_type == t2->e.array.array_type
&& hlsl_types_are_equal(t1->e.array.type, t2->e.array.type); && hlsl_types_are_equal(t1->e.array.type, t2->e.array.type);
case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_TECHNIQUE:
...@@ -1251,6 +1260,7 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, ...@@ -1251,6 +1260,7 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
return NULL; return NULL;
} }
type->e.array.elements_count = old->e.array.elements_count; type->e.array.elements_count = old->e.array.elements_count;
type->e.array.array_type = old->e.array.array_type;
break; break;
case HLSL_CLASS_STRUCT: case HLSL_CLASS_STRUCT:
...@@ -2833,22 +2843,32 @@ static void hlsl_dump_type(struct vkd3d_string_buffer *buffer, const struct hlsl ...@@ -2833,22 +2843,32 @@ static void hlsl_dump_type(struct vkd3d_string_buffer *buffer, const struct hlsl
return; return;
case HLSL_CLASS_ARRAY: case HLSL_CLASS_ARRAY:
{ if (hlsl_type_is_patch_array(type))
const struct hlsl_type *t;
for (t = type; t->class == HLSL_CLASS_ARRAY; t = t->e.array.type)
;
hlsl_dump_type(buffer, t);
for (t = type; t->class == HLSL_CLASS_ARRAY; t = t->e.array.type)
{ {
if (t->e.array.elements_count == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) if (type->e.array.array_type == HLSL_ARRAY_PATCH_INPUT)
vkd3d_string_buffer_printf(buffer, "[]"); vkd3d_string_buffer_printf(buffer, "InputPatch<");
else else
vkd3d_string_buffer_printf(buffer, "[%u]", t->e.array.elements_count); vkd3d_string_buffer_printf(buffer, "OutputPatch<");
hlsl_dump_type(buffer, type->e.array.type);
vkd3d_string_buffer_printf(buffer, ", %u>", type->e.array.elements_count);
}
else
{
const struct hlsl_type *t;
for (t = type; t->class == HLSL_CLASS_ARRAY; t = t->e.array.type)
;
hlsl_dump_type(buffer, t);
for (t = type; t->class == HLSL_CLASS_ARRAY; t = t->e.array.type)
{
if (t->e.array.elements_count == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT)
vkd3d_string_buffer_printf(buffer, "[]");
else
vkd3d_string_buffer_printf(buffer, "[%u]", t->e.array.elements_count);
}
} }
return; return;
}
case HLSL_CLASS_STRUCT: case HLSL_CLASS_STRUCT:
vkd3d_string_buffer_printf(buffer, "<anonymous struct>"); vkd3d_string_buffer_printf(buffer, "<anonymous struct>");
...@@ -4561,6 +4581,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil ...@@ -4561,6 +4581,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
ctx->output_control_point_count = UINT_MAX; ctx->output_control_point_count = UINT_MAX;
ctx->output_primitive = 0; ctx->output_primitive = 0;
ctx->partitioning = 0; ctx->partitioning = 0;
ctx->input_control_point_count = UINT_MAX;
return true; return true;
} }
......
...@@ -145,6 +145,13 @@ enum hlsl_regset ...@@ -145,6 +145,13 @@ enum hlsl_regset
HLSL_REGSET_LAST = HLSL_REGSET_NUMERIC, HLSL_REGSET_LAST = HLSL_REGSET_NUMERIC,
}; };
enum hlsl_array_type
{
HLSL_ARRAY_GENERIC,
HLSL_ARRAY_PATCH_INPUT,
HLSL_ARRAY_PATCH_OUTPUT,
};
/* An HLSL source-level data type, including anonymous structs and typedefs. */ /* An HLSL source-level data type, including anonymous structs and typedefs. */
struct hlsl_type struct hlsl_type
{ {
...@@ -195,6 +202,7 @@ struct hlsl_type ...@@ -195,6 +202,7 @@ struct hlsl_type
struct hlsl_type *type; struct hlsl_type *type;
/* Array length, or HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT if it is not known yet at parse time. */ /* Array length, or HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT if it is not known yet at parse time. */
unsigned int elements_count; unsigned int elements_count;
enum hlsl_array_type array_type;
} array; } array;
/* Additional information if the class is HLSL_CLASS_TEXTURE or /* Additional information if the class is HLSL_CLASS_TEXTURE or
* HLSL_CLASS_UAV. */ * HLSL_CLASS_UAV. */
...@@ -1147,11 +1155,30 @@ struct hlsl_ctx ...@@ -1147,11 +1155,30 @@ struct hlsl_ctx
* compute shader profiles. It is set using the numthreads() attribute in the entry point. */ * compute shader profiles. It is set using the numthreads() attribute in the entry point. */
uint32_t thread_count[3]; uint32_t thread_count[3];
/* Declared information in tessellation shaders.
*
* The following fields are specific to hull shaders: output_control_point_count,
* output_control_point_type, output_primitive, partitioning, and patch_constant_func.
*
* The output_control_point_count and output_control_point_type fields correspond to the return
* type and the "outputcontrolpoints" attribute of a hull shader's control point function,
* respectively. Moreover, if an OutputPatch parameter is declared in the hull shader's patch
* constant function, its type and element count must match these fields.
*
* The input_control_point_count and input_control_point_type fields are specified by the
* InputPatch parameter in hull shaders, or by the _OutputPatch_ parameter in domain
* shaders.
*
* For input_ and output_control_point_count, the value UINT_MAX indicates that the value is
* unknown or not set by the shader. */
enum vkd3d_tessellator_domain domain; enum vkd3d_tessellator_domain domain;
unsigned int output_control_point_count; unsigned int output_control_point_count;
struct hlsl_type *output_control_point_type;
enum vkd3d_shader_tessellator_output_primitive output_primitive; enum vkd3d_shader_tessellator_output_primitive output_primitive;
enum vkd3d_shader_tessellator_partitioning partitioning; enum vkd3d_shader_tessellator_partitioning partitioning;
struct hlsl_ir_function_decl *patch_constant_func; struct hlsl_ir_function_decl *patch_constant_func;
unsigned int input_control_point_count;
struct hlsl_type *input_control_point_type;
/* In some cases we generate opcodes by parsing an HLSL function and then /* In some cases we generate opcodes by parsing an HLSL function and then
* invoking it. If not NULL, this field is the name of the function that we * invoking it. If not NULL, this field is the name of the function that we
...@@ -1527,7 +1554,8 @@ struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, co ...@@ -1527,7 +1554,8 @@ struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, co
const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type); const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type);
struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size); struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type,
unsigned int array_size, enum hlsl_array_type array_type);
struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1,
struct hlsl_ir_node *arg2); struct hlsl_ir_node *arg2);
struct hlsl_ir_node *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const struct vkd3d_shader_location *loc);
...@@ -1659,6 +1687,7 @@ unsigned int hlsl_type_major_size(const struct hlsl_type *type); ...@@ -1659,6 +1687,7 @@ unsigned int hlsl_type_major_size(const struct hlsl_type *type);
unsigned int hlsl_type_element_count(const struct hlsl_type *type); unsigned int hlsl_type_element_count(const struct hlsl_type *type);
bool hlsl_type_is_resource(const struct hlsl_type *type); bool hlsl_type_is_resource(const struct hlsl_type *type);
bool hlsl_type_is_shader(const struct hlsl_type *type); bool hlsl_type_is_shader(const struct hlsl_type *type);
bool hlsl_type_is_patch_array(const struct hlsl_type *type);
unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset); unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset);
bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2); bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2);
......
...@@ -104,6 +104,7 @@ if {return KW_IF; } ...@@ -104,6 +104,7 @@ if {return KW_IF; }
in {return KW_IN; } in {return KW_IN; }
inline {return KW_INLINE; } inline {return KW_INLINE; }
inout {return KW_INOUT; } inout {return KW_INOUT; }
InputPatch {return KW_INPUTPATCH; }
LineStream {return KW_LINESTREAM; } LineStream {return KW_LINESTREAM; }
linear {return KW_LINEAR; } linear {return KW_LINEAR; }
matrix {return KW_MATRIX; } matrix {return KW_MATRIX; }
...@@ -112,6 +113,7 @@ nointerpolation {return KW_NOINTERPOLATION; } ...@@ -112,6 +113,7 @@ nointerpolation {return KW_NOINTERPOLATION; }
noperspective {return KW_NOPERSPECTIVE; } noperspective {return KW_NOPERSPECTIVE; }
NULL {return KW_NULL; } NULL {return KW_NULL; }
out {return KW_OUT; } out {return KW_OUT; }
OutputPatch {return KW_OUTPUTPATCH; }
packoffset {return KW_PACKOFFSET; } packoffset {return KW_PACKOFFSET; }
pass {return KW_PASS; } pass {return KW_PASS; }
PixelShader {return KW_PIXELSHADER; } PixelShader {return KW_PIXELSHADER; }
......
...@@ -415,7 +415,7 @@ static bool add_explicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *blo ...@@ -415,7 +415,7 @@ static bool add_explicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *blo
dst_type = ctx->builtin_types.error; dst_type = ctx->builtin_types.error;
break; break;
} }
dst_type = hlsl_new_array_type(ctx, dst_type, arrays->sizes[i]); dst_type = hlsl_new_array_type(ctx, dst_type, arrays->sizes[i], HLSL_ARRAY_GENERIC);
} }
if (instr->data_type->class == HLSL_CLASS_ERROR) if (instr->data_type->class == HLSL_CLASS_ERROR)
...@@ -1118,7 +1118,7 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, ...@@ -1118,7 +1118,7 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields,
break; break;
} }
field->type = hlsl_new_array_type(ctx, field->type, v->arrays.sizes[k]); field->type = hlsl_new_array_type(ctx, field->type, v->arrays.sizes[k], HLSL_ARRAY_GENERIC);
} }
} }
...@@ -1214,7 +1214,7 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type, ...@@ -1214,7 +1214,7 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type,
break; break;
} }
if (!(type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i]))) if (!(type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i], HLSL_ARRAY_GENERIC)))
{ {
free_parse_variable_def(v); free_parse_variable_def(v);
ret = false; ret = false;
...@@ -2669,7 +2669,7 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) ...@@ -2669,7 +2669,7 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
v->arrays.sizes[i] = size / elem_components; v->arrays.sizes[i] = size / elem_components;
} }
} }
type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i]); type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i], HLSL_ARRAY_GENERIC);
} }
} }
...@@ -2717,6 +2717,12 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) ...@@ -2717,6 +2717,12 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"packoffset() is only allowed inside constant buffer declarations."); "packoffset() is only allowed inside constant buffer declarations.");
} }
else
{
if ((type->modifiers & HLSL_MODIFIER_CONST) && !v->initializer.args_count)
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INITIALIZER,
"Const variable \"%s\" is missing an initializer.", var->name);
}
if (ctx->cur_scope == ctx->globals) if (ctx->cur_scope == ctx->globals)
{ {
...@@ -7001,6 +7007,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, ...@@ -7001,6 +7007,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
enum hlsl_buffer_type buffer_type; enum hlsl_buffer_type buffer_type;
enum hlsl_sampler_dim sampler_dim; enum hlsl_sampler_dim sampler_dim;
enum hlsl_so_object_type so_type; enum hlsl_so_object_type so_type;
enum hlsl_array_type patch_type;
struct hlsl_attribute *attr; struct hlsl_attribute *attr;
struct parse_attribute_list attr_list; struct parse_attribute_list attr_list;
struct hlsl_ir_switch_case *switch_case; struct hlsl_ir_switch_case *switch_case;
...@@ -7043,6 +7050,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, ...@@ -7043,6 +7050,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
%token KW_IN %token KW_IN
%token KW_INLINE %token KW_INLINE
%token KW_INOUT %token KW_INOUT
%token KW_INPUTPATCH
%token KW_LINEAR %token KW_LINEAR
%token KW_LINESTREAM %token KW_LINESTREAM
%token KW_MATRIX %token KW_MATRIX
...@@ -7051,6 +7059,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, ...@@ -7051,6 +7059,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
%token KW_NOPERSPECTIVE %token KW_NOPERSPECTIVE
%token KW_NULL %token KW_NULL
%token KW_OUT %token KW_OUT
%token KW_OUTPUTPATCH
%token KW_PACKOFFSET %token KW_PACKOFFSET
%token KW_PASS %token KW_PASS
%token KW_PIXELSHADER %token KW_PIXELSHADER
...@@ -7232,6 +7241,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, ...@@ -7232,6 +7241,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
%type <reg_reservation> packoffset_reservation %type <reg_reservation> packoffset_reservation
%type <sampler_dim> texture_type texture_ms_type uav_type rov_type %type <sampler_dim> texture_type texture_ms_type uav_type rov_type
%type <patch_type> patch_type
%type <semantic> semantic %type <semantic> semantic
...@@ -8141,7 +8151,7 @@ parameter_decl: ...@@ -8141,7 +8151,7 @@ parameter_decl:
break; break;
} }
type = hlsl_new_array_type(ctx, type, $4.sizes[i]); type = hlsl_new_array_type(ctx, type, $4.sizes[i], HLSL_ARRAY_GENERIC);
} }
vkd3d_free($4.sizes); vkd3d_free($4.sizes);
...@@ -8284,6 +8294,16 @@ resource_format: ...@@ -8284,6 +8294,16 @@ resource_format:
YYABORT; YYABORT;
} }
patch_type:
KW_INPUTPATCH
{
$$ = HLSL_ARRAY_PATCH_INPUT;
}
| KW_OUTPUTPATCH
{
$$ = HLSL_ARRAY_PATCH_OUTPUT;
}
type_no_void: type_no_void:
KW_VECTOR '<' type ',' C_INTEGER '>' KW_VECTOR '<' type ',' C_INTEGER '>'
{ {
...@@ -8422,6 +8442,20 @@ type_no_void: ...@@ -8422,6 +8442,20 @@ type_no_void:
{ {
$$ = hlsl_new_stream_output_type(ctx, $1, $3); $$ = hlsl_new_stream_output_type(ctx, $1, $3);
} }
| patch_type '<' type ',' C_INTEGER '>'
{
struct hlsl_type *type;
if ($5 < 1)
{
hlsl_error(ctx, &@5, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE,
"Control point size %d is not positive.", $5);
YYABORT;
}
type = hlsl_new_array_type(ctx, $3, $5, $1);
$$ = hlsl_type_clone(ctx, type, 0, HLSL_MODIFIER_CONST);
}
| KW_RWBYTEADDRESSBUFFER | KW_RWBYTEADDRESSBUFFER
{ {
$$ = hlsl_new_uav_type(ctx, HLSL_SAMPLER_DIM_RAW_BUFFER, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), false); $$ = hlsl_new_uav_type(ctx, HLSL_SAMPLER_DIM_RAW_BUFFER, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), false);
......
...@@ -2968,7 +2968,7 @@ static struct hlsl_type *clone_texture_array_as_combined_sampler_array(struct hl ...@@ -2968,7 +2968,7 @@ static struct hlsl_type *clone_texture_array_as_combined_sampler_array(struct hl
if (!(sampler_type = clone_texture_array_as_combined_sampler_array(ctx, type->e.array.type))) if (!(sampler_type = clone_texture_array_as_combined_sampler_array(ctx, type->e.array.type)))
return NULL; return NULL;
return hlsl_new_array_type(ctx, sampler_type, type->e.array.elements_count); return hlsl_new_array_type(ctx, sampler_type, type->e.array.elements_count, HLSL_ARRAY_GENERIC);
} }
return ctx->builtin_types.sampler[type->sampler_dim]; return ctx->builtin_types.sampler[type->sampler_dim];
...@@ -3132,7 +3132,8 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in ...@@ -3132,7 +3132,8 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
for (i = 0; i < load->resource.path_len; ++i) for (i = 0; i < load->resource.path_len; ++i)
{ {
VKD3D_ASSERT(arr_type->class == HLSL_CLASS_ARRAY); VKD3D_ASSERT(arr_type->class == HLSL_CLASS_ARRAY);
texture_array_type = hlsl_new_array_type(ctx, texture_array_type, arr_type->e.array.elements_count); texture_array_type = hlsl_new_array_type(ctx, texture_array_type,
arr_type->e.array.elements_count, HLSL_ARRAY_GENERIC);
arr_type = arr_type->e.array.type; arr_type = arr_type->e.array.type;
} }
...@@ -6809,6 +6810,77 @@ static void validate_hull_shader_attributes(struct hlsl_ctx *ctx, const struct h ...@@ -6809,6 +6810,77 @@ static void validate_hull_shader_attributes(struct hlsl_ctx *ctx, const struct h
} }
} }
static void validate_and_record_patch_type(struct hlsl_ctx *ctx, bool is_patch_constant_func, struct hlsl_ir_var *var)
{
unsigned int control_point_count = var->data_type->e.array.elements_count;
enum hlsl_array_type array_type = var->data_type->e.array.array_type;
struct hlsl_type *control_point_type = var->data_type->e.array.type;
const struct hlsl_profile_info *profile = ctx->profile;
if (array_type == HLSL_ARRAY_PATCH_INPUT)
{
if (profile->type != VKD3D_SHADER_TYPE_HULL
&& !(profile->type == VKD3D_SHADER_TYPE_GEOMETRY && hlsl_version_ge(ctx, 5, 0)))
{
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
"InputPatch parameters can only be used in hull shaders, "
"and geometry shaders with shader model 5.0 or higher.");
return;
}
}
else
{
if (!is_patch_constant_func && profile->type != VKD3D_SHADER_TYPE_DOMAIN)
{
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
"OutputPatch parameters can only be used in "
"hull shader patch constant functions and domain shaders.");
return;
}
}
if (control_point_count > 32)
{
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT,
"Control point count %u exceeds 32.", control_point_count);
return;
}
VKD3D_ASSERT(control_point_count > 0);
if (is_patch_constant_func && array_type == HLSL_ARRAY_PATCH_OUTPUT)
{
if (control_point_count != ctx->output_control_point_count)
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT,
"Output control point count %u does not match the count %u specified in the control point function.",
control_point_count, ctx->output_control_point_count);
if (!hlsl_types_are_equal(control_point_type, ctx->output_control_point_type))
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
"Output control point type does not match the output type of the control point function.");
return;
}
if (ctx->input_control_point_count != UINT_MAX)
{
VKD3D_ASSERT(is_patch_constant_func);
if (control_point_count != ctx->input_control_point_count)
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT,
"Input control point count %u does not match the count %u specified in the control point function.",
control_point_count, ctx->input_control_point_count);
if (!hlsl_types_are_equal(control_point_type, ctx->input_control_point_type))
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
"Input control point type does not match the input type specified in the control point function.");
return;
}
ctx->input_control_point_count = control_point_count;
ctx->input_control_point_type = control_point_type;
}
static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *body) static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *body)
{ {
struct hlsl_ir_node *instr, *next; struct hlsl_ir_node *instr, *next;
...@@ -10916,7 +10988,8 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl ...@@ -10916,7 +10988,8 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
} }
else if (version.type == VKD3D_SHADER_TYPE_HULL) else if (version.type == VKD3D_SHADER_TYPE_HULL)
{ {
program->input_control_point_count = 1; /* TODO: Obtain from InputPatch */ program->input_control_point_count = ctx->input_control_point_count == UINT_MAX
? 1 : ctx->input_control_point_count;
program->output_control_point_count = ctx->output_control_point_count; program->output_control_point_count = ctx->output_control_point_count;
program->tess_domain = ctx->domain; program->tess_domain = ctx->domain;
program->tess_partitioning = ctx->partitioning; program->tess_partitioning = ctx->partitioning;
...@@ -10924,7 +10997,8 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl ...@@ -10924,7 +10997,8 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
} }
else if (version.type == VKD3D_SHADER_TYPE_DOMAIN) else if (version.type == VKD3D_SHADER_TYPE_DOMAIN)
{ {
program->input_control_point_count = 0; /* TODO: Obtain from OutputPatch */ program->input_control_point_count = ctx->input_control_point_count == UINT_MAX
? 0 : ctx->input_control_point_count;
program->tess_domain = ctx->domain; program->tess_domain = ctx->domain;
} }
...@@ -12133,6 +12207,8 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct ...@@ -12133,6 +12207,8 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct
static void process_entry_function(struct hlsl_ctx *ctx, static void process_entry_function(struct hlsl_ctx *ctx,
const struct hlsl_block *global_uniform_block, struct hlsl_ir_function_decl *entry_func) const struct hlsl_block *global_uniform_block, struct hlsl_ir_function_decl *entry_func)
{ {
bool is_patch_constant_func = entry_func == ctx->patch_constant_func;
const struct hlsl_ir_var *input_patch = NULL, *output_patch = NULL;
const struct hlsl_profile_info *profile = ctx->profile; const struct hlsl_profile_info *profile = ctx->profile;
struct hlsl_block static_initializers, global_uniforms; struct hlsl_block static_initializers, global_uniforms;
struct hlsl_block *const body = &entry_func->body; struct hlsl_block *const body = &entry_func->body;
...@@ -12183,12 +12259,42 @@ static void process_entry_function(struct hlsl_ctx *ctx, ...@@ -12183,12 +12259,42 @@ static void process_entry_function(struct hlsl_ctx *ctx,
} }
else if ((var->storage_modifiers & HLSL_STORAGE_UNIFORM)) else if ((var->storage_modifiers & HLSL_STORAGE_UNIFORM))
{ {
if (ctx->profile->type == VKD3D_SHADER_TYPE_HULL && entry_func == ctx->patch_constant_func) if (ctx->profile->type == VKD3D_SHADER_TYPE_HULL && is_patch_constant_func)
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
"Patch constant function parameter \"%s\" cannot be uniform.", var->name); "Patch constant function parameter \"%s\" cannot be uniform.", var->name);
else else
prepend_uniform_copy(ctx, body, var); prepend_uniform_copy(ctx, body, var);
} }
else if (hlsl_type_is_patch_array(var->data_type))
{
if (var->data_type->e.array.array_type == HLSL_ARRAY_PATCH_INPUT)
{
if (input_patch)
{
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_DUPLICATE_PATCH,
"Found multiple InputPatch parameters.");
hlsl_note(ctx, &input_patch->loc, VKD3D_SHADER_LOG_ERROR,
"The InputPatch parameter was previously declared here.");
continue;
}
input_patch = var;
}
else
{
if (output_patch)
{
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_DUPLICATE_PATCH,
"Found multiple OutputPatch parameters.");
hlsl_note(ctx, &output_patch->loc, VKD3D_SHADER_LOG_ERROR,
"The OutputPatch parameter was previously declared here.");
continue;
}
output_patch = var;
}
validate_and_record_patch_type(ctx, is_patch_constant_func, var);
hlsl_fixme(ctx, &var->loc, "InputPatch/OutputPatch parameters.");
}
else else
{ {
if (hlsl_get_multiarray_element_type(var->data_type)->class != HLSL_CLASS_STRUCT if (hlsl_get_multiarray_element_type(var->data_type)->class != HLSL_CLASS_STRUCT
...@@ -12202,7 +12308,13 @@ static void process_entry_function(struct hlsl_ctx *ctx, ...@@ -12202,7 +12308,13 @@ static void process_entry_function(struct hlsl_ctx *ctx,
if (var->storage_modifiers & HLSL_STORAGE_IN) if (var->storage_modifiers & HLSL_STORAGE_IN)
prepend_input_var_copy(ctx, entry_func, var); prepend_input_var_copy(ctx, entry_func, var);
if (var->storage_modifiers & HLSL_STORAGE_OUT) if (var->storage_modifiers & HLSL_STORAGE_OUT)
append_output_var_copy(ctx, entry_func, var); {
if (profile->type == VKD3D_SHADER_TYPE_HULL && !is_patch_constant_func)
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
"Output parameters are not supported in hull shader control point functions.");
else
append_output_var_copy(ctx, entry_func, var);
}
} }
} }
if (entry_func->return_var) if (entry_func->return_var)
...@@ -12212,6 +12324,14 @@ static void process_entry_function(struct hlsl_ctx *ctx, ...@@ -12212,6 +12324,14 @@ static void process_entry_function(struct hlsl_ctx *ctx,
"Entry point \"%s\" is missing a return value semantic.", entry_func->func->name); "Entry point \"%s\" is missing a return value semantic.", entry_func->func->name);
append_output_var_copy(ctx, entry_func, entry_func->return_var); append_output_var_copy(ctx, entry_func, entry_func->return_var);
if (profile->type == VKD3D_SHADER_TYPE_HULL && !is_patch_constant_func)
ctx->output_control_point_type = entry_func->return_var->data_type;
}
else
{
if (profile->type == VKD3D_SHADER_TYPE_HULL && !is_patch_constant_func)
hlsl_fixme(ctx, &entry_func->loc, "Passthrough hull shader control point function.");
} }
if (hlsl_version_ge(ctx, 4, 0)) if (hlsl_version_ge(ctx, 4, 0))
......
...@@ -166,6 +166,7 @@ enum vkd3d_shader_error ...@@ -166,6 +166,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_HLSL_INVALID_PARTITIONING = 5038, VKD3D_SHADER_ERROR_HLSL_INVALID_PARTITIONING = 5038,
VKD3D_SHADER_ERROR_HLSL_MISPLACED_SAMPLER_STATE = 5039, VKD3D_SHADER_ERROR_HLSL_MISPLACED_SAMPLER_STATE = 5039,
VKD3D_SHADER_ERROR_HLSL_AMBIGUOUS_CALL = 5040, VKD3D_SHADER_ERROR_HLSL_AMBIGUOUS_CALL = 5040,
VKD3D_SHADER_ERROR_HLSL_DUPLICATE_PATCH = 5041,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300,
VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301, VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301,
......
...@@ -163,3 +163,30 @@ float4 main(uniform float4 b) : POSITION ...@@ -163,3 +163,30 @@ float4 main(uniform float4 b) : POSITION
{ {
return a + b + tex[uint2(0, 0)]; return a + b + tex[uint2(0, 0)];
} }
% Output parameters are not supported in control point functions for SM < 6.
[hull shader fail(sm<6)]
struct data
{
float4 val : VAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
patch_constant_data patch_constant()
{
return (patch_constant_data)0;
}
[domain("isoline")]
[outputcontrolpoints(3)]
[partitioning("integer")]
[outputtopology("point")]
[patchconstantfunc("patch_constant")]
void main(out data ret, InputPatch<data, 3> input)
{
ret.val = 0;
}
...@@ -275,3 +275,22 @@ float4 main() : sv_target ...@@ -275,3 +275,22 @@ float4 main() : sv_target
[pixel shader fail] [pixel shader fail]
float4 main() : sv_target; float4 main() : sv_target;
[pixel shader fail(sm<6)]
float4 main(void) : sv_target
{
const float a;
return 0;
}
[pixel shader fail(sm<6)]
struct s
{
float4 f;
};
float4 main(void) : sv_target
{
const struct s a;
return 0;
}
% Patch objects are equivalent to const arrays if not used as inputs/outputs to tessellation shaders.
[pixel shader]
InputPatch<float, 2> patch;
float4 main() : SV_TARGET
{
return patch[0];
}
[test]
uniform 0 float 1
uniform 1 float 2
draw quad
probe (0, 0) rgba(1.0, 1.0, 1.0, 1.0)
[pixel shader]
OutputPatch<float, 2> patch;
float4 main() : SV_TARGET
{
return patch[0];
}
[test]
uniform 0 float 1
uniform 1 float 2
draw quad
probe (0, 0) rgba(1.0, 1.0, 1.0, 1.0)
% Assigning a patch with an array is not allowed in SM6.
[pixel shader fail(sm>=6)]
float data[2];
float4 main() : SV_TARGET
{
InputPatch<float, 2> patch = data;
return patch[0];
}
[test]
uniform 0 float 1
uniform 1 float 2
draw quad
probe (0, 0) rgba(1.0, 1.0, 1.0, 1.0)
[pixel shader fail]
float data[2];
float4 main() : SV_TARGET
{
InputPatch<float, 2> patch = data;
patch[0] = 3;
return patch[0];
}
[pixel shader fail(sm<6)]
float4 main() : SV_TARGET
{
InputPatch<float, 2> patch; // Missing initializer.
return 0;
}
[pixel shader fail(sm<6)]
InputPatch<float, 0> patch; // Element count must be non-zero.
float4 main() : SV_TARGET
{
return 0;
}
[pixel shader fail(sm>=6)]
float data[2];
float4 main() : SV_TARGET
{
OutputPatch<float, 2> patch = data;
return patch[0];
}
[test]
uniform 0 float 1
uniform 1 float 2
draw quad
probe (0, 0) rgba(1.0, 1.0, 1.0, 1.0)
[pixel shader fail]
float data[2];
float4 main() : SV_TARGET
{
OutputPatch<float, 2> patch = data;
patch[0] = 3;
return patch[0];
}
[pixel shader fail(sm<6)]
float4 main() : SV_TARGET
{
OutputPatch<float, 2> patch; // Missing initializer.
return 0;
}
[pixel shader fail(sm<6)]
OutputPatch<float, 0> patch; // Element count must be non-zero.
float4 main() : SV_TARGET
{
return 0;
}
% InputPatch parameters can only be used in hull and geometry shaders (SM>=5).
[pixel shader fail]
struct data
{
float4 val : VAL;
};
float4 main(InputPatch<data, 2> patch) : SV_TARGET
{
return 0;
}
[hull shader todo]
struct data
{
float4 val : VAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
patch_constant_data patch_constant()
{
return (patch_constant_data)0;
}
[domain("isoline")]
[outputcontrolpoints(2)]
[partitioning("integer")]
[outputtopology("point")]
[patchconstantfunc("patch_constant")]
float4 main(InputPatch<data, 2> patch) : POSITION
{
return 0;
}
[hull shader todo]
struct data
{
float4 val : VAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
patch_constant_data patch_constant(InputPatch<data, 2> patch)
{
return (patch_constant_data)0;
}
[domain("isoline")]
[outputcontrolpoints(2)]
[partitioning("integer")]
[outputtopology("point")]
[patchconstantfunc("patch_constant")]
float4 main(InputPatch<data, 2> patch) : POSITION
{
return 0;
}
[domain shader fail(sm<6)]
struct data
{
float4 val : VAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
[domain("isoline")]
float4 main(patch_constant_data input, InputPatch<data, 2> patch) : POSITION
{
return 0;
}
[geometry shader fail(sm<5) todo(sm>=5)]
struct data
{
float4 val : VAL;
};
[maxvertexcount(1)]
void main(InputPatch<data, 2> patch, inout PointStream<data> vout)
{
vout.Append(patch[0]);
}
% OutputPatch parameters can only be used in hull shader patch constant functions and domain shaders.
[pixel shader fail]
struct data
{
float val : VAL;
};
float4 main(OutputPatch<data, 2> patch) : SV_TARGET
{
return 0;
}
[hull shader fail]
struct data
{
float4 val : VAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
patch_constant_data patch_constant()
{
return (patch_constant_data)0;
}
[domain("isoline")]
[outputcontrolpoints(2)]
[partitioning("integer")]
[outputtopology("point")]
[patchconstantfunc("patch_constant")]
float4 main(OutputPatch<data, 2> patch) : POSITION
{
return patch[0].val;
}
[hull shader todo]
struct data
{
float4 val : VAL;
};
struct out_data
{
float outval : OUTVAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
patch_constant_data patch_constant(OutputPatch<out_data, 2> patch)
{
return (patch_constant_data)0;
}
[domain("isoline")]
[outputcontrolpoints(2)]
[partitioning("integer")]
[outputtopology("point")]
[patchconstantfunc("patch_constant")]
out_data main()
{
return (out_data)0;
}
[domain shader todo]
struct data
{
float4 val : VAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
[domain("isoline")]
float4 main(patch_constant_data input, OutputPatch<data, 2> patch) : POSITION
{
return 0;
}
[geometry shader fail]
struct data
{
float4 val : VAL;
};
[maxvertexcount(1)]
void main(OutputPatch<data, 2> patch, inout PointStream<data> vout)
{
vout.Append(patch[0]);
}
% Patch parameters can't have more than 32 control points.
[hull shader todo]
struct data
{
float4 val : VAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
patch_constant_data patch_constant()
{
return (patch_constant_data)0;
}
[domain("isoline")]
[outputcontrolpoints(2)]
[partitioning("integer")]
[outputtopology("point")]
[patchconstantfunc("patch_constant")]
float4 main(InputPatch<data, 32> patch) : POSITION
{
return 0;
}
[hull shader fail]
struct data
{
float4 val : VAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
patch_constant_data patch_constant()
{
return (patch_constant_data)0;
}
[domain("isoline")]
[outputcontrolpoints(2)]
[partitioning("integer")]
[outputtopology("point")]
[patchconstantfunc("patch_constant")]
float4 main(InputPatch<data, 33> patch) : POSITION
{
return 0;
}
[domain shader todo]
struct data
{
float4 val : VAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
[domain("isoline")]
float4 main(patch_constant_data input, OutputPatch<data, 32> patch) : POSITION
{
return 0;
}
[domain shader fail]
struct data
{
float4 val : VAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
[domain("isoline")]
float4 main(patch_constant_data input, OutputPatch<data, 33> patch) : POSITION
{
return 0;
}
% However, patch objects used in non tessellation shaders can have more than 32 elements.
[pixel shader]
InputPatch<float, 64> patch;
float4 main() : SV_TARGET
{
return patch[0];
}
% Multiple patch parameters are not allowed.
[hull shader fail]
struct data
{
float4 val : VAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
patch_constant_data patch_constant()
{
return (patch_constant_data)0;
}
[domain("isoline")]
[outputcontrolpoints(2)]
[partitioning("integer")]
[outputtopology("point")]
[patchconstantfunc("patch_constant")]
float4 main(InputPatch<data, 2> patch, uint i : SV_OutputControlPointID, InputPatch<data, 2> patch2) : POSITION
{
return 0;
}
[domain shader fail]
struct data
{
float4 val : VAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
[domain("isoline")]
float4 main(OutputPatch<data, 2> patch, patch_constant_data input, OutputPatch<data, 2> patch2) : POSITION
{
return 0;
}
% InputPatch types must match between the main function and the patch constant function of a hull shader.
[hull shader fail todo]
struct data
{
float4 val : VAL;
};
struct data2
{
float4 apple : APPLE;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
patch_constant_data patch_constant(InputPatch<data2, 2> patch)
{
return (patch_constant_data)0;
}
[domain("isoline")]
[outputcontrolpoints(2)]
[partitioning("integer")]
[outputtopology("point")]
[patchconstantfunc("patch_constant")]
float4 main(InputPatch<data, 2> patch) : POSITION
{
return 0;
}
[hull shader fail todo]
struct data
{
float4 val : VAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
patch_constant_data patch_constant(InputPatch<data, 3> patch)
{
return (patch_constant_data)0;
}
[domain("isoline")]
[outputcontrolpoints(2)]
[partitioning("integer")]
[outputtopology("point")]
[patchconstantfunc("patch_constant")]
float4 main(InputPatch<data, 2> patch) : POSITION
{
return 0;
}
% The type of a OutputPatch parameters in a hull shader patch constant function must match
% the output type of the shader's main function.
[hull shader fail]
struct data
{
float4 val : VAL;
};
struct out_data
{
float outval : OUTVAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
patch_constant_data patch_constant(OutputPatch<data, 2> patch)
{
return (patch_constant_data)0;
}
[domain("isoline")]
[outputcontrolpoints(2)]
[partitioning("integer")]
[outputtopology("point")]
[patchconstantfunc("patch_constant")]
out_data main()
{
return (out_data)0;
}
[hull shader fail]
struct out_data
{
float outval : OUTVAL;
};
struct patch_constant_data
{
float edges[2] : SV_TessFactor;
};
patch_constant_data patch_constant(OutputPatch<out_data, 3> patch)
{
return (patch_constant_data)0;
}
[domain("isoline")]
[outputcontrolpoints(2)]
[partitioning("integer")]
[outputtopology("point")]
[patchconstantfunc("patch_constant")]
out_data main()
{
return (out_data)0;
}
...@@ -96,3 +96,38 @@ float4 main(data input) : sv_target ...@@ -96,3 +96,38 @@ float4 main(data input) : sv_target
[test] [test]
todo(sm<6) draw 3 control point patch list 3 todo(sm<6) draw 3 control point patch list 3
todo(mvk) probe (0, 0, 640, 480) rgba(0.0, 1.0, 0.0, 1.0) todo(mvk) probe (0, 0, 640, 480) rgba(0.0, 1.0, 0.0, 1.0)
% Passthrough hull shader control point function.
[hull shader todo]
struct data
{
float4 position : SV_Position;
float r : RED;
float g : GREEN;
float b : BLUE;
};
struct patch_constant_data
{
float edges[3] : SV_TessFactor;
float inside : SV_InsideTessFactor;
};
void patch_constant(InputPatch<data, 3> input, out patch_constant_data output)
{
output.edges[0] = output.edges[1] = output.edges[2] = 1.0f;
output.inside = 1.0f;
}
[domain("tri")]
[outputcontrolpoints(3)]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[patchconstantfunc("patch_constant")]
void main(InputPatch<data, 3> input)
{
}
[test]
todo(sm<6) draw 3 control point patch list 3
todo(mvk) probe (0, 0, 640, 480) rgba(0.0, 1.0, 0.0, 1.0)