mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-08 23:40:12 +01:00
i965/vs: Implement vec4_visitor::visit(ir_texture *).
This translates the GLSL compiler's IR into vec4_instruction IR, generating code to load coordinates, LOD info, shadow comparitors, and so on into the appropriate message registers. It turns out that the SIMD4x2 parameters are identical on Gen 5-7, and the Gen4 code is similar enough that, unlike in the FS, it's easy enough to support all generations in a single function. v2: Load zeros for missing coordinates (fixing vs-texelFetch-sampler1D and 2D on G45), and fix G45 message length for shadow comparisons. Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
parent
ca182cd0fa
commit
d93aa54d2d
1 changed files with 120 additions and 7 deletions
|
|
@ -25,6 +25,7 @@
|
|||
extern "C" {
|
||||
#include "main/macros.h"
|
||||
#include "program/prog_parameter.h"
|
||||
#include "program/sampler.h"
|
||||
}
|
||||
|
||||
namespace brw {
|
||||
|
|
@ -1755,13 +1756,125 @@ vec4_visitor::visit(ir_call *ir)
|
|||
void
|
||||
vec4_visitor::visit(ir_texture *ir)
|
||||
{
|
||||
/* FINISHME: Implement vertex texturing.
|
||||
*
|
||||
* With 0 vertex samplers available, the linker will reject
|
||||
* programs that do vertex texturing, but after our visitor has
|
||||
* run.
|
||||
*/
|
||||
this->result = src_reg(this, glsl_type::vec4_type);
|
||||
int sampler = _mesa_get_sampler_uniform_value(ir->sampler, prog, &vp->Base);
|
||||
sampler = vp->Base.SamplerUnits[sampler];
|
||||
|
||||
/* Should be lowered by do_lower_texture_projection */
|
||||
assert(!ir->projector);
|
||||
|
||||
vec4_instruction *inst;
|
||||
switch (ir->op) {
|
||||
case ir_tex:
|
||||
case ir_txl:
|
||||
inst = new(mem_ctx) vec4_instruction(this, SHADER_OPCODE_TXL);
|
||||
break;
|
||||
case ir_txd:
|
||||
inst = new(mem_ctx) vec4_instruction(this, SHADER_OPCODE_TXD);
|
||||
break;
|
||||
case ir_txf:
|
||||
inst = new(mem_ctx) vec4_instruction(this, SHADER_OPCODE_TXF);
|
||||
break;
|
||||
case ir_txs:
|
||||
inst = new(mem_ctx) vec4_instruction(this, SHADER_OPCODE_TXS);
|
||||
break;
|
||||
case ir_txb:
|
||||
assert(!"TXB is not valid for vertex shaders.");
|
||||
}
|
||||
|
||||
inst->header_present = intel->gen < 5;
|
||||
inst->base_mrf = 2;
|
||||
inst->mlen = inst->header_present + 1; /* always at least one */
|
||||
inst->sampler = sampler;
|
||||
inst->dst = dst_reg(this, glsl_type::get_instance(ir->type->base_type,4,1));
|
||||
inst->shadow_compare = ir->shadow_comparitor != NULL;
|
||||
|
||||
/* MRF for the first parameter */
|
||||
int param_base = inst->base_mrf + inst->header_present;
|
||||
|
||||
if (ir->op == ir_txs) {
|
||||
ir->lod_info.lod->accept(this);
|
||||
int writemask = intel->gen == 4 ? WRITEMASK_W : WRITEMASK_X;
|
||||
emit(MOV(dst_reg(MRF, param_base, ir->lod_info.lod->type, writemask),
|
||||
this->result));
|
||||
} else {
|
||||
int i, coord_mask = 0, zero_mask = 0;
|
||||
/* Load the coordinate */
|
||||
/* FINISHME: gl_clamp_mask and saturate */
|
||||
for (i = 0; i < ir->coordinate->type->vector_elements; i++)
|
||||
coord_mask |= (1 << i);
|
||||
for (; i < 4; i++)
|
||||
zero_mask |= (1 << i);
|
||||
|
||||
ir->coordinate->accept(this);
|
||||
emit(MOV(dst_reg(MRF, param_base, ir->coordinate->type, coord_mask),
|
||||
this->result));
|
||||
emit(MOV(dst_reg(MRF, param_base, ir->coordinate->type, zero_mask),
|
||||
src_reg(0)));
|
||||
/* Load the shadow comparitor */
|
||||
if (ir->shadow_comparitor) {
|
||||
ir->shadow_comparitor->accept(this);
|
||||
emit(MOV(dst_reg(MRF, param_base + 1, ir->shadow_comparitor->type,
|
||||
WRITEMASK_X),
|
||||
this->result));
|
||||
inst->mlen++;
|
||||
}
|
||||
|
||||
/* Load the LOD info */
|
||||
if (ir->op == ir_txl) {
|
||||
int mrf, writemask;
|
||||
if (intel->gen >= 5) {
|
||||
mrf = param_base + 1;
|
||||
if (ir->shadow_comparitor) {
|
||||
writemask = WRITEMASK_Y;
|
||||
/* mlen already incremented */
|
||||
} else {
|
||||
writemask = WRITEMASK_X;
|
||||
inst->mlen++;
|
||||
}
|
||||
} else /* intel->gen == 4 */ {
|
||||
mrf = param_base;
|
||||
writemask = WRITEMASK_Z;
|
||||
}
|
||||
ir->lod_info.lod->accept(this);
|
||||
emit(MOV(dst_reg(MRF, mrf, ir->lod_info.lod->type, writemask),
|
||||
this->result));
|
||||
} else if (ir->op == ir_txf) {
|
||||
ir->lod_info.lod->accept(this);
|
||||
emit(MOV(dst_reg(MRF, param_base, ir->lod_info.lod->type, WRITEMASK_W),
|
||||
this->result));
|
||||
} else if (ir->op == ir_txd) {
|
||||
const glsl_type *type = ir->lod_info.grad.dPdx->type;
|
||||
|
||||
ir->lod_info.grad.dPdx->accept(this);
|
||||
src_reg dPdx = this->result;
|
||||
ir->lod_info.grad.dPdy->accept(this);
|
||||
src_reg dPdy = this->result;
|
||||
|
||||
if (intel->gen >= 5) {
|
||||
dPdx.swizzle = BRW_SWIZZLE4(SWIZZLE_X,SWIZZLE_X,SWIZZLE_Y,SWIZZLE_Y);
|
||||
dPdy.swizzle = BRW_SWIZZLE4(SWIZZLE_X,SWIZZLE_X,SWIZZLE_Y,SWIZZLE_Y);
|
||||
emit(MOV(dst_reg(MRF, param_base + 1, type, WRITEMASK_XZ), dPdx));
|
||||
emit(MOV(dst_reg(MRF, param_base + 1, type, WRITEMASK_YW), dPdy));
|
||||
inst->mlen++;
|
||||
|
||||
if (ir->type->vector_elements == 3) {
|
||||
dPdx.swizzle = BRW_SWIZZLE_ZZZZ;
|
||||
dPdy.swizzle = BRW_SWIZZLE_ZZZZ;
|
||||
emit(MOV(dst_reg(MRF, param_base + 2, type, WRITEMASK_X), dPdx));
|
||||
emit(MOV(dst_reg(MRF, param_base + 2, type, WRITEMASK_Y), dPdy));
|
||||
inst->mlen++;
|
||||
}
|
||||
} else /* intel->gen == 4 */ {
|
||||
emit(MOV(dst_reg(MRF, param_base + 1, type, WRITEMASK_XYZ), dPdx));
|
||||
emit(MOV(dst_reg(MRF, param_base + 2, type, WRITEMASK_XYZ), dPdy));
|
||||
inst->mlen += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emit(inst);
|
||||
|
||||
this->result = src_reg(inst->dst);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue