mirror of
https://github.com/elwrcl/intel-hard-graphics.git
synced 2026-11-01 19:28:02 +03:00
init
This commit is contained in:
12511 files changed
+6156641
No files matched your search
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2024 Alyssa Rosenzweig
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "agx_builder.h"
|
||||
#include "agx_compiler.h"
|
||||
#include "agx_opcodes.h"
|
||||
|
||||
static bool
|
||||
is_shuffle(enum agx_opcode op)
|
||||
{
|
||||
switch (op) {
|
||||
case AGX_OPCODE_SHUFFLE:
|
||||
case AGX_OPCODE_SHUFFLE_UP:
|
||||
case AGX_OPCODE_SHUFFLE_DOWN:
|
||||
case AGX_OPCODE_SHUFFLE_XOR:
|
||||
case AGX_OPCODE_QUAD_SHUFFLE:
|
||||
case AGX_OPCODE_QUAD_SHUFFLE_UP:
|
||||
case AGX_OPCODE_QUAD_SHUFFLE_DOWN:
|
||||
case AGX_OPCODE_QUAD_SHUFFLE_XOR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* AGX shuffle instructions read indices to shuffle with from the entire quad
|
||||
* and accumulate them. That means that an inactive thread anywhere in the quad
|
||||
* can make the whole shuffle undefined! To workaround, we reserve a scratch
|
||||
* register (r0h) which we keep zero throughout the program... except for when
|
||||
* actually shuffling, when we copy the shuffle index into r0h for the
|
||||
* operation. This ensures that inactive threads read 0 for their index and
|
||||
* hence do not contribute to the accumulated index.
|
||||
*/
|
||||
void
|
||||
agx_lower_divergent_shuffle(agx_context *ctx)
|
||||
{
|
||||
agx_builder b = agx_init_builder(ctx, agx_before_function(ctx));
|
||||
agx_index scratch = agx_register(1, AGX_SIZE_16);
|
||||
|
||||
assert(ctx->any_quad_divergent_shuffle);
|
||||
agx_mov_imm_to(&b, scratch, 0);
|
||||
|
||||
agx_foreach_block(ctx, block) {
|
||||
bool needs_zero = false;
|
||||
|
||||
agx_foreach_instr_in_block_safe(block, I) {
|
||||
if (is_shuffle(I->op) && I->src[1].type == AGX_INDEX_REGISTER) {
|
||||
assert(I->dest[0].value != scratch.value);
|
||||
assert(I->src[0].value != scratch.value);
|
||||
assert(I->src[1].value != scratch.value);
|
||||
|
||||
/* Use scratch register for our input, then zero it at the end of
|
||||
* the block so all inactive threads read zero.
|
||||
*/
|
||||
b.cursor = agx_before_instr(I);
|
||||
agx_mov_to(&b, scratch, I->src[1]);
|
||||
needs_zero = true;
|
||||
|
||||
I->src[1] = scratch;
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_zero) {
|
||||
b.cursor = agx_after_block_logical(block);
|
||||
agx_mov_imm_to(&b, scratch, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user