From 6af960cef28c608a9be7c2b350969a5416e610a6 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 17 Feb 2025 20:58:45 +0900 Subject: [PATCH] [qfcc] Implement `discard` I had no idea how to do it back when I started working on the glsl parser, but intrinsics made it very easy. It's just OpKill for now (and might stay that way for glsl). --- tools/qfcc/source/glsl-builtins.c | 1 + tools/qfcc/source/glsl-parse.y | 6 +++++- tools/qfcc/source/target_spirv.c | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/qfcc/source/glsl-builtins.c b/tools/qfcc/source/glsl-builtins.c index 0d20b55da..f126b52f2 100644 --- a/tools/qfcc/source/glsl-builtins.c +++ b/tools/qfcc/source/glsl-builtins.c @@ -1128,6 +1128,7 @@ SRC_LINE //fragment processing functions static const char *glsl_fragment_functions = SRC_LINE +"void __discard() = " SPV(OpKill) ";" "\n" "@generic(genFType=@vector(float)) {" "\n" "genFType dFdx(genFType p) = " SPV(OpDPdx) ";" "\n" "genFType dFdy(genFType p) = " SPV(OpDPdy) ";" "\n" diff --git a/tools/qfcc/source/glsl-parse.y b/tools/qfcc/source/glsl-parse.y index 2d178ab04..7799b3796 100644 --- a/tools/qfcc/source/glsl-parse.y +++ b/tools/qfcc/source/glsl-parse.y @@ -1326,7 +1326,11 @@ jump_statement } | RETURN ';' { $$ = new_return_expr (nullptr); } | RETURN expression ';' { $$ = new_return_expr ($2); } - | DISCARD ';' { $$ = nullptr; } //XXX + | DISCARD ';' + { + auto func = new_name_expr ("__discard"); + $$ = new_call_expr (func, nullptr, nullptr); + } ; %% diff --git a/tools/qfcc/source/target_spirv.c b/tools/qfcc/source/target_spirv.c index c9db14731..c4ec7e2a9 100644 --- a/tools/qfcc/source/target_spirv.c +++ b/tools/qfcc/source/target_spirv.c @@ -129,7 +129,8 @@ is_block_terminated (defspace_t *code_space) || (INSN(last_insn, 0) & SpvOpCodeMask) == SpvOpReturnValue || (INSN(last_insn, 0) & SpvOpCodeMask) == SpvOpUnreachable || (INSN(last_insn, 0) & SpvOpCodeMask) == SpvOpBranchConditional - || (INSN(last_insn, 0) & SpvOpCodeMask) == SpvOpBranch)) { + || (INSN(last_insn, 0) & SpvOpCodeMask) == SpvOpBranch + || (INSN(last_insn, 0) & SpvOpCodeMask) == SpvOpKill)) { return true; } return false;