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
Commits on Source (13)
......@@ -80,7 +80,7 @@ vkd3d_shader_tests = \
tests/hlsl/ceil.shader_test \
tests/hlsl/cf-cond-types.shader_test \
tests/hlsl/clamp.shader_test \
tests/hlsl/clip-distance.shader_test \
tests/hlsl/clip-cull-distance.shader_test \
tests/hlsl/clip-planes.shader_test \
tests/hlsl/clip.shader_test \
tests/hlsl/combined-samplers.shader_test \
......
......@@ -1688,9 +1688,6 @@ struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned
void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count);
void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rdef);
enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type,
unsigned int storage_modifiers);
struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ctx, const char *name, const char *hlsl);
int hlsl_lexer_compile(struct hlsl_ctx *ctx, const struct vkd3d_shader_code *hlsl);
......
......@@ -5489,7 +5489,8 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun
return allocator.reg_count;
}
enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, unsigned int storage_modifiers)
static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type,
unsigned int storage_modifiers)
{
unsigned int i;
......@@ -10083,6 +10084,207 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx,
generate_vsir_add_program_instruction(ctx, program, &func->loc, VKD3DSIH_RET, 0, 0);
}
static int sm4_compare_extern_resources(const void *a, const void *b)
{
const struct extern_resource *aa = a;
const struct extern_resource *bb = b;
int r;
if ((r = vkd3d_u32_compare(aa->regset, bb->regset)))
return r;
if ((r = vkd3d_u32_compare(aa->space, bb->space)))
return r;
return vkd3d_u32_compare(aa->index, bb->index);
}
static const char *string_skip_tag(const char *string)
{
if (!strncmp(string, "<resource>", strlen("<resource>")))
return string + strlen("<resource>");
return string;
}
void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count)
{
unsigned int i;
for (i = 0; i < count; ++i)
{
vkd3d_free(extern_resources[i].name);
}
vkd3d_free(extern_resources);
}
struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count)
{
bool separate_components = ctx->profile->major_version == 5 && ctx->profile->minor_version == 0;
struct extern_resource *extern_resources = NULL;
const struct hlsl_ir_var *var;
struct hlsl_buffer *buffer;
enum hlsl_regset regset;
size_t capacity = 0;
char *name;
*count = 0;
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
if (separate_components)
{
unsigned int component_count = hlsl_type_component_count(var->data_type);
unsigned int k, regset_offset;
for (k = 0; k < component_count; ++k)
{
struct hlsl_type *component_type = hlsl_type_get_component_type(ctx, var->data_type, k);
struct vkd3d_string_buffer *name_buffer;
if (!hlsl_type_is_resource(component_type))
continue;
regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, &regset);
if (regset_offset > var->regs[regset].allocation_size)
continue;
if (!var->objects_usage[regset][regset_offset].used)
continue;
if (!(hlsl_array_reserve(ctx, (void **)&extern_resources,
&capacity, *count + 1, sizeof(*extern_resources))))
{
sm4_free_extern_resources(extern_resources, *count);
*count = 0;
return NULL;
}
if (!(name_buffer = hlsl_component_to_string(ctx, var, k)))
{
sm4_free_extern_resources(extern_resources, *count);
*count = 0;
return NULL;
}
if (!(name = hlsl_strdup(ctx, string_skip_tag(name_buffer->buffer))))
{
sm4_free_extern_resources(extern_resources, *count);
*count = 0;
hlsl_release_string_buffer(ctx, name_buffer);
return NULL;
}
hlsl_release_string_buffer(ctx, name_buffer);
extern_resources[*count].var = NULL;
extern_resources[*count].buffer = NULL;
extern_resources[*count].name = name;
extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type;
extern_resources[*count].component_type = component_type;
extern_resources[*count].regset = regset;
extern_resources[*count].id = var->regs[regset].id;
extern_resources[*count].space = var->regs[regset].space;
extern_resources[*count].index = var->regs[regset].index + regset_offset;
extern_resources[*count].bind_count = 1;
extern_resources[*count].loc = var->loc;
++*count;
}
}
else
{
unsigned int r;
if (!hlsl_type_is_resource(var->data_type))
continue;
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
{
if (!var->regs[r].allocated)
continue;
if (!(hlsl_array_reserve(ctx, (void **)&extern_resources,
&capacity, *count + 1, sizeof(*extern_resources))))
{
sm4_free_extern_resources(extern_resources, *count);
*count = 0;
return NULL;
}
if (!(name = hlsl_strdup(ctx, string_skip_tag(var->name))))
{
sm4_free_extern_resources(extern_resources, *count);
*count = 0;
return NULL;
}
extern_resources[*count].var = var;
extern_resources[*count].buffer = NULL;
extern_resources[*count].name = name;
/* For some reason 5.1 resources aren't marked as
* user-packed, but cbuffers still are. */
extern_resources[*count].is_user_packed = hlsl_version_lt(ctx, 5, 1)
&& !!var->reg_reservation.reg_type;
extern_resources[*count].component_type = hlsl_type_get_component_type(ctx, var->data_type, 0);
extern_resources[*count].regset = r;
extern_resources[*count].id = var->regs[r].id;
extern_resources[*count].space = var->regs[r].space;
extern_resources[*count].index = var->regs[r].index;
extern_resources[*count].bind_count = var->bind_count[r];
extern_resources[*count].loc = var->loc;
++*count;
}
}
}
LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry)
{
if (!buffer->reg.allocated)
continue;
if (!(hlsl_array_reserve(ctx, (void **)&extern_resources,
&capacity, *count + 1, sizeof(*extern_resources))))
{
sm4_free_extern_resources(extern_resources, *count);
*count = 0;
return NULL;
}
if (!(name = hlsl_strdup(ctx, buffer->name)))
{
sm4_free_extern_resources(extern_resources, *count);
*count = 0;
return NULL;
}
extern_resources[*count].var = NULL;
extern_resources[*count].buffer = buffer;
extern_resources[*count].name = name;
extern_resources[*count].is_user_packed = !!buffer->reservation.reg_type;
extern_resources[*count].component_type = NULL;
extern_resources[*count].regset = HLSL_REGSET_NUMERIC;
extern_resources[*count].id = buffer->reg.id;
extern_resources[*count].space = buffer->reg.space;
extern_resources[*count].index = buffer->reg.index;
extern_resources[*count].bind_count = 1;
extern_resources[*count].loc = buffer->loc;
++*count;
}
qsort(extern_resources, *count, sizeof(*extern_resources), sm4_compare_extern_resources);
return extern_resources;
}
static void generate_vsir_scan_required_features(struct hlsl_ctx *ctx, struct vsir_program *program)
{
struct extern_resource *extern_resources;
......
......@@ -8141,6 +8141,16 @@ static void vsir_validate_dst_param(struct validation_context *ctx,
}
}
static void vsir_validate_io_src_param(struct validation_context *ctx,
const struct vkd3d_shader_src_param *src)
{
struct vsir_io_register_data io_reg_data;
if (!vsir_get_io_register_data(ctx, src->reg.type, &io_reg_data) || !(io_reg_data.flags & INPUT_BIT))
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
"Invalid register type %#x used as source parameter.", src->reg.type);
}
static void vsir_validate_src_param(struct validation_context *ctx,
const struct vkd3d_shader_src_param *src)
{
......@@ -8176,18 +8186,24 @@ static void vsir_validate_src_param(struct validation_context *ctx,
"Invalid NULL register used as source parameter.");
break;
case VKD3DSPR_INPUT:
vsir_validate_io_src_param(ctx, src);
break;
case VKD3DSPR_OUTPUT:
if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL
|| (ctx->phase != VKD3DSIH_HS_FORK_PHASE && ctx->phase != VKD3DSIH_HS_JOIN_PHASE))
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
"Invalid OUTPUT register used as source parameter.");
vsir_validate_io_src_param(ctx, src);
break;
case VKD3DSPR_INCONTROLPOINT:
vsir_validate_io_src_param(ctx, src);
break;
case VKD3DSPR_OUTCONTROLPOINT:
vsir_validate_io_src_param(ctx, src);
break;
case VKD3DSPR_PATCHCONST:
if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_DOMAIN
&& ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE,
"PATCHCONST register used as source parameters are only allowed in Hull and Domain Shaders.");
vsir_validate_io_src_param(ctx, src);
break;
default:
......@@ -8293,6 +8309,11 @@ static void vsir_validate_signature_element(struct validation_context *ctx,
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
"element %u of %s signature: Invalid zero register count.", idx, signature_type_name);
if (ctx->program->normalisation_level < VSIR_NORMALISED_SM6 && element->register_count != 1)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
"element %u of %s signature: Invalid register count %u.", idx, signature_type_name,
element->register_count);
if (element->register_index != UINT_MAX && (element->register_index >= MAX_REG_OUTPUT
|| MAX_REG_OUTPUT - element->register_index < element->register_count))
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
......
......@@ -3483,205 +3483,6 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ
}
}
static int sm4_compare_extern_resources(const void *a, const void *b)
{
const struct extern_resource *aa = (const struct extern_resource *)a;
const struct extern_resource *bb = (const struct extern_resource *)b;
int r;
if ((r = vkd3d_u32_compare(aa->regset, bb->regset)))
return r;
if ((r = vkd3d_u32_compare(aa->space, bb->space)))
return r;
return vkd3d_u32_compare(aa->index, bb->index);
}
void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count)
{
unsigned int i;
for (i = 0; i < count; ++i)
vkd3d_free(extern_resources[i].name);
vkd3d_free(extern_resources);
}
static const char *string_skip_tag(const char *string)
{
if (!strncmp(string, "<resource>", strlen("<resource>")))
return string + strlen("<resource>");
return string;
}
struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count)
{
bool separate_components = ctx->profile->major_version == 5 && ctx->profile->minor_version == 0;
struct extern_resource *extern_resources = NULL;
const struct hlsl_ir_var *var;
struct hlsl_buffer *buffer;
enum hlsl_regset regset;
size_t capacity = 0;
char *name;
*count = 0;
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
if (separate_components)
{
unsigned int component_count = hlsl_type_component_count(var->data_type);
unsigned int k, regset_offset;
for (k = 0; k < component_count; ++k)
{
struct hlsl_type *component_type = hlsl_type_get_component_type(ctx, var->data_type, k);
struct vkd3d_string_buffer *name_buffer;
if (!hlsl_type_is_resource(component_type))
continue;
regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, &regset);
if (regset_offset > var->regs[regset].allocation_size)
continue;
if (var->objects_usage[regset][regset_offset].used)
{
if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1,
sizeof(*extern_resources))))
{
sm4_free_extern_resources(extern_resources, *count);
*count = 0;
return NULL;
}
if (!(name_buffer = hlsl_component_to_string(ctx, var, k)))
{
sm4_free_extern_resources(extern_resources, *count);
*count = 0;
return NULL;
}
if (!(name = hlsl_strdup(ctx, string_skip_tag(name_buffer->buffer))))
{
sm4_free_extern_resources(extern_resources, *count);
*count = 0;
hlsl_release_string_buffer(ctx, name_buffer);
return NULL;
}
hlsl_release_string_buffer(ctx, name_buffer);
extern_resources[*count].var = NULL;
extern_resources[*count].buffer = NULL;
extern_resources[*count].name = name;
extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type;
extern_resources[*count].component_type = component_type;
extern_resources[*count].regset = regset;
extern_resources[*count].id = var->regs[regset].id;
extern_resources[*count].space = var->regs[regset].space;
extern_resources[*count].index = var->regs[regset].index + regset_offset;
extern_resources[*count].bind_count = 1;
extern_resources[*count].loc = var->loc;
++*count;
}
}
}
else
{
unsigned int r;
if (!hlsl_type_is_resource(var->data_type))
continue;
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
{
if (!var->regs[r].allocated)
continue;
if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1,
sizeof(*extern_resources))))
{
sm4_free_extern_resources(extern_resources, *count);
*count = 0;
return NULL;
}
if (!(name = hlsl_strdup(ctx, string_skip_tag(var->name))))
{
sm4_free_extern_resources(extern_resources, *count);
*count = 0;
return NULL;
}
extern_resources[*count].var = var;
extern_resources[*count].buffer = NULL;
extern_resources[*count].name = name;
/* For some reason 5.1 resources aren't marked as
* user-packed, but cbuffers still are. */
extern_resources[*count].is_user_packed = hlsl_version_lt(ctx, 5, 1)
&& !!var->reg_reservation.reg_type;
extern_resources[*count].component_type = hlsl_type_get_component_type(ctx, var->data_type, 0);
extern_resources[*count].regset = r;
extern_resources[*count].id = var->regs[r].id;
extern_resources[*count].space = var->regs[r].space;
extern_resources[*count].index = var->regs[r].index;
extern_resources[*count].bind_count = var->bind_count[r];
extern_resources[*count].loc = var->loc;
++*count;
}
}
}
LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry)
{
if (!buffer->reg.allocated)
continue;
if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1,
sizeof(*extern_resources))))
{
sm4_free_extern_resources(extern_resources, *count);
*count = 0;
return NULL;
}
if (!(name = hlsl_strdup(ctx, buffer->name)))
{
sm4_free_extern_resources(extern_resources, *count);
*count = 0;
return NULL;
}
extern_resources[*count].var = NULL;
extern_resources[*count].buffer = buffer;
extern_resources[*count].name = name;
extern_resources[*count].is_user_packed = !!buffer->reservation.reg_type;
extern_resources[*count].component_type = NULL;
extern_resources[*count].regset = HLSL_REGSET_NUMERIC;
extern_resources[*count].id = buffer->reg.id;
extern_resources[*count].space = buffer->reg.space;
extern_resources[*count].index = buffer->reg.index;
extern_resources[*count].bind_count = 1;
extern_resources[*count].loc = buffer->loc;
++*count;
}
qsort(extern_resources, *count, sizeof(*extern_resources), sm4_compare_extern_resources);
return extern_resources;
}
/* For some reason, for matrices, values from default value initializers end up in different
* components than from regular initializers. Default value initializers fill the matrix in
* vertical reading order (left-to-right top-to-bottom) instead of regular reading order
......
......@@ -480,6 +480,11 @@ static inline bool is_mesa_device(ID3D12Device *device)
return false;
}
static inline bool is_mesa_device_lt(ID3D12Device *device, uint32_t major, uint32_t minor, uint32_t patch)
{
return false;
}
static inline bool is_mesa_intel_device(ID3D12Device *device)
{
return false;
......@@ -531,10 +536,12 @@ static inline bool is_depth_clip_enable_supported(ID3D12Device *device)
#define VKD3D_AGILITY_SDK_EXPORTS
#include "vulkan_utils.h"
#define DECLARE_VK_PFN(name) static PFN_##name name;
DECLARE_VK_PFN(vkGetInstanceProcAddr)
#define VK_INSTANCE_PFN DECLARE_VK_PFN
#include "vulkan_procs.h"
#undef DECLARE_VK_PFN
static bool check_device_extension(VkPhysicalDevice vk_physical_device, const char *name)
{
......@@ -750,9 +757,17 @@ static inline bool is_mesa_device(ID3D12Device *device)
VkPhysicalDeviceDriverPropertiesKHR properties;
get_driver_properties(device, NULL, &properties);
return properties.driverID == VK_DRIVER_ID_MESA_RADV_KHR
|| properties.driverID == VK_DRIVER_ID_MESA_LLVMPIPE
|| properties.driverID == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR;
return is_mesa_vulkan_driver(&properties);
}
static inline bool is_mesa_device_lt(ID3D12Device *device, uint32_t major, uint32_t minor, uint32_t patch)
{
VkPhysicalDeviceDriverPropertiesKHR driver_properties;
VkPhysicalDeviceProperties device_properties;
get_driver_properties(device, &device_properties, &driver_properties);
return is_mesa_vulkan_driver(&driver_properties)
&& !is_vulkan_driver_version_ge(&device_properties, &driver_properties, major, minor, patch);
}
static inline bool is_mesa_intel_device(ID3D12Device *device)
......@@ -778,24 +793,8 @@ static inline bool is_llvmpipe_device_gte(ID3D12Device *device,
VkPhysicalDeviceProperties device_properties;
get_driver_properties(device, &device_properties, &driver_properties);
if (driver_properties.driverID != VK_DRIVER_ID_MESA_LLVMPIPE)
return false;
if (device_properties.driverVersion == 1)
{
uint32_t driver_major, driver_minor, driver_patch;
/* llvmpipe doesn't provide a valid driverVersion value, so we resort to parsing the
* driverInfo string. */
if (sscanf(driver_properties.driverInfo, "Mesa %u.%u.%u",
&driver_major, &driver_minor, &driver_patch) == 3)
{
device_properties.driverVersion = VK_MAKE_API_VERSION(0,
driver_major, driver_minor, driver_patch);
}
}
return device_properties.driverVersion >= VK_MAKE_API_VERSION(0, major, minor, patch);
return driver_properties.driverID == VK_DRIVER_ID_MESA_LLVMPIPE
&& is_vulkan_driver_version_ge(&device_properties, &driver_properties, major, minor, patch);
}
static inline bool is_nvidia_device(ID3D12Device *device)
......
[require]
shader model >= 4.0
[input layout]
0 r32g32-float POSITION
1 r32-float CLIP_DISTANCE
[vb 0]
-1.0 -1.0
-1.0 1.0
1.0 -1.0
1.0 1.0
[vb 1]
1.0
1.0
1.0
1.0
[rtv 0]
format r32g32b32a32-float
size (2d, 640, 480)
[vertex shader todo]
struct input
{
float4 position : POSITION;
float distance : CLIP_DISTANCE;
};
struct vertex
{
float4 position : SV_POSITION;
float clip : SV_ClipDistance;
};
void main(input vin, out vertex vertex)
{
vertex.position = vin.position;
vertex.clip = vin.distance;
}
[pixel shader]
float4 main(const in float4 position : SV_Position) : SV_Target
{
return float4(0.0f, 1.0f, 0.0f, 1.0f);
}
[test]
clear rtv 0 1.0 1.0 1.0 1.0
todo(sm<6) draw triangle strip 4
probe (0, 0, 640, 480) rgba(0.0, 1.0, 0.0, 1.0)
[vb 1]
0.0
0.0
0.0
0.0
[test]
clear rtv 0 1.0 1.0 1.0 1.0
todo(sm<6) draw triangle strip 4
probe (0, 0, 640, 480) rgba(0.0, 1.0, 0.0, 1.0)
[vb 1]
-1.0
-1.0
-1.0
-1.0
[test]
clear rtv 0 1.0 1.0 1.0 1.0
todo(sm<6) draw triangle strip 4
probe (0, 0, 640, 480) rgba(1.0, 1.0, 1.0, 1.0)
[vb 1]
1.0
1.0
-1.0
-1.0
[test]
clear rtv 0 1.0 1.0 1.0 1.0
todo(sm<6) draw triangle strip 4
probe rtv 0 (160, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 240) rgba(1.0, 1.0, 1.0, 1.0)
[vb 1]
-1.0
1.0
-1.0
1.0
[test]
clear rtv 0 1.0 1.0 1.0 1.0
todo(sm<6) draw triangle strip 4
probe rtv 0 (320, 120) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 360) rgba(1.0, 1.0, 1.0, 1.0)
% A single clip distance.
[vertex shader todo]
static const float2 vertices[3] =
{
{-1.0f, 1.0f},
{ 3.0f, 1.0f},
{-1.0f, -3.0f},
};
struct vs_out
{
float4 position : SV_Position;
float clip : SV_ClipDistance;
};
void main(uint id : SV_VertexID, out vs_out o)
{
const float2 pos = vertices[id];
o.position = float4(pos, 0.0f, 1.0f);
o.clip = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
}
[test]
clear rtv 0 1.0 1.0 0.0 1.0
todo(sm<6) draw triangle strip 4
probe rtv 0 (160, 120) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 240) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 120) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 120) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 360) rgba(0.0, 1.0, 0.0, 1.0)
% A single clip distance, disguised as an array.
[vertex shader todo]
static const float2 vertices[3] =
{
{-1.0f, 1.0f},
{ 3.0f, 1.0f},
{-1.0f, -3.0f},
};
struct vs_out
{
float4 position : SV_Position;
float clip[1] : SV_ClipDistance1;
};
void main(uint id : SV_VertexID, out vs_out o)
{
const float2 pos = vertices[id];
o.position = float4(pos, 0.0f, 1.0f);
o.clip[0] = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
}
[test]
clear rtv 0 1.0 1.0 0.0 1.0
todo(sm<6) draw triangle strip 4
probe rtv 0 (160, 120) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 240) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 120) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 120) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 360) rgba(0.0, 1.0, 0.0, 1.0)
% Two clip distances.
[vertex shader todo]
static const float2 vertices[3] =
{
{-1.0f, 1.0f},
{ 3.0f, 1.0f},
{-1.0f, -3.0f},
};
struct vs_out
{
float4 position : SV_Position;
float2 clip : SV_ClipDistance;
};
void main(uint id : SV_VertexID, out vs_out o)
{
const float2 pos = vertices[id];
o.position = float4(pos, 0.0f, 1.0f);
o.clip.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
o.clip.y = 0.15f + 0.6f * pos.x - 0.4f * pos.y;
}
[test]
clear rtv 0 1.0 1.0 0.0 1.0
todo(sm<6) draw triangle strip 4
probe rtv 0 (160, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 240) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 120) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 360) rgba(0.0, 1.0, 0.0, 1.0)
% Five clip distances.
[vertex shader todo]
static const float2 vertices[3] =
{
{-1.0f, 1.0f},
{ 3.0f, 1.0f},
{-1.0f, -3.0f},
};
struct vs_out
{
float4 position : SV_Position;
float2 clip : SV_ClipDistance;
float3 clip2 : SV_ClipDistance1;
};
void main(uint id : SV_VertexID, out vs_out o)
{
const float2 pos = vertices[id];
o.position = float4(pos, 0.0f, 1.0f);
o.clip.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
o.clip.y = 0.15f + 0.6f * pos.x - 0.4f * pos.y;
o.clip2.x = 0.55f - 0.6f * pos.x + 0.4f * pos.y;
o.clip2.y = 0.25f - 0.6f * pos.x + 0.4f * pos.y;
o.clip2.z = 0.25f - 0.6f * pos.x - 0.4f * pos.y;
}
[test]
clear rtv 0 1.0 1.0 0.0 1.0
todo(sm<6) draw triangle strip 4
probe rtv 0 (160, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 240) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 240) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 360) rgba(1.0, 1.0, 0.0, 1.0)
% Now it works. Here all the cull distances are effectively ignored, because
% they do not leave the only triangle entirely on one side. (Also, they
% coincide with other clip distances.)
[vertex shader todo]
static const float2 vertices[3] =
{
{-1.0f, 1.0f},
{ 3.0f, 1.0f},
{-1.0f, -3.0f},
};
struct vs_out
{
float4 position : SV_Position;
float2 clip : SV_ClipDistance;
float3 clip2 : SV_ClipDistance1;
float2 cull2 : SV_CullDistance1;
float1 cull : SV_CullDistance;
};
void main(uint id : SV_VertexID, out vs_out o)
{
const float2 pos = vertices[id];
o.position = float4(pos, 0.0f, 1.0f);
o.clip.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
o.clip.y = 0.15f + 0.6f * pos.x - 0.4f * pos.y;
o.clip2.x = 0.55f - 0.6f * pos.x + 0.4f * pos.y;
o.clip2.y = 0.25f - 0.6f * pos.x + 0.4f * pos.y;
o.clip2.z = 0.25f - 0.6f * pos.x - 0.4f * pos.y;
o.cull.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
o.cull2.x = 0.55f - 0.6f * pos.x + 0.4f * pos.y;
o.cull2.y = 0.25f - 0.6f * pos.x + 0.4f * pos.y;
}
[test]
clear rtv 0 1.0 1.0 0.0 1.0
todo(sm<6) draw triangle strip 4
probe rtv 0 (160, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 240) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 240) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 360) rgba(1.0, 1.0, 0.0, 1.0)
% Let clip and cull distances go through a geometry shader.
[geometry shader todo]
struct vs_out
{
float4 position : SV_Position;
float2 clip : SV_ClipDistance;
float3 clip2 : SV_ClipDistance1;
float2 cull2 : SV_CullDistance1;
float1 cull : SV_CullDistance;
};
[maxvertexcount(3)]
void main(triangle vs_out input[3], inout TriangleStream<vs_out> stream)
{
unsigned int i;
vs_out output;
for (i = 0; i < 3; ++i)
{
output = input[i];
stream.Append(output);
}
}
[test]
clear rtv 0 1.0 1.0 0.0 1.0
todo draw triangle strip 4
probe rtv 0 (160, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 240) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 240) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 360) rgba(1.0, 1.0, 0.0, 1.0)
% Generate clip and cull distances in the geometry shader.
[vertex shader]
static const float2 vertices[3] =
{
{-1.0f, 1.0f},
{ 3.0f, 1.0f},
{-1.0f, -3.0f},
};
struct vs_out
{
float4 position : SV_Position;
uint id : VERTEXID;
};
void main(uint id : SV_VertexID, out vs_out o)
{
const float2 pos = vertices[id];
o.position = float4(pos, 0.0f, 1.0f);
o.id = id;
}
[geometry shader todo]
struct vs_out
{
float4 position : SV_Position;
uint id : VERTEXID;
};
struct gs_out
{
float4 position : SV_Position;
float2 clip : SV_ClipDistance;
float3 clip2 : SV_ClipDistance1;
float2 cull2 : SV_CullDistance1;
float1 cull : SV_CullDistance;
};
void emit_position(float4 pos, inout TriangleStream<gs_out> stream)
{
gs_out output;
output.position = pos;
output.clip.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
output.clip.y = 0.15f + 0.6f * pos.x - 0.4f * pos.y;
output.clip2.x = 0.55f - 0.6f * pos.x + 0.4f * pos.y;
output.clip2.y = 0.25f - 0.6f * pos.x + 0.4f * pos.y;
output.clip2.z = 0.25f - 0.6f * pos.x - 0.4f * pos.y;
output.cull.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
output.cull2.x = 0.55f - 0.6f * pos.x + 0.4f * pos.y;
output.cull2.y = 0.25f - 0.6f * pos.x + 0.4f * pos.y;
stream.Append(output);
}
[maxvertexcount(3)]
void main(triangle vs_out input[3], inout TriangleStream<gs_out> stream)
{
unsigned int i;
for (i = 0; i < 3; ++i)
emit_position(input[i].position, stream);
}
[test]
clear rtv 0 1.0 1.0 0.0 1.0
todo(sm<6) draw triangle strip 4
probe rtv 0 (160, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 240) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 240) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 360) rgba(1.0, 1.0, 0.0, 1.0)
% Now let's test cull distances for real: we remove the clip distances they
% duplicate and use the geometry shader to create many little triangles around
% the test points; first we check that we're drawing properly disabling all
% clipping and culling.
[geometry shader todo]
struct vs_out
{
float4 position : SV_Position;
uint id : VERTEXID;
};
struct gs_out
{
float4 position : SV_Position;
float2 clip : SV_ClipDistance;
float2 cull2 : SV_CullDistance1;
float1 cull : SV_CullDistance;
};
void emit_position(float4 pos, inout TriangleStream<gs_out> stream)
{
gs_out output;
output.position = pos;
output.clip = 1.0f;
output.cull = 1.0f;
output.cull2 = 1.0f;
stream.Append(output);
}
static const float4 displacements[3] =
{
{ 0.01f, 0.01f, 0.0f, 0.0f},
{-0.02f, 0.01f, 0.0f, 0.0f},
{ 0.01f, -0.02f, 0.0f, 0.0f},
};
[maxvertexcount(27)]
void main(triangle vs_out input[3], inout TriangleStream<gs_out> stream)
{
unsigned int i, j;
for (i = 0; i < 3; ++i)
{
for (j = 0; j < 3; ++j)
{
float4 pos = float4(0.0f, 0.0f, 0.0f, 1.0f);
pos.x = 0.5f - 0.5f * i;
pos.y = 0.5f - 0.5f * j;
emit_position(pos + displacements[0], stream);
emit_position(pos + displacements[1], stream);
emit_position(pos + displacements[2], stream);
stream.RestartStrip();
}
}
}
[test]
clear rtv 0 1.0 1.0 0.0 1.0
todo(sm<6) draw triangle strip 4
probe rtv 0 (160, 120) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 360) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 120) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 360) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 120) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 360) rgba(0.0, 1.0, 0.0, 1.0)
% Then we add clipping and culling: at first only a few distances.
[geometry shader todo]
struct vs_out
{
float4 position : SV_Position;
uint id : VERTEXID;
};
struct gs_out
{
float4 position : SV_Position;
float2 clip : SV_ClipDistance;
float2 cull2 : SV_CullDistance1;
float1 cull : SV_CullDistance;
};
void emit_position(float4 pos, inout TriangleStream<gs_out> stream)
{
gs_out output;
output.position = pos;
output.clip = 1.0f;
output.clip.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
output.cull = 1.0f;
output.cull.x = 0.25f - 0.6f * pos.x - 0.4f * pos.y;
output.cull2 = 1.0f;
stream.Append(output);
}
static const float4 displacements[3] =
{
{ 0.01f, 0.01f, 0.0f, 0.0f},
{-0.02f, 0.01f, 0.0f, 0.0f},
{ 0.01f, -0.02f, 0.0f, 0.0f},
};
[maxvertexcount(27)]
void main(triangle vs_out input[3], inout TriangleStream<gs_out> stream)
{
unsigned int i, j;
for (i = 0; i < 3; ++i)
{
for (j = 0; j < 3; ++j)
{
float4 pos = float4(0.0f, 0.0f, 0.0f, 1.0f);
pos.x = 0.5f - 0.5f * i;
pos.y = 0.5f - 0.5f * j;
emit_position(pos + displacements[0], stream);
emit_position(pos + displacements[1], stream);
emit_position(pos + displacements[2], stream);
stream.RestartStrip();
}
}
}
[test]
clear rtv 0 1.0 1.0 0.0 1.0
todo(sm<6) draw triangle strip 4
probe rtv 0 (160, 120) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 240) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 120) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 240) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 360) rgba(0.0, 1.0, 0.0, 1.0)
% Then enough to get rid of nearly all test points.
[geometry shader todo]
struct vs_out
{
float4 position : SV_Position;
uint id : VERTEXID;
};
struct gs_out
{
float4 position : SV_Position;
float2 clip : SV_ClipDistance;
float2 cull2 : SV_CullDistance1;
float1 cull : SV_CullDistance;
};
void emit_position(float4 pos, inout TriangleStream<gs_out> stream)
{
gs_out output;
output.position = pos;
output.clip.x = 0.15f + 0.6f * pos.x + 0.4f * pos.y;
output.clip.y = 0.15f + 0.6f * pos.x - 0.4f * pos.y;
output.cull.x = 0.25f - 0.6f * pos.x - 0.4f * pos.y;
output.cull2.x = 0.55f - 0.6f * pos.x + 0.4f * pos.y;
output.cull2.y = 0.25f - 0.6f * pos.x + 0.4f * pos.y;
stream.Append(output);
}
static const float4 displacements[3] =
{
{ 0.05f, 0.05f, 0.0f, 0.0f},
{-0.1f, 0.05f, 0.0f, 0.0f},
{ 0.05f, -0.1f, 0.0f, 0.0f},
};
[maxvertexcount(27)]
void main(triangle vs_out input[3], inout TriangleStream<gs_out> stream)
{
unsigned int i, j;
for (i = 0; i < 3; ++i)
{
for (j = 0; j < 3; ++j)
{
float4 pos = float4(0.0f, 0.0f, 0.0f, 1.0f);
pos.x = 0.5f - 0.5f * i;
pos.y = 0.5f - 0.5f * j;
emit_position(pos + displacements[0], stream);
emit_position(pos + displacements[1], stream);
emit_position(pos + displacements[2], stream);
stream.RestartStrip();
}
}
}
[test]
clear rtv 0 1.0 1.0 0.0 1.0
todo(sm<6) draw triangle strip 4
probe rtv 0 (160, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 240) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (160, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 240) rgba(0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 360) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 120) rgba(1.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 240) rgba(1.0, 1.0, 0.0, 1.0)
bug(mesa<23.3) probe rtv 0 (480, 360) rgba(1.0, 1.0, 0.0, 1.0)
[require]
shader model >= 4.0
[input layout]
0 r32g32-float POSITION
1 r32-float CLIP_DISTANCE
[vb 0]
-1.0 -1.0
-1.0 1.0
1.0 -1.0
1.0 1.0
[vb 1]
1.0
1.0
1.0
1.0
[rtv 0]
format r32g32b32a32-float
size (2d, 640, 480)
[vertex shader todo]
struct input
{
float4 position : POSITION;
float distance : CLIP_DISTANCE;
};
struct vertex
{
float4 position : SV_POSITION;
float clip : SV_ClipDistance;
};
void main(input vin, out vertex vertex)
{
vertex.position = vin.position;
vertex.clip = vin.distance;
}
[pixel shader]
float4 main(const in float4 position : SV_Position) : SV_Target
{
return float4(0.0f, 1.0f, 0.0f, 1.0f);
}
[test]
clear rtv 0 1.0 1.0 1.0 1.0
todo(sm<6) draw triangle strip 4
probe (0, 0, 640, 480) rgba (0.0, 1.0, 0.0, 1.0)
[vb 1]
0.0
0.0
0.0
0.0
[test]
clear rtv 0 1.0 1.0 1.0 1.0
todo(sm<6) draw triangle strip 4
probe (0, 0, 640, 480) rgba (0.0, 1.0, 0.0, 1.0)
[vb 1]
-1.0
-1.0
-1.0
-1.0
[test]
clear rtv 0 1.0 1.0 1.0 1.0
todo(sm<6) draw triangle strip 4
probe (0, 0, 640, 480) rgba (1.0, 1.0, 1.0, 1.0)
[vb 1]
1.0
1.0
-1.0
-1.0
[test]
clear rtv 0 1.0 1.0 1.0 1.0
todo(sm<6) draw triangle strip 4
probe rtv 0 (160, 240) rgba (0.0, 1.0, 0.0, 1.0)
probe rtv 0 (480, 240) rgba (1.0, 1.0, 1.0, 1.0)
[vb 1]
-1.0
1.0
-1.0
1.0
[test]
clear rtv 0 1.0 1.0 1.0 1.0
todo(sm<6) draw triangle strip 4
probe rtv 0 (320, 120) rgba (0.0, 1.0, 0.0, 1.0)
probe rtv 0 (320, 360) rgba (1.0, 1.0, 1.0, 1.0)
......@@ -135,7 +135,7 @@ float4 main(): sv_target
}
[pixel shader fail(sm>=5.1) todo(sm>=5.1)]
[pixel shader fail(sm>=6)]
// default value initializers make it more permissive but if types don't match
// then the whole initializer is discarded.
float4 f = {
......@@ -206,6 +206,8 @@ float4 main(): sv_target
[require]
shader model >= 5.0
% Segfaults with 5.1 on d3dcompiler_47 10.0.19041.868
shader model < 5.1
options: backcompat
[pixel shader fail(sm>=5.1) todo(sm>=5.1)]
......
......@@ -75,7 +75,7 @@ size (2d, 3, 3)
0.0 1.0 0.0 1.0 1.0 1.0 0.0 1.0 2.0 1.0 0.0 1.0
0.0 2.0 0.0 1.0 1.0 2.0 0.0 1.0 2.0 2.0 0.0 1.0
[pixel shader fail(sm>=6)]
[pixel shader fail(sm>=5.1) todo(sm>=5.1)]
sampler s;
float4 f;
......
......@@ -143,7 +143,7 @@ static bool match_tag(struct shader_runner *runner, const char *tag)
static bool check_qualifier_args_conjunction(struct shader_runner *runner,
const char *line, const char **const rest, uint32_t *model_mask)
{
static const char *const valid_tags[] = {"d3d12", "glsl", "llvmpipe", "msl", "mvk", "vulkan"};
static const char *const valid_tags[] = {"d3d12", "glsl", "llvmpipe", "msl", "mvk", "vulkan", "mesa<23.3"};
bool holds = true;
*model_mask = ~0u;
......@@ -1612,6 +1612,7 @@ static HRESULT dxc_compiler_compile_shader(void *dxc_compiler, enum shader_type
ID3D10Blob *compile_hlsl(const struct shader_runner *runner, enum shader_type type)
{
const char *source = runner->shader_source[type];
unsigned int options = runner->compile_options;
ID3D10Blob *blob = NULL, *errors = NULL;
char profile[7];
HRESULT hr;
......@@ -1627,16 +1628,22 @@ ID3D10Blob *compile_hlsl(const struct shader_runner *runner, enum shader_type ty
[SHADER_MODEL_6_0] = "6_0",
};
/* Behaviour is inconsistent between different versions of
* d3dcompiler_47.dll. Version 10.0.17134.12 seems to reject
* D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY for 5.1 profiles, while
* version 10.0.10150.0 apparently doesn't. */
if (runner->minimum_shader_model >= SHADER_MODEL_5_1)
options &= ~D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
if (runner->minimum_shader_model >= SHADER_MODEL_6_0)
{
assert(runner->dxc_compiler);
hr = dxc_compiler_compile_shader(runner->dxc_compiler, type, runner->compile_options, source, &blob);
hr = dxc_compiler_compile_shader(runner->dxc_compiler, type, options, source, &blob);
}
else
{
sprintf(profile, "%s_%s", shader_type_string(type), shader_models[runner->minimum_shader_model]);
hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main",
profile, runner->compile_options, 0, &blob, &errors);
hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", profile, options, 0, &blob, &errors);
}
if (hr != S_OK)
{
......@@ -1656,6 +1663,7 @@ static void compile_shader(struct shader_runner *runner, const char *source,
size_t len, enum shader_type type, enum shader_model model)
{
bool use_dxcompiler = (model >= SHADER_MODEL_6_0);
unsigned int options = runner->compile_options;
ID3D10Blob *blob = NULL, *errors = NULL;
char profile[7];
HRESULT hr;
......@@ -1686,10 +1694,17 @@ static void compile_shader(struct shader_runner *runner, const char *source,
if (model < SHADER_MODEL_5_0 && (type == SHADER_TYPE_HS || type == SHADER_TYPE_DS))
return;
/* Behaviour is inconsistent between different versions of
* d3dcompiler_47.dll. Version 10.0.17134.12 seems to reject
* D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY for 5.1 profiles, while
* version 10.0.10150.0 apparently doesn't. */
if (model >= SHADER_MODEL_5_1)
options &= ~D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
if (use_dxcompiler)
{
assert(runner->dxc_compiler);
hr = dxc_compiler_compile_shader(runner->dxc_compiler, type, runner->compile_options, source, &blob);
hr = dxc_compiler_compile_shader(runner->dxc_compiler, type, options, source, &blob);
}
else
{
......@@ -1697,7 +1712,7 @@ static void compile_shader(struct shader_runner *runner, const char *source,
sprintf(profile, "%s_%s", shader_type_string(type), effect_models[model]);
else
sprintf(profile, "%s_%s", shader_type_string(type), shader_models[model]);
hr = D3DCompile(source, len, NULL, NULL, NULL, "main", profile, runner->compile_options, 0, &blob, &errors);
hr = D3DCompile(source, len, NULL, NULL, NULL, "main", profile, options, 0, &blob, &errors);
}
hr = map_special_hrs(hr);
todo_if (runner->hlsl_todo[model])
......@@ -1983,7 +1998,8 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c
break;
case STATE_TEST:
if (test_action == TEST_ACTION_SKIP_EXECUTION)
if (test_action == TEST_ACTION_SKIP_EXECUTION
&& runner->minimum_shader_model <= runner->maximum_shader_model)
skip("Missing capabilities.\n");
break;
......
......@@ -155,7 +155,7 @@ enum shader_cap
struct shader_runner_caps
{
const char *runner;
const char *tags[2];
const char *tags[3];
size_t tag_count;
enum shader_model minimum_shader_model;
enum shader_model maximum_shader_model;
......
......@@ -1037,11 +1037,17 @@ static void d3d12_runner_init_caps(struct d3d12_shader_runner *runner,
runner->caps.tag_count = 0;
runner->caps.tags[runner->caps.tag_count++] = "d3d12";
if (is_mvk_device(device))
{
runner->caps.tags[runner->caps.tag_count++] = "mvk";
else if (is_llvmpipe_device(device))
runner->caps.tags[runner->caps.tag_count++] = "llvmpipe";
}
else
{
if (is_llvmpipe_device(device))
runner->caps.tags[runner->caps.tag_count++] = "llvmpipe";
if (is_mesa_device_lt(device, 23, 3, 0))
runner->caps.tags[runner->caps.tag_count++] = "mesa<23.3";
}
for (unsigned int i = 0; i < ARRAY_SIZE(formats); ++i)
{
......
......@@ -1720,11 +1720,19 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner)
runner->caps.tag_count = 0;
runner->caps.tags[runner->caps.tag_count++] = "vulkan";
if (device_info.driver_properties.driverID == VK_DRIVER_ID_MOLTENVK)
{
runner->caps.tags[runner->caps.tag_count++] = "mvk";
else if (device_info.driver_properties.driverID == VK_DRIVER_ID_MESA_LLVMPIPE)
runner->caps.tags[runner->caps.tag_count++] = "llvmpipe";
}
else
{
if (device_info.driver_properties.driverID == VK_DRIVER_ID_MESA_LLVMPIPE)
runner->caps.tags[runner->caps.tag_count++] = "llvmpipe";
if (is_mesa_vulkan_driver(&device_info.driver_properties)
&& !is_vulkan_driver_version_ge(&device_info.properties2.properties,
&device_info.driver_properties, 23, 3, 0))
runner->caps.tags[runner->caps.tag_count++] = "mesa<23.3";
}
runner->caps.shader_caps[SHADER_CAP_CLIP_PLANES] = true;
runner->caps.shader_caps[SHADER_CAP_FOG] = true;
......
......@@ -49,6 +49,8 @@ struct vulkan_test_context
#include "vulkan_procs.h"
};
#undef DECLARE_VK_PFN
#define VK_CALL(f) (context->f)
static inline void begin_command_buffer(const struct vulkan_test_context *context)
......@@ -265,7 +267,7 @@ static inline bool vulkan_test_context_init_instance(struct vulkan_test_context
{
VkInstanceCreateInfo instance_desc = {.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO};
struct vulkan_extension_list enabled_extensions;
DECLARE_VK_PFN(vkGetInstanceProcAddr)
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
void *libvulkan;
uint32_t count;
VkResult vr;
......@@ -417,4 +419,44 @@ static inline void vulkan_test_context_destroy(const struct vulkan_test_context
VK_CALL(vkDestroyInstance(context->instance, NULL));
}
/* This doesn't work for NVIDIA, because they use a different bit pattern. */
static inline bool is_vulkan_driver_version_ge(const VkPhysicalDeviceProperties *device_properties,
const VkPhysicalDeviceDriverPropertiesKHR *driver_properties,
uint32_t major, uint32_t minor, uint32_t patch)
{
uint32_t version = device_properties->driverVersion;
if (version == 1)
{
uint32_t driver_major, driver_minor, driver_patch;
/* llvmpipe doesn't provide a valid driverVersion value, so we resort to
* parsing the driverInfo string. */
if (sscanf(driver_properties->driverInfo, "Mesa %u.%u.%u",
&driver_major, &driver_minor, &driver_patch) == 3)
version = VK_MAKE_API_VERSION(0, driver_major, driver_minor, driver_patch);
}
return version >= VK_MAKE_API_VERSION(0, major, minor, patch);
}
static inline bool is_mesa_vulkan_driver(const VkPhysicalDeviceDriverPropertiesKHR *properties)
{
switch (properties->driverID)
{
case VK_DRIVER_ID_MESA_RADV_KHR:
case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA:
case VK_DRIVER_ID_MESA_LLVMPIPE:
case VK_DRIVER_ID_MESA_TURNIP:
case VK_DRIVER_ID_MESA_V3DV:
case VK_DRIVER_ID_MESA_PANVK:
case VK_DRIVER_ID_MESA_VENUS:
case VK_DRIVER_ID_MESA_DOZEN:
return true;
default:
return false;
}
}
#endif /* __VKD3D_VULKAN_UTILS_H */