Commit 68a82384 by Nicolas Capens Committed by Nicolas Capens

Duplicate source files for Vulkan.

The Vulkan implementation needs a directory for each architectural layer, similar to the OpenGL ES stack. The entire rendering stack is duplicated, leaving only Reactor common between them: Renderer -> Device Shader -> Pipeline Common -> System Main -> WSI Bug b/117152542 Change-Id: I9c26b23654016d637f88ec2416f019ef65b9afbd Reviewed-on: https://swiftshader-review.googlesource.com/c/21248Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 64d537a5
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_Blitter_hpp
#define sw_Blitter_hpp
#include "Surface.hpp"
#include "RoutineCache.hpp"
#include "Reactor/Reactor.hpp"
#include <string.h>
namespace sw
{
class Blitter
{
struct Options
{
Options() = default;
Options(bool filter, bool useStencil, bool convertSRGB)
: writeMask(0xF), clearOperation(false), filter(filter), useStencil(useStencil), convertSRGB(convertSRGB), clampToEdge(false) {}
Options(unsigned int writeMask)
: writeMask(writeMask), clearOperation(true), filter(false), useStencil(false), convertSRGB(true), clampToEdge(false) {}
union
{
struct
{
bool writeRed : 1;
bool writeGreen : 1;
bool writeBlue : 1;
bool writeAlpha : 1;
};
unsigned char writeMask;
};
bool clearOperation : 1;
bool filter : 1;
bool useStencil : 1;
bool convertSRGB : 1;
bool clampToEdge : 1;
};
struct State : Options
{
State() = default;
State(const Options &options) : Options(options) {}
bool operator==(const State &state) const
{
return memcmp(this, &state, sizeof(State)) == 0;
}
Format sourceFormat;
Format destFormat;
int destSamples;
};
struct BlitData
{
void *source;
void *dest;
int sPitchB;
int dPitchB;
int dSliceB;
float x0;
float y0;
float w;
float h;
int y0d;
int y1d;
int x0d;
int x1d;
int sWidth;
int sHeight;
};
public:
Blitter();
virtual ~Blitter();
void clear(void *pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask);
void blit(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, const Options &options);
void blit3D(Surface *source, Surface *dest);
private:
bool fastClear(void *pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask);
bool read(Float4 &color, Pointer<Byte> element, const State &state);
bool write(Float4 &color, Pointer<Byte> element, const State &state);
bool read(Int4 &color, Pointer<Byte> element, const State &state);
bool write(Int4 &color, Pointer<Byte> element, const State &state);
static bool GetScale(float4& scale, Format format);
static bool ApplyScaleAndClamp(Float4 &value, const State &state, bool preScaled = false);
static Int ComputeOffset(Int &x, Int &y, Int &pitchB, int bytes, bool quadLayout);
static Float4 LinearToSRGB(Float4 &color);
static Float4 sRGBtoLinear(Float4 &color);
bool blitReactor(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, const Options &options);
Routine *generate(const State &state);
RoutineCache<State> *blitCache;
MutexLock criticalSection;
};
}
#endif // sw_Blitter_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "Clipper.hpp"
#include "Polygon.hpp"
#include "Renderer.hpp"
#include "Common/Debug.hpp"
namespace sw
{
Clipper::Clipper(bool symmetricNormalizedDepth)
{
n = symmetricNormalizedDepth ? -1.0f : 0.0f;
}
Clipper::~Clipper()
{
}
unsigned int Clipper::computeClipFlags(const float4 &v)
{
return ((v.x > v.w) ? CLIP_RIGHT : 0) |
((v.y > v.w) ? CLIP_TOP : 0) |
((v.z > v.w) ? CLIP_FAR : 0) |
((v.x < -v.w) ? CLIP_LEFT : 0) |
((v.y < -v.w) ? CLIP_BOTTOM : 0) |
((v.z < n * v.w) ? CLIP_NEAR : 0) |
Clipper::CLIP_FINITE; // FIXME: xyz finite
}
bool Clipper::clip(Polygon &polygon, int clipFlagsOr, const DrawCall &draw)
{
if(clipFlagsOr & CLIP_FRUSTUM)
{
if(clipFlagsOr & CLIP_NEAR) clipNear(polygon);
if(polygon.n >= 3) {
if(clipFlagsOr & CLIP_FAR) clipFar(polygon);
if(polygon.n >= 3) {
if(clipFlagsOr & CLIP_LEFT) clipLeft(polygon);
if(polygon.n >= 3) {
if(clipFlagsOr & CLIP_RIGHT) clipRight(polygon);
if(polygon.n >= 3) {
if(clipFlagsOr & CLIP_TOP) clipTop(polygon);
if(polygon.n >= 3) {
if(clipFlagsOr & CLIP_BOTTOM) clipBottom(polygon);
}}}}}
}
if(clipFlagsOr & CLIP_USER)
{
int clipFlags = draw.clipFlags;
DrawData &data = *draw.data;
if(polygon.n >= 3) {
if(clipFlags & CLIP_PLANE0) clipPlane(polygon, data.clipPlane[0]);
if(polygon.n >= 3) {
if(clipFlags & CLIP_PLANE1) clipPlane(polygon, data.clipPlane[1]);
if(polygon.n >= 3) {
if(clipFlags & CLIP_PLANE2) clipPlane(polygon, data.clipPlane[2]);
if(polygon.n >= 3) {
if(clipFlags & CLIP_PLANE3) clipPlane(polygon, data.clipPlane[3]);
if(polygon.n >= 3) {
if(clipFlags & CLIP_PLANE4) clipPlane(polygon, data.clipPlane[4]);
if(polygon.n >= 3) {
if(clipFlags & CLIP_PLANE5) clipPlane(polygon, data.clipPlane[5]);
}}}}}}
}
return polygon.n >= 3;
}
void Clipper::clipNear(Polygon &polygon)
{
const float4 **V = polygon.P[polygon.i];
const float4 **T = polygon.P[polygon.i + 1];
int t = 0;
for(int i = 0; i < polygon.n; i++)
{
int j = i == polygon.n - 1 ? 0 : i + 1;
float di = V[i]->z - n * V[i]->w;
float dj = V[j]->z - n * V[j]->w;
if(di >= 0)
{
T[t++] = V[i];
if(dj < 0)
{
clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
T[t++] = &polygon.B[polygon.b++];
}
}
else
{
if(dj > 0)
{
clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
T[t++] = &polygon.B[polygon.b++];
}
}
}
polygon.n = t;
polygon.i += 1;
}
void Clipper::clipFar(Polygon &polygon)
{
const float4 **V = polygon.P[polygon.i];
const float4 **T = polygon.P[polygon.i + 1];
int t = 0;
for(int i = 0; i < polygon.n; i++)
{
int j = i == polygon.n - 1 ? 0 : i + 1;
float di = V[i]->w - V[i]->z;
float dj = V[j]->w - V[j]->z;
if(di >= 0)
{
T[t++] = V[i];
if(dj < 0)
{
clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
T[t++] = &polygon.B[polygon.b++];
}
}
else
{
if(dj > 0)
{
clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
T[t++] = &polygon.B[polygon.b++];
}
}
}
polygon.n = t;
polygon.i += 1;
}
void Clipper::clipLeft(Polygon &polygon)
{
const float4 **V = polygon.P[polygon.i];
const float4 **T = polygon.P[polygon.i + 1];
int t = 0;
for(int i = 0; i < polygon.n; i++)
{
int j = i == polygon.n - 1 ? 0 : i + 1;
float di = V[i]->w + V[i]->x;
float dj = V[j]->w + V[j]->x;
if(di >= 0)
{
T[t++] = V[i];
if(dj < 0)
{
clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
T[t++] = &polygon.B[polygon.b++];
}
}
else
{
if(dj > 0)
{
clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
T[t++] = &polygon.B[polygon.b++];
}
}
}
polygon.n = t;
polygon.i += 1;
}
void Clipper::clipRight(Polygon &polygon)
{
const float4 **V = polygon.P[polygon.i];
const float4 **T = polygon.P[polygon.i + 1];
int t = 0;
for(int i = 0; i < polygon.n; i++)
{
int j = i == polygon.n - 1 ? 0 : i + 1;
float di = V[i]->w - V[i]->x;
float dj = V[j]->w - V[j]->x;
if(di >= 0)
{
T[t++] = V[i];
if(dj < 0)
{
clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
T[t++] = &polygon.B[polygon.b++];
}
}
else
{
if(dj > 0)
{
clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
T[t++] = &polygon.B[polygon.b++];
}
}
}
polygon.n = t;
polygon.i += 1;
}
void Clipper::clipTop(Polygon &polygon)
{
const float4 **V = polygon.P[polygon.i];
const float4 **T = polygon.P[polygon.i + 1];
int t = 0;
for(int i = 0; i < polygon.n; i++)
{
int j = i == polygon.n - 1 ? 0 : i + 1;
float di = V[i]->w - V[i]->y;
float dj = V[j]->w - V[j]->y;
if(di >= 0)
{
T[t++] = V[i];
if(dj < 0)
{
clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
T[t++] = &polygon.B[polygon.b++];
}
}
else
{
if(dj > 0)
{
clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
T[t++] = &polygon.B[polygon.b++];
}
}
}
polygon.n = t;
polygon.i += 1;
}
void Clipper::clipBottom(Polygon &polygon)
{
const float4 **V = polygon.P[polygon.i];
const float4 **T = polygon.P[polygon.i + 1];
int t = 0;
for(int i = 0; i < polygon.n; i++)
{
int j = i == polygon.n - 1 ? 0 : i + 1;
float di = V[i]->w + V[i]->y;
float dj = V[j]->w + V[j]->y;
if(di >= 0)
{
T[t++] = V[i];
if(dj < 0)
{
clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
T[t++] = &polygon.B[polygon.b++];
}
}
else
{
if(dj > 0)
{
clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
T[t++] = &polygon.B[polygon.b++];
}
}
}
polygon.n = t;
polygon.i += 1;
}
void Clipper::clipPlane(Polygon &polygon, const Plane &p)
{
const float4 **V = polygon.P[polygon.i];
const float4 **T = polygon.P[polygon.i + 1];
int t = 0;
for(int i = 0; i < polygon.n; i++)
{
int j = i == polygon.n - 1 ? 0 : i + 1;
float di = p.A * V[i]->x + p.B * V[i]->y + p.C * V[i]->z + p.D * V[i]->w;
float dj = p.A * V[j]->x + p.B * V[j]->y + p.C * V[j]->z + p.D * V[j]->w;
if(di >= 0)
{
T[t++] = V[i];
if(dj < 0)
{
clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
T[t++] = &polygon.B[polygon.b++];
}
}
else
{
if(dj > 0)
{
clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
T[t++] = &polygon.B[polygon.b++];
}
}
}
polygon.n = t;
polygon.i += 1;
}
inline void Clipper::clipEdge(float4 &Vo, const float4 &Vi, const float4 &Vj, float di, float dj) const
{
float D = 1.0f / (dj - di);
Vo.x = (dj * Vi.x - di * Vj.x) * D;
Vo.y = (dj * Vi.y - di * Vj.y) * D;
Vo.z = (dj * Vi.z - di * Vj.z) * D;
Vo.w = (dj * Vi.w - di * Vj.w) * D;
}
}
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_Clipper_hpp
#define sw_Clipper_hpp
#include "Plane.hpp"
#include "Common/Types.hpp"
namespace sw
{
struct Polygon;
struct DrawCall;
struct DrawData;
class Clipper
{
public:
enum ClipFlags
{
// Indicates the vertex is outside the respective frustum plane
CLIP_RIGHT = 1 << 0,
CLIP_TOP = 1 << 1,
CLIP_FAR = 1 << 2,
CLIP_LEFT = 1 << 3,
CLIP_BOTTOM = 1 << 4,
CLIP_NEAR = 1 << 5,
CLIP_FRUSTUM = 0x003F,
CLIP_FINITE = 1 << 7, // All position coordinates are finite
// User-defined clipping planes
CLIP_PLANE0 = 1 << 8,
CLIP_PLANE1 = 1 << 9,
CLIP_PLANE2 = 1 << 10,
CLIP_PLANE3 = 1 << 11,
CLIP_PLANE4 = 1 << 12,
CLIP_PLANE5 = 1 << 13,
CLIP_USER = 0x3F00
};
Clipper(bool symmetricNormalizedDepth);
~Clipper();
unsigned int computeClipFlags(const float4 &v);
bool clip(Polygon &polygon, int clipFlagsOr, const DrawCall &draw);
private:
void clipNear(Polygon &polygon);
void clipFar(Polygon &polygon);
void clipLeft(Polygon &polygon);
void clipRight(Polygon &polygon);
void clipTop(Polygon &polygon);
void clipBottom(Polygon &polygon);
void clipPlane(Polygon &polygon, const Plane &plane);
void clipEdge(float4 &Vo, const float4 &Vi, const float4 &Vj, float di, float dj) const;
float n; // Near clip plane distance
};
}
#endif // sw_Clipper_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "Color.hpp"
namespace sw
{
}
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "Config.hpp"
#include "Common/Thread.hpp"
#include "Common/Timer.hpp"
namespace sw
{
Profiler profiler;
Profiler::Profiler()
{
reset();
}
void Profiler::reset()
{
framesSec = 0;
framesTotal = 0;
FPS = 0;
#if PERF_PROFILE
for(int i = 0; i < PERF_TIMERS; i++)
{
cycles[i] = 0;
}
ropOperations = 0;
ropOperationsTotal = 0;
ropOperationsFrame = 0;
texOperations = 0;
texOperationsTotal = 0;
texOperationsFrame = 0;
compressedTex = 0;
compressedTexTotal = 0;
compressedTexFrame = 0;
#endif
};
void Profiler::nextFrame()
{
#if PERF_PROFILE
ropOperationsFrame = sw::atomicExchange(&ropOperations, 0);
texOperationsFrame = sw::atomicExchange(&texOperations, 0);
compressedTexFrame = sw::atomicExchange(&compressedTex, 0);
ropOperationsTotal += ropOperationsFrame;
texOperationsTotal += texOperationsFrame;
compressedTexTotal += compressedTexFrame;
#endif
static double fpsTime = sw::Timer::seconds();
double time = sw::Timer::seconds();
double delta = time - fpsTime;
framesSec++;
if(delta > 1.0)
{
FPS = framesSec / delta;
fpsTime = time;
framesTotal += framesSec;
framesSec = 0;
}
}
}
\ No newline at end of file
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_Config_hpp
#define sw_Config_hpp
#include "Common/Types.hpp"
#define PERF_HUD 0 // Display time spent on vertex, setup and pixel processing for each thread
#define PERF_PROFILE 0 // Profile various pipeline stages and display the timing in SwiftConfig
#define ASTC_SUPPORT 0
// Worker thread count when not set by SwiftConfig
// 0 = process affinity count (recommended)
// 1 = rendering on main thread (no worker threads), useful for debugging
#ifndef DEFAULT_THREAD_COUNT
#define DEFAULT_THREAD_COUNT 0
#endif
namespace sw
{
enum
{
PERF_PIXEL,
PERF_PIPE,
PERF_INTERP,
PERF_SHADER,
PERF_TEX,
PERF_ROP,
PERF_TIMERS
};
struct Profiler
{
Profiler();
void reset();
void nextFrame();
int framesSec;
int framesTotal;
double FPS;
#if PERF_PROFILE
double cycles[PERF_TIMERS];
int64_t ropOperations;
int64_t ropOperationsTotal;
int64_t ropOperationsFrame;
int64_t texOperations;
int64_t texOperationsTotal;
int64_t texOperationsFrame;
int64_t compressedTex;
int64_t compressedTexTotal;
int64_t compressedTexFrame;
#endif
};
extern Profiler profiler;
enum
{
OUTLINE_RESOLUTION = 8192, // Maximum vertical resolution of the render target
MIPMAP_LEVELS = 14,
TEXTURE_IMAGE_UNITS = 16,
VERTEX_TEXTURE_IMAGE_UNITS = 16,
TOTAL_IMAGE_UNITS = TEXTURE_IMAGE_UNITS + VERTEX_TEXTURE_IMAGE_UNITS,
FRAGMENT_UNIFORM_VECTORS = 264,
VERTEX_UNIFORM_VECTORS = 259,
MAX_VERTEX_INPUTS = 32,
MAX_VERTEX_OUTPUTS = 34,
MAX_FRAGMENT_INPUTS = 32,
MAX_FRAGMENT_UNIFORM_BLOCKS = 12,
MAX_VERTEX_UNIFORM_BLOCKS = 12,
MAX_UNIFORM_BUFFER_BINDINGS = MAX_FRAGMENT_UNIFORM_BLOCKS + MAX_VERTEX_UNIFORM_BLOCKS, // Limited to 127 by SourceParameter.bufferIndex in Shader.hpp
MAX_UNIFORM_BLOCK_SIZE = 16384,
MAX_CLIP_PLANES = 6,
MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 64,
MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 64,
MIN_PROGRAM_TEXEL_OFFSET = -8,
MAX_PROGRAM_TEXEL_OFFSET = 7,
MAX_TEXTURE_LOD = MIPMAP_LEVELS - 2, // Trilinear accesses lod+1
RENDERTARGETS = 8,
NUM_TEMPORARY_REGISTERS = 4096,
};
}
#endif // sw_Config_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
class ETC_Decoder
{
public:
enum InputType
{
ETC_R_SIGNED,
ETC_R_UNSIGNED,
ETC_RG_SIGNED,
ETC_RG_UNSIGNED,
ETC_RGB,
ETC_RGB_PUNCHTHROUGH_ALPHA,
ETC_RGBA
};
/// ETC_Decoder::Decode - Decodes 1 to 4 channel images to 8 bit output
/// @param src Pointer to ETC2 encoded image
/// @param dst Pointer to BGRA, 8 bit output
/// @param w src image width
/// @param h src image height
/// @param dstW dst image width
/// @param dstH dst image height
/// @param dstPitch dst image pitch (bytes per row)
/// @param dstBpp dst image bytes per pixel
/// @param inputType src's format
/// @return true if the decoding was performed
static bool Decode(const unsigned char* src, unsigned char *dst, int w, int h, int dstW, int dstH, int dstPitch, int dstBpp, InputType inputType);
};
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_LRUCache_hpp
#define sw_LRUCache_hpp
#include "Common/Math.hpp"
namespace sw
{
template<class Key, class Data>
class LRUCache
{
public:
LRUCache(int n);
~LRUCache();
Data *query(const Key &key) const;
Data *add(const Key &key, Data *data);
int getSize() {return size;}
Key &getKey(int i) {return key[i];}
private:
int size;
int mask;
int top;
int fill;
Key *key;
Key **ref;
Data **data;
};
}
namespace sw
{
template<class Key, class Data>
LRUCache<Key, Data>::LRUCache(int n)
{
size = ceilPow2(n);
mask = size - 1;
top = 0;
fill = 0;
key = new Key[size];
ref = new Key*[size];
data = new Data*[size];
for(int i = 0; i < size; i++)
{
data[i] = nullptr;
ref[i] = &key[i];
}
}
template<class Key, class Data>
LRUCache<Key, Data>::~LRUCache()
{
delete[] key;
key = nullptr;
delete[] ref;
ref = nullptr;
for(int i = 0; i < size; i++)
{
if(data[i])
{
data[i]->unbind();
data[i] = nullptr;
}
}
delete[] data;
data = nullptr;
}
template<class Key, class Data>
Data *LRUCache<Key, Data>::query(const Key &key) const
{
for(int i = top; i > top - fill; i--)
{
int j = i & mask;
if(key == *ref[j])
{
Data *hit = data[j];
if(i != top)
{
// Move one up
int k = (j + 1) & mask;
Data *swapD = data[k];
data[k] = data[j];
data[j] = swapD;
Key *swapK = ref[k];
ref[k] = ref[j];
ref[j] = swapK;
}
return hit;
}
}
return nullptr; // Not found
}
template<class Key, class Data>
Data *LRUCache<Key, Data>::add(const Key &key, Data *data)
{
top = (top + 1) & mask;
fill = fill + 1 < size ? fill + 1 : size;
*ref[top] = key;
data->bind();
if(this->data[top])
{
this->data[top]->unbind();
}
this->data[top] = data;
return data;
}
}
#endif // sw_LRUCache_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef Matrix_hpp
#define Matrix_hpp
namespace sw
{
struct Vector;
struct Point;
struct float4;
struct Matrix
{
Matrix();
Matrix(const int i);
Matrix(const float m[16]);
Matrix(const float m[4][4]);
Matrix(float m11, float m12, float m13,
float m21, float m22, float m23,
float m31, float m32, float m33);
Matrix(float m11, float m12, float m13, float m14,
float m21, float m22, float m23, float m24,
float m31, float m32, float m33, float m34,
float m41, float m42, float m43, float m44);
Matrix(const Vector &v1, const Vector &v2, const Vector &v3); // Column vectors
Matrix &operator=(const Matrix &N);
// Row major order
float m[4][4];
static Matrix diag(float m11, float m22, float m33, float m44);
operator float*();
Matrix operator+() const;
Matrix operator-() const;
Matrix operator!() const; // Inverse
Matrix operator~() const; // Transpose
Matrix &operator+=(const Matrix &N);
Matrix &operator-=(const Matrix &N);
Matrix &operator*=(float s);
Matrix &operator*=(const Matrix &N);
Matrix &operator/=(float s);
float *operator[](int i); // Access element [row][col], starting with [0][0]
const float *operator[](int i) const;
float &operator()(int i, int j); // Access element (row, col), starting with (1, 1)
const float &operator()(int i, int j) const;
friend bool operator==(const Matrix &M, const Matrix &N);
friend bool operator!=(const Matrix &M, const Matrix &N);
friend Matrix operator+(const Matrix &M, const Matrix &N);
friend Matrix operator-(const Matrix &M, const Matrix &N);
friend Matrix operator*(float s, const Matrix &M);
friend Matrix operator*(const Matrix &M, const Matrix &N);
friend Matrix operator/(const Matrix &M, float s);
float4 operator*(const float4 &v) const;
static float det(const Matrix &M);
static float det(float m11);
static float det(float m11, float m12,
float m21, float m22);
static float det(float m11, float m12, float m13,
float m21, float m22, float m23,
float m31, float m32, float m33);
static float det(float m11, float m12, float m13, float m14,
float m21, float m22, float m23, float m24,
float m31, float m32, float m33, float m34,
float m41, float m42, float m43, float m44);
static float det(const Vector &v1, const Vector &v2, const Vector &v3);
static float det3(const Matrix &M);
static float tr(const Matrix &M);
Matrix &orthogonalise(); // Gram-Schmidt orthogonalisation of 3x3 submatrix
static Matrix eulerRotate(const Vector &v);
static Matrix eulerRotate(float x, float y, float z);
static Matrix translate(const Vector &v);
static Matrix translate(float x, float y, float z);
static Matrix scale(const Vector &v);
static Matrix scale(float x, float y, float z);
static Matrix lookAt(const Vector &v);
static Matrix lookAt(float x, float y, float z);
};
}
#include "Vector.hpp"
namespace sw
{
inline Matrix::Matrix()
{
}
inline Matrix::Matrix(const int i)
{
const float s = (float)i;
Matrix &M = *this;
M(1, 1) = s; M(1, 2) = 0; M(1, 3) = 0; M(1, 4) = 0;
M(2, 1) = 0; M(2, 2) = s; M(2, 3) = 0; M(2, 4) = 0;
M(3, 1) = 0; M(3, 2) = 0; M(3, 3) = s; M(3, 4) = 0;
M(4, 1) = 0; M(4, 2) = 0; M(4, 3) = 0; M(4, 4) = s;
}
inline Matrix::Matrix(const float m[16])
{
Matrix &M = *this;
M(1, 1) = m[0]; M(1, 2) = m[1]; M(1, 3) = m[2]; M(1, 4) = m[3];
M(2, 1) = m[4]; M(2, 2) = m[5]; M(2, 3) = m[6]; M(2, 4) = m[7];
M(3, 1) = m[8]; M(3, 2) = m[8]; M(3, 3) = m[10]; M(3, 4) = m[11];
M(4, 1) = m[12]; M(4, 2) = m[13]; M(4, 3) = m[14]; M(4, 4) = m[15];
}
inline Matrix::Matrix(const float m[4][4])
{
Matrix &M = *this;
M[0][0] = m[0][0]; M[0][1] = m[0][1]; M[0][2] = m[0][2]; M[0][3] = m[0][3];
M[1][0] = m[1][0]; M[1][1] = m[1][1]; M[1][2] = m[1][2]; M[1][3] = m[1][3];
M[2][0] = m[2][0]; M[2][1] = m[2][1]; M[2][2] = m[2][2]; M[2][3] = m[2][3];
M[3][0] = m[3][0]; M[3][1] = m[3][1]; M[3][2] = m[3][2]; M[3][3] = m[3][3];
}
inline Matrix::Matrix(float m11, float m12, float m13,
float m21, float m22, float m23,
float m31, float m32, float m33)
{
Matrix &M = *this;
M(1, 1) = m11; M(1, 2) = m12; M(1, 3) = m13; M(1, 4) = 0;
M(2, 1) = m21; M(2, 2) = m22; M(2, 3) = m23; M(2, 4) = 0;
M(3, 1) = m31; M(3, 2) = m32; M(3, 3) = m33; M(3, 4) = 0;
M(4, 1) = 0; M(4, 2) = 0; M(4, 3) = 0; M(4, 4) = 1;
}
inline Matrix::Matrix(float m11, float m12, float m13, float m14,
float m21, float m22, float m23, float m24,
float m31, float m32, float m33, float m34,
float m41, float m42, float m43, float m44)
{
Matrix &M = *this;
M(1, 1) = m11; M(1, 2) = m12; M(1, 3) = m13; M(1, 4) = m14;
M(2, 1) = m21; M(2, 2) = m22; M(2, 3) = m23; M(2, 4) = m24;
M(3, 1) = m31; M(3, 2) = m32; M(3, 3) = m33; M(3, 4) = m34;
M(4, 1) = m41; M(4, 2) = m42; M(4, 3) = m43; M(4, 4) = m44;
}
inline Matrix::Matrix(const Vector &v1, const Vector &v2, const Vector &v3)
{
Matrix &M = *this;
M(1, 1) = v1.x; M(1, 2) = v2.x; M(1, 3) = v3.x; M(1, 4) = 0;
M(2, 1) = v1.y; M(2, 2) = v2.y; M(2, 3) = v3.y; M(2, 4) = 0;
M(3, 1) = v1.z; M(3, 2) = v2.z; M(3, 3) = v3.z; M(3, 4) = 0;
M(4, 1) = 0; M(4, 2) = 0; M(4, 3) = 0; M(4, 4) = 1;
}
inline Matrix &Matrix::operator=(const Matrix &N)
{
Matrix &M = *this;
M(1, 1) = N(1, 1); M(1, 2) = N(1, 2); M(1, 3) = N(1, 3); M(1, 4) = N(1, 4);
M(2, 1) = N(2, 1); M(2, 2) = N(2, 2); M(2, 3) = N(2, 3); M(2, 4) = N(2, 4);
M(3, 1) = N(3, 1); M(3, 2) = N(3, 2); M(3, 3) = N(3, 3); M(3, 4) = N(3, 4);
M(4, 1) = N(4, 1); M(4, 2) = N(4, 2); M(4, 3) = N(4, 3); M(4, 4) = N(4, 4);
return M;
}
inline float *Matrix::operator[](int i)
{
return m[i];
}
inline const float *Matrix::operator[](int i) const
{
return m[i];
}
inline float &Matrix::operator()(int i, int j)
{
return m[i - 1][j - 1];
}
inline const float &Matrix::operator()(int i, int j) const
{
return m[i - 1][j - 1];
}
}
#endif // Matrix_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "Plane.hpp"
#include "Matrix.hpp"
namespace sw
{
Plane::Plane()
{
}
Plane::Plane(float p_A, float p_B, float p_C, float p_D)
{
A = p_A;
B = p_B;
C = p_C;
D = p_D;
}
Plane::Plane(const float ABCD[4])
{
A = ABCD[0];
B = ABCD[1];
C = ABCD[2];
D = ABCD[3];
}
Plane operator*(const Plane &p, const Matrix &T)
{
Matrix M = !T;
return Plane(p.A * M(1, 1) + p.B * M(1, 2) + p.C * M(1, 3) + p.D * M(1, 4),
p.A * M(2, 1) + p.B * M(2, 2) + p.C * M(2, 3) + p.D * M(2, 4),
p.A * M(3, 1) + p.B * M(3, 2) + p.C * M(3, 3) + p.D * M(3, 4),
p.A * M(4, 1) + p.B * M(4, 2) + p.C * M(4, 3) + p.D * M(4, 4));
}
Plane operator*(const Matrix &T, const Plane &p)
{
Matrix M = !T;
return Plane(M(1, 1) * p.A + M(2, 1) * p.B + M(3, 1) * p.C + M(4, 1) * p.D,
M(1, 2) * p.A + M(2, 2) * p.B + M(3, 2) * p.C + M(4, 2) * p.D,
M(1, 3) * p.A + M(2, 3) * p.B + M(3, 3) * p.C + M(4, 3) * p.D,
M(1, 4) * p.A + M(2, 4) * p.B + M(3, 4) * p.C + M(4, 4) * p.D);
}
}
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef Plane_hpp
#define Plane_hpp
#include "Vector.hpp"
namespace sw
{
struct Matrix;
struct Plane
{
float A;
float B;
float C;
float D;
Plane();
Plane(float A, float B, float C, float D); // Plane equation
Plane(const float ABCD[4]);
friend Plane operator*(const Plane &p, const Matrix &A); // Transform plane by matrix (post-multiply)
friend Plane operator*(const Matrix &A, const Plane &p); // Transform plane by matrix (pre-multiply)
};
}
#endif // Plane_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "Point.hpp"
#include "Matrix.hpp"
namespace sw
{
Point &Point::operator+=(const Vector &v)
{
x += v.x;
y += v.y;
z += v.z;
return *this;
}
Point &Point::operator-=(const Vector &v)
{
x -= v.x;
y -= v.y;
z -= v.z;
return *this;
}
Point operator+(const Point &P, const Vector &v)
{
return Point(P.x + v.x, P.y + v.y, P.z + v.z);
}
Point operator-(const Point &P, const Vector &v)
{
return Point(P.x - v.x, P.y - v.y, P.z - v.z);
}
Vector operator-(const Point &P, const Point &Q)
{
return Vector(P.x - Q.x, P.y - Q.y, P.z - Q.z);
}
Point operator*(const Matrix &M, const Point &P)
{
return Point(M(1, 1) * P.x + M(1, 2) * P.y + M(1, 3) * P.z + M(1, 4),
M(2, 1) * P.x + M(2, 2) * P.y + M(2, 3) * P.z + M(2, 4),
M(3, 1) * P.x + M(3, 2) * P.y + M(3, 3) * P.z + M(3, 4));
}
Point operator*(const Point &P, const Matrix &M)
{
return Point(P.x * M(1, 1) + P.y * M(2, 1) + P.z * M(3, 1),
P.x * M(1, 2) + P.y * M(2, 2) + P.z * M(3, 2),
P.x * M(1, 3) + P.y * M(2, 3) + P.z * M(3, 3));
}
Point &operator*=(Point &P, const Matrix &M)
{
return P = P * M;
}
float Point::d(const Point &P) const
{
return Vector::N(*this - P);
}
float Point::d2(const Point &P) const
{
return Vector::N2(*this - P);
}
float Point::d(const Point &P, const Point &Q)
{
return Vector::N(P - Q);
}
float Point::d2(const Point &P, const Point &Q)
{
return Vector::N2(P - Q);
}
}
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef Point_hpp
#define Point_hpp
namespace sw
{
struct Vector;
struct Matrix;
struct Point
{
Point();
Point(const int i);
Point(const Point &P);
Point(const Vector &v);
Point(float Px, float Py, float Pz);
Point &operator=(const Point &P);
union
{
float p[3];
struct
{
float x;
float y;
float z;
};
};
float &operator[](int i);
float &operator()(int i);
const float &operator[](int i) const;
const float &operator()(int i) const;
Point &operator+=(const Vector &v);
Point &operator-=(const Vector &v);
friend Point operator+(const Point &P, const Vector &v);
friend Point operator-(const Point &P, const Vector &v);
friend Vector operator-(const Point &P, const Point &Q);
friend Point operator*(const Matrix &M, const Point& P);
friend Point operator*(const Point &P, const Matrix &M);
friend Point &operator*=(Point &P, const Matrix &M);
float d(const Point &P) const; // Distance between two points
float d2(const Point &P) const; // Squared distance between two points
static float d(const Point &P, const Point &Q); // Distance between two points
static float d2(const Point &P, const Point &Q); // Squared distance between two points
};
}
#include "Vector.hpp"
namespace sw
{
inline Point::Point()
{
}
inline Point::Point(const int i)
{
const float s = (float)i;
x = s;
y = s;
z = s;
}
inline Point::Point(const Point &P)
{
x = P.x;
y = P.y;
z = P.z;
}
inline Point::Point(const Vector &v)
{
x = v.x;
y = v.y;
z = v.z;
}
inline Point::Point(float P_x, float P_y, float P_z)
{
x = P_x;
y = P_y;
z = P_z;
}
inline Point &Point::operator=(const Point &P)
{
x = P.x;
y = P.y;
z = P.z;
return *this;
}
inline float &Point::operator()(int i)
{
return p[i];
}
inline float &Point::operator[](int i)
{
return p[i];
}
inline const float &Point::operator()(int i) const
{
return p[i];
}
inline const float &Point::operator[](int i) const
{
return p[i];
}
}
#endif // Point_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_Polygon_hpp
#define sw_Polygon_hpp
#include "Vertex.hpp"
namespace sw
{
struct Polygon
{
Polygon(const float4 *P0, const float4 *P1, const float4 *P2)
{
P[0][0] = P0;
P[0][1] = P1;
P[0][2] = P2;
n = 3;
i = 0;
b = 0;
}
Polygon(const float4 *P, int n)
{
for(int i = 0; i < n; i++)
{
this->P[0][i] = &P[i];
}
this->n = n;
this->i = 0;
this->b = 0;
}
float4 B[16]; // Buffer for clipped vertices
const float4 *P[16][16]; // Pointers to clipped polygon's vertices
int n; // Number of vertices
int i; // Level of P to use
int b; // Next available new vertex
};
}
#endif // sw_Polygon_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_Primitive_hpp
#define sw_Primitive_hpp
#include "Vertex.hpp"
#include "Main/Config.hpp"
namespace sw
{
struct Triangle
{
Vertex v0;
Vertex v1;
Vertex v2;
};
struct PlaneEquation // z = A * x + B * y + C
{
float4 A;
float4 B;
float4 C;
};
struct Primitive
{
int yMin;
int yMax;
float4 xQuad;
float4 yQuad;
PlaneEquation z;
PlaneEquation w;
union
{
struct
{
PlaneEquation C[2][4];
PlaneEquation T[8][4];
PlaneEquation f;
};
PlaneEquation V[MAX_FRAGMENT_INPUTS][4];
};
float area;
// Masks for two-sided stencil
int64_t clockwiseMask;
int64_t invClockwiseMask;
struct Span
{
unsigned short left;
unsigned short right;
};
// The rasterizer adds a zero length span to the top and bottom of the polygon to allow
// for 2x2 pixel processing. We need an even number of spans to keep accesses aligned.
Span outlineUnderflow[2];
Span outline[OUTLINE_RESOLUTION];
Span outlineOverflow[2];
};
}
#endif // sw_Primitive_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "QuadRasterizer.hpp"
#include "Primitive.hpp"
#include "Renderer.hpp"
#include "Shader/Constants.hpp"
#include "Common/Math.hpp"
#include "Common/Debug.hpp"
namespace sw
{
extern bool veryEarlyDepthTest;
extern bool complementaryDepthBuffer;
extern bool fullPixelPositionRegister;
extern int clusterCount;
QuadRasterizer::QuadRasterizer(const PixelProcessor::State &state, const PixelShader *pixelShader) : state(state), shader(pixelShader)
{
}
QuadRasterizer::~QuadRasterizer()
{
}
void QuadRasterizer::generate()
{
#if PERF_PROFILE
for(int i = 0; i < PERF_TIMERS; i++)
{
cycles[i] = 0;
}
Long pixelTime = Ticks();
#endif
constants = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,constants));
occlusion = 0;
int clusterCount = Renderer::getClusterCount();
Do
{
Int yMin = *Pointer<Int>(primitive + OFFSET(Primitive,yMin));
Int yMax = *Pointer<Int>(primitive + OFFSET(Primitive,yMax));
Int cluster2 = cluster + cluster;
yMin += clusterCount * 2 - 2 - cluster2;
yMin &= -clusterCount * 2;
yMin += cluster2;
If(yMin < yMax)
{
rasterize(yMin, yMax);
}
primitive += sizeof(Primitive) * state.multiSample;
count--;
}
Until(count == 0)
if(state.occlusionEnabled)
{
UInt clusterOcclusion = *Pointer<UInt>(data + OFFSET(DrawData,occlusion) + 4 * cluster);
clusterOcclusion += occlusion;
*Pointer<UInt>(data + OFFSET(DrawData,occlusion) + 4 * cluster) = clusterOcclusion;
}
#if PERF_PROFILE
cycles[PERF_PIXEL] = Ticks() - pixelTime;
for(int i = 0; i < PERF_TIMERS; i++)
{
*Pointer<Long>(data + OFFSET(DrawData,cycles[i]) + 8 * cluster) += cycles[i];
}
#endif
Return();
}
void QuadRasterizer::rasterize(Int &yMin, Int &yMax)
{
Pointer<Byte> cBuffer[RENDERTARGETS];
Pointer<Byte> zBuffer;
Pointer<Byte> sBuffer;
for(int index = 0; index < RENDERTARGETS; index++)
{
if(state.colorWriteActive(index))
{
cBuffer[index] = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,colorBuffer[index])) + yMin * *Pointer<Int>(data + OFFSET(DrawData,colorPitchB[index]));
}
}
if(state.depthTestActive)
{
zBuffer = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,depthBuffer)) + yMin * *Pointer<Int>(data + OFFSET(DrawData,depthPitchB));
}
if(state.stencilActive)
{
sBuffer = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,stencilBuffer)) + yMin * *Pointer<Int>(data + OFFSET(DrawData,stencilPitchB));
}
Int y = yMin;
Do
{
Int x0a = Int(*Pointer<Short>(primitive + OFFSET(Primitive,outline->left) + (y + 0) * sizeof(Primitive::Span)));
Int x0b = Int(*Pointer<Short>(primitive + OFFSET(Primitive,outline->left) + (y + 1) * sizeof(Primitive::Span)));
Int x0 = Min(x0a, x0b);
for(unsigned int q = 1; q < state.multiSample; q++)
{
x0a = Int(*Pointer<Short>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline->left) + (y + 0) * sizeof(Primitive::Span)));
x0b = Int(*Pointer<Short>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline->left) + (y + 1) * sizeof(Primitive::Span)));
x0 = Min(x0, Min(x0a, x0b));
}
x0 &= 0xFFFFFFFE;
Int x1a = Int(*Pointer<Short>(primitive + OFFSET(Primitive,outline->right) + (y + 0) * sizeof(Primitive::Span)));
Int x1b = Int(*Pointer<Short>(primitive + OFFSET(Primitive,outline->right) + (y + 1) * sizeof(Primitive::Span)));
Int x1 = Max(x1a, x1b);
for(unsigned int q = 1; q < state.multiSample; q++)
{
x1a = Int(*Pointer<Short>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline->right) + (y + 0) * sizeof(Primitive::Span)));
x1b = Int(*Pointer<Short>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline->right) + (y + 1) * sizeof(Primitive::Span)));
x1 = Max(x1, Max(x1a, x1b));
}
Float4 yyyy = Float4(Float(y)) + *Pointer<Float4>(primitive + OFFSET(Primitive,yQuad), 16);
if(interpolateZ())
{
for(unsigned int q = 0; q < state.multiSample; q++)
{
Float4 y = yyyy;
if(state.multiSample > 1)
{
y -= *Pointer<Float4>(constants + OFFSET(Constants,Y) + q * sizeof(float4));
}
Dz[q] = *Pointer<Float4>(primitive + OFFSET(Primitive,z.C), 16) + y * *Pointer<Float4>(primitive + OFFSET(Primitive,z.B), 16);
}
}
if(veryEarlyDepthTest && state.multiSample == 1 && !state.depthOverride)
{
if(!state.stencilActive && state.depthTestActive && (state.depthCompareMode == DEPTH_LESSEQUAL || state.depthCompareMode == DEPTH_LESS)) // FIXME: Both modes ok?
{
Float4 xxxx = Float4(Float(x0)) + *Pointer<Float4>(primitive + OFFSET(Primitive,xQuad), 16);
Pointer<Byte> buffer;
Int pitch;
if(!state.quadLayoutDepthBuffer)
{
buffer = zBuffer + 4 * x0;
pitch = *Pointer<Int>(data + OFFSET(DrawData,depthPitchB));
}
else
{
buffer = zBuffer + 8 * x0;
}
For(Int x = x0, x < x1, x += 2)
{
Float4 z = interpolate(xxxx, Dz[0], z, primitive + OFFSET(Primitive,z), false, false, state.depthClamp);
Float4 zValue;
if(!state.quadLayoutDepthBuffer)
{
// FIXME: Properly optimizes?
zValue.xy = *Pointer<Float4>(buffer);
zValue.zw = *Pointer<Float4>(buffer + pitch - 8);
}
else
{
zValue = *Pointer<Float4>(buffer, 16);
}
Int4 zTest;
if(complementaryDepthBuffer)
{
zTest = CmpLE(zValue, z);
}
else
{
zTest = CmpNLT(zValue, z);
}
Int zMask = SignMask(zTest);
If(zMask == 0)
{
x0 += 2;
}
Else
{
x = x1;
}
xxxx += Float4(2);
if(!state.quadLayoutDepthBuffer)
{
buffer += 8;
}
else
{
buffer += 16;
}
}
}
}
If(x0 < x1)
{
if(interpolateW())
{
Dw = *Pointer<Float4>(primitive + OFFSET(Primitive,w.C), 16) + yyyy * *Pointer<Float4>(primitive + OFFSET(Primitive,w.B), 16);
}
for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
{
for(int component = 0; component < 4; component++)
{
if(state.interpolant[interpolant].component & (1 << component))
{
Dv[interpolant][component] = *Pointer<Float4>(primitive + OFFSET(Primitive,V[interpolant][component].C), 16);
if(!(state.interpolant[interpolant].flat & (1 << component)))
{
Dv[interpolant][component] += yyyy * *Pointer<Float4>(primitive + OFFSET(Primitive,V[interpolant][component].B), 16);
}
}
}
}
if(state.fog.component)
{
Df = *Pointer<Float4>(primitive + OFFSET(Primitive,f.C), 16);
if(!state.fog.flat)
{
Df += yyyy * *Pointer<Float4>(primitive + OFFSET(Primitive,f.B), 16);
}
}
Short4 xLeft[4];
Short4 xRight[4];
for(unsigned int q = 0; q < state.multiSample; q++)
{
xLeft[q] = *Pointer<Short4>(primitive + q * sizeof(Primitive) + OFFSET(Primitive,outline) + y * sizeof(Primitive::Span));
xRight[q] = xLeft[q];
xLeft[q] = Swizzle(xLeft[q], 0xA0) - Short4(1, 2, 1, 2);
xRight[q] = Swizzle(xRight[q], 0xF5) - Short4(0, 1, 0, 1);
}
For(Int x = x0, x < x1, x += 2)
{
Short4 xxxx = Short4(x);
Int cMask[4];
for(unsigned int q = 0; q < state.multiSample; q++)
{
Short4 mask = CmpGT(xxxx, xLeft[q]) & CmpGT(xRight[q], xxxx);
cMask[q] = SignMask(PackSigned(mask, mask)) & 0x0000000F;
}
quad(cBuffer, zBuffer, sBuffer, cMask, x, y);
}
}
int clusterCount = Renderer::getClusterCount();
for(int index = 0; index < RENDERTARGETS; index++)
{
if(state.colorWriteActive(index))
{
cBuffer[index] += *Pointer<Int>(data + OFFSET(DrawData,colorPitchB[index])) << (1 + sw::log2(clusterCount)); // FIXME: Precompute
}
}
if(state.depthTestActive)
{
zBuffer += *Pointer<Int>(data + OFFSET(DrawData,depthPitchB)) << (1 + sw::log2(clusterCount)); // FIXME: Precompute
}
if(state.stencilActive)
{
sBuffer += *Pointer<Int>(data + OFFSET(DrawData,stencilPitchB)) << (1 + sw::log2(clusterCount)); // FIXME: Precompute
}
y += 2 * clusterCount;
}
Until(y >= yMax)
}
Float4 QuadRasterizer::interpolate(Float4 &x, Float4 &D, Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective, bool clamp)
{
Float4 interpolant = D;
if(!flat)
{
interpolant += x * *Pointer<Float4>(planeEquation + OFFSET(PlaneEquation, A), 16);
if(perspective)
{
interpolant *= rhw;
}
}
if(clamp)
{
interpolant = Min(Max(interpolant, Float4(0.0f)), Float4(1.0f));
}
return interpolant;
}
bool QuadRasterizer::interpolateZ() const
{
return state.depthTestActive || state.pixelFogActive() || (shader && shader->isVPosDeclared() && fullPixelPositionRegister);
}
bool QuadRasterizer::interpolateW() const
{
return state.perspective || (shader && shader->isVPosDeclared() && fullPixelPositionRegister);
}
}
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_QuadRasterizer_hpp
#define sw_QuadRasterizer_hpp
#include "Rasterizer.hpp"
#include "Shader/ShaderCore.hpp"
#include "Shader/PixelShader.hpp"
#include "Common/Types.hpp"
namespace sw
{
class QuadRasterizer : public Rasterizer
{
public:
QuadRasterizer(const PixelProcessor::State &state, const PixelShader *shader);
virtual ~QuadRasterizer();
void generate();
protected:
Pointer<Byte> constants;
Float4 Dz[4];
Float4 Dw;
Float4 Dv[MAX_FRAGMENT_INPUTS][4];
Float4 Df;
UInt occlusion;
#if PERF_PROFILE
Long cycles[PERF_TIMERS];
#endif
virtual void quad(Pointer<Byte> cBuffer[4], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x, Int &y) = 0;
bool interpolateZ() const;
bool interpolateW() const;
Float4 interpolate(Float4 &x, Float4 &D, Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective, bool clamp);
const PixelProcessor::State &state;
const PixelShader *const shader;
private:
void rasterize(Int &yMin, Int &yMax);
};
}
#endif // sw_QuadRasterizer_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_Rasterizer_hpp
#define sw_Rasterizer_hpp
#include "Context.hpp"
#include "PixelProcessor.hpp"
#include "Main/Config.hpp"
namespace sw
{
class Rasterizer : public Function<Void(Pointer<Byte>, Int, Int, Pointer<Byte>)>
{
public:
Rasterizer() : primitive(Arg<0>()), count(Arg<1>()), cluster(Arg<2>()), data(Arg<3>()) {}
virtual ~Rasterizer() {};
protected:
Pointer<Byte> primitive;
Int count;
Int cluster;
Pointer<Byte> data;
};
}
#endif // sw_Rasterizer_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_RoutineCache_hpp
#define sw_RoutineCache_hpp
#include "LRUCache.hpp"
#include "Reactor/Reactor.hpp"
namespace sw
{
template<class State>
class RoutineCache : public LRUCache<State, Routine>
{
public:
RoutineCache(int n, const char *precache = 0);
~RoutineCache();
private:
const char *precache;
#if defined(_WIN32)
HMODULE precacheDLL;
#endif
};
template<class State>
RoutineCache<State>::RoutineCache(int n, const char *precache) : LRUCache<State, Routine>(n), precache(precache)
{
}
template<class State>
RoutineCache<State>::~RoutineCache()
{
}
}
#endif // sw_RoutineCache_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_Sampler_hpp
#define sw_Sampler_hpp
#include "Main/Config.hpp"
#include "Renderer/Surface.hpp"
#include "Common/Types.hpp"
namespace sw
{
struct Mipmap
{
const void *buffer[6];
float4 fWidth;
float4 fHeight;
float4 fDepth;
short uHalf[4];
short vHalf[4];
short wHalf[4];
short width[4];
short height[4];
short depth[4];
short onePitchP[4];
int4 pitchP;
int4 sliceP;
};
struct Texture
{
Mipmap mipmap[MIPMAP_LEVELS];
float LOD;
float4 widthHeightLOD;
float4 widthLOD;
float4 heightLOD;
float4 depthLOD;
word4 borderColor4[4];
float4 borderColorF[4];
float maxAnisotropy;
int baseLevel;
int maxLevel;
float minLod;
float maxLod;
};
enum SamplerType
{
SAMPLER_PIXEL,
SAMPLER_VERTEX
};
enum TextureType ENUM_UNDERLYING_TYPE_UNSIGNED_INT
{
TEXTURE_NULL,
TEXTURE_2D,
TEXTURE_RECTANGLE,
TEXTURE_CUBE,
TEXTURE_3D,
TEXTURE_2D_ARRAY,
TEXTURE_LAST = TEXTURE_2D_ARRAY
};
enum FilterType ENUM_UNDERLYING_TYPE_UNSIGNED_INT
{
FILTER_POINT,
FILTER_GATHER,
FILTER_MIN_POINT_MAG_LINEAR,
FILTER_MIN_LINEAR_MAG_POINT,
FILTER_LINEAR,
FILTER_ANISOTROPIC,
FILTER_LAST = FILTER_ANISOTROPIC
};
enum MipmapType ENUM_UNDERLYING_TYPE_UNSIGNED_INT
{
MIPMAP_NONE,
MIPMAP_POINT,
MIPMAP_LINEAR,
MIPMAP_LAST = MIPMAP_LINEAR
};
enum AddressingMode ENUM_UNDERLYING_TYPE_UNSIGNED_INT
{
ADDRESSING_WRAP,
ADDRESSING_CLAMP,
ADDRESSING_MIRROR,
ADDRESSING_MIRRORONCE,
ADDRESSING_BORDER, // Single color
ADDRESSING_SEAMLESS, // Border of pixels
ADDRESSING_LAYER,
ADDRESSING_TEXELFETCH,
ADDRESSING_LAST = ADDRESSING_TEXELFETCH
};
enum CompareFunc ENUM_UNDERLYING_TYPE_UNSIGNED_INT
{
COMPARE_BYPASS,
COMPARE_LESSEQUAL,
COMPARE_GREATEREQUAL,
COMPARE_LESS,
COMPARE_GREATER,
COMPARE_EQUAL,
COMPARE_NOTEQUAL,
COMPARE_ALWAYS,
COMPARE_NEVER,
COMPARE_LAST = COMPARE_NEVER
};
enum SwizzleType ENUM_UNDERLYING_TYPE_UNSIGNED_INT
{
SWIZZLE_RED,
SWIZZLE_GREEN,
SWIZZLE_BLUE,
SWIZZLE_ALPHA,
SWIZZLE_ZERO,
SWIZZLE_ONE,
SWIZZLE_LAST = SWIZZLE_ONE
};
class Sampler
{
public:
struct State
{
State();
TextureType textureType : BITS(TEXTURE_LAST);
Format textureFormat : BITS(FORMAT_LAST);
FilterType textureFilter : BITS(FILTER_LAST);
AddressingMode addressingModeU : BITS(ADDRESSING_LAST);
AddressingMode addressingModeV : BITS(ADDRESSING_LAST);
AddressingMode addressingModeW : BITS(ADDRESSING_LAST);
MipmapType mipmapFilter : BITS(FILTER_LAST);
bool sRGB : 1;
SwizzleType swizzleR : BITS(SWIZZLE_LAST);
SwizzleType swizzleG : BITS(SWIZZLE_LAST);
SwizzleType swizzleB : BITS(SWIZZLE_LAST);
SwizzleType swizzleA : BITS(SWIZZLE_LAST);
bool highPrecisionFiltering : 1;
CompareFunc compare : BITS(COMPARE_LAST);
#if PERF_PROFILE
bool compressedFormat : 1;
#endif
};
Sampler();
~Sampler();
State samplerState() const;
void setTextureLevel(int face, int level, Surface *surface, TextureType type);
void setTextureFilter(FilterType textureFilter);
void setMipmapFilter(MipmapType mipmapFilter);
void setGatherEnable(bool enable);
void setAddressingModeU(AddressingMode addressingMode);
void setAddressingModeV(AddressingMode addressingMode);
void setAddressingModeW(AddressingMode addressingMode);
void setReadSRGB(bool sRGB);
void setBorderColor(const Color<float> &borderColor);
void setMaxAnisotropy(float maxAnisotropy);
void setHighPrecisionFiltering(bool highPrecisionFiltering);
void setSwizzleR(SwizzleType swizzleR);
void setSwizzleG(SwizzleType swizzleG);
void setSwizzleB(SwizzleType swizzleB);
void setSwizzleA(SwizzleType swizzleA);
void setCompareFunc(CompareFunc compare);
void setBaseLevel(int baseLevel);
void setMaxLevel(int maxLevel);
void setMinLod(float minLod);
void setMaxLod(float maxLod);
void setSyncRequired(bool isSincRequired);
static void setFilterQuality(FilterType maximumFilterQuality);
static void setMipmapQuality(MipmapType maximumFilterQuality);
void setMipmapLOD(float lod);
bool hasTexture() const;
bool hasUnsignedTexture() const;
bool hasCubeTexture() const;
bool hasVolumeTexture() const;
bool requiresSync() const;
const Texture &getTextureData();
private:
MipmapType mipmapFilter() const;
TextureType getTextureType() const;
FilterType getTextureFilter() const;
AddressingMode getAddressingModeU() const;
AddressingMode getAddressingModeV() const;
AddressingMode getAddressingModeW() const;
CompareFunc getCompareFunc() const;
Format externalTextureFormat;
Format internalTextureFormat;
TextureType textureType;
FilterType textureFilter;
AddressingMode addressingModeU;
AddressingMode addressingModeV;
AddressingMode addressingModeW;
MipmapType mipmapFilterState;
bool sRGB;
bool gather;
bool highPrecisionFiltering;
bool syncRequired;
int border;
SwizzleType swizzleR;
SwizzleType swizzleG;
SwizzleType swizzleB;
SwizzleType swizzleA;
CompareFunc compare;
Texture texture;
float exp2LOD;
static FilterType maximumTextureFilterQuality;
static MipmapType maximumMipmapFilterQuality;
};
}
#endif // sw_Sampler_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "SetupProcessor.hpp"
#include "Primitive.hpp"
#include "Polygon.hpp"
#include "Context.hpp"
#include "Renderer.hpp"
#include "Shader/SetupRoutine.hpp"
#include "Shader/Constants.hpp"
#include "Common/Debug.hpp"
namespace sw
{
extern bool complementaryDepthBuffer;
extern bool fullPixelPositionRegister;
bool precacheSetup = false;
unsigned int SetupProcessor::States::computeHash()
{
unsigned int *state = (unsigned int*)this;
unsigned int hash = 0;
for(unsigned int i = 0; i < sizeof(States) / 4; i++)
{
hash ^= state[i];
}
return hash;
}
SetupProcessor::State::State(int i)
{
memset(this, 0, sizeof(State));
}
bool SetupProcessor::State::operator==(const State &state) const
{
if(hash != state.hash)
{
return false;
}
return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
}
SetupProcessor::SetupProcessor(Context *context) : context(context)
{
routineCache = 0;
setRoutineCacheSize(1024);
}
SetupProcessor::~SetupProcessor()
{
delete routineCache;
routineCache = 0;
}
SetupProcessor::State SetupProcessor::update() const
{
State state;
bool vPosZW = (context->pixelShader && context->pixelShader->isVPosDeclared() && fullPixelPositionRegister);
state.isDrawPoint = context->isDrawPoint(true);
state.isDrawLine = context->isDrawLine(true);
state.isDrawTriangle = context->isDrawTriangle(false);
state.isDrawSolidTriangle = context->isDrawTriangle(true);
state.interpolateZ = context->depthBufferActive() || context->pixelFogActive() != FOG_NONE || vPosZW;
state.interpolateW = context->perspectiveActive() || vPosZW;
state.perspective = context->perspectiveActive();
state.pointSprite = context->pointSpriteActive();
state.cullMode = context->cullMode;
state.twoSidedStencil = context->stencilActive() && context->twoSidedStencil;
state.slopeDepthBias = context->slopeDepthBias != 0.0f;
state.vFace = context->pixelShader && context->pixelShader->isVFaceDeclared();
state.positionRegister = Pos;
state.pointSizeRegister = Unused;
state.multiSample = context->getMultiSampleCount();
state.rasterizerDiscard = context->rasterizerDiscard;
if(context->vertexShader)
{
state.positionRegister = context->vertexShader->getPositionRegister();
state.pointSizeRegister = context->vertexShader->getPointSizeRegister();
}
else if(context->pointSizeActive())
{
state.pointSizeRegister = Pts;
}
for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
{
for(int component = 0; component < 4; component++)
{
state.gradient[interpolant][component].attribute = Unused;
state.gradient[interpolant][component].flat = false;
state.gradient[interpolant][component].wrap = false;
}
}
state.fog.attribute = Unused;
state.fog.flat = false;
state.fog.wrap = false;
const bool point = context->isDrawPoint(true);
const bool sprite = context->pointSpriteActive();
const bool flatShading = (context->shadingMode == SHADING_FLAT) || point;
if(context->vertexShader && context->pixelShader)
{
for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
{
for(int component = 0; component < 4; component++)
{
int project = context->isProjectionComponent(interpolant - 2, component) ? 1 : 0;
const Shader::Semantic& semantic = context->pixelShader->getInput(interpolant, component - project);
if(semantic.active())
{
int input = interpolant;
for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
{
if(semantic == context->vertexShader->getOutput(i, component - project))
{
input = i;
break;
}
}
bool flat = point;
switch(semantic.usage)
{
case Shader::USAGE_TEXCOORD: flat = point && !sprite; break;
case Shader::USAGE_COLOR: flat = semantic.flat || flatShading; break;
}
state.gradient[interpolant][component].attribute = input;
state.gradient[interpolant][component].flat = flat;
}
}
}
}
else if(context->preTransformed && context->pixelShader)
{
for(int interpolant = 0; interpolant < MAX_FRAGMENT_INPUTS; interpolant++)
{
for(int component = 0; component < 4; component++)
{
const Shader::Semantic& semantic = context->pixelShader->getInput(interpolant, component);
switch(semantic.usage)
{
case 0xFF:
break;
case Shader::USAGE_TEXCOORD:
state.gradient[interpolant][component].attribute = T0 + semantic.index;
state.gradient[interpolant][component].flat = semantic.flat || (point && !sprite);
break;
case Shader::USAGE_COLOR:
state.gradient[interpolant][component].attribute = C0 + semantic.index;
state.gradient[interpolant][component].flat = semantic.flat || flatShading;
break;
default:
ASSERT(false);
}
}
}
}
else if(context->pixelShaderModel() < 0x0300)
{
for(int coordinate = 0; coordinate < 8; coordinate++)
{
for(int component = 0; component < 4; component++)
{
if(context->textureActive(coordinate, component))
{
state.texture[coordinate][component].attribute = T0 + coordinate;
state.texture[coordinate][component].flat = point && !sprite;
state.texture[coordinate][component].wrap = (context->textureWrap[coordinate] & (1 << component)) != 0;
}
}
}
for(int color = 0; color < 2; color++)
{
for(int component = 0; component < 4; component++)
{
if(context->colorActive(color, component))
{
state.color[color][component].attribute = C0 + color;
state.color[color][component].flat = flatShading;
}
}
}
}
else ASSERT(false);
if(context->fogActive())
{
state.fog.attribute = Fog;
state.fog.flat = point;
}
state.hash = state.computeHash();
return state;
}
Routine *SetupProcessor::routine(const State &state)
{
Routine *routine = routineCache->query(state);
if(!routine)
{
SetupRoutine *generator = new SetupRoutine(state);
generator->generate();
routine = generator->getRoutine();
delete generator;
routineCache->add(state, routine);
}
return routine;
}
void SetupProcessor::setRoutineCacheSize(int cacheSize)
{
delete routineCache;
routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheSetup ? "sw-setup" : 0);
}
}
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_SetupProcessor_hpp
#define sw_SetupProcessor_hpp
#include "Context.hpp"
#include "RoutineCache.hpp"
#include "Shader/VertexShader.hpp"
#include "Shader/PixelShader.hpp"
#include "Common/Types.hpp"
namespace sw
{
struct Primitive;
struct Triangle;
struct Polygon;
struct Vertex;
struct DrawCall;
struct DrawData;
class SetupProcessor
{
public:
struct States
{
unsigned int computeHash();
bool isDrawPoint : 1;
bool isDrawLine : 1;
bool isDrawTriangle : 1;
bool isDrawSolidTriangle : 1;
bool interpolateZ : 1;
bool interpolateW : 1;
bool perspective : 1;
bool pointSprite : 1;
unsigned int positionRegister : BITS(VERTEX_OUTPUT_LAST);
unsigned int pointSizeRegister : BITS(VERTEX_OUTPUT_LAST);
CullMode cullMode : BITS(CULL_LAST);
bool twoSidedStencil : 1;
bool slopeDepthBias : 1;
bool vFace : 1;
unsigned int multiSample : 3; // 1, 2 or 4
bool rasterizerDiscard : 1;
struct Gradient
{
unsigned char attribute : BITS(VERTEX_OUTPUT_LAST);
bool flat : 1;
bool wrap : 1;
};
union
{
struct
{
Gradient color[2][4];
Gradient texture[8][4];
Gradient fog;
};
Gradient gradient[MAX_FRAGMENT_INPUTS][4];
};
};
struct State : States
{
State(int i = 0);
bool operator==(const State &states) const;
unsigned int hash;
};
typedef bool (*RoutinePointer)(Primitive *primitive, const Triangle *triangle, const Polygon *polygon, const DrawData *draw);
SetupProcessor(Context *context);
~SetupProcessor();
protected:
State update() const;
Routine *routine(const State &state);
void setRoutineCacheSize(int cacheSize);
private:
Context *const context;
RoutineCache<State> *routineCache;
};
}
#endif // sw_SetupProcessor_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_Stream_hpp
#define sw_Stream_hpp
#include "Common/Types.hpp"
namespace sw
{
class Resource;
enum StreamType ENUM_UNDERLYING_TYPE_UNSIGNED_INT
{
STREAMTYPE_COLOR, // 4 normalized unsigned bytes, ZYXW order
STREAMTYPE_UDEC3, // 3 unsigned 10-bit fields
STREAMTYPE_DEC3N, // 3 normalized signed 10-bit fields
STREAMTYPE_INDICES, // 4 unsigned bytes, stored unconverted into X component
STREAMTYPE_FLOAT, // Normalization ignored
STREAMTYPE_BYTE,
STREAMTYPE_SBYTE,
STREAMTYPE_SHORT,
STREAMTYPE_USHORT,
STREAMTYPE_INT,
STREAMTYPE_UINT,
STREAMTYPE_FIXED, // Normalization ignored (16.16 format)
STREAMTYPE_HALF, // Normalization ignored
STREAMTYPE_2_10_10_10_INT,
STREAMTYPE_2_10_10_10_UINT,
STREAMTYPE_LAST = STREAMTYPE_2_10_10_10_UINT
};
struct StreamResource
{
Resource *resource;
const void *buffer;
unsigned int stride;
};
struct Stream : public StreamResource
{
Stream(Resource *resource = 0, const void *buffer = 0, unsigned int stride = 0)
{
this->resource = resource;
this->buffer = buffer;
this->stride = stride;
}
Stream &define(StreamType type, unsigned int count, bool normalized = false)
{
this->type = type;
this->count = count;
this->normalized = normalized;
return *this;
}
Stream &define(const void *buffer, StreamType type, unsigned int count, bool normalized = false)
{
this->buffer = buffer;
this->type = type;
this->count = count;
this->normalized = normalized;
return *this;
}
Stream &defaults()
{
static const float4 null = {0, 0, 0, 1};
resource = 0;
buffer = &null;
stride = 0;
type = STREAMTYPE_FLOAT;
count = 0;
normalized = false;
return *this;
}
operator bool() const // Returns true if stream contains data
{
return count != 0;
}
StreamType type;
unsigned char count;
bool normalized;
};
}
#endif // sw_Stream_hpp
This source diff could not be displayed because it is too large. You can view the blob instead.
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_SwiftConfig_hpp
#define sw_SwiftConfig_hpp
#include "Reactor/Nucleus.hpp"
#include "Common/Thread.hpp"
#include "Common/MutexLock.hpp"
#include "Common/Socket.hpp"
#include <string>
namespace sw
{
class SwiftConfig
{
public:
struct Configuration
{
int pixelShaderVersion;
int vertexShaderVersion;
int textureMemory;
int identifier;
int vertexRoutineCacheSize;
int pixelRoutineCacheSize;
int setupRoutineCacheSize;
int vertexCacheSize;
int textureSampleQuality;
int mipmapQuality;
bool perspectiveCorrection;
int transcendentalPrecision;
int threadCount;
bool enableSSE;
bool enableSSE2;
bool enableSSE3;
bool enableSSSE3;
bool enableSSE4_1;
Optimization optimization[10];
bool disableServer;
bool keepSystemCursor;
bool forceWindowed;
bool complementaryDepthBuffer;
bool postBlendSRGB;
bool exactColorRounding;
bool disableAlphaMode;
bool disable10BitMode;
int transparencyAntialiasing;
int frameBufferAPI;
bool precache;
int shadowMapping;
bool forceClearRegisters;
#ifndef NDEBUG
unsigned int minPrimitives;
unsigned int maxPrimitives;
#endif
};
SwiftConfig(bool disableServerOverride);
~SwiftConfig();
bool hasNewConfiguration(bool reset = true);
void getConfiguration(Configuration &configuration);
private:
enum Status
{
OK = 200,
NotFound = 404
};
void createServer();
void destroyServer();
static void serverRoutine(void *parameters);
void serverLoop();
void respond(Socket *clientSocket, const char *request);
std::string page();
std::string profile();
void send(Socket *clientSocket, Status code, std::string body = "");
void parsePost(const char *post);
void readConfiguration(bool disableServerOverride = false);
void writeConfiguration();
Configuration config;
Thread *serverThread;
volatile bool terminate;
MutexLock criticalSection; // Protects reading and writing the configuration settings
bool newConfig;
Socket *listenSocket;
int bufferLength;
char *receiveBuffer;
};
}
#endif // sw_SwiftConfig_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_TextureStage_hpp
#define sw_TextureStage_hpp
#include "Common/Types.hpp"
#include "Common/Math.hpp"
#include "Renderer/Color.hpp"
namespace sw
{
class Sampler;
class PixelRoutine;
class Context;
class TextureStage
{
friend class Context; // FIXME
public:
enum StageOperation
{
STAGE_DISABLE,
STAGE_SELECTARG1,
STAGE_SELECTARG2,
STAGE_SELECTARG3,
STAGE_MODULATE,
STAGE_MODULATE2X,
STAGE_MODULATE4X,
STAGE_ADD,
STAGE_ADDSIGNED,
STAGE_ADDSIGNED2X,
STAGE_SUBTRACT,
STAGE_ADDSMOOTH,
STAGE_MULTIPLYADD,
STAGE_LERP,
STAGE_DOT3,
STAGE_BLENDCURRENTALPHA,
STAGE_BLENDDIFFUSEALPHA,
STAGE_BLENDFACTORALPHA,
STAGE_BLENDTEXTUREALPHA,
STAGE_BLENDTEXTUREALPHAPM,
STAGE_PREMODULATE,
STAGE_MODULATEALPHA_ADDCOLOR,
STAGE_MODULATECOLOR_ADDALPHA,
STAGE_MODULATEINVALPHA_ADDCOLOR,
STAGE_MODULATEINVCOLOR_ADDALPHA,
STAGE_BUMPENVMAP,
STAGE_BUMPENVMAPLUMINANCE,
STAGE_LAST = STAGE_BUMPENVMAPLUMINANCE
};
enum SourceArgument
{
SOURCE_TEXTURE,
SOURCE_CONSTANT,
SOURCE_CURRENT,
SOURCE_DIFFUSE,
SOURCE_SPECULAR,
SOURCE_TEMP,
SOURCE_TFACTOR,
SOURCE_LAST = SOURCE_TFACTOR
};
enum DestinationArgument
{
DESTINATION_CURRENT,
DESTINATION_TEMP,
DESTINATION_LAST = DESTINATION_TEMP
};
enum ArgumentModifier
{
MODIFIER_COLOR,
MODIFIER_INVCOLOR,
MODIFIER_ALPHA,
MODIFIER_INVALPHA,
MODIFIER_LAST = MODIFIER_INVALPHA
};
struct State
{
State();
unsigned int stageOperation : BITS(STAGE_LAST);
unsigned int firstArgument : BITS(SOURCE_LAST);
unsigned int secondArgument : BITS(SOURCE_LAST);
unsigned int thirdArgument : BITS(SOURCE_LAST);
unsigned int stageOperationAlpha : BITS(STAGE_LAST);
unsigned int firstArgumentAlpha : BITS(SOURCE_LAST);
unsigned int secondArgumentAlpha : BITS(SOURCE_LAST);
unsigned int thirdArgumentAlpha : BITS(SOURCE_LAST);
unsigned int firstModifier : BITS(MODIFIER_LAST);
unsigned int secondModifier : BITS(MODIFIER_LAST);
unsigned int thirdModifier : BITS(MODIFIER_LAST);
unsigned int firstModifierAlpha : BITS(MODIFIER_LAST);
unsigned int secondModifierAlpha : BITS(MODIFIER_LAST);
unsigned int thirdModifierAlpha : BITS(MODIFIER_LAST);
unsigned int destinationArgument : BITS(DESTINATION_LAST);
unsigned int texCoordIndex : BITS(7);
unsigned int cantUnderflow : 1;
unsigned int usesTexture : 1;
};
struct Uniforms
{
word4 constantColor4[4];
float4 bumpmapMatrix4F[2][2];
word4 bumpmapMatrix4W[2][2];
word4 luminanceScale4;
word4 luminanceOffset4;
};
TextureStage();
~TextureStage();
void init(int stage, const Sampler *sampler, const TextureStage *previousStage);
State textureStageState() const;
void setConstantColor(const Color<float> &constantColor);
void setBumpmapMatrix(int element, float value);
void setLuminanceScale(float value);
void setLuminanceOffset(float value);
void setTexCoordIndex(unsigned int texCoordIndex);
void setStageOperation(StageOperation stageOperation);
void setFirstArgument(SourceArgument firstArgument);
void setSecondArgument(SourceArgument secondArgument);
void setThirdArgument(SourceArgument thirdArgument);
void setStageOperationAlpha(StageOperation stageOperationAlpha);
void setFirstArgumentAlpha(SourceArgument firstArgumentAlpha);
void setSecondArgumentAlpha(SourceArgument secondArgumentAlpha);
void setThirdArgumentAlpha(SourceArgument thirdArgumentAlpha);
void setFirstModifier(ArgumentModifier firstModifier);
void setSecondModifier(ArgumentModifier secondModifier);
void setThirdModifier(ArgumentModifier thirdModifier);
void setFirstModifierAlpha(ArgumentModifier firstModifierAlpha);
void setSecondModifierAlpha(ArgumentModifier secondModifierAlpha);
void setThirdModifierAlpha(ArgumentModifier thirdModifierAlpha);
void setDestinationArgument(DestinationArgument destinationArgument);
Uniforms uniforms; // FIXME: Private
private:
bool usesColor(SourceArgument source) const;
bool usesAlpha(SourceArgument source) const;
bool uses(SourceArgument source) const;
bool usesCurrent() const;
bool usesDiffuse() const;
bool usesSpecular() const;
bool usesTexture() const;
bool isStageDisabled() const;
bool writesCurrent() const;
int stage;
StageOperation stageOperation;
SourceArgument firstArgument;
SourceArgument secondArgument;
SourceArgument thirdArgument;
StageOperation stageOperationAlpha;
SourceArgument firstArgumentAlpha;
SourceArgument secondArgumentAlpha;
SourceArgument thirdArgumentAlpha;
ArgumentModifier firstModifier;
ArgumentModifier secondModifier;
ArgumentModifier thirdModifier;
ArgumentModifier firstModifierAlpha;
ArgumentModifier secondModifierAlpha;
ArgumentModifier thirdModifierAlpha;
DestinationArgument destinationArgument;
int texCoordIndex;
const Sampler *sampler;
const TextureStage *previousStage;
};
}
#endif // sw_TextureStage_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_Triangle_hpp
#define sw_Triangle_hpp
#include "Vertex.hpp"
namespace sw
{
struct Triangle
{
Vertex V0;
Vertex V1;
Vertex V2;
};
}
#endif // sw_Triangle_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "Vector.hpp"
#include "Matrix.hpp"
#include "Common/Math.hpp"
namespace sw
{
Vector Vector::operator+() const
{
return *this;
}
Vector Vector::operator-() const
{
return Vector(-x, -y, -z);
}
Vector &Vector::operator+=(const Vector &v)
{
x += v.x;
y += v.y;
z += v.z;
return *this;
}
Vector &Vector::operator-=(const Vector &v)
{
x -= v.x;
y -= v.y;
z -= v.z;
return *this;
}
Vector &Vector::operator*=(float s)
{
x *= s;
y *= s;
z *= s;
return *this;
}
Vector &Vector::operator/=(float s)
{
float r = 1.0f / s;
return *this *= r;
}
bool operator==(const Vector &U, const Vector &v)
{
if(U.x == v.x && U.y == v.y && U.z == v.z)
return true;
else
return false;
}
bool operator!=(const Vector &U, const Vector &v)
{
if(U.x != v.x || U.y != v.y || U.z != v.z)
return true;
else
return false;
}
bool operator>(const Vector &u, const Vector &v)
{
if((u^2) > (v^2))
return true;
else
return false;
}
bool operator<(const Vector &u, const Vector &v)
{
if((u^2) < (v^2))
return true;
else
return false;
}
Vector operator+(const Vector &u, const Vector &v)
{
return Vector(u.x + v.x, u.y + v.y, u.z + v.z);
}
Vector operator-(const Vector &u, const Vector &v)
{
return Vector(u.x - v.x, u.y - v.y, u.z - v.z);
}
float operator*(const Vector &u, const Vector &v)
{
return u.x * v.x + u.y * v.y + u.z * v.z;
}
Vector operator*(float s, const Vector &v)
{
return Vector(s * v.x, s * v.y, s * v.z);
}
Vector operator*(const Vector &v, float s)
{
return Vector(v.x * s, v.y * s, v.z * s);
}
Vector operator/(const Vector &v, float s)
{
float r = 1.0f / s;
return Vector(v.x * r, v.y * r, v.z * r);
}
float operator^(const Vector &u, const Vector &v)
{
return acos(u / Vector::N(u) * v / Vector::N(v));
}
Vector operator%(const Vector &u, const Vector &v)
{
return Vector(u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x);
}
Vector operator*(const Matrix &M, const Vector &v)
{
return Vector(M(1, 1) * v.x + M(1, 2) * v.y + M(1, 3) * v.z,
M(2, 1) * v.x + M(2, 2) * v.y + M(2, 3) * v.z,
M(3, 1) * v.x + M(3, 2) * v.y + M(3, 3) * v.z);
}
Vector operator*(const Vector &v, const Matrix &M)
{
return Vector(v.x * M(1, 1) + v.y * M(2, 1) + v.z * M(3, 1) + M(4, 1),
v.x * M(1, 2) + v.y * M(2, 2) + v.z * M(3, 2) + M(4, 2),
v.x * M(1, 3) + v.y * M(2, 3) + v.z * M(3, 3) + M(4, 3));
}
Vector &operator*=(Vector &v, const Matrix &M)
{
return v = v * M;
}
float Vector::N(const Vector &v)
{
return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
}
float Vector::N2(const Vector &v)
{
return v.x*v.x + v.y*v.y + v.z*v.z;
}
Vector lerp(const Vector &u, const Vector &v, float t)
{
return Vector(u.x + t * (v.x - u.x),
u.y + t * (v.y - u.y),
u.z + t * (v.z - u.x));
}
}
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef Vector_hpp
#define Vector_hpp
namespace sw
{
struct Point;
struct Matrix;
struct Plane;
struct Vector
{
Vector();
Vector(const int i);
Vector(const Vector &v);
Vector(const Point &p);
Vector(float v_x, float v_y, float v_z);
Vector &operator=(const Vector &v);
union
{
float v[3];
struct
{
float x;
float y;
float z;
};
};
float &operator[](int i);
float &operator()(int i);
const float &operator[](int i) const;
const float &operator()(int i) const;
Vector operator+() const;
Vector operator-() const;
Vector &operator+=(const Vector &v);
Vector &operator-=(const Vector &v);
Vector &operator*=(float s);
Vector &operator/=(float s);
friend bool operator==(const Vector &u, const Vector &v);
friend bool operator!=(const Vector &u, const Vector &v);
friend Vector operator+(const Vector &u, const Vector &v);
friend Vector operator-(const Vector &u, const Vector &v);
friend float operator*(const Vector &u, const Vector &v); // Dot product
friend Vector operator*(float s, const Vector &v);
friend Vector operator*(const Vector &v, float s);
friend Vector operator/(const Vector &v, float s);
friend float operator^(const Vector &u, const Vector &v); // Angle between vectors
friend Vector operator%(const Vector &u, const Vector &v); // Cross product
friend Vector operator*(const Matrix &M, const Vector& v);
friend Vector operator*(const Vector &v, const Matrix &M);
friend Vector &operator*=(Vector &v, const Matrix &M);
static float N(const Vector &v); // Norm
static float N2(const Vector &v); // Squared norm
static Vector mirror(const Vector &v, const Plane &p);
static Vector reflect(const Vector &v, const Plane &p);
static Vector lerp(const Vector &u, const Vector &v, float t);
};
}
#include "Point.hpp"
namespace sw
{
inline Vector::Vector()
{
}
inline Vector::Vector(const int i)
{
const float s = (float)i;
x = s;
y = s;
z = s;
}
inline Vector::Vector(const Vector &v)
{
x = v.x;
y = v.y;
z = v.z;
}
inline Vector::Vector(const Point &P)
{
x = P.x;
y = P.y;
z = P.z;
}
inline Vector::Vector(float v_x, float v_y, float v_z)
{
x = v_x;
y = v_y;
z = v_z;
}
inline Vector &Vector::operator=(const Vector &v)
{
x = v.x;
y = v.y;
z = v.z;
return *this;
}
inline float &Vector::operator()(int i)
{
return v[i];
}
inline float &Vector::operator[](int i)
{
return v[i];
}
inline const float &Vector::operator()(int i) const
{
return v[i];
}
inline const float &Vector::operator[](int i) const
{
return v[i];
}
}
#endif // Vector_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef Vertex_hpp
#define Vertex_hpp
#include "Color.hpp"
#include "Common/Types.hpp"
#include "Main/Config.hpp"
namespace sw
{
enum Out
{
// Default vertex output semantics
Pos = 0,
C0 = 1, // Diffuse
C1 = 2, // Specular
T0 = 3,
T1 = 4,
T2 = 5,
T3 = 6,
T4 = 7,
T5 = 8,
T6 = 9,
T7 = 10,
Fog = 11, // x component
Pts = Fog, // y component
// Variable semantics
V0 = 0,
Vn_1 = MAX_VERTEX_OUTPUTS - 1,
Unused,
VERTEX_OUTPUT_LAST = Unused,
};
struct UVWQ
{
float u;
float v;
float w;
float q;
float &operator[](int i)
{
return (&u)[i];
}
};
ALIGN(16, struct Vertex
{
union
{
struct // Fixed semantics
{
// Position
float x;
float y;
float z;
float w;
float4 C[2]; // Diffuse and specular color
UVWQ T[8]; // Texture coordinates
float f; // Fog
float pSize; // Point size
};
float4 v[MAX_VERTEX_OUTPUTS]; // Generic components using semantic declaration
};
// Projected coordinates
int X;
int Y;
float Z;
float W;
int clipFlags;
int padding[3];
});
static_assert((sizeof(Vertex) & 0x0000000F) == 0, "Vertex size not a multiple of 16 bytes (alignment requirement)");
}
#endif // Vertex_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_Constants_hpp
#define sw_Constants_hpp
#include "Common/Types.hpp"
namespace sw
{
struct Constants
{
Constants();
unsigned int transposeBit0[16];
unsigned int transposeBit1[16];
unsigned int transposeBit2[16];
ushort4 cWeight[17];
float4 uvWeight[17];
float4 uvStart[17];
unsigned int occlusionCount[16];
byte8 maskB4Q[16];
byte8 invMaskB4Q[16];
word4 maskW4Q[16];
word4 invMaskW4Q[16];
dword4 maskD4X[16];
dword4 invMaskD4X[16];
qword maskQ0Q[16];
qword maskQ1Q[16];
qword maskQ2Q[16];
qword maskQ3Q[16];
qword invMaskQ0Q[16];
qword invMaskQ1Q[16];
qword invMaskQ2Q[16];
qword invMaskQ3Q[16];
dword4 maskX0X[16];
dword4 maskX1X[16];
dword4 maskX2X[16];
dword4 maskX3X[16];
dword4 invMaskX0X[16];
dword4 invMaskX1X[16];
dword4 invMaskX2X[16];
dword4 invMaskX3X[16];
dword2 maskD01Q[16];
dword2 maskD23Q[16];
dword2 invMaskD01Q[16];
dword2 invMaskD23Q[16];
qword2 maskQ01X[16];
qword2 maskQ23X[16];
qword2 invMaskQ01X[16];
qword2 invMaskQ23X[16];
word4 maskW01Q[4];
dword4 maskD01X[4];
word4 mask565Q[8];
unsigned short sRGBtoLinear8_16[256];
unsigned short sRGBtoLinear6_16[64];
unsigned short sRGBtoLinear5_16[32];
unsigned short linearToSRGB12_16[4096];
unsigned short sRGBtoLinear12_16[4096];
// Centroid parameters
float4 sampleX[4][16];
float4 sampleY[4][16];
float4 weight[16];
// Fragment offsets
int Xf[4];
int Yf[4];
float4 X[4];
float4 Y[4];
dword maxX[16];
dword maxY[16];
dword maxZ[16];
dword minX[16];
dword minY[16];
dword minZ[16];
dword fini[16];
dword4 maxPos;
float4 unscaleByte;
float4 unscaleSByte;
float4 unscaleShort;
float4 unscaleUShort;
float4 unscaleInt;
float4 unscaleUInt;
float4 unscaleFixed;
float half2float[65536];
};
extern Constants constants;
}
#endif // sw_Constants_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#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), current(rs[0]), diffuse(vs[0]), specular(vs[1]), perturbate(false), luminance(false), previousScaling(false) {}
virtual ~PixelPipeline() {}
protected:
virtual void setBuiltins(Int &x, Int &y, Float4(&z)[4], Float4 &w);
virtual void applyShader(Int cMask[4]);
virtual Bool alphaTest(Int cMask[4]);
virtual void rasterOperation(Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]);
private:
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();
void blendTexture(Vector4s &temp, Vector4s &texture, int stage);
void fogBlend(Vector4s &current, Float4 &fog);
void specularPixel(Vector4s &current, Vector4s &specular);
Vector4s sampleTexture(int coordinates, int sampler, bool project = false);
Vector4s sampleTexture(int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, bool project = false);
Short4 convertFixed12(RValue<Float4> cf);
void convertFixed12(Vector4s &cs, Vector4f &cf);
Float4 convertSigned12(Short4 &cs);
void convertSigned12(Vector4f &cf, Vector4s &cs);
void writeDestination(Vector4s &d, const Dst &dst);
Vector4s fetchRegister(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(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src);
void TEXDP3TEX(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(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, bool project);
void TEXLD(Vector4s &dst, Vector4s &src, int stage, bool project);
void TEXBEM(Vector4s &dst, Vector4s &src, Float4 &u, Float4 &v, Float4 &s, int stage);
void TEXBEML(Vector4s &dst, Vector4s &src, Float4 &u, Float4 &v, Float4 &s, int stage);
void TEXREG2AR(Vector4s &dst, Vector4s &src0, int stage);
void TEXREG2GB(Vector4s &dst, Vector4s &src0, int stage);
void TEXREG2RGB(Vector4s &dst, Vector4s &src0, int stage);
void TEXM3X2DEPTH(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src, bool signedScaling);
void TEXM3X2PAD(Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, int component, bool signedScaling);
void TEXM3X2TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, bool signedScaling);
void TEXM3X3(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, bool signedScaling);
void TEXM3X3PAD(Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, int component, bool signedScaling);
void TEXM3X3SPEC(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, Vector4s &src1);
void TEXM3X3TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, bool singedScaling);
void TEXM3X3VSPEC(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0);
void TEXDEPTH();
void CND(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2);
void CMP(Vector4s &dst, Vector4s &src0, Vector4s &src1, Vector4s &src2);
void BEM(Vector4s &dst, Vector4s &src0, Vector4s &src1, int stage);
bool perturbate;
bool luminance;
bool previousScaling;
};
}
#endif
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_PixelProgram_hpp
#define sw_PixelProgram_hpp
#include "PixelRoutine.hpp"
#include "SamplerCore.hpp"
namespace sw
{
class PixelProgram : public PixelRoutine
{
public:
PixelProgram(const PixelProcessor::State &state, const PixelShader *shader) :
PixelRoutine(state, shader), r(shader->indirectAddressableTemporaries),
loopDepth(-1), ifDepth(0), loopRepDepth(0), currentLabel(-1), whileTest(false)
{
for(int i = 0; i < 2048; ++i)
{
labelBlock[i] = 0;
}
enableStack[0] = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
if(shader->containsBreakInstruction())
{
enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
}
if(shader->containsContinueInstruction())
{
enableContinue = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
}
}
virtual ~PixelProgram() {}
protected:
virtual void setBuiltins(Int &x, Int &y, Float4(&z)[4], Float4 &w);
virtual void applyShader(Int cMask[4]);
virtual Bool alphaTest(Int cMask[4]);
virtual void rasterOperation(Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]);
private:
// Temporary registers
RegisterArray<NUM_TEMPORARY_REGISTERS> r;
// Color outputs
Vector4f c[RENDERTARGETS];
RegisterArray<RENDERTARGETS, true> oC;
// 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;
Vector4f sampleTexture(const Src &sampler, Vector4f &uvwq, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
Vector4f sampleTexture(int samplerIndex, Vector4f &uvwq, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
// Raster operations
void clampColor(Vector4f oC[RENDERTARGETS]);
Int4 enableMask(const Shader::Instruction *instruction);
Vector4f fetchRegister(const Src &src, unsigned int offset = 0);
Vector4f readConstant(const Src &src, unsigned int offset = 0);
RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index);
RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index, Int& offset);
Int relativeAddress(const Shader::Relative &rel, int bufferIndex = -1);
Int4 dynamicAddress(const Shader::Relative &rel);
Float4 linearToSRGB(const Float4 &x);
// Instructions
typedef Shader::Control Control;
void M3X2(Vector4f &dst, Vector4f &src0, const Src &src1);
void M3X3(Vector4f &dst, Vector4f &src0, const Src &src1);
void M3X4(Vector4f &dst, Vector4f &src0, const Src &src1);
void M4X3(Vector4f &dst, Vector4f &src0, const Src &src1);
void M4X4(Vector4f &dst, Vector4f &src0, const Src &src1);
void TEX(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias);
void TEXLOD(Vector4f &dst, Vector4f &src0, const Src &src1, Float4 &lod);
void TEXBIAS(Vector4f &dst, Vector4f &src0, const Src &src1, Float4 &bias);
void TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1);
void TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask);
void TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset);
void TEXOFFSETBIAS(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, Float4 &bias);
void TEXLODOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, Float4 &lod);
void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src &, Float4 &lod);
void TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src, const Src &, Vector4f &offset, Float4 &lod);
void TEXGRAD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &dsx, Vector4f &dsy);
void TEXGRADOFFSET(Vector4f &dst, Vector4f &src, const Src &, Vector4f &dsx, Vector4f &dsy, Vector4f &offset);
void DISCARD(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();
void BREAKC(Vector4f &src0, Vector4f &src1, Control);
void BREAKP(const Src &predicateRegister);
void BREAK(Int4 &condition);
void CONTINUE();
void TEST();
void CALL(int labelIndex, int callSiteIndex);
void CALLNZ(int labelIndex, int callSiteIndex, const Src &src);
void CALLNZb(int labelIndex, int callSiteIndex, const Src &boolRegister);
void CALLNZp(int labelIndex, int callSiteIndex, const Src &predicateRegister);
void ELSE();
void ENDIF();
void ENDLOOP();
void ENDREP();
void ENDWHILE();
void ENDSWITCH();
void IF(const Src &src);
void IFb(const Src &boolRegister);
void IFp(const Src &predicateRegister);
void IFC(Vector4f &src0, Vector4f &src1, Control);
void IF(Int4 &condition);
void LABEL(int labelIndex);
void LOOP(const Src &integerRegister);
void REP(const Src &integerRegister);
void WHILE(const Src &temporaryRegister);
void SWITCH();
void RET();
void LEAVE();
int ifDepth;
int loopRepDepth;
int currentLabel;
bool whileTest;
BasicBlock *ifFalseBlock[24 + 24];
BasicBlock *loopRepTestBlock[4];
BasicBlock *loopRepEndBlock[4];
BasicBlock *labelBlock[2048];
std::vector<BasicBlock*> callRetBlock[2048];
BasicBlock *returnBlock;
bool isConditionalIf[24 + 24];
};
}
#endif
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_PixelRoutine_hpp
#define sw_PixelRoutine_hpp
#include "Renderer/QuadRasterizer.hpp"
namespace sw
{
class PixelShader;
class SamplerCore;
class PixelRoutine : public sw::QuadRasterizer, public ShaderCore
{
public:
PixelRoutine(const PixelProcessor::State &state, const PixelShader *shader);
virtual ~PixelRoutine();
protected:
Float4 z[4]; // Multisampled z
Float4 w; // Used as is
Float4 rhw; // Reciprocal w
RegisterArray<MAX_FRAGMENT_INPUTS> v; // Varying registers
// Depth output
Float4 oDepth;
typedef Shader::SourceParameter Src;
typedef Shader::DestinationParameter Dst;
virtual void setBuiltins(Int &x, Int &y, Float4(&z)[4], Float4 &w) = 0;
virtual void applyShader(Int cMask[4]) = 0;
virtual Bool alphaTest(Int cMask[4]) = 0;
virtual void rasterOperation(Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]) = 0;
virtual void quad(Pointer<Byte> cBuffer[4], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x, Int &y);
void alphaTest(Int &aMask, Short4 &alpha);
void alphaToCoverage(Int cMask[4], Float4 &alpha);
void fogBlend(Vector4f &c0, Float4 &fog);
void pixelFog(Float4 &visibility);
// Raster operations
void alphaBlend(int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x);
void logicOperation(int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x);
void writeColor(int index, Pointer<Byte> &cBuffer, Int &i, Vector4s &current, Int &sMask, Int &zMask, Int &cMask);
void alphaBlend(int index, Pointer<Byte> &cBuffer, Vector4f &oC, Int &x);
void writeColor(int index, Pointer<Byte> &cBuffer, Int &i, Vector4f &oC, Int &sMask, Int &zMask, Int &cMask);
bool isSRGB(int index) const;
UShort4 convertFixed16(Float4 &cf, bool saturate = true);
void linearToSRGB12_16(Vector4s &c);
private:
Float4 interpolateCentroid(Float4 &x, Float4 &y, Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective);
void stencilTest(Pointer<Byte> &sBuffer, int q, Int &x, Int &sMask, Int &cMask);
void stencilTest(Byte8 &value, StencilCompareMode stencilCompareMode, bool CCW);
void stencilOperation(Byte8 &newValue, Byte8 &bufferValue, StencilOperation stencilPassOperation, StencilOperation stencilZFailOperation, StencilOperation stencilFailOperation, bool CCW, Int &zMask, Int &sMask);
void stencilOperation(Byte8 &output, Byte8 &bufferValue, StencilOperation operation, bool CCW);
Bool depthTest(Pointer<Byte> &zBuffer, int q, Int &x, Float4 &z, Int &sMask, Int &zMask, Int &cMask);
// Raster operations
void blendFactor(Vector4s &blendFactor, const Vector4s &current, const Vector4s &pixel, BlendFactor blendFactorActive);
void blendFactorAlpha(Vector4s &blendFactor, const Vector4s &current, const Vector4s &pixel, BlendFactor blendFactorAlphaActive);
void readPixel(int index, Pointer<Byte> &cBuffer, Int &x, Vector4s &pixel);
void blendFactor(Vector4f &blendFactor, const Vector4f &oC, const Vector4f &pixel, BlendFactor blendFactorActive);
void blendFactorAlpha(Vector4f &blendFactor, const Vector4f &oC, const Vector4f &pixel, BlendFactor blendFactorAlphaActive);
void writeStencil(Pointer<Byte> &sBuffer, int q, Int &x, Int &sMask, Int &zMask, Int &cMask);
void writeDepth(Pointer<Byte> &zBuffer, int q, Int &x, Float4 &z, Int &zMask);
void sRGBtoLinear16_12_16(Vector4s &c);
void linearToSRGB16_12_16(Vector4s &c);
Float4 sRGBtoLinear(const Float4 &x);
bool colorUsed();
};
}
#endif // sw_PixelRoutine_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_PixelShader_hpp
#define sw_PixelShader_hpp
#include "Shader.hpp"
#include "Main/Config.hpp"
namespace sw
{
class PixelShader : public Shader
{
public:
explicit PixelShader(const PixelShader *ps = 0);
explicit PixelShader(const unsigned long *token);
virtual ~PixelShader();
static int validate(const unsigned long *const token); // Returns number of instructions if valid
bool depthOverride() const;
bool containsKill() const;
bool containsCentroid() const;
bool usesDiffuse(int component) const;
bool usesSpecular(int component) const;
bool usesTexture(int coordinate, int component) const;
void setInput(int inputIdx, int nbComponents, const Semantic& semantic);
const Semantic& getInput(int inputIdx, int component) const;
void declareVPos() { vPosDeclared = true; }
void declareVFace() { vFaceDeclared = true; }
bool isVPosDeclared() const { return vPosDeclared; }
bool isVFaceDeclared() const { return vFaceDeclared; }
private:
void analyze();
void analyzeZOverride();
void analyzeKill();
void analyzeInterpolants();
Semantic input[MAX_FRAGMENT_INPUTS][4];
bool vPosDeclared;
bool vFaceDeclared;
bool zOverride;
bool kill;
bool centroid;
};
}
#endif // sw_PixelShader_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_SamplerCore_hpp
#define sw_SamplerCore_hpp
#include "PixelRoutine.hpp"
#include "Reactor/Reactor.hpp"
namespace sw
{
enum SamplerMethod
{
Implicit, // Compute gradients (pixel shader only).
Bias, // Compute gradients and add provided bias.
Lod, // Use provided LOD.
Grad, // Use provided gradients.
Fetch, // Use provided integer coordinates.
Base // Sample base level.
};
enum SamplerOption
{
None,
Offset // Offset sample location by provided integer coordinates.
};
struct SamplerFunction
{
SamplerFunction(SamplerMethod method, SamplerOption option = None) : method(method), option(option) {}
operator SamplerMethod() { return method; }
const SamplerMethod method;
const SamplerOption option;
};
class SamplerCore
{
public:
SamplerCore(Pointer<Byte> &constants, const Sampler::State &state);
Vector4s sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy);
Vector4f sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
static Vector4f textureSize(Pointer<Byte> &mipmap, Float4 &lod);
private:
Vector4s sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function, bool fixed12);
void border(Short4 &mask, Float4 &coordinates);
void border(Int4 &mask, Float4 &coordinates);
Short4 offsetSample(Short4 &uvw, Pointer<Byte> &mipmap, int halfOffset, bool wrap, int count, Float &lod);
Vector4s sampleFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function);
Vector4s sampleAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function);
Vector4s sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
Vector4s sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
Vector4s sample3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloatFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function);
Vector4f sampleFloatAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function);
Vector4f sampleFloat(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
Vector4f sampleFloat2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
Vector4f sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
Float log2sqrt(Float lod);
Float log2(Float lod);
void computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &u, Float4 &v, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function);
void computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, Float4 &M, SamplerFunction function);
void computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function);
void cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &x, Float4 &y, Float4 &z, Float4 &M);
Short4 applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, AddressingMode mode);
void computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, SamplerFunction function);
void computeIndices(UInt index[4], Int4& uuuu, Int4& vvvv, Int4& wwww, const Pointer<Byte> &mipmap, SamplerFunction function);
Vector4s sampleTexel(Short4 &u, Short4 &v, Short4 &s, Vector4f &offset, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4], SamplerFunction function);
Vector4s sampleTexel(UInt index[4], Pointer<Byte> buffer[4]);
Vector4f sampleTexel(Int4 &u, Int4 &v, Int4 &s, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4], SamplerFunction function);
void selectMipmap(Pointer<Byte> &texture, Pointer<Byte> buffer[4], Pointer<Byte> &mipmap, Float &lod, Int face[4], bool secondLOD);
Short4 address(Float4 &uw, AddressingMode addressingMode, Pointer<Byte>& mipmap);
void address(Float4 &uw, Int4& xyz0, Int4& xyz1, Float4& f, Pointer<Byte>& mipmap, Float4 &texOffset, Int4 &filter, int whd, AddressingMode addressingMode, SamplerFunction function);
Int4 computeFilterOffset(Float &lod);
void convertFixed12(Short4 &ci, Float4 &cf);
void convertFixed12(Vector4s &cs, Vector4f &cf);
void convertSigned12(Float4 &cf, Short4 &ci);
void convertSigned15(Float4 &cf, Short4 &ci);
void convertUnsigned16(Float4 &cf, Short4 &ci);
void sRGBtoLinear16_8_16(Short4 &c);
void sRGBtoLinear16_6_16(Short4 &c);
void sRGBtoLinear16_5_16(Short4 &c);
bool hasFloatTexture() const;
bool hasUnnormalizedIntegerTexture() const;
bool hasUnsignedTextureComponent(int component) const;
int textureComponentCount() const;
bool hasThirdCoordinate() const;
bool has16bitTextureFormat() const;
bool has8bitTextureComponents() const;
bool has16bitTextureComponents() const;
bool has32bitIntegerTextureComponents() const;
bool hasYuvFormat() const;
bool isRGBComponent(int component) const;
Pointer<Byte> &constants;
const Sampler::State &state;
};
}
#endif // sw_SamplerCore_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_SetupRoutine_hpp
#define sw_SetupRoutine_hpp
#include "Renderer/SetupProcessor.hpp"
#include "Reactor/Reactor.hpp"
namespace sw
{
class Context;
class SetupRoutine
{
public:
SetupRoutine(const SetupProcessor::State &state);
virtual ~SetupRoutine();
void generate();
Routine *getRoutine();
private:
void setupGradient(Pointer<Byte> &primitive, Pointer<Byte> &triangle, Float4 &w012, Float4 (&m)[3], Pointer<Byte> &v0, Pointer<Byte> &v1, Pointer<Byte> &v2, int attribute, int planeEquation, bool flatShading, bool sprite, bool perspective, bool wrap, int component);
void edge(Pointer<Byte> &primitive, Pointer<Byte> &data, const Int &Xa, const Int &Ya, const Int &Xb, const Int &Yb, Int &q);
void conditionalRotate1(Bool condition, Pointer<Byte> &v0, Pointer<Byte> &v1, Pointer<Byte> &v2);
void conditionalRotate2(Bool condition, Pointer<Byte> &v0, Pointer<Byte> &v1, Pointer<Byte> &v2);
const SetupProcessor::State &state;
Routine *routine;
};
}
#endif // sw_SetupRoutine_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_VertexPipeline_hpp
#define sw_VertexPipeline_hpp
#include "VertexRoutine.hpp"
#include "Renderer/Context.hpp"
#include "Renderer/VertexProcessor.hpp"
namespace sw
{
class VertexPipeline : public VertexRoutine
{
public:
VertexPipeline(const VertexProcessor::State &state);
virtual ~VertexPipeline();
private:
void pipeline(UInt &index) override;
void processTextureCoordinate(int stage, Vector4f &normal, Vector4f &position);
void processPointSize();
Vector4f transformBlend(const Register &src, const Pointer<Byte> &matrix, bool homogenous);
Vector4f transform(const Register &src, const Pointer<Byte> &matrix, bool homogenous);
Vector4f transform(const Register &src, const Pointer<Byte> &matrix, UInt index[4], bool homogenous);
Vector4f normalize(Vector4f &src);
Float4 power(Float4 &src0, Float4 &src1);
};
};
#endif // sw_VertexPipeline_hpp
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef sw_VertexProgram_hpp
#define sw_VertexProgram_hpp
#include "VertexRoutine.hpp"
#include "ShaderCore.hpp"
#include "SamplerCore.hpp"
#include "Renderer/Stream.hpp"
#include "Common/Types.hpp"
namespace sw
{
struct Stream;
class VertexShader;
class VertexProgram : public VertexRoutine, public ShaderCore
{
public:
VertexProgram(const VertexProcessor::State &state, const VertexShader *vertexShader);
virtual ~VertexProgram();
private:
const VertexShader *const shader;
RegisterArray<NUM_TEMPORARY_REGISTERS> r; // Temporary registers
Vector4f a0;
Array<Int, 4> aL;
Vector4f p0;
Array<Int, 4> increment;
Array<Int, 4> iteration;
Int loopDepth;
Int stackIndex; // FIXME: Inc/decrement callStack
Array<UInt, 16> callStack;
Int enableIndex;
Array<Int4, 1 + 24> enableStack;
Int4 enableBreak;
Int4 enableContinue;
Int4 enableLeave;
Int instanceID;
Int4 vertexID;
typedef Shader::DestinationParameter Dst;
typedef Shader::SourceParameter Src;
typedef Shader::Control Control;
typedef Shader::Usage Usage;
void pipeline(UInt &index) override;
void program(UInt &index);
void passThrough();
Vector4f fetchRegister(const Src &src, unsigned int offset = 0);
Vector4f readConstant(const Src &src, unsigned int offset = 0);
RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index);
RValue<Pointer<Byte>> uniformAddress(int bufferIndex, unsigned int index, Int &offset);
Int relativeAddress(const Shader::Relative &rel, int bufferIndex = -1);
Int4 dynamicAddress(const Shader::Relative &rel);
Int4 enableMask(const Shader::Instruction *instruction);
void M3X2(Vector4f &dst, Vector4f &src0, Src &src1);
void M3X3(Vector4f &dst, Vector4f &src0, Src &src1);
void M3X4(Vector4f &dst, Vector4f &src0, Src &src1);
void M4X3(Vector4f &dst, Vector4f &src0, Src &src1);
void M4X4(Vector4f &dst, Vector4f &src0, Src &src1);
void BREAK();
void BREAKC(Vector4f &src0, Vector4f &src1, Control);
void BREAKP(const Src &predicateRegister);
void BREAK(Int4 &condition);
void CONTINUE();
void TEST();
void CALL(int labelIndex, int callSiteIndex);
void CALLNZ(int labelIndex, int callSiteIndex, const Src &src);
void CALLNZb(int labelIndex, int callSiteIndex, const Src &boolRegister);
void CALLNZp(int labelIndex, int callSiteIndex, const Src &predicateRegister);
void ELSE();
void ENDIF();
void ENDLOOP();
void ENDREP();
void ENDWHILE();
void ENDSWITCH();
void IF(const Src &src);
void IFb(const Src &boolRegister);
void IFp(const Src &predicateRegister);
void IFC(Vector4f &src0, Vector4f &src1, Control);
void IF(Int4 &condition);
void LABEL(int labelIndex);
void LOOP(const Src &integerRegister);
void REP(const Src &integerRegister);
void WHILE(const Src &temporaryRegister);
void SWITCH();
void RET();
void LEAVE();
void TEX(Vector4f &dst, Vector4f &src, const Src&);
void TEXOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &offset);
void TEXLOD(Vector4f &dst, Vector4f &src, const Src&, Float4 &lod);
void TEXLODOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &offset, Float4 &lod);
void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&, Float4 &lod);
void TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &offset, Float4 &lod);
void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &dsx, Vector4f &dsy);
void TEXGRADOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &dsx, Vector4f &dsy, Vector4f &offset);
void TEXSIZE(Vector4f &dst, Float4 &lod, const Src&);
Vector4f sampleTexture(const Src &s, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
Vector4f sampleTexture(int sampler, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
int ifDepth;
int loopRepDepth;
int currentLabel;
bool whileTest;
BasicBlock *ifFalseBlock[24 + 24];
BasicBlock *loopRepTestBlock[4];
BasicBlock *loopRepEndBlock[4];
BasicBlock *labelBlock[2048];
std::vector<BasicBlock*> callRetBlock[2048];
BasicBlock *returnBlock;
bool isConditionalIf[24 + 24];
};
}
#endif // sw_VertexProgram_hpp
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