Commit 25d47fc9 by Alexis Hetu Committed by Alexis Hétu

Texture function refactoring

To make it easier to branch on the different texture fetching options, a new TextureFunction class is introduced here, which performs the string comparisons and identifies the different options. I also had to add a 5th argument for textureGradOffset and textureProjGradOffset. I added function stubs (with the UNIMPLEMENTED markers) for all new texture functions. Change-Id: I58cde91a2bacb0012bdc34ec85b0befa19a85326 Reviewed-on: https://swiftshader-review.googlesource.com/4116Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 2ea6f557
......@@ -113,6 +113,86 @@ namespace glsl
return 0;
}
OutputASM::TextureFunction::TextureFunction(const TString& nodeName) : method(IMPLICIT), proj(false), offset(false)
{
TString name = TFunction::unmangleName(nodeName);
if(name == "texture2D" || name == "textureCube" || name == "texture" || name == "texture3D")
{
method = IMPLICIT;
}
else if(name == "texture2DProj" || name == "textureProj")
{
method = IMPLICIT;
proj = true;
}
else if(name == "texture2DLod" || name == "textureCubeLod" || name == "textureLod")
{
method = LOD;
}
else if(name == "texture2DProjLod" || name == "textureProjLod")
{
method = LOD;
proj = true;
}
else if(name == "textureSize")
{
method = SIZE;
}
else if(name == "textureOffset")
{
method = IMPLICIT;
offset = true;
}
else if(name == "textureProjOffset")
{
method = IMPLICIT;
offset = true;
proj = true;
}
else if(name == "textureLodOffset")
{
method = LOD;
offset = true;
}
else if(name == "textureProjLodOffset")
{
method = LOD;
proj = true;
offset = true;
}
else if(name == "texelFetch")
{
method = FETCH;
}
else if(name == "texelFetchOffset")
{
method = FETCH;
offset = true;
}
else if(name == "textureGrad")
{
method = GRAD;
}
else if(name == "textureGradOffset")
{
method = GRAD;
offset = true;
}
else if(name == "textureProjGrad")
{
method = GRAD;
proj = true;
}
else if(name == "textureProjGradOffset")
{
method = GRAD;
proj = true;
offset = true;
}
else UNREACHABLE(0);
}
OutputASM::OutputASM(TParseContext &context, Shader *shaderObject) : TIntermTraverser(true, true, true), mContext(context), shaderObject(shaderObject)
{
shader = 0;
......@@ -1042,105 +1122,161 @@ namespace glsl
}
else
{
TString name = TFunction::unmangleName(node->getName());
if(name == "texture" || name == "texture2D" || name == "textureCube" || name == "texture3D")
const TextureFunction textureFunction(node->getName());
switch(textureFunction.method)
{
if(argumentCount == 2)
case TextureFunction::IMPLICIT:
{
emit(sw::Shader::OPCODE_TEX, result, arg[1], arg[0]);
}
else if(argumentCount == 3) // bias
{
Temporary uvwb(this);
emit(sw::Shader::OPCODE_MOV, &uvwb, arg[1]);
Instruction *bias = emit(sw::Shader::OPCODE_MOV, &uvwb, arg[2]);
bias->dst.mask = 0x8;
Instruction *tex = emit(sw::Shader::OPCODE_TEX, result, &uvwb, arg[0]); // FIXME: Implement an efficient TEXLDB instruction
tex->bias = true;
}
else UNREACHABLE(argumentCount);
}
else if(name == "texture2DProj" || name == "textureProj")
{
TIntermTyped *t = arg[1]->getAsTyped();
TIntermTyped *t = arg[1]->getAsTyped();
if(argumentCount == 2)
{
Instruction *tex = emit(sw::Shader::OPCODE_TEX, result, arg[1], arg[0]);
tex->project = true;
TIntermNode* offset = textureFunction.offset ? arg[2] : 0;
if(t->getNominalSize() == 3)
if(argumentCount == 2 || (textureFunction.offset && argumentCount == 3))
{
Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX,
result, arg[1], arg[0], offset);
if(textureFunction.proj)
{
tex->project = true;
switch(t->getNominalSize())
{
case 2: tex->src[0].swizzle = 0x54; break; // xyyy
case 3: tex->src[0].swizzle = 0xA4; break; // xyzz
case 4: break; // xyzw
default:
UNREACHABLE(t->getNominalSize());
break;
}
}
}
else if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4)) // bias
{
tex->src[0].swizzle = 0xA4;
Temporary proj(this);
if(textureFunction.proj)
{
Instruction *div = emit(sw::Shader::OPCODE_DIV, &proj, arg[1], arg[1]);
div->dst.mask = 0x3;
switch(t->getNominalSize())
{
case 2:
case 3:
case 4:
div->src[1].swizzle = 0x55 * (t->getNominalSize() - 1);
break;
default:
UNREACHABLE(t->getNominalSize());
break;
}
}
else
{
emit(sw::Shader::OPCODE_MOV, &proj, arg[1]);
}
Instruction *bias = emit(sw::Shader::OPCODE_MOV, &proj, arg[textureFunction.offset ? 3 : 2]);
bias->dst.mask = 0x8;
Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX,
result, &proj, arg[0], offset); // FIXME: Implement an efficient TEXLDB instruction
tex->bias = true;
}
else ASSERT(t->getNominalSize() == 4);
else UNREACHABLE(argumentCount);
}
else if(argumentCount == 3) // bias
break;
case TextureFunction::LOD:
{
TIntermTyped *t = arg[1]->getAsTyped();
Temporary proj(this);
if(t->getNominalSize() == 3)
if(textureFunction.proj)
{
Instruction *div = emit(sw::Shader::OPCODE_DIV, &proj, arg[1], arg[1]);
div->src[1].swizzle = 0xAA;
div->dst.mask = 0x3;
Instruction *div = emit(sw::Shader::OPCODE_DIV, &proj, arg[1], arg[1]);
div->dst.mask = 0x3;
switch(t->getNominalSize())
{
case 2:
case 3:
case 4:
div->src[1].swizzle = 0x55 * (t->getNominalSize() - 1);
break;
default:
UNREACHABLE(t->getNominalSize());
break;
}
}
else if(t->getNominalSize() == 4)
else
{
Instruction *div = emit(sw::Shader::OPCODE_DIV, &proj, arg[1], arg[1]);
div->src[1].swizzle = 0xFF;
div->dst.mask = 0x3;
emit(sw::Shader::OPCODE_MOV, &proj, arg[1]);
}
else UNREACHABLE(t->getNominalSize());
Instruction *bias = emit(sw::Shader::OPCODE_MOV, &proj, arg[2]);
bias->dst.mask = 0x8;
Instruction *lod = emit(sw::Shader::OPCODE_MOV, &proj, arg[2]);
lod->dst.mask = 0x8;
Instruction *tex = emit(sw::Shader::OPCODE_TEX, result, &proj, arg[0]);
tex->bias = true;
emit(textureFunction.offset ? sw::Shader::OPCODE_TEXLDLOFFSET : sw::Shader::OPCODE_TEXLDL,
result, &proj, arg[0], textureFunction.offset ? arg[3] : 0);
}
else UNREACHABLE(argumentCount);
}
else if(name == "texture2DLod" || name == "textureCubeLod" || name == "textureLod")
{
Temporary uvwb(this);
emit(sw::Shader::OPCODE_MOV, &uvwb, arg[1]);
Instruction *lod = emit(sw::Shader::OPCODE_MOV, &uvwb, arg[2]);
lod->dst.mask = 0x8;
break;
case TextureFunction::FETCH:
{
TIntermTyped *t = arg[1]->getAsTyped();
emit(sw::Shader::OPCODE_TEXLDL, result, &uvwb, arg[0]);
}
else if(name == "texture2DProjLod" || name == "textureProjLod")
{
TIntermTyped *t = arg[1]->getAsTyped();
Temporary proj(this);
if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4))
{
TIntermNode* offset = textureFunction.offset ? arg[3] : 0;
if(t->getNominalSize() == 3)
{
Instruction *div = emit(sw::Shader::OPCODE_DIV, &proj, arg[1], arg[1]);
div->src[1].swizzle = 0xAA;
div->dst.mask = 0x3;
emit(textureFunction.offset ? sw::Shader::OPCODE_TEXELFETCHOFFSET : sw::Shader::OPCODE_TEXELFETCH,
result, arg[1], arg[0], arg[2], offset);
}
else UNREACHABLE(argumentCount);
}
else if(t->getNominalSize() == 4)
break;
case TextureFunction::GRAD:
{
Instruction *div = emit(sw::Shader::OPCODE_DIV, &proj, arg[1], arg[1]);
div->src[1].swizzle = 0xFF;
div->dst.mask = 0x3;
}
else UNREACHABLE(t->getNominalSize());
Instruction *lod = emit(sw::Shader::OPCODE_MOV, &proj, arg[2]);
lod->dst.mask = 0x8;
TIntermTyped *t = arg[1]->getAsTyped();
emit(sw::Shader::OPCODE_TEXLDL, result, &proj, arg[0]);
}
else if(name == "textureSize")
{
if(argumentCount == 4 || (textureFunction.offset && argumentCount == 5))
{
Temporary uvwb(this);
if(textureFunction.proj)
{
Instruction *div = emit(sw::Shader::OPCODE_DIV, &uvwb, arg[1], arg[1]);
div->dst.mask = 0x3;
switch(t->getNominalSize())
{
case 2:
case 3:
case 4:
div->src[1].swizzle = 0x55 * (t->getNominalSize() - 1);
break;
default:
UNREACHABLE(t->getNominalSize());
break;
}
}
else
{
emit(sw::Shader::OPCODE_MOV, &uvwb, arg[1]);
}
TIntermNode* offset = textureFunction.offset ? arg[4] : 0;
emit(textureFunction.offset ? sw::Shader::OPCODE_TEXGRADOFFSET : sw::Shader::OPCODE_TEXGRAD,
result, &uvwb, arg[0], arg[2], arg[3], offset);
}
else UNREACHABLE(argumentCount);
}
break;
case TextureFunction::SIZE:
emit(sw::Shader::OPCODE_TEXSIZE, result, arg[1], arg[0]);
break;
default:
UNREACHABLE(textureFunction.method);
}
else UNREACHABLE(0);
}
}
break;
......@@ -1483,7 +1619,7 @@ namespace glsl
TIntermTyped *condition = node->getCondition();
TIntermTyped *expression = node->getExpression();
TIntermNode *body = node->getBody();
if(node->getType() == ELoopDoWhile)
{
Temporary iterate(this);
......@@ -1607,7 +1743,7 @@ namespace glsl
return IsSampler(type.getBasicType()) && (type.getQualifier() == EvqUniform || type.getQualifier() == EvqTemporary);
}
Instruction *OutputASM::emit(sw::Shader::Opcode op, TIntermTyped *dst, TIntermNode *src0, TIntermNode *src1, TIntermNode *src2, TIntermNode *src3, int index)
Instruction *OutputASM::emit(sw::Shader::Opcode op, TIntermTyped *dst, TIntermNode *src0, TIntermNode *src1, TIntermNode *src2, TIntermNode *src3, TIntermNode *src4, int index)
{
if(isSamplerRegister(dst))
{
......@@ -1628,6 +1764,7 @@ namespace glsl
argument(instruction->src[1], src1, index);
argument(instruction->src[2], src2, index);
argument(instruction->src[3], src3, index);
argument(instruction->src[4], src4, index);
shader->append(instruction);
......@@ -1683,7 +1820,7 @@ namespace glsl
{
for(int index = 0; index < dst->elementRegisterCount(); index++)
{
emit(op, dst, src0, src1, src2, 0, index);
emit(op, dst, src0, src1, src2, 0, 0, index);
}
}
......
......@@ -164,6 +164,24 @@ namespace glsl
FUNCTION
};
struct TextureFunction
{
TextureFunction(const TString& name);
enum Method
{
IMPLICIT, // Mipmap LOD determined implicitly (standard lookup)
LOD,
SIZE, // textureSize()
FETCH,
GRAD
};
Method method;
bool proj;
bool offset;
};
void emitShader(Scope scope);
// Visit AST nodes and output their code to the body stream
......@@ -176,7 +194,7 @@ namespace glsl
virtual bool visitBranch(Visit visit, TIntermBranch*);
sw::Shader::Opcode getOpcode(sw::Shader::Opcode op, TIntermTyped *in) const;
Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0, TIntermNode *src3 = 0, int index = 0);
Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0, TIntermNode *src3 = 0, TIntermNode *src4 = 0, int index = 0);
Instruction *emitCast(TIntermTyped *dst, TIntermTyped *src);
void emitBinary(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0);
void emitAssign(sw::Shader::Opcode op, TIntermTyped *result, TIntermTyped *lhs, TIntermTyped *src0, TIntermTyped *src1 = 0);
......
......@@ -110,6 +110,7 @@ namespace sw
const Src &src1 = instruction->src[1];
const Src &src2 = instruction->src[2];
const Src &src3 = instruction->src[3];
const Src &src4 = instruction->src[4];
bool predicate = instruction->predicate;
Control control = instruction->control;
......@@ -122,6 +123,7 @@ namespace sw
Vector4f s1;
Vector4f s2;
Vector4f s3;
Vector4f s4;
if(opcode == Shader::OPCODE_TEXKILL) // Takes destination as input
{
......@@ -142,6 +144,7 @@ namespace sw
if(src1.type != Shader::PARAMETER_VOID) s1 = fetchRegisterF(r, src1);
if(src2.type != Shader::PARAMETER_VOID) s2 = fetchRegisterF(r, src2);
if(src3.type != Shader::PARAMETER_VOID) s3 = fetchRegisterF(r, src3);
if(src4.type != Shader::PARAMETER_VOID) s4 = fetchRegisterF(r, src4);
switch(opcode)
{
......@@ -275,6 +278,12 @@ namespace sw
case Shader::OPCODE_TEXLDL: TEXLDL(r, d, s0, src1, project, bias); break;
case Shader::OPCODE_TEXSIZE: TEXSIZE(r, d, s0.x, src1); break;
case Shader::OPCODE_TEXKILL: TEXKILL(cMask, d, dst.mask); break;
case Shader::OPCODE_TEXOFFSET: TEXOFFSET(r, d, s0, src1, s2, s3, project, bias); break;
case Shader::OPCODE_TEXLDLOFFSET: TEXLDL(r, d, s0, src1, s2, project, bias); break;
case Shader::OPCODE_TEXELFETCH: TEXELFETCH(r, d, s0, src1, s2); break;
case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCH(r, d, s0, src1, s2, s3); break;
case Shader::OPCODE_TEXGRAD: TEXGRAD(r, d, s0, src1, s2, s3); break;
case Shader::OPCODE_TEXGRADOFFSET: TEXGRAD(r, d, s0, src1, s2, s3, s4); break;
case Shader::OPCODE_DISCARD: DISCARD(r, cMask, instruction); break;
case Shader::OPCODE_DFDX: DFDX(d, s0); break;
case Shader::OPCODE_DFDY: DFDY(d, s0); break;
......@@ -1030,6 +1039,36 @@ namespace sw
dst.w = tmp[(src1.swizzle >> 6) & 0x3];
}
void PixelProgram::TEXOFFSET(Registers &r, Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3, bool project, bool bias)
{
UNIMPLEMENTED();
}
void PixelProgram::TEXLDL(Registers &r, Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, bool project, bool bias)
{
UNIMPLEMENTED();
}
void PixelProgram::TEXELFETCH(Registers &r, Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2)
{
UNIMPLEMENTED();
}
void PixelProgram::TEXELFETCH(Registers &r, Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &offset)
{
UNIMPLEMENTED();
}
void PixelProgram::TEXGRAD(Registers &r, Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3)
{
UNIMPLEMENTED();
}
void PixelProgram::TEXGRAD(Registers &r, Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3, Vector4f &offset)
{
UNIMPLEMENTED();
}
void PixelProgram::TEXLDD(Registers &r, Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3, bool project, bool bias)
{
Vector4f tmp;
......
......@@ -112,6 +112,12 @@ namespace sw
void TEXLDL(Registers &r, Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias);
void TEXSIZE(Registers &r, Vector4f &dst, Float4 &lod, const Src &src1);
void TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask);
void TEXOFFSET(Registers &r, Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, bool project, bool bias);
void TEXLDL(Registers &r, Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool project, bool bias);
void TEXELFETCH(Registers &r, Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2);
void TEXELFETCH(Registers &r, Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3);
void TEXGRAD(Registers &r, Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3);
void TEXGRAD(Registers &r, Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, Vector4f &src4);
void DISCARD(Registers &r, Int cMask[4], const Shader::Instruction *instruction);
void DFDX(Vector4f &dst, Vector4f &src);
void DFDY(Vector4f &dst, Vector4f &src);
......
......@@ -299,6 +299,12 @@ namespace sw
case Shader::OPCODE_TEX:
case Shader::OPCODE_TEXLDD:
case Shader::OPCODE_TEXLDL:
case Shader::OPCODE_TEXOFFSET:
case Shader::OPCODE_TEXLDLOFFSET:
case Shader::OPCODE_TEXELFETCH:
case Shader::OPCODE_TEXELFETCHOFFSET:
case Shader::OPCODE_TEXGRAD:
case Shader::OPCODE_TEXGRADOFFSET:
{
int sampler = instruction[i]->src[1].index;
......
......@@ -865,6 +865,12 @@ namespace sw
case OPCODE_TEXLDD: return "texldd";
case OPCODE_CMP: return "cmp";
case OPCODE_TEXLDL: return "texldl";
case OPCODE_TEXOFFSET: return "texoffset";
case OPCODE_TEXLDLOFFSET: return "texldloffset";
case OPCODE_TEXELFETCH: return "texelfetch";
case OPCODE_TEXELFETCHOFFSET: return "texelfetchoffset";
case OPCODE_TEXGRAD: return "texgrad";
case OPCODE_TEXGRADOFFSET: return "texgradoffset";
case OPCODE_BREAKP: return "breakp";
case OPCODE_TEXSIZE: return "texsize";
case OPCODE_PHASE: return "phase";
......@@ -1772,6 +1778,12 @@ namespace sw
case OPCODE_TEXM3X2DEPTH:
case OPCODE_TEXLDD:
case OPCODE_TEXLDL:
case OPCODE_TEXOFFSET:
case OPCODE_TEXLDLOFFSET:
case OPCODE_TEXELFETCH:
case OPCODE_TEXELFETCHOFFSET:
case OPCODE_TEXGRAD:
case OPCODE_TEXGRADOFFSET:
{
Parameter &dst = instruction[i]->dst;
Parameter &src1 = instruction[i]->src[1];
......
......@@ -205,6 +205,12 @@ namespace sw
OPCODE_SMOOTH,
OPCODE_ISNAN,
OPCODE_ISINF,
OPCODE_TEXOFFSET,
OPCODE_TEXLDLOFFSET,
OPCODE_TEXELFETCH,
OPCODE_TEXELFETCHOFFSET,
OPCODE_TEXGRAD,
OPCODE_TEXGRADOFFSET,
OPCODE_FLOATBITSTOINT,
OPCODE_FLOATBITSTOUINT,
OPCODE_INTBITSTOFLOAT,
......@@ -511,7 +517,7 @@ namespace sw
unsigned char usageIndex;
DestinationParameter dst;
SourceParameter src[4];
SourceParameter src[5];
union
{
......
......@@ -103,6 +103,7 @@ namespace sw
Src src1 = instruction->src[1];
Src src2 = instruction->src[2];
Src src3 = instruction->src[3];
Src src4 = instruction->src[4];
bool predicate = instruction->predicate;
Control control = instruction->control;
......@@ -114,11 +115,13 @@ namespace sw
Vector4f s1;
Vector4f s2;
Vector4f s3;
Vector4f s4;
if(src0.type != Shader::PARAMETER_VOID) s0 = fetchRegisterF(r, src0);
if(src1.type != Shader::PARAMETER_VOID) s1 = fetchRegisterF(r, src1);
if(src2.type != Shader::PARAMETER_VOID) s2 = fetchRegisterF(r, src2);
if(src3.type != Shader::PARAMETER_VOID) s3 = fetchRegisterF(r, src3);
if(src4.type != Shader::PARAMETER_VOID) s4 = fetchRegisterF(r, src4);
switch(opcode)
{
......@@ -289,6 +292,12 @@ namespace sw
case Shader::OPCODE_NE: notEqual(d, s0, s1); break;
case Shader::OPCODE_TEXLDL: TEXLDL(r, d, s0, src1); break;
case Shader::OPCODE_TEX: TEX(r, d, s0, src1); break;
case Shader::OPCODE_TEXOFFSET: TEXOFFSET(r, d, s0, src1, s2, s3); break;
case Shader::OPCODE_TEXLDLOFFSET: TEXLDL(r, d, s0, src1, s2); break;
case Shader::OPCODE_TEXELFETCH: TEXELFETCH(r, d, s0, src1, s2); break;
case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCH(r, d, s0, src1, s2, s3); break;
case Shader::OPCODE_TEXGRAD: TEXGRAD(r, d, s0, src1, s2, s3); break;
case Shader::OPCODE_TEXGRADOFFSET: TEXGRAD(r, d, s0, src1, s2, s3, s4); break;
case Shader::OPCODE_TEXSIZE: TEXSIZE(r, d, s0.x, src1); break;
case Shader::OPCODE_END: break;
default:
......@@ -1488,6 +1497,36 @@ namespace sw
dst.w = tmp[(src1.swizzle >> 6) & 0x3];
}
void VertexProgram::TEXOFFSET(Registers &r, Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3)
{
UNIMPLEMENTED();
}
void VertexProgram::TEXLDL(Registers &r, Vector4f &dst, Vector4f &src, const Src&, Vector4f &offset)
{
UNIMPLEMENTED();
}
void VertexProgram::TEXELFETCH(Registers &r, Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2)
{
UNIMPLEMENTED();
}
void VertexProgram::TEXELFETCH(Registers &r, Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &offset)
{
UNIMPLEMENTED();
}
void VertexProgram::TEXGRAD(Registers &r, Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3)
{
UNIMPLEMENTED();
}
void VertexProgram::TEXGRAD(Registers &r, Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3, Vector4f &offset)
{
UNIMPLEMENTED();
}
void VertexProgram::TEXSIZE(Registers &r, Vector4f &dst, Float4 &lod, const Src &src1)
{
Pointer<Byte> textureMipmap = r.data + OFFSET(DrawData, mipmap[16]) + src1.index * sizeof(Texture) + OFFSET(Texture, mipmap);
......
......@@ -79,6 +79,12 @@ namespace sw
void LEAVE(Registers &r);
void TEXLDL(Registers &r, Vector4f &dst, Vector4f &src, const Src&);
void TEX(Registers &r, Vector4f &dst, Vector4f &src, const Src&);
void TEXOFFSET(Registers &r, Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3);
void TEXLDL(Registers &r, Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2);
void TEXELFETCH(Registers &r, Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2);
void TEXELFETCH(Registers &r, Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3);
void TEXGRAD(Registers &r, Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3);
void TEXGRAD(Registers &r, Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, Vector4f &src4);
void TEXSIZE(Registers &r, Vector4f &dst, Float4 &lod, const Src&);
void sampleTexture(Registers &r, Vector4f &c, const Src &s, Float4 &u, Float4 &v, Float4 &w, Float4 &q);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment