summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2017-09-28 03:45:04 +0200
committerRoland Scheidegger <[email protected]>2017-09-30 02:58:09 +0200
commit740a1618c34c095f85d4929e11ef107d560f7450 (patch)
treeeb956477a8c8d7dbc3a2d04282620f10e17ef703
parentd5e7ce28b5f6e0a7e4857d1e56143c00eba0c265 (diff)
gallium: add new LOD opcode
The operation performed is all the same as LODQ, but with the usual differences between dx10 and GL texture opcodes, that is separate resource and sampler indices (plus result swizzling, and setting z/w channels to zero). Reviewed-by: Jose Fonseca <[email protected]> Acked-by: Nicolai Hähnle <[email protected]>
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c14
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c48
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info_opcodes.h1
-rw-r--r--src/gallium/docs/source/tgsi.rst12
-rw-r--r--src/gallium/include/pipe/p_shader_tokens.h4
5 files changed, 74 insertions, 5 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index e5d0293b8f9..de18f629cd0 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -3284,6 +3284,18 @@ sviewinfo_emit(
emit_size_query(bld, emit_data->inst, emit_data->output, TRUE);
}
+static void
+lod_emit(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
+
+ emit_sample(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_NONE,
+ FALSE, LP_SAMPLER_OP_LODQ, emit_data->output);
+}
+
static LLVMValueRef
mask_vec(struct lp_build_tgsi_context *bld_base)
{
@@ -3898,6 +3910,8 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm,
bld.bld_base.op_actions[TGSI_OPCODE_SAMPLE_L].emit = sample_l_emit;
bld.bld_base.op_actions[TGSI_OPCODE_GATHER4].emit = gather4_emit;
bld.bld_base.op_actions[TGSI_OPCODE_SVIEWINFO].emit = sviewinfo_emit;
+ bld.bld_base.op_actions[TGSI_OPCODE_LOD].emit = lod_emit;
+
if (gs_iface) {
/* There's no specific value for this because it should always
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 9c019a311d7..afed96c9b1d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -2351,15 +2351,22 @@ static void
exec_lodq(struct tgsi_exec_machine *mach,
const struct tgsi_full_instruction *inst)
{
- uint unit;
+ uint resource_unit, sampler_unit;
int dim;
int i;
union tgsi_exec_channel coords[4];
const union tgsi_exec_channel *args[ARRAY_SIZE(coords)];
union tgsi_exec_channel r[2];
- unit = fetch_sampler_unit(mach, inst, 1);
- dim = tgsi_util_get_texture_coord_dim(inst->Texture.Texture);
+ resource_unit = fetch_sampler_unit(mach, inst, 1);
+ if (inst->Instruction.Opcode == TGSI_OPCODE_LOD) {
+ uint target = mach->SamplerViews[resource_unit].Resource;
+ dim = tgsi_util_get_texture_coord_dim(target);
+ sampler_unit = fetch_sampler_unit(mach, inst, 2);
+ } else {
+ dim = tgsi_util_get_texture_coord_dim(inst->Texture.Texture);
+ sampler_unit = resource_unit;
+ }
assert(dim <= ARRAY_SIZE(coords));
/* fetch coordinates */
for (i = 0; i < dim; i++) {
@@ -2369,7 +2376,7 @@ exec_lodq(struct tgsi_exec_machine *mach,
for (i = dim; i < ARRAY_SIZE(coords); i++) {
args[i] = &ZeroVec;
}
- mach->Sampler->query_lod(mach->Sampler, unit, unit,
+ mach->Sampler->query_lod(mach->Sampler, resource_unit, sampler_unit,
args[0]->f,
args[1]->f,
args[2]->f,
@@ -2386,6 +2393,35 @@ exec_lodq(struct tgsi_exec_machine *mach,
store_dest(mach, &r[1], &inst->Dst[0], inst, TGSI_CHAN_Y,
TGSI_EXEC_DATA_FLOAT);
}
+ if (inst->Instruction.Opcode == TGSI_OPCODE_LOD) {
+ unsigned char swizzles[4];
+ unsigned chan;
+ swizzles[0] = inst->Src[1].Register.SwizzleX;
+ swizzles[1] = inst->Src[1].Register.SwizzleY;
+ swizzles[2] = inst->Src[1].Register.SwizzleZ;
+ swizzles[3] = inst->Src[1].Register.SwizzleW;
+
+ for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ if (swizzles[chan] >= 2) {
+ store_dest(mach, &ZeroVec,
+ &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ } else {
+ store_dest(mach, &r[swizzles[chan]],
+ &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ }
+ }
+ }
+ } else {
+ if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
+ store_dest(mach, &r[0], &inst->Dst[0], inst, TGSI_CHAN_X,
+ TGSI_EXEC_DATA_FLOAT);
+ }
+ if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
+ store_dest(mach, &r[1], &inst->Dst[0], inst, TGSI_CHAN_Y,
+ TGSI_EXEC_DATA_FLOAT);
+ }
+ }
}
static void
@@ -5718,6 +5754,10 @@ exec_instruction(
assert(0);
break;
+ case TGSI_OPCODE_LOD:
+ exec_lodq(mach, inst);
+ break;
+
case TGSI_OPCODE_UARL:
exec_vector_unary(mach, inst, micro_uarl, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_UINT);
break;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_info_opcodes.h b/src/gallium/auxiliary/tgsi/tgsi_info_opcodes.h
index fdb0f1078a1..1b2803cf3fe 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info_opcodes.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_info_opcodes.h
@@ -249,3 +249,4 @@ OPCODE(1, 2, COMP, U64DIV)
OPCODE(1, 2, COMP, I64MOD)
OPCODE(1, 2, COMP, U64MOD)
OPCODE(1, 2, COMP, DDIV)
+OPCODE(1, 3, OTHR, LOD)
diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst
index 274646703b4..551e9dd379f 100644
--- a/src/gallium/docs/source/tgsi.rst
+++ b/src/gallium/docs/source/tgsi.rst
@@ -2479,6 +2479,18 @@ after lookup.
NOTE: no driver has implemented this opcode yet (and no state tracker
emits it). This information is subject to change.
+.. opcode:: LOD - level of detail
+
+ Same syntax as the SAMPLE opcode but instead of performing an actual
+ texture lookup/filter, return the computed LOD information that the
+ texture pipe would use to access the texture. The Y component contains
+ the computed LOD lambda_prime. The X component contains the LOD that will
+ be accessed, based on min/max lod's and mipmap filters.
+ The Z and W components are set to 0.
+
+ Syntax: ``LOD dst, address, sampler_view, sampler``
+
+
.. _resourceopcodes:
Resource Access Opcodes
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index a5adedd9875..97deef73830 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -607,7 +607,9 @@ struct tgsi_property_data {
#define TGSI_OPCODE_DDIV 248
-#define TGSI_OPCODE_LAST 249
+#define TGSI_OPCODE_LOD 249
+
+#define TGSI_OPCODE_LAST 250
/**
* Opcode is the operation code to execute. A given operation defines the