mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-04-13 05:43:18 -07:00
vkd3d-shader/ir: Allow controlling fog through parameters.
Fog requires several parameters to even implement the most basic of functionality correctly, so this commit is relatively large.
This commit is contained in:
committed by
Henri Verbeet
parent
a1de406de4
commit
f86d1e72a4
Notes:
Henri Verbeet
2024-12-02 17:19:05 +01:00
Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1265
@ -476,6 +476,45 @@ enum vkd3d_shader_binding_flag
|
|||||||
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_BINDING_FLAG),
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_BINDING_FLAG),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The factor used to interpolate the fragment output colour with fog.
|
||||||
|
*
|
||||||
|
* See VKD3D_SHADER_PARAMETER_NAME_FOG_FRAGMENT_MODE for specification of the
|
||||||
|
* interpolation factor as defined here.
|
||||||
|
*
|
||||||
|
* The following variables may be used to determine the interpolation factor:
|
||||||
|
*
|
||||||
|
* c = The fog coordinate value output from the vertex shader. This is an
|
||||||
|
* inter-stage varying with the semantic name "FOG" and semantic index 0.
|
||||||
|
* E = The value of VKD3D_SHADER_PARAMETER_NAME_FOG_END.
|
||||||
|
* k = The value of VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE.
|
||||||
|
*
|
||||||
|
* \since 1.15
|
||||||
|
*/
|
||||||
|
enum vkd3d_shader_fog_fragment_mode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* No fog interpolation is applied;
|
||||||
|
* the output colour is passed through unmodified.
|
||||||
|
* Equivalently, the fog interpolation factor is 1.
|
||||||
|
*/
|
||||||
|
VKD3D_SHADER_FOG_FRAGMENT_NONE = 0x0,
|
||||||
|
/**
|
||||||
|
* The fog interpolation factor is (E - c) * k.
|
||||||
|
*
|
||||||
|
* In order to implement traditional linear fog, as present in Direct3D and
|
||||||
|
* OpenGL, i.e.
|
||||||
|
*
|
||||||
|
* (end - c) / (end - start)
|
||||||
|
*
|
||||||
|
* set
|
||||||
|
*
|
||||||
|
* E = end
|
||||||
|
* k = 1 / (end - start)
|
||||||
|
*/
|
||||||
|
VKD3D_SHADER_FOG_FRAGMENT_LINEAR = 0x3,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The manner in which a parameter value is provided to the shader, used in
|
* The manner in which a parameter value is provided to the shader, used in
|
||||||
* struct vkd3d_shader_parameter and struct vkd3d_shader_parameter1.
|
* struct vkd3d_shader_parameter and struct vkd3d_shader_parameter1.
|
||||||
@ -739,6 +778,73 @@ enum vkd3d_shader_parameter_name
|
|||||||
* \since 1.14
|
* \since 1.14
|
||||||
*/
|
*/
|
||||||
VKD3D_SHADER_PARAMETER_NAME_POINT_SPRITE,
|
VKD3D_SHADER_PARAMETER_NAME_POINT_SPRITE,
|
||||||
|
/**
|
||||||
|
* Fog mode used in fragment shaders.
|
||||||
|
*
|
||||||
|
* The value specified by this parameter must be a member of
|
||||||
|
* enum vkd3d_shader_fog_fragment_mode.
|
||||||
|
*
|
||||||
|
* If not VKD3D_SHADER_FOG_FRAGMENT_NONE, the pixel shader colour output at
|
||||||
|
* location 0 is linearly interpolated with the fog colour defined by
|
||||||
|
* VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR. The interpolation factor is
|
||||||
|
* defined according to the enumerant selected by this parameter.
|
||||||
|
* The interpolated value is then outputted instead of the original value at
|
||||||
|
* location 0.
|
||||||
|
*
|
||||||
|
* An interpolation factor of 0 specifies to use the fog colour; a factor of
|
||||||
|
* 1 specifies to use the original colour output. The interpolation factor
|
||||||
|
* is clamped to the [0, 1] range before interpolating.
|
||||||
|
*
|
||||||
|
* The default value is VKD3D_SHADER_FOG_FRAGMENT_NONE.
|
||||||
|
*
|
||||||
|
* The data type for this parameter must be
|
||||||
|
* VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32.
|
||||||
|
*
|
||||||
|
* Only VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT is supported in this
|
||||||
|
* version of vkd3d-shader.
|
||||||
|
*
|
||||||
|
* \since 1.15
|
||||||
|
*/
|
||||||
|
VKD3D_SHADER_PARAMETER_NAME_FOG_FRAGMENT_MODE,
|
||||||
|
/**
|
||||||
|
* Fog colour.
|
||||||
|
* See VKD3D_SHADER_PARAMETER_NAME_FOG_FRAGMENT_MODE for documentation of
|
||||||
|
* fog.
|
||||||
|
*
|
||||||
|
* The data type for this parameter must be
|
||||||
|
* VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4.
|
||||||
|
*
|
||||||
|
* The default value is transparent black, i.e. the vector {0, 0, 0, 0}.
|
||||||
|
*
|
||||||
|
* \since 1.15
|
||||||
|
*/
|
||||||
|
VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR,
|
||||||
|
/**
|
||||||
|
* End coordinate for linear fog.
|
||||||
|
* See VKD3D_SHADER_PARAMETER_NAME_FOG_FRAGMENT_MODE for documentation of
|
||||||
|
* fog.
|
||||||
|
*
|
||||||
|
* The data type for this parameter must be
|
||||||
|
* VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32.
|
||||||
|
*
|
||||||
|
* The default value is 1.0.
|
||||||
|
*
|
||||||
|
* \since 1.15
|
||||||
|
*/
|
||||||
|
VKD3D_SHADER_PARAMETER_NAME_FOG_END,
|
||||||
|
/**
|
||||||
|
* Scale value for linear fog.
|
||||||
|
* See VKD3D_SHADER_PARAMETER_NAME_FOG_FRAGMENT_MODE for documentation of
|
||||||
|
* fog.
|
||||||
|
*
|
||||||
|
* The data type for this parameter must be
|
||||||
|
* VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32.
|
||||||
|
*
|
||||||
|
* The default value is 1.0.
|
||||||
|
*
|
||||||
|
* \since 1.15
|
||||||
|
*/
|
||||||
|
VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE,
|
||||||
|
|
||||||
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_NAME),
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_NAME),
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2023 Conor McCarthy for CodeWeavers
|
* Copyright 2023 Conor McCarthy for CodeWeavers
|
||||||
|
* Copyright 2023-2024 Elizabeth Figura for CodeWeavers
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -222,6 +223,14 @@ static void src_param_init_parameter(struct vkd3d_shader_src_param *src, uint32_
|
|||||||
src->reg.idx[0].offset = idx;
|
src->reg.idx[0].offset = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void src_param_init_parameter_vec4(struct vkd3d_shader_src_param *src, uint32_t idx, enum vkd3d_data_type type)
|
||||||
|
{
|
||||||
|
vsir_src_param_init(src, VKD3DSPR_PARAMETER, type, 1);
|
||||||
|
src->reg.idx[0].offset = idx;
|
||||||
|
src->reg.dimension = VSIR_DIMENSION_VEC4;
|
||||||
|
src->swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
||||||
|
}
|
||||||
|
|
||||||
static void vsir_src_param_init_resource(struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx)
|
static void vsir_src_param_init_resource(struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx)
|
||||||
{
|
{
|
||||||
vsir_src_param_init(src, VKD3DSPR_RESOURCE, VKD3D_DATA_UNUSED, 2);
|
vsir_src_param_init(src, VKD3DSPR_RESOURCE, VKD3D_DATA_UNUSED, 2);
|
||||||
@ -251,6 +260,14 @@ static void src_param_init_ssa_float(struct vkd3d_shader_src_param *src, unsigne
|
|||||||
src->reg.idx[0].offset = idx;
|
src->reg.idx[0].offset = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void src_param_init_ssa_float4(struct vkd3d_shader_src_param *src, unsigned int idx)
|
||||||
|
{
|
||||||
|
vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_FLOAT, 1);
|
||||||
|
src->reg.idx[0].offset = idx;
|
||||||
|
src->reg.dimension = VSIR_DIMENSION_VEC4;
|
||||||
|
src->swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
||||||
|
}
|
||||||
|
|
||||||
static void src_param_init_temp_bool(struct vkd3d_shader_src_param *src, unsigned int idx)
|
static void src_param_init_temp_bool(struct vkd3d_shader_src_param *src, unsigned int idx)
|
||||||
{
|
{
|
||||||
vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1);
|
vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1);
|
||||||
@ -306,6 +323,14 @@ static void dst_param_init_ssa_float(struct vkd3d_shader_dst_param *dst, unsigne
|
|||||||
dst->reg.idx[0].offset = idx;
|
dst->reg.idx[0].offset = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dst_param_init_ssa_float4(struct vkd3d_shader_dst_param *dst, unsigned int idx)
|
||||||
|
{
|
||||||
|
vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_FLOAT, 1);
|
||||||
|
dst->reg.idx[0].offset = idx;
|
||||||
|
dst->reg.dimension = VSIR_DIMENSION_VEC4;
|
||||||
|
dst->write_mask = VKD3DSP_WRITEMASK_ALL;
|
||||||
|
}
|
||||||
|
|
||||||
static void dst_param_init_temp_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
|
static void dst_param_init_temp_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
|
||||||
{
|
{
|
||||||
vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1);
|
vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1);
|
||||||
@ -864,11 +889,36 @@ static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program,
|
|||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool add_signature_element(struct shader_signature *signature, const char *semantic_name,
|
||||||
|
uint32_t semantic_index, uint32_t mask, uint32_t register_index,
|
||||||
|
enum vkd3d_shader_interpolation_mode interpolation_mode)
|
||||||
|
{
|
||||||
|
struct signature_element *new_elements, *e;
|
||||||
|
|
||||||
|
if (!(new_elements = vkd3d_realloc(signature->elements,
|
||||||
|
(signature->element_count + 1) * sizeof(*signature->elements))))
|
||||||
|
return false;
|
||||||
|
signature->elements = new_elements;
|
||||||
|
e = &signature->elements[signature->element_count++];
|
||||||
|
memset(e, 0, sizeof(*e));
|
||||||
|
e->semantic_name = vkd3d_strdup(semantic_name);
|
||||||
|
e->semantic_index = semantic_index;
|
||||||
|
e->sysval_semantic = VKD3D_SHADER_SV_NONE;
|
||||||
|
e->component_type = VKD3D_SHADER_COMPONENT_FLOAT;
|
||||||
|
e->register_count = 1;
|
||||||
|
e->mask = mask;
|
||||||
|
e->used_mask = mask;
|
||||||
|
e->register_index = register_index;
|
||||||
|
e->target_location = register_index;
|
||||||
|
e->interpolation_mode = interpolation_mode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *program,
|
static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *program,
|
||||||
struct vsir_transformation_context *ctx)
|
struct vsir_transformation_context *ctx)
|
||||||
{
|
{
|
||||||
struct shader_signature *signature = &program->output_signature;
|
struct shader_signature *signature = &program->output_signature;
|
||||||
struct signature_element *new_elements, *e;
|
struct signature_element *e;
|
||||||
|
|
||||||
if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX)
|
if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX)
|
||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
@ -881,22 +931,8 @@ static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *pr
|
|||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(new_elements = vkd3d_realloc(signature->elements,
|
if (!add_signature_element(signature, "COLOR", 0, VKD3DSP_WRITEMASK_ALL, SM1_COLOR_REGISTER_OFFSET, VKD3DSIM_NONE))
|
||||||
(signature->element_count + 1) * sizeof(*signature->elements))))
|
|
||||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
signature->elements = new_elements;
|
|
||||||
e = &signature->elements[signature->element_count++];
|
|
||||||
memset(e, 0, sizeof(*e));
|
|
||||||
e->semantic_name = vkd3d_strdup("COLOR");
|
|
||||||
e->sysval_semantic = VKD3D_SHADER_SV_NONE;
|
|
||||||
e->component_type = VKD3D_SHADER_COMPONENT_FLOAT;
|
|
||||||
e->register_count = 1;
|
|
||||||
e->mask = VKD3DSP_WRITEMASK_ALL;
|
|
||||||
e->used_mask = VKD3DSP_WRITEMASK_ALL;
|
|
||||||
e->register_index = SM1_COLOR_REGISTER_OFFSET;
|
|
||||||
e->target_location = SM1_COLOR_REGISTER_OFFSET;
|
|
||||||
e->interpolation_mode = VKD3DSIM_NONE;
|
|
||||||
|
|
||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6685,6 +6721,187 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr
|
|||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum vkd3d_result vsir_program_add_fog_input(struct vsir_program *program,
|
||||||
|
struct vsir_transformation_context *ctx)
|
||||||
|
{
|
||||||
|
struct shader_signature *signature = &program->input_signature;
|
||||||
|
uint32_t register_idx = 0;
|
||||||
|
|
||||||
|
if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL)
|
||||||
|
return VKD3D_OK;
|
||||||
|
|
||||||
|
if (!vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_FOG_FRAGMENT_MODE))
|
||||||
|
return VKD3D_OK;
|
||||||
|
|
||||||
|
/* We could check the value and skip this if NONE, but chances are if a
|
||||||
|
* user specifies the fog fragment mode as a parameter, they'll want to
|
||||||
|
* enable it dynamically. Always specifying it (and hence always outputting
|
||||||
|
* it from the VS) avoids an extra VS variant. */
|
||||||
|
|
||||||
|
if (vsir_signature_find_element_by_name(signature, "FOG", 0))
|
||||||
|
return VKD3D_OK;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < signature->element_count; ++i)
|
||||||
|
register_idx = max(register_idx, signature->elements[i].register_index + 1);
|
||||||
|
|
||||||
|
if (!add_signature_element(signature, "FOG", 0, VKD3DSP_WRITEMASK_0, register_idx, VKD3DSIM_LINEAR))
|
||||||
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
|
return VKD3D_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *program,
|
||||||
|
const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_fog_fragment_mode mode,
|
||||||
|
uint32_t fog_signature_idx, uint32_t colour_signature_idx, uint32_t colour_temp,
|
||||||
|
size_t *ret_pos, struct vkd3d_shader_message_context *message_context)
|
||||||
|
{
|
||||||
|
struct vkd3d_shader_instruction_array *instructions = &program->instructions;
|
||||||
|
struct vkd3d_shader_location loc = ret->location;
|
||||||
|
uint32_t ssa_factor = program->ssa_count++;
|
||||||
|
size_t pos = ret - instructions->elements;
|
||||||
|
struct vkd3d_shader_instruction *ins;
|
||||||
|
uint32_t ssa_temp;
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case VKD3D_SHADER_FOG_FRAGMENT_LINEAR:
|
||||||
|
/* We generate the following code:
|
||||||
|
*
|
||||||
|
* add sr0, FOG_END, -vFOG.x
|
||||||
|
* mul_sat srFACTOR, sr0, FOG_SCALE
|
||||||
|
*/
|
||||||
|
if (!shader_instruction_array_insert_at(&program->instructions, pos, 4))
|
||||||
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
|
*ret_pos = pos + 4;
|
||||||
|
|
||||||
|
ssa_temp = program->ssa_count++;
|
||||||
|
|
||||||
|
ins = &program->instructions.elements[pos];
|
||||||
|
|
||||||
|
vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_ADD, 1, 2);
|
||||||
|
dst_param_init_ssa_float(&ins->dst[0], ssa_temp);
|
||||||
|
src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VKD3D_DATA_FLOAT);
|
||||||
|
vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1);
|
||||||
|
ins->src[1].reg.idx[0].offset = fog_signature_idx;
|
||||||
|
ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
|
||||||
|
ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
|
||||||
|
ins->src[1].modifiers = VKD3DSPSM_NEG;
|
||||||
|
|
||||||
|
vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_MUL, 1, 2);
|
||||||
|
dst_param_init_ssa_float(&ins->dst[0], ssa_factor);
|
||||||
|
ins->dst[0].modifiers = VKD3DSPDM_SATURATE;
|
||||||
|
src_param_init_ssa_float(&ins->src[0], ssa_temp);
|
||||||
|
src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VKD3D_DATA_FLOAT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
vkd3d_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We generate the following code:
|
||||||
|
*
|
||||||
|
* add sr0, FRAG_COLOUR, -FOG_COLOUR
|
||||||
|
* mad oC0, sr0, srFACTOR, FOG_COLOUR
|
||||||
|
*/
|
||||||
|
|
||||||
|
vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_ADD, 1, 2);
|
||||||
|
dst_param_init_ssa_float4(&ins->dst[0], program->ssa_count++);
|
||||||
|
src_param_init_temp_float4(&ins->src[0], colour_temp);
|
||||||
|
src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VKD3D_DATA_FLOAT);
|
||||||
|
ins->src[1].modifiers = VKD3DSPSM_NEG;
|
||||||
|
|
||||||
|
vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_MAD, 1, 3);
|
||||||
|
dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, colour_signature_idx,
|
||||||
|
program->output_signature.elements[colour_signature_idx].mask);
|
||||||
|
src_param_init_ssa_float4(&ins->src[0], program->ssa_count - 1);
|
||||||
|
src_param_init_ssa_float(&ins->src[1], ssa_factor);
|
||||||
|
src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VKD3D_DATA_FLOAT);
|
||||||
|
|
||||||
|
return VKD3D_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *program,
|
||||||
|
struct vsir_transformation_context *ctx)
|
||||||
|
{
|
||||||
|
struct vkd3d_shader_message_context *message_context = ctx->message_context;
|
||||||
|
uint32_t colour_signature_idx, fog_signature_idx, colour_temp;
|
||||||
|
const struct vkd3d_shader_parameter1 *mode_parameter = NULL;
|
||||||
|
static const struct vkd3d_shader_location no_loc;
|
||||||
|
const struct signature_element *fog_element;
|
||||||
|
enum vkd3d_shader_fog_fragment_mode mode;
|
||||||
|
struct vkd3d_shader_instruction *ins;
|
||||||
|
size_t new_pos;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL)
|
||||||
|
return VKD3D_OK;
|
||||||
|
|
||||||
|
if (!vsir_signature_find_sysval(&program->output_signature, VKD3D_SHADER_SV_TARGET, 0, &colour_signature_idx))
|
||||||
|
return VKD3D_OK;
|
||||||
|
|
||||||
|
if (!(mode_parameter = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_FOG_FRAGMENT_MODE)))
|
||||||
|
return VKD3D_OK;
|
||||||
|
|
||||||
|
if (mode_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT)
|
||||||
|
{
|
||||||
|
vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
|
||||||
|
"Unsupported fog fragment mode parameter type %#x.", mode_parameter->type);
|
||||||
|
return VKD3D_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
if (mode_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32)
|
||||||
|
{
|
||||||
|
vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
|
||||||
|
"Invalid fog fragment mode parameter data type %#x.", mode_parameter->data_type);
|
||||||
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
mode = mode_parameter->u.immediate_constant.u.u32;
|
||||||
|
|
||||||
|
if (mode == VKD3D_SHADER_FOG_FRAGMENT_NONE)
|
||||||
|
return VKD3D_OK;
|
||||||
|
|
||||||
|
/* Should have been added by vsir_program_add_fog_input(). */
|
||||||
|
if (!(fog_element = vsir_signature_find_element_by_name(&program->input_signature, "FOG", 0)))
|
||||||
|
{
|
||||||
|
ERR("Fog input not found.\n");
|
||||||
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
|
}
|
||||||
|
fog_signature_idx = fog_element - program->input_signature.elements;
|
||||||
|
|
||||||
|
/* We're going to be reading from the output, so we need to go
|
||||||
|
* through the whole shader and convert it to a temp. */
|
||||||
|
colour_temp = program->temp_count++;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < program->instructions.count; ++i)
|
||||||
|
{
|
||||||
|
ins = &program->instructions.elements[i];
|
||||||
|
|
||||||
|
if (vsir_instruction_is_dcl(ins))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ins->opcode == VKD3DSIH_RET)
|
||||||
|
{
|
||||||
|
if ((ret = insert_fragment_fog_before_ret(program, ins, mode, fog_signature_idx,
|
||||||
|
colour_signature_idx, colour_temp, &new_pos, message_context)) < 0)
|
||||||
|
return ret;
|
||||||
|
i = new_pos;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t j = 0; j < ins->dst_count; ++j)
|
||||||
|
{
|
||||||
|
struct vkd3d_shader_dst_param *dst = &ins->dst[j];
|
||||||
|
|
||||||
|
/* Note we run after I/O normalization. */
|
||||||
|
if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == colour_signature_idx)
|
||||||
|
{
|
||||||
|
dst->reg.type = VKD3DSPR_TEMP;
|
||||||
|
dst->reg.idx[0].offset = colour_temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return VKD3D_OK;
|
||||||
|
}
|
||||||
|
|
||||||
struct validation_context
|
struct validation_context
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_message_context *message_context;
|
struct vkd3d_shader_message_context *message_context;
|
||||||
@ -8769,6 +8986,9 @@ enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uin
|
|||||||
if (program->shader_version.major <= 2)
|
if (program->shader_version.major <= 2)
|
||||||
vsir_transform(&ctx, vsir_program_add_diffuse_output);
|
vsir_transform(&ctx, vsir_program_add_diffuse_output);
|
||||||
|
|
||||||
|
/* For vsir_program_insert_fragment_fog(). */
|
||||||
|
vsir_transform(&ctx, vsir_program_add_fog_input);
|
||||||
|
|
||||||
return ctx.result;
|
return ctx.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8823,6 +9043,7 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t
|
|||||||
vsir_transform(&ctx, vsir_program_insert_point_size);
|
vsir_transform(&ctx, vsir_program_insert_point_size);
|
||||||
vsir_transform(&ctx, vsir_program_insert_point_size_clamp);
|
vsir_transform(&ctx, vsir_program_insert_point_size_clamp);
|
||||||
vsir_transform(&ctx, vsir_program_insert_point_coord);
|
vsir_transform(&ctx, vsir_program_insert_point_coord);
|
||||||
|
vsir_transform(&ctx, vsir_program_insert_fragment_fog);
|
||||||
|
|
||||||
if (TRACE_ON())
|
if (TRACE_ON())
|
||||||
vsir_program_trace(program);
|
vsir_program_trace(program);
|
||||||
|
@ -3316,13 +3316,19 @@ static uint32_t spirv_compiler_emit_variable(struct spirv_compiler *compiler,
|
|||||||
static const struct vkd3d_spec_constant_info
|
static const struct vkd3d_spec_constant_info
|
||||||
{
|
{
|
||||||
enum vkd3d_shader_parameter_name name;
|
enum vkd3d_shader_parameter_name name;
|
||||||
uint32_t default_value;
|
union
|
||||||
|
{
|
||||||
|
uint32_t u;
|
||||||
|
float f;
|
||||||
|
} default_value;
|
||||||
const char *debug_name;
|
const char *debug_name;
|
||||||
}
|
}
|
||||||
vkd3d_shader_parameters[] =
|
vkd3d_shader_parameters[] =
|
||||||
{
|
{
|
||||||
{VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT, 1, "sample_count"},
|
{VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT, {.u = 1}, "sample_count"},
|
||||||
{VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, 0, "alpha_test_ref"},
|
{VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, {.f = 0.0f}, "alpha_test_ref"},
|
||||||
|
{VKD3D_SHADER_PARAMETER_NAME_FOG_END, {.f = 1.0f}, "fog_end"},
|
||||||
|
{VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, {.f = 1.0f}, "fog_scale"},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct vkd3d_spec_constant_info *get_spec_constant_info(enum vkd3d_shader_parameter_name name)
|
static const struct vkd3d_spec_constant_info *get_spec_constant_info(enum vkd3d_shader_parameter_name name)
|
||||||
@ -3383,7 +3389,7 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile
|
|||||||
const struct vkd3d_spec_constant_info *info;
|
const struct vkd3d_spec_constant_info *info;
|
||||||
|
|
||||||
info = get_spec_constant_info(name);
|
info = get_spec_constant_info(name);
|
||||||
default_value = info ? info->default_value : 0;
|
default_value = info ? info->default_value.u : 0;
|
||||||
|
|
||||||
scalar_type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), 1);
|
scalar_type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), 1);
|
||||||
vector_type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), component_count);
|
vector_type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), component_count);
|
||||||
|
@ -27,3 +27,46 @@ float4 main(float2 fog : fog) : sv_target
|
|||||||
[test]
|
[test]
|
||||||
todo(msl) draw quad
|
todo(msl) draw quad
|
||||||
probe (0, 0) rgba (0.1, 0.2, 0, 1)
|
probe (0, 0) rgba (0.1, 0.2, 0, 1)
|
||||||
|
|
||||||
|
|
||||||
|
[require]
|
||||||
|
fog
|
||||||
|
|
||||||
|
[input layout]
|
||||||
|
0 r32g32b32a32-float position
|
||||||
|
|
||||||
|
[vb 0]
|
||||||
|
-1.0 -1.0 0.2 1.0
|
||||||
|
-1.0 1.0 0.2 1.0
|
||||||
|
1.0 -1.0 0.6 1.0
|
||||||
|
1.0 1.0 0.6 1.0
|
||||||
|
|
||||||
|
[vertex shader]
|
||||||
|
float4 main(float4 pos : position, out float fog : fog) : sv_position
|
||||||
|
{
|
||||||
|
fog = 0.2;
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
[pixel shader]
|
||||||
|
float4 main() : sv_target
|
||||||
|
{
|
||||||
|
return float4(0, 0, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[test]
|
||||||
|
fog-colour 0.0 1.0 1.0 1.0
|
||||||
|
|
||||||
|
fog disable
|
||||||
|
draw triangle strip 4
|
||||||
|
probe (160, 120) rgba (0.0, 0.0, 1.0, 1.0)
|
||||||
|
probe (480, 360) rgba (0.0, 0.0, 1.0, 1.0)
|
||||||
|
probe (160, 120) rgba (0.0, 0.0, 1.0, 1.0)
|
||||||
|
probe (480, 360) rgba (0.0, 0.0, 1.0, 1.0)
|
||||||
|
|
||||||
|
fog none
|
||||||
|
draw triangle strip 4
|
||||||
|
probe (160, 120) rgba (0.0, 0.8, 1.0, 1.0)
|
||||||
|
probe (480, 360) rgba (0.0, 0.8, 1.0, 1.0)
|
||||||
|
probe (160, 120) rgba (0.0, 0.8, 1.0, 1.0)
|
||||||
|
probe (480, 360) rgba (0.0, 0.8, 1.0, 1.0)
|
||||||
|
@ -335,6 +335,7 @@ static const char *const shader_cap_strings[] =
|
|||||||
[SHADER_CAP_CLIP_PLANES] = "clip-planes",
|
[SHADER_CAP_CLIP_PLANES] = "clip-planes",
|
||||||
[SHADER_CAP_DEPTH_BOUNDS] = "depth-bounds",
|
[SHADER_CAP_DEPTH_BOUNDS] = "depth-bounds",
|
||||||
[SHADER_CAP_FLOAT64] = "float64",
|
[SHADER_CAP_FLOAT64] = "float64",
|
||||||
|
[SHADER_CAP_FOG] = "fog",
|
||||||
[SHADER_CAP_GEOMETRY_SHADER] = "geometry-shader",
|
[SHADER_CAP_GEOMETRY_SHADER] = "geometry-shader",
|
||||||
[SHADER_CAP_INT64] = "int64",
|
[SHADER_CAP_INT64] = "int64",
|
||||||
[SHADER_CAP_POINT_SIZE] = "point-size",
|
[SHADER_CAP_POINT_SIZE] = "point-size",
|
||||||
@ -1424,6 +1425,28 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
|
|||||||
else
|
else
|
||||||
runner->point_sprite = false;
|
runner->point_sprite = false;
|
||||||
}
|
}
|
||||||
|
else if (match_string(line, "fog", &line))
|
||||||
|
{
|
||||||
|
if (match_string(line, "disable", &line))
|
||||||
|
runner->fog_mode = FOG_MODE_DISABLE;
|
||||||
|
else if (match_string(line, "none", &line))
|
||||||
|
runner->fog_mode = FOG_MODE_NONE;
|
||||||
|
else if (match_string(line, "linear", &line))
|
||||||
|
runner->fog_mode = FOG_MODE_LINEAR;
|
||||||
|
else if (match_string(line, "exp", &line))
|
||||||
|
runner->fog_mode = FOG_MODE_EXP;
|
||||||
|
else if (match_string(line, "exp2", &line))
|
||||||
|
runner->fog_mode = FOG_MODE_EXP2;
|
||||||
|
else
|
||||||
|
fatal_error("Invalid fog mode '%s'.\n", line);
|
||||||
|
}
|
||||||
|
else if (match_string(line, "fog-colour", &line))
|
||||||
|
{
|
||||||
|
struct vec4 *v = &runner->fog_colour;
|
||||||
|
|
||||||
|
if (sscanf(line, "%f %f %f %f", &v->x, &v->y, &v->z, &v->w) < 4)
|
||||||
|
fatal_error("Malformed float4 constant '%s'.\n", line);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fatal_error("Unknown test directive '%s'.\n", line);
|
fatal_error("Unknown test directive '%s'.\n", line);
|
||||||
@ -1872,6 +1895,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c
|
|||||||
runner->point_size = 1.0f;
|
runner->point_size = 1.0f;
|
||||||
runner->point_size_min = 1.0f;
|
runner->point_size_min = 1.0f;
|
||||||
runner->point_size_max = FLT_MAX;
|
runner->point_size_max = FLT_MAX;
|
||||||
|
runner->fog_mode = FOG_MODE_DISABLE;
|
||||||
|
|
||||||
runner->sample_mask = ~0u;
|
runner->sample_mask = ~0u;
|
||||||
runner->depth_bounds = false;
|
runner->depth_bounds = false;
|
||||||
|
@ -141,6 +141,7 @@ enum shader_cap
|
|||||||
SHADER_CAP_CLIP_PLANES,
|
SHADER_CAP_CLIP_PLANES,
|
||||||
SHADER_CAP_DEPTH_BOUNDS,
|
SHADER_CAP_DEPTH_BOUNDS,
|
||||||
SHADER_CAP_FLOAT64,
|
SHADER_CAP_FLOAT64,
|
||||||
|
SHADER_CAP_FOG,
|
||||||
SHADER_CAP_GEOMETRY_SHADER,
|
SHADER_CAP_GEOMETRY_SHADER,
|
||||||
SHADER_CAP_INT64,
|
SHADER_CAP_INT64,
|
||||||
SHADER_CAP_POINT_SIZE,
|
SHADER_CAP_POINT_SIZE,
|
||||||
@ -173,6 +174,15 @@ static inline unsigned int shader_runner_caps_get_feature_flags(const struct sha
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum fog_mode
|
||||||
|
{
|
||||||
|
FOG_MODE_NONE = 0,
|
||||||
|
FOG_MODE_EXP = 1,
|
||||||
|
FOG_MODE_EXP2 = 2,
|
||||||
|
FOG_MODE_LINEAR = 3,
|
||||||
|
FOG_MODE_DISABLE,
|
||||||
|
};
|
||||||
|
|
||||||
struct shader_runner
|
struct shader_runner
|
||||||
{
|
{
|
||||||
const struct shader_runner_ops *ops;
|
const struct shader_runner_ops *ops;
|
||||||
@ -222,6 +232,8 @@ struct shader_runner
|
|||||||
struct vec4 clip_planes[8];
|
struct vec4 clip_planes[8];
|
||||||
float point_size, point_size_min, point_size_max;
|
float point_size, point_size_min, point_size_max;
|
||||||
bool point_sprite;
|
bool point_sprite;
|
||||||
|
struct vec4 fog_colour;
|
||||||
|
enum fog_mode fog_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct shader_runner_ops
|
struct shader_runner_ops
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2021 Zebediah Figura for CodeWeavers
|
* Copyright 2021-2024 Elizabeth Figura for CodeWeavers
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -145,6 +145,7 @@ static bool init_test_context(struct d3d9_shader_runner *runner)
|
|||||||
runner->caps.minimum_shader_model = SHADER_MODEL_2_0;
|
runner->caps.minimum_shader_model = SHADER_MODEL_2_0;
|
||||||
runner->caps.maximum_shader_model = SHADER_MODEL_3_0;
|
runner->caps.maximum_shader_model = SHADER_MODEL_3_0;
|
||||||
runner->caps.shader_caps[SHADER_CAP_CLIP_PLANES] = true;
|
runner->caps.shader_caps[SHADER_CAP_CLIP_PLANES] = true;
|
||||||
|
runner->caps.shader_caps[SHADER_CAP_FOG] = true;
|
||||||
runner->caps.shader_caps[SHADER_CAP_POINT_SIZE] = true;
|
runner->caps.shader_caps[SHADER_CAP_POINT_SIZE] = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -325,16 +326,19 @@ static bool d3d9_runner_dispatch(struct shader_runner *r, unsigned int x, unsign
|
|||||||
fatal_error("Compute shaders are not supported.\n");
|
fatal_error("Compute shaders are not supported.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t d3d_color_from_vec4(const struct vec4 *v)
|
||||||
|
{
|
||||||
|
return vkd3d_make_u32(vkd3d_make_u16(v->z * 255.0f, v->y * 255.0f),
|
||||||
|
vkd3d_make_u16(v->x * 255.0f, v->w * 255.0f));
|
||||||
|
}
|
||||||
|
|
||||||
static void d3d9_runner_clear(struct shader_runner *r, struct resource *resource, const struct vec4 *clear_value)
|
static void d3d9_runner_clear(struct shader_runner *r, struct resource *resource, const struct vec4 *clear_value)
|
||||||
{
|
{
|
||||||
struct d3d9_shader_runner *runner = d3d9_shader_runner(r);
|
struct d3d9_shader_runner *runner = d3d9_shader_runner(r);
|
||||||
unsigned int colour;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
colour = vkd3d_make_u32(vkd3d_make_u16(clear_value->z * 255.0, clear_value->y * 255.0),
|
hr = IDirect3DDevice9_ColorFill(runner->device, d3d9_resource(resource)->surface,
|
||||||
vkd3d_make_u16(clear_value->x * 255.0, clear_value->w * 255.0));
|
NULL, d3d_color_from_vec4(clear_value));
|
||||||
|
|
||||||
hr = IDirect3DDevice9_ColorFill(runner->device, d3d9_resource(resource)->surface, NULL, colour);
|
|
||||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,6 +502,16 @@ static bool d3d9_runner_draw(struct shader_runner *r,
|
|||||||
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, runner->r.point_sprite);
|
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, runner->r.point_sprite);
|
||||||
ok(hr == D3D_OK, "Failed to set render state, hr %#lx.\n", hr);
|
ok(hr == D3D_OK, "Failed to set render state, hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, (runner->r.fog_mode != FOG_MODE_DISABLE));
|
||||||
|
ok(hr == D3D_OK, "Failed to set render state, hr %#lx.\n", hr);
|
||||||
|
if (runner->r.fog_mode != FOG_MODE_DISABLE)
|
||||||
|
{
|
||||||
|
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, runner->r.fog_mode);
|
||||||
|
ok(hr == D3D_OK, "Failed to set render state, hr %#lx.\n", hr);
|
||||||
|
}
|
||||||
|
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, d3d_color_from_vec4(&runner->r.fog_colour));
|
||||||
|
ok(hr == D3D_OK, "Failed to set render state, hr %#lx.\n", hr);
|
||||||
|
|
||||||
hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
|
hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
|
||||||
ok(hr == D3D_OK, "Failed to create vertex declaration, hr %#lx.\n", hr);
|
ok(hr == D3D_OK, "Failed to create vertex declaration, hr %#lx.\n", hr);
|
||||||
hr = IDirect3DDevice9_CreateVertexShader(device, ID3D10Blob_GetBufferPointer(vs_code), &vs);
|
hr = IDirect3DDevice9_CreateVertexShader(device, ID3D10Blob_GetBufferPointer(vs_code), &vs);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Shader runner which uses libvkd3d-shader to compile HLSL -> D3D bytecode -> SPIR-V
|
* Shader runner which uses libvkd3d-shader to compile HLSL -> D3D bytecode -> SPIR-V
|
||||||
*
|
*
|
||||||
* Copyright 2020-2022 Zebediah Figura for CodeWeavers
|
* Copyright 2020-2024 Elizabeth Figura for CodeWeavers
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -267,15 +267,27 @@ static void vulkan_runner_destroy_resource(struct shader_runner *r, struct resou
|
|||||||
free(resource);
|
free(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum vkd3d_shader_fog_fragment_mode get_fog_fragment_mode(enum fog_mode mode)
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case FOG_MODE_DISABLE: return VKD3D_SHADER_FOG_FRAGMENT_NONE;
|
||||||
|
case FOG_MODE_NONE: return VKD3D_SHADER_FOG_FRAGMENT_LINEAR;
|
||||||
|
default: fatal_error("Unhandled fog mode %#x.\n", mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool compile_hlsl_and_scan(struct vulkan_shader_runner *runner, enum shader_type type)
|
static bool compile_hlsl_and_scan(struct vulkan_shader_runner *runner, enum shader_type type)
|
||||||
{
|
{
|
||||||
|
struct vkd3d_shader_parameter_info parameter_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_PARAMETER_INFO};
|
||||||
struct vkd3d_shader_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO};
|
struct vkd3d_shader_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO};
|
||||||
|
struct vkd3d_shader_parameter1 parameters[1];
|
||||||
enum vkd3d_result ret;
|
enum vkd3d_result ret;
|
||||||
|
|
||||||
if (!(runner->d3d_blobs[type] = compile_hlsl(&runner->r, type)))
|
if (!(runner->d3d_blobs[type] = compile_hlsl(&runner->r, type)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
info.next = &runner->signatures[type];
|
info.next = ¶meter_info;
|
||||||
info.source.code = ID3D10Blob_GetBufferPointer(runner->d3d_blobs[type]);
|
info.source.code = ID3D10Blob_GetBufferPointer(runner->d3d_blobs[type]);
|
||||||
info.source.size = ID3D10Blob_GetBufferSize(runner->d3d_blobs[type]);
|
info.source.size = ID3D10Blob_GetBufferSize(runner->d3d_blobs[type]);
|
||||||
if (runner->r.minimum_shader_model < SHADER_MODEL_4_0)
|
if (runner->r.minimum_shader_model < SHADER_MODEL_4_0)
|
||||||
@ -284,6 +296,15 @@ static bool compile_hlsl_and_scan(struct vulkan_shader_runner *runner, enum shad
|
|||||||
info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
|
info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
|
||||||
info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
|
info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
|
||||||
|
|
||||||
|
parameter_info.next = &runner->signatures[type];
|
||||||
|
parameter_info.parameter_count = ARRAY_SIZE(parameters);
|
||||||
|
parameter_info.parameters = parameters;
|
||||||
|
|
||||||
|
parameters[0].name = VKD3D_SHADER_PARAMETER_NAME_FOG_FRAGMENT_MODE;
|
||||||
|
parameters[0].type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
|
||||||
|
parameters[0].data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32;
|
||||||
|
parameters[0].u.immediate_constant.u.u32 = get_fog_fragment_mode(runner->r.fog_mode);
|
||||||
|
|
||||||
runner->signatures[type].type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO;
|
runner->signatures[type].type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO;
|
||||||
runner->signatures[type].next = NULL;
|
runner->signatures[type].next = NULL;
|
||||||
ret = vkd3d_shader_scan(&info, NULL);
|
ret = vkd3d_shader_scan(&info, NULL);
|
||||||
@ -306,7 +327,7 @@ static bool compile_d3d_code(struct vulkan_shader_runner *runner,
|
|||||||
struct vkd3d_shader_varying_map varying_map[12];
|
struct vkd3d_shader_varying_map varying_map[12];
|
||||||
struct vkd3d_shader_resource_binding *binding;
|
struct vkd3d_shader_resource_binding *binding;
|
||||||
struct vkd3d_shader_compile_option options[2];
|
struct vkd3d_shader_compile_option options[2];
|
||||||
struct vkd3d_shader_parameter1 parameters[17];
|
struct vkd3d_shader_parameter1 parameters[21];
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char *messages;
|
char *messages;
|
||||||
int ret;
|
int ret;
|
||||||
@ -460,6 +481,30 @@ static bool compile_d3d_code(struct vulkan_shader_runner *runner,
|
|||||||
parameters[16].data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32;
|
parameters[16].data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32;
|
||||||
parameters[16].u.immediate_constant.u.u32 = runner->r.point_sprite;
|
parameters[16].u.immediate_constant.u.u32 = runner->r.point_sprite;
|
||||||
|
|
||||||
|
parameters[17].name = VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR;
|
||||||
|
parameters[17].type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
|
||||||
|
parameters[17].data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4;
|
||||||
|
memcpy(parameters[17].u.immediate_constant.u.f32_vec4, &runner->r.fog_colour, sizeof(struct vec4));
|
||||||
|
|
||||||
|
parameters[18].name = VKD3D_SHADER_PARAMETER_NAME_FOG_FRAGMENT_MODE;
|
||||||
|
parameters[18].type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
|
||||||
|
parameters[18].data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32;
|
||||||
|
parameters[18].u.immediate_constant.u.u32 = get_fog_fragment_mode(runner->r.fog_mode);
|
||||||
|
|
||||||
|
parameters[19].name = VKD3D_SHADER_PARAMETER_NAME_FOG_END;
|
||||||
|
parameters[19].type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
|
||||||
|
parameters[19].data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32;
|
||||||
|
|
||||||
|
parameters[20].name = VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE;
|
||||||
|
parameters[20].type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
|
||||||
|
parameters[20].data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32;
|
||||||
|
|
||||||
|
if (runner->r.fog_mode == FOG_MODE_NONE)
|
||||||
|
{
|
||||||
|
parameters[19].u.immediate_constant.u.f32 = 0.0f;
|
||||||
|
parameters[20].u.immediate_constant.u.f32 = -1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
parameter_info.parameter_count = ARRAY_SIZE(parameters);
|
parameter_info.parameter_count = ARRAY_SIZE(parameters);
|
||||||
parameter_info.parameters = parameters;
|
parameter_info.parameters = parameters;
|
||||||
|
|
||||||
@ -1656,6 +1701,7 @@ static bool init_vulkan_runner(struct vulkan_shader_runner *runner)
|
|||||||
}
|
}
|
||||||
|
|
||||||
runner->caps.shader_caps[SHADER_CAP_CLIP_PLANES] = true;
|
runner->caps.shader_caps[SHADER_CAP_CLIP_PLANES] = true;
|
||||||
|
runner->caps.shader_caps[SHADER_CAP_FOG] = true;
|
||||||
runner->caps.shader_caps[SHADER_CAP_POINT_SIZE] = true;
|
runner->caps.shader_caps[SHADER_CAP_POINT_SIZE] = true;
|
||||||
|
|
||||||
device_desc.pEnabledFeatures = &features;
|
device_desc.pEnabledFeatures = &features;
|
||||||
@ -1758,6 +1804,9 @@ void run_shader_tests_vulkan(void)
|
|||||||
runner.caps.maximum_shader_model = SHADER_MODEL_3_0;
|
runner.caps.maximum_shader_model = SHADER_MODEL_3_0;
|
||||||
run_shader_tests(&runner.r, &runner.caps, &vulkan_runner_ops, NULL);
|
run_shader_tests(&runner.r, &runner.caps, &vulkan_runner_ops, NULL);
|
||||||
|
|
||||||
|
/* Fog requires remapping, which is only correct for sm1. */
|
||||||
|
runner.caps.shader_caps[SHADER_CAP_FOG] = false;
|
||||||
|
|
||||||
runner.caps.minimum_shader_model = SHADER_MODEL_4_0;
|
runner.caps.minimum_shader_model = SHADER_MODEL_4_0;
|
||||||
runner.caps.maximum_shader_model = SHADER_MODEL_5_1;
|
runner.caps.maximum_shader_model = SHADER_MODEL_5_1;
|
||||||
run_shader_tests(&runner.r, &runner.caps, &vulkan_runner_ops, NULL);
|
run_shader_tests(&runner.r, &runner.caps, &vulkan_runner_ops, NULL);
|
||||||
|
Reference in New Issue
Block a user