Commit f2a8c37e by Alexis Hetu Committed by Alexis Hétu

Splitting PixelRoutine into PixelProgram and PixelPipeline

This cl splits PixelRoutine into 2 specialized classes: PixelProgram and PixelPipeline. In this cl: - Moved all specialized behavior of PixelRoutine into the PixelProgram and PixelPipeline classes. - Inverted hierarchical dependency between PixelRoutine and QuadRasterizer. QuadRasterizer is now the base class. - Added a check to PixelProcessor::routine() to either create a PixelPipeline object or a PixelProgram object. - Moved a few interpolation related utility functions from PixelRoutine down to QuadRasterizer. - Added Registers hierarchy. PixelProgram specific Registers and PixelPipeline specific Registers are now mutually exclusive. - Made the quad functions virtual - Added a few virtual functions (setBuiltins, ps, alphaTest, rasterOperation) for Program/Pipeline specific implementations Bug 20257503 Change-Id: I6abe536a5521d9842f757a8bbb52e3947e3c9250 Reviewed-on: https://swiftshader-review.googlesource.com/3634Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent d9e4c610
......@@ -55,6 +55,8 @@ LOCAL_SRC_FILES += \
LOCAL_SRC_FILES += \
Shader/Constants.cpp \
Shader/PixelPipeline.cpp \
Shader/PixelProgram.cpp \
Shader/PixelRoutine.cpp \
Shader/PixelShader.cpp \
Shader/SamplerCore.cpp \
......
......@@ -233,6 +233,10 @@
<Unit filename="../../Renderer/VertexProcessor.hpp" />
<Unit filename="../../Shader/Constants.cpp" />
<Unit filename="../../Shader/Constants.hpp" />
<Unit filename="../../Shader/PixelPipeline.cpp" />
<Unit filename="../../Shader/PixelPipeline.hpp" />
<Unit filename="../../Shader/PixelProgram.cpp" />
<Unit filename="../../Shader/PixelProgram.hpp" />
<Unit filename="../../Shader/PixelRoutine.cpp" />
<Unit filename="../../Shader/PixelRoutine.hpp" />
<Unit filename="../../Shader/PixelShader.cpp" />
......
......@@ -232,6 +232,10 @@
<Unit filename="../../Renderer/VertexProcessor.hpp" />
<Unit filename="../../Shader/Constants.cpp" />
<Unit filename="../../Shader/Constants.hpp" />
<Unit filename="../../Shader/PixelPipeline.cpp" />
<Unit filename="../../Shader/PixelPipeline.hpp" />
<Unit filename="../../Shader/PixelProgram.cpp" />
<Unit filename="../../Shader/PixelProgram.hpp" />
<Unit filename="../../Shader/PixelRoutine.cpp" />
<Unit filename="../../Shader/PixelRoutine.hpp" />
<Unit filename="../../Shader/PixelShader.cpp" />
......
......@@ -11,7 +11,8 @@
#include "PixelProcessor.hpp"
#include "QuadRasterizer.hpp"
#include "PixelPipeline.hpp"
#include "PixelProgram.hpp"
#include "PixelShader.hpp"
#include "MetaMacro.hpp"
#include "Surface.hpp"
......@@ -1057,7 +1058,16 @@ namespace sw
if(!routine)
{
Rasterizer *generator = new QuadRasterizer(state, context->pixelShader);
const bool integerPipeline = (context->pixelShaderVersion() <= 0x0104);
Rasterizer *generator = nullptr;
if(integerPipeline)
{
generator = new PixelPipeline(state, context->pixelShader);
}
else
{
generator = new PixelProgram(state, context->pixelShader);
}
generator->generate();
routine = generator->getRoutine();
delete generator;
......
......@@ -21,10 +21,23 @@ namespace sw
{
extern bool veryEarlyDepthTest;
extern bool complementaryDepthBuffer;
extern bool fullPixelPositionRegister;
extern int clusterCount;
QuadRasterizer::QuadRasterizer(const PixelProcessor::State &state, const PixelShader *pixelShader) : PixelRoutine(state, pixelShader)
QuadRasterizer::Registers::Registers()
{
occlusion = 0;
#if PERF_PROFILE
for(int i = 0; i < PERF_TIMERS; i++)
{
cycles[i] = 0;
}
#endif
}
QuadRasterizer::QuadRasterizer(const PixelProcessor::State &state, const PixelShader *pixelShader) : Rasterizer(state), shader(pixelShader)
{
}
......@@ -45,7 +58,7 @@ namespace sw
Int cluster(function.arg(2));
Pointer<Byte> data(function.arg(3));
Registers r(shader);
Registers& r = *createRegisters(shader);
r.constants = *Pointer<Pointer<Byte> >(data + OFFSET(DrawData,constants));
r.cluster = cluster;
r.data = data;
......@@ -89,6 +102,8 @@ namespace sw
#endif
Return();
delete &r;
}
routine = function(L"PixelRoutine_%0.8X", state.shaderID);
......@@ -317,4 +332,31 @@ namespace sw
}
Until(y >= yMax)
}
Float4 QuadRasterizer::interpolate(Float4 &x, Float4 &D, Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective)
{
Float4 interpolant = D;
if(!flat)
{
interpolant += x * *Pointer<Float4>(planeEquation + OFFSET(PlaneEquation, A), 16);
if(perspective)
{
interpolant *= rhw;
}
}
return interpolant;
}
bool QuadRasterizer::interpolateZ() const
{
return state.depthTestActive || state.pixelFogActive() || (shader && shader->vPosDeclared && fullPixelPositionRegister);
}
bool QuadRasterizer::interpolateW() const
{
return state.perspective || (shader && shader->vPosDeclared && fullPixelPositionRegister);
}
}
......@@ -13,17 +13,51 @@
#define sw_QuadRasterizer_hpp
#include "Rasterizer.hpp"
#include "PixelRoutine.hpp"
#include "ShaderCore.hpp"
#include "PixelShader.hpp"
#include "Types.hpp"
namespace sw
{
class QuadRasterizer : public PixelRoutine
class QuadRasterizer : public Rasterizer
{
public:
QuadRasterizer(const PixelProcessor::State &state, const PixelShader *pixelShader);
protected:
QuadRasterizer(const PixelProcessor::State &state, const PixelShader *shader);
virtual ~QuadRasterizer();
struct Registers
{
Registers();
Pointer<Byte> constants;
Pointer<Byte> primitive;
Int cluster;
Pointer<Byte> data;
Float4 Dz[4];
Float4 Dw;
Float4 Dv[10][4];
Float4 Df;
UInt occlusion;
#if PERF_PROFILE
Long cycles[PERF_TIMERS];
#endif
};
virtual void quad(Registers &r, Pointer<Byte> cBuffer[4], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x, Int &y) = 0;
virtual Registers* createRegisters(const PixelShader *shader) = 0;
bool interpolateZ() const;
bool interpolateW() const;
Float4 interpolate(Float4 &x, Float4 &D, Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective);
const PixelShader *const shader;
private:
void generate();
......
// SwiftShader Software Renderer
//
// Copyright(c) 2015 Google Inc.
//
// All rights reserved. No part of this software may be copied, distributed, transmitted,
// transcribed, stored in a retrieval system, translated into any human or computer
// language by any means, or disclosed to third parties without the explicit written
// agreement of Google Inc. Without such an agreement, no rights or licenses, express
// or implied, including but not limited to any patent rights, are granted to you.
//
#ifndef sw_PixelPipeline_hpp
#define sw_PixelPipeline_hpp
#include "PixelRoutine.hpp"
namespace sw
{
class PixelPipeline : public PixelRoutine
{
public:
PixelPipeline(const PixelProcessor::State &state, const PixelShader *shader) :
PixelRoutine(state, shader), perturbate(false), luminance(false), previousScaling(false) {}
virtual ~PixelPipeline() {}
protected:
virtual void setBuiltins(PixelRoutine::Registers &r, Int &x, Int &y, Float4(&z)[4], Float4 &w);
virtual void applyShader(PixelRoutine::Registers &r, Int cMask[4]);
virtual Bool alphaTest(PixelRoutine::Registers &r, Int cMask[4]);
virtual void rasterOperation(PixelRoutine::Registers &r, Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]);
virtual QuadRasterizer::Registers* createRegisters(const PixelShader *shader) { return new PixelPipeline::Registers(shader); };
private:
struct Registers : public PixelRoutine::Registers
{
Registers(const PixelShader *shader) : PixelRoutine::Registers(shader), current(rs[0]), diffuse(vs[0]), specular(vs[1]) {}
Vector4s &current;
Vector4s &diffuse;
Vector4s &specular;
Vector4s rs[6];
Vector4s vs[2];
Vector4s ts[6];
// bem(l) offsets and luminance
Float4 du;
Float4 dv;
Short4 L;
// texm3x3 temporaries
Float4 u_; // FIXME
Float4 v_; // FIXME
Float4 w_; // FIXME
Float4 U; // FIXME
Float4 V; // FIXME
Float4 W; // FIXME
};
void fixedFunction(Registers& r);
void blendTexture(Registers &r, Vector4s &temp, Vector4s &texture, int stage);
void fogBlend(Registers &r, Vector4s &current, Float4 &fog, Float4 &z, Float4 &rhw);
void specularPixel(Vector4s &current, Vector4s &specular);
void sampleTexture(Registers &r, Vector4s &c, int coordinates, int sampler, bool project = false);
void sampleTexture(Registers &r, Vector4s &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, bool project = false, bool bias = false);
void sampleTexture(Registers &r, Vector4s &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project = false, bool bias = false, bool gradients = false, bool lodProvided = false);
Short4 convertFixed12(RValue<Float4> cf);
void convertFixed12(Vector4s &cs, Vector4f &cf);
Float4 convertSigned12(Short4 &cs);
void convertSigned12(Vector4f &cf, Vector4s &cs);
void writeDestination(Registers &r, Vector4s &d, const Dst &dst);
Vector4s fetchRegisterS(Registers &r, const Src &src);
// Instructions
void MOV(Vector4s &dst, Vector4s &src0);
void ADD(Vector4s &dst, Vector4s &src0, Vector4s &src1);
void SUB(Vector4s &dst, Vector4s &src0, Vector4s &src1);
void MAD(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2);
void MUL(Vector4s &dst, Vector4s &src0, Vector4s &src1);
void DP3(Vector4s &dst, Vector4s &src0, Vector4s &src1);
void DP4(Vector4s &dst, Vector4s &src0, Vector4s &src1);
void LRP(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2);
void TEXCOORD(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int coordinate);
void TEXCRD(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int coordinate, bool project);
void TEXDP3(Registers &r, Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src);
void TEXDP3TEX(Registers &r, Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0);
void TEXKILL(Int cMask[4], Float4 &u, Float4 &v, Float4 &s);
void TEXKILL(Int cMask[4], Vector4s &dst);
void TEX(Registers &r, Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, bool project);
void TEXLD(Registers &r, Vector4s &dst, Vector4s &src, int stage, bool project);
void TEXBEM(Registers &r, Vector4s &dst, Vector4s &src, Float4 &u, Float4 &v, Float4 &s, int stage);
void TEXBEML(Registers &r, Vector4s &dst, Vector4s &src, Float4 &u, Float4 &v, Float4 &s, int stage);
void TEXREG2AR(Registers &r, Vector4s &dst, Vector4s &src0, int stage);
void TEXREG2GB(Registers &r, Vector4s &dst, Vector4s &src0, int stage);
void TEXREG2RGB(Registers &r, Vector4s &dst, Vector4s &src0, int stage);
void TEXM3X2DEPTH(Registers &r, Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src, bool signedScaling);
void TEXM3X2PAD(Registers &r, Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, int component, bool signedScaling);
void TEXM3X2TEX(Registers &r, Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, bool signedScaling);
void TEXM3X3(Registers &r, Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, bool signedScaling);
void TEXM3X3PAD(Registers &r, Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, int component, bool signedScaling);
void TEXM3X3SPEC(Registers &r, Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, Vector4s &src1);
void TEXM3X3TEX(Registers &r, Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, bool singedScaling);
void TEXM3X3VSPEC(Registers &r, Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0);
void TEXDEPTH(Registers &r);
void CND(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2);
void CMP(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2);
void BEM(Registers &r, Vector4s &dst, Vector4s &src0, Vector4s &src1, int stage);
bool perturbate;
bool luminance;
bool previousScaling;
};
}
#endif
// SwiftShader Software Renderer
//
// Copyright(c) 2015 Google Inc.
//
// All rights reserved. No part of this software may be copied, distributed, transmitted,
// transcribed, stored in a retrieval system, translated into any human or computer
// language by any means, or disclosed to third parties without the explicit written
// agreement of Google Inc. Without such an agreement, no rights or licenses, express
// or implied, including but not limited to any patent rights, are granted to you.
//
#ifndef sw_PixelProgram_hpp
#define sw_PixelProgram_hpp
#include "PixelRoutine.hpp"
namespace sw
{
class PixelProgram : public PixelRoutine
{
public:
PixelProgram(const PixelProcessor::State &state, const PixelShader *shader) :
PixelRoutine(state, shader), ifDepth(0), loopRepDepth(0), breakDepth(0), currentLabel(-1), whileTest(false)
{
for(int i = 0; i < 2048; ++i)
{
labelBlock[i] = 0;
}
}
virtual ~PixelProgram() {}
protected:
virtual void setBuiltins(PixelRoutine::Registers &r, Int &x, Int &y, Float4(&z)[4], Float4 &w);
virtual void applyShader(PixelRoutine::Registers &r, Int cMask[4]);
virtual Bool alphaTest(PixelRoutine::Registers &r, Int cMask[4]);
virtual void rasterOperation(PixelRoutine::Registers &r, Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]);
virtual QuadRasterizer::Registers* createRegisters(const PixelShader *shader) { return new PixelProgram::Registers(shader); };
private:
struct Registers : public PixelRoutine::Registers
{
Registers(const PixelShader *shader) : PixelRoutine::Registers(shader), loopDepth(-1)
{
enableStack[0] = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
if(shader && shader->containsBreakInstruction())
{
enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
}
if(shader && shader->containsContinueInstruction())
{
enableContinue = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
}
}
// Shader variables
Vector4f vPos;
Vector4f vFace;
// DX9 specific variables
Vector4f p0;
Array<Int, 4> aL;
Array<Int, 4> increment;
Array<Int, 4> iteration;
Int loopDepth; // FIXME: Add support for switch
Int stackIndex; // FIXME: Inc/decrement callStack
Array<UInt, 16> callStack;
// Per pixel based on conditions reached
Int enableIndex;
Array<Int4, 1 + 24> enableStack;
Int4 enableBreak;
Int4 enableContinue;
Int4 enableLeave;
};
void sampleTexture(Registers &r, Vector4f &c, const Src &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project = false, bool bias = false, bool gradients = false, bool lodProvided = false);
void sampleTexture(Registers &r, Vector4f &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project = false, bool bias = false, bool gradients = false, bool lodProvided = false);
// Raster operations
void clampColor(Vector4f oC[4]);
Int4 enableMask(Registers &r, const Shader::Instruction *instruction);
Vector4f fetchRegisterF(Registers &r, const Src &src, int offset = 0);
Vector4f readConstant(Registers &r, const Src &src, int offset = 0);
Int relativeAddress(Registers &r, const Shader::Parameter &var);
Float4 linearToSRGB(const Float4 &x);
// Instructions
typedef Shader::Control Control;
void M3X2(Registers &r, Vector4f &dst, Vector4f &src0, const Src &src1);
void M3X3(Registers &r, Vector4f &dst, Vector4f &src0, const Src &src1);
void M3X4(Registers &r, Vector4f &dst, Vector4f &src0, const Src &src1);
void M4X3(Registers &r, Vector4f &dst, Vector4f &src0, const Src &src1);
void M4X4(Registers &r, Vector4f &dst, Vector4f &src0, const Src &src1);
void TEXLD(Registers &r, Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias);
void TEXLDD(Registers &r, Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3, bool project, bool bias);
void TEXLDL(Registers &r, Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias);
void TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask);
void DISCARD(Registers &r, Int cMask[4], const Shader::Instruction *instruction);
void DFDX(Vector4f &dst, Vector4f &src);
void DFDY(Vector4f &dst, Vector4f &src);
void FWIDTH(Vector4f &dst, Vector4f &src);
void BREAK(Registers &r);
void BREAKC(Registers &r, Vector4f &src0, Vector4f &src1, Control);
void BREAKP(Registers &r, const Src &predicateRegister);
void BREAK(Registers &r, Int4 &condition);
void CONTINUE(Registers &r);
void TEST();
void CALL(Registers &r, int labelIndex, int callSiteIndex);
void CALLNZ(Registers &r, int labelIndex, int callSiteIndex, const Src &src);
void CALLNZb(Registers &r, int labelIndex, int callSiteIndex, const Src &boolRegister);
void CALLNZp(Registers &r, int labelIndex, int callSiteIndex, const Src &predicateRegister);
void ELSE(Registers &r);
void ENDIF(Registers &r);
void ENDLOOP(Registers &r);
void ENDREP(Registers &r);
void ENDWHILE(Registers &r);
void IF(Registers &r, const Src &src);
void IFb(Registers &r, const Src &boolRegister);
void IFp(Registers &r, const Src &predicateRegister);
void IFC(Registers &r, Vector4f &src0, Vector4f &src1, Control);
void IF(Registers &r, Int4 &condition);
void LABEL(int labelIndex);
void LOOP(Registers &r, const Src &integerRegister);
void REP(Registers &r, const Src &integerRegister);
void WHILE(Registers &r, const Src &temporaryRegister);
void RET(Registers &r);
void LEAVE(Registers &r);
int ifDepth;
int loopRepDepth;
int breakDepth;
int currentLabel;
bool whileTest;
// FIXME: Get rid of llvm::
llvm::BasicBlock *ifFalseBlock[24 + 24];
llvm::BasicBlock *loopRepTestBlock[4];
llvm::BasicBlock *loopRepEndBlock[4];
llvm::BasicBlock *labelBlock[2048];
std::vector<llvm::BasicBlock*> callRetBlock[2048];
llvm::BasicBlock *returnBlock;
bool isConditionalIf[24 + 24];
};
}
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -321,6 +321,8 @@
<ClCompile Include="..\Main\FrameBufferWin.cpp" />
<ClCompile Include="..\Main\Register.cpp" />
<ClCompile Include="..\Shader\Constants.cpp" />
<ClCompile Include="..\Shader\PixelPipeline.cpp" />
<ClCompile Include="..\Shader\PixelProgram.cpp" />
<ClCompile Include="..\Shader\PixelRoutine.cpp" />
<ClCompile Include="..\Shader\PixelShader.cpp" />
<ClCompile Include="..\Shader\SamplerCore.cpp" />
......@@ -390,6 +392,8 @@
<ClInclude Include="..\Main\FrameBufferWin.hpp" />
<ClInclude Include="..\Main\Register.hpp" />
<ClInclude Include="..\Renderer\RoutineCache.hpp" />
<ClInclude Include="..\Shader\PixelPipeline.hpp" />
<ClInclude Include="..\Shader\PixelProgram.hpp" />
<ClInclude Include="MemoryManager.hpp" />
<ClInclude Include="..\Shader\Constants.hpp" />
<ClInclude Include="..\Shader\PixelRoutine.hpp" />
......
......@@ -179,6 +179,12 @@
<ClCompile Include="..\Main\crc.cpp">
<Filter>Source Files\Main</Filter>
</ClCompile>
<ClCompile Include="..\Shader\PixelPipeline.cpp">
<Filter>Source Files\Shader</Filter>
</ClCompile>
<ClCompile Include="..\Shader\PixelProgram.cpp">
<Filter>Source Files\Shader</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="MemoryManager.hpp">
......@@ -356,6 +362,12 @@
<ClInclude Include="..\Common\SharedLibrary.hpp">
<Filter>Header Files\Common</Filter>
</ClInclude>
<ClInclude Include="..\Shader\PixelProgram.hpp">
<Filter>Header Files\Shader</Filter>
</ClInclude>
<ClInclude Include="..\Shader\PixelPipeline.hpp">
<Filter>Header Files\Shader</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="SwiftShader.ini" />
......
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