mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-06 01:11:59 +00:00
[qfcc] Implement shadow coord/comp extraction
This took sorting out a few issues with type property evaluation, but it seems to work nicely now. Just one known error to sort out and then it's time to get the spir-v correct.
This commit is contained in:
parent
42f1f39329
commit
a4acfc30d7
4 changed files with 83 additions and 7 deletions
|
@ -1166,6 +1166,7 @@ void decl_process (const expr_t *expr, rua_ctx_t *ctx);
|
|||
const expr_t *expr_process (const expr_t *expr, rua_ctx_t *ctx);
|
||||
specifier_t spec_process (specifier_t spec, rua_ctx_t *ctx);
|
||||
bool can_inline (const expr_t *expr, symbol_t *fsym);
|
||||
bool proc_do_list (ex_list_t *out, const ex_list_t *in, rua_ctx_t *ctx);
|
||||
|
||||
///@}
|
||||
|
||||
|
|
|
@ -405,7 +405,7 @@ proc_symbol (const expr_t *expr, rua_ctx_t *ctx)
|
|||
return error (expr, "undefined symbol `%s`", expr->symbol->name);
|
||||
}
|
||||
|
||||
static bool
|
||||
bool
|
||||
proc_do_list (ex_list_t *out, const ex_list_t *in, rua_ctx_t *ctx)
|
||||
{
|
||||
int count = list_count (in);
|
||||
|
|
|
@ -198,8 +198,20 @@ evaluate_property (int arg_count, const expr_t **args, rua_ctx_t *ctx)
|
|||
if (!type->property) {
|
||||
return error (args[0], "type doesn't support properties");
|
||||
} else {
|
||||
auto e = type->property (type, args[1]->typ.property);
|
||||
if (!is_error (e)) {
|
||||
auto property = args[1]->typ.property;
|
||||
if (property->params) {
|
||||
scoped_src_loc (property->params);
|
||||
auto params = new_list_expr (nullptr);
|
||||
if (!proc_do_list (¶ms->list, &property->params->list,
|
||||
ctx)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto prop = new_type_expr (nullptr);
|
||||
property = new_attrfunc (property->name, params);
|
||||
args[1] = prop;
|
||||
}
|
||||
auto e = type->property (type, property);
|
||||
if (e->type == ex_type) {
|
||||
e = eval_type (e, ctx);
|
||||
}
|
||||
return e;
|
||||
|
@ -873,10 +885,7 @@ process_type (const expr_t *te, rua_ctx_t *ctx)
|
|||
int arg_count = list_count (&te->typ.params->list);
|
||||
const expr_t *args[arg_count];
|
||||
list_scatter (&te->typ.params->list, args);
|
||||
if (type_funcs[op].resolve) {
|
||||
auto type = type_funcs[op].resolve (arg_count, args, ctx);
|
||||
return new_type_expr (type);
|
||||
} else if (type_funcs[op].evaluate) {
|
||||
if (type_funcs[op].evaluate) {
|
||||
return type_funcs[op].evaluate (arg_count, args, ctx);
|
||||
} else {
|
||||
internal_error (te, "invalid type op: %s", type_funcs[op].name);
|
||||
|
@ -920,6 +929,12 @@ eval_type (const expr_t *te, rua_ctx_t *ctx)
|
|||
internal_error (te, "not a type expression");
|
||||
}
|
||||
unsigned op = te->typ.op;
|
||||
if (op == 0) {
|
||||
if (!te->typ.type) {
|
||||
internal_error (te, "type ref with no type");
|
||||
}
|
||||
return te;
|
||||
}
|
||||
if (op >= sizeof (type_funcs) / sizeof (type_funcs[0])
|
||||
|| !type_funcs[op].name) {
|
||||
internal_error (te, "invalid type op: %d", op);
|
||||
|
|
|
@ -66,6 +66,24 @@ static struct_def_t glsl_sampled_image_struct[] = {
|
|||
static int dim_widths[7] = { 1, 2, 3, 3, 2, 1, 0 };
|
||||
static int size_widths[7] = { 1, 2, 3, 2, 2, 1, 0 };
|
||||
static int shadow_widths[7] = { 3, 3, 0, 4, 3, 0, 0 };
|
||||
static const char *shadow_swizzle[7][2] = {
|
||||
{ "x", "xy" },
|
||||
{ "xy", "xyz" },
|
||||
{},
|
||||
{ "xyz", "xyzw" },
|
||||
{ "xy", "xyz" },
|
||||
{},
|
||||
{},
|
||||
};
|
||||
static const char *shadow_comp_swizzle[7][2] = {
|
||||
{ "z", "z" }, // glsl braindeadery for 1d (non-arrayed) images
|
||||
{ "z", "w" },
|
||||
{},
|
||||
{ "w", "" }, // cubemap array shadows get comp from a param
|
||||
{ "z", "w" },
|
||||
{},
|
||||
{},
|
||||
};
|
||||
|
||||
static const expr_t *
|
||||
image_property (const type_t *type, const attribute_t *property)
|
||||
|
@ -103,6 +121,33 @@ image_property (const type_t *type, const attribute_t *property)
|
|||
return error (0, "no property %s on %s", property->name, type->name + 4);
|
||||
}
|
||||
|
||||
static const expr_t *
|
||||
sampled_shadow_swizzle (const attribute_t *property, const char *swizzle[7][2],
|
||||
glsl_image_t *image)
|
||||
{
|
||||
int count = list_count (&property->params->list);
|
||||
if (count != 1) {
|
||||
return error (property->params, "wrong number of params");
|
||||
}
|
||||
const expr_t *params[count];
|
||||
list_scatter (&property->params->list, params);
|
||||
const char *swiz = swizzle[image->dim][image->arrayed];
|
||||
if (!swiz) {
|
||||
return error (property->params, "image does not support"
|
||||
" shadow sampling");
|
||||
}
|
||||
if (!swiz[0]) {
|
||||
// cube map array
|
||||
return error (property->params, "cube map array shadow compare is not"
|
||||
" in the coordinate vector");
|
||||
}
|
||||
if (strcmp (swiz, "xyzw") == 0) {
|
||||
// no-op swizzle
|
||||
return params[0];
|
||||
}
|
||||
return new_swizzle_expr (params[0], swiz);
|
||||
}
|
||||
|
||||
static const expr_t *
|
||||
sampled_image_property (const type_t *type, const attribute_t *property)
|
||||
{
|
||||
|
@ -123,6 +168,21 @@ sampled_image_property (const type_t *type, const attribute_t *property)
|
|||
return new_type_expr (vector_type (&type_float, width));
|
||||
} else if (strcmp (property->name, "shadow_coord") == 0) {
|
||||
if (property->params) {
|
||||
return sampled_shadow_swizzle (property, shadow_swizzle, image);
|
||||
} else {
|
||||
int width = shadow_widths[image->dim];
|
||||
if (!image->depth || !width) {
|
||||
return new_type_expr (&type_void);
|
||||
}
|
||||
if (image->dim == glid_2d) {
|
||||
width += image->arrayed;
|
||||
}
|
||||
return new_type_expr (vector_type (&type_float, width));
|
||||
}
|
||||
} else if (strcmp (property->name, "comp") == 0) {
|
||||
if (property->params) {
|
||||
return sampled_shadow_swizzle (property, shadow_comp_swizzle,
|
||||
image);
|
||||
} else {
|
||||
int width = shadow_widths[image->dim];
|
||||
if (!image->depth || !width) {
|
||||
|
|
Loading…
Reference in a new issue