nvc0: add support for VOTE tgsi opcodes
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
This commit is contained in:
@@ -44,7 +44,7 @@ Note: some of the new features are only available with certain drivers.
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
TBD
|
<li>GL_ARB_shader_group_vote on nvc0</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>Bug fixes</h2>
|
<h2>Bug fixes</h2>
|
||||||
|
@@ -1481,16 +1481,31 @@ CodeEmitterGK110::emitFlow(const Instruction *i)
|
|||||||
void
|
void
|
||||||
CodeEmitterGK110::emitVOTE(const Instruction *i)
|
CodeEmitterGK110::emitVOTE(const Instruction *i)
|
||||||
{
|
{
|
||||||
assert(i->src(0).getFile() == FILE_PREDICATE &&
|
assert(i->src(0).getFile() == FILE_PREDICATE);
|
||||||
i->def(1).getFile() == FILE_PREDICATE);
|
|
||||||
|
|
||||||
code[0] = 0x00000002;
|
code[0] = 0x00000002;
|
||||||
code[1] = 0x86c00000 | (i->subOp << 19);
|
code[1] = 0x86c00000 | (i->subOp << 19);
|
||||||
|
|
||||||
emitPredicate(i);
|
emitPredicate(i);
|
||||||
|
|
||||||
defId(i->def(0), 2);
|
unsigned rp = 0;
|
||||||
defId(i->def(1), 48);
|
for (int d = 0; i->defExists(d); d++) {
|
||||||
|
if (i->def(d).getFile() == FILE_PREDICATE) {
|
||||||
|
assert(!(rp & 2));
|
||||||
|
rp |= 2;
|
||||||
|
defId(i->def(d), 48);
|
||||||
|
} else if (i->def(d).getFile() == FILE_GPR) {
|
||||||
|
assert(!(rp & 1));
|
||||||
|
rp |= 1;
|
||||||
|
defId(i->def(d), 2);
|
||||||
|
} else {
|
||||||
|
assert(!"Unhandled def");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(rp & 1))
|
||||||
|
code[0] |= 255 << 2;
|
||||||
|
if (!(rp & 2))
|
||||||
|
code[1] |= 7 << 16;
|
||||||
if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
|
if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
|
||||||
code[1] |= 1 << 13;
|
code[1] |= 1 << 13;
|
||||||
srcId(i->src(0), 42);
|
srcId(i->src(0), 42);
|
||||||
|
@@ -2788,23 +2788,26 @@ CodeEmitterGM107::emitMEMBAR()
|
|||||||
void
|
void
|
||||||
CodeEmitterGM107::emitVOTE()
|
CodeEmitterGM107::emitVOTE()
|
||||||
{
|
{
|
||||||
int subOp;
|
assert(insn->src(0).getFile() == FILE_PREDICATE);
|
||||||
|
|
||||||
assert(insn->src(0).getFile() == FILE_PREDICATE &&
|
int r = -1, p = -1;
|
||||||
insn->def(1).getFile() == FILE_PREDICATE);
|
for (int i = 0; insn->defExists(i); i++) {
|
||||||
|
if (insn->def(i).getFile() == FILE_GPR)
|
||||||
switch (insn->subOp) {
|
r = i;
|
||||||
case NV50_IR_SUBOP_VOTE_ANY: subOp = 1; break;
|
else if (insn->def(i).getFile() == FILE_PREDICATE)
|
||||||
default:
|
p = i;
|
||||||
assert(insn->subOp == NV50_IR_SUBOP_VOTE_ALL);
|
|
||||||
subOp = 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emitInsn (0x50d80000);
|
emitInsn (0x50d80000);
|
||||||
emitField(0x30, 2, subOp);
|
emitField(0x30, 2, insn->subOp);
|
||||||
emitGPR (0x00, insn->def(0));
|
if (r >= 0)
|
||||||
emitPRED (0x2d, insn->def(1));
|
emitGPR (0x00, insn->def(r));
|
||||||
|
else
|
||||||
|
emitGPR (0x00);
|
||||||
|
if (p >= 0)
|
||||||
|
emitPRED (0x2d, insn->def(p));
|
||||||
|
else
|
||||||
|
emitPRED (0x2d);
|
||||||
emitField(0x2a, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT));
|
emitField(0x2a, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT));
|
||||||
emitPRED (0x27, insn->src(0));
|
emitPRED (0x27, insn->src(0));
|
||||||
}
|
}
|
||||||
|
@@ -2472,16 +2472,31 @@ CodeEmitterNVC0::emitPIXLD(const Instruction *i)
|
|||||||
void
|
void
|
||||||
CodeEmitterNVC0::emitVOTE(const Instruction *i)
|
CodeEmitterNVC0::emitVOTE(const Instruction *i)
|
||||||
{
|
{
|
||||||
assert(i->src(0).getFile() == FILE_PREDICATE &&
|
assert(i->src(0).getFile() == FILE_PREDICATE);
|
||||||
i->def(1).getFile() == FILE_PREDICATE);
|
|
||||||
|
|
||||||
code[0] = 0x00000004 | (i->subOp << 5);
|
code[0] = 0x00000004 | (i->subOp << 5);
|
||||||
code[1] = 0x48000000;
|
code[1] = 0x48000000;
|
||||||
|
|
||||||
emitPredicate(i);
|
emitPredicate(i);
|
||||||
|
|
||||||
defId(i->def(0), 14);
|
unsigned rp = 0;
|
||||||
defId(i->def(1), 32 + 22);
|
for (int d = 0; i->defExists(d); d++) {
|
||||||
|
if (i->def(d).getFile() == FILE_PREDICATE) {
|
||||||
|
assert(!(rp & 2));
|
||||||
|
rp |= 2;
|
||||||
|
defId(i->def(d), 32 + 22);
|
||||||
|
} else if (i->def(d).getFile() == FILE_GPR) {
|
||||||
|
assert(!(rp & 1));
|
||||||
|
rp |= 1;
|
||||||
|
defId(i->def(d), 14);
|
||||||
|
} else {
|
||||||
|
assert(!"Unhandled def");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(rp & 1))
|
||||||
|
code[0] |= 63 << 14;
|
||||||
|
if (!(rp & 2))
|
||||||
|
code[1] |= 7 << 22;
|
||||||
if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
|
if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT))
|
||||||
code[0] |= 1 << 23;
|
code[0] |= 1 << 23;
|
||||||
srcId(i->src(0), 20);
|
srcId(i->src(0), 20);
|
||||||
|
@@ -548,6 +548,9 @@ nv50_ir::DataType Instruction::inferSrcType() const
|
|||||||
case TGSI_OPCODE_UBFE:
|
case TGSI_OPCODE_UBFE:
|
||||||
case TGSI_OPCODE_UMSB:
|
case TGSI_OPCODE_UMSB:
|
||||||
case TGSI_OPCODE_UP2H:
|
case TGSI_OPCODE_UP2H:
|
||||||
|
case TGSI_OPCODE_VOTE_ALL:
|
||||||
|
case TGSI_OPCODE_VOTE_ANY:
|
||||||
|
case TGSI_OPCODE_VOTE_EQ:
|
||||||
return nv50_ir::TYPE_U32;
|
return nv50_ir::TYPE_U32;
|
||||||
case TGSI_OPCODE_I2F:
|
case TGSI_OPCODE_I2F:
|
||||||
case TGSI_OPCODE_I2D:
|
case TGSI_OPCODE_I2D:
|
||||||
@@ -835,6 +838,10 @@ static nv50_ir::operation translateOpcode(uint opcode)
|
|||||||
NV50_IR_OPCODE_CASE(IMSB, BFIND);
|
NV50_IR_OPCODE_CASE(IMSB, BFIND);
|
||||||
NV50_IR_OPCODE_CASE(UMSB, BFIND);
|
NV50_IR_OPCODE_CASE(UMSB, BFIND);
|
||||||
|
|
||||||
|
NV50_IR_OPCODE_CASE(VOTE_ALL, VOTE);
|
||||||
|
NV50_IR_OPCODE_CASE(VOTE_ANY, VOTE);
|
||||||
|
NV50_IR_OPCODE_CASE(VOTE_EQ, VOTE);
|
||||||
|
|
||||||
NV50_IR_OPCODE_CASE(END, EXIT);
|
NV50_IR_OPCODE_CASE(END, EXIT);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -861,6 +868,9 @@ static uint16_t opcodeToSubOp(uint opcode)
|
|||||||
case TGSI_OPCODE_IMUL_HI:
|
case TGSI_OPCODE_IMUL_HI:
|
||||||
case TGSI_OPCODE_UMUL_HI:
|
case TGSI_OPCODE_UMUL_HI:
|
||||||
return NV50_IR_SUBOP_MUL_HIGH;
|
return NV50_IR_SUBOP_MUL_HIGH;
|
||||||
|
case TGSI_OPCODE_VOTE_ALL: return NV50_IR_SUBOP_VOTE_ALL;
|
||||||
|
case TGSI_OPCODE_VOTE_ANY: return NV50_IR_SUBOP_VOTE_ANY;
|
||||||
|
case TGSI_OPCODE_VOTE_EQ: return NV50_IR_SUBOP_VOTE_UNI;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -3187,6 +3197,17 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
|
|||||||
mkCmp(op, tgsi.getSetCond(), dstTy, dst0[c], srcTy, src0, src1);
|
mkCmp(op, tgsi.getSetCond(), dstTy, dst0[c], srcTy, src0, src1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TGSI_OPCODE_VOTE_ALL:
|
||||||
|
case TGSI_OPCODE_VOTE_ANY:
|
||||||
|
case TGSI_OPCODE_VOTE_EQ:
|
||||||
|
val0 = new_LValue(func, FILE_PREDICATE);
|
||||||
|
FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi) {
|
||||||
|
mkCmp(OP_SET, CC_NE, TYPE_U32, val0, TYPE_U32, fetchSrc(0, c), zero);
|
||||||
|
mkOp1(op, dstTy, val0, val0)
|
||||||
|
->subOp = tgsi::opcodeToSubOp(tgsi.getOpcode());
|
||||||
|
mkCvt(OP_CVT, TYPE_U32, dst0[c], TYPE_U8, val0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case TGSI_OPCODE_KILL_IF:
|
case TGSI_OPCODE_KILL_IF:
|
||||||
val0 = new_LValue(func, FILE_PREDICATE);
|
val0 = new_LValue(func, FILE_PREDICATE);
|
||||||
mask = 0;
|
mask = 0;
|
||||||
|
@@ -230,11 +230,11 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||||||
case PIPE_CAP_CULL_DISTANCE:
|
case PIPE_CAP_CULL_DISTANCE:
|
||||||
case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
|
case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
|
||||||
case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
|
case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
|
||||||
|
case PIPE_CAP_COMPUTE:
|
||||||
|
case PIPE_CAP_TGSI_VOTE:
|
||||||
return 1;
|
return 1;
|
||||||
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
|
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
|
||||||
return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
|
return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
|
||||||
case PIPE_CAP_COMPUTE:
|
|
||||||
return 1;
|
|
||||||
case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
|
case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
|
||||||
return nouveau_screen(pscreen)->vram_domain & NOUVEAU_BO_VRAM ? 1 : 0;
|
return nouveau_screen(pscreen)->vram_domain & NOUVEAU_BO_VRAM ? 1 : 0;
|
||||||
|
|
||||||
@@ -261,7 +261,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||||||
case PIPE_CAP_PCI_BUS:
|
case PIPE_CAP_PCI_BUS:
|
||||||
case PIPE_CAP_PCI_DEVICE:
|
case PIPE_CAP_PCI_DEVICE:
|
||||||
case PIPE_CAP_PCI_FUNCTION:
|
case PIPE_CAP_PCI_FUNCTION:
|
||||||
case PIPE_CAP_TGSI_VOTE:
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case PIPE_CAP_VENDOR_ID:
|
case PIPE_CAP_VENDOR_ID:
|
||||||
|
Reference in New Issue
Block a user