Commit d9762743 by Maxime Grégoire

Implementation of glLogicOp

Bug 22375329 Change-Id: Id6684e33bf3cd37fce48e7607e6a65fe64309f72 Reviewed-on: https://swiftshader-review.googlesource.com/2764Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarMaxime Grégoire <mgregoire@google.com>
parent 04c967a3
...@@ -98,6 +98,8 @@ Context::Context(const Context *shareContext) ...@@ -98,6 +98,8 @@ Context::Context(const Context *shareContext)
mState.dither = true; mState.dither = true;
mState.generateMipmapHint = GL_DONT_CARE; mState.generateMipmapHint = GL_DONT_CARE;
mState.fragmentShaderDerivativeHint = GL_DONT_CARE; mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
mState.colorLogicOp = false;
mState.logicalOperation = GL_COPY;
mState.lineWidth = 1.0f; mState.lineWidth = 1.0f;
...@@ -1815,6 +1817,21 @@ void Context::applyState(GLenum drawMode) ...@@ -1815,6 +1817,21 @@ void Context::applyState(GLenum drawMode)
mBlendStateDirty = false; mBlendStateDirty = false;
} }
if(mColorLogicOperatorDirty)
{
if(mState.colorLogicOp)
{
device->setColorLogicOpEnabled(true);
device->setLogicalOperation(es2sw::ConvertLogicalOperation(mState.logicalOperation));
}
else
{
device->setColorLogicOpEnabled(false);
}
mColorLogicOperatorDirty = false;
}
if(mStencilStateDirty || mFrontFaceDirty) if(mStencilStateDirty || mFrontFaceDirty)
{ {
if(mState.stencilTest && framebuffer->hasStencil()) if(mState.stencilTest && framebuffer->hasStencil())
...@@ -3597,6 +3614,25 @@ void Context::end() ...@@ -3597,6 +3614,25 @@ void Context::end()
drawing = false; drawing = false;
} }
void Context::setColorLogicOpEnable(bool colorLogicOpEnabled)
{
if(mState.colorLogicOp != colorLogicOpEnabled)
{
mState.colorLogicOp = colorLogicOpEnabled;
mColorLogicOperatorDirty = true;
}
}
bool Context::isColorLogicOpEnabled()
{
return mState.colorLogicOp;
}
void Context::setLogicalOperation(GLenum logicalOperation)
{
mState.logicalOperation = logicalOperation;
}
void Context::setColorMaterial(bool enable) void Context::setColorMaterial(bool enable)
{ {
device->setColorVertexEnable(enable); device->setColorVertexEnable(enable);
......
...@@ -452,6 +452,8 @@ struct State ...@@ -452,6 +452,8 @@ struct State
bool sampleCoverageInvert; bool sampleCoverageInvert;
bool scissorTest; bool scissorTest;
bool dither; bool dither;
bool colorLogicOp;
GLenum logicalOperation;
GLfloat lineWidth; GLfloat lineWidth;
...@@ -717,6 +719,10 @@ public: ...@@ -717,6 +719,10 @@ public:
void setColorMaterial(bool enable); void setColorMaterial(bool enable);
void setColorMaterialMode(GLenum mode); void setColorMaterialMode(GLenum mode);
void setColorLogicOpEnable(bool colorLogicOpEnabled);
bool isColorLogicOpEnabled();
void setLogicalOperation(GLenum logicalOperation);
Device *getDevice(); Device *getDevice();
private: private:
...@@ -779,6 +785,7 @@ private: ...@@ -779,6 +785,7 @@ private:
bool mSampleStateDirty; bool mSampleStateDirty;
bool mFrontFaceDirty; bool mFrontFaceDirty;
bool mDitherStateDirty; bool mDitherStateDirty;
bool mColorLogicOperatorDirty;
Device *device; Device *device;
ResourceManager *mResourceManager; ResourceManager *mResourceManager;
......
...@@ -87,6 +87,8 @@ namespace gl ...@@ -87,6 +87,8 @@ namespace gl
setDestBlendFactorAlpha(BLEND_ZERO); setDestBlendFactorAlpha(BLEND_ZERO);
setBlendOperationAlpha(BLENDOP_ADD); setBlendOperationAlpha(BLENDOP_ADD);
setPointSpriteEnable(true); setPointSpriteEnable(true);
setColorLogicOpEnabled(false);
setLogicalOperation(LOGICALOP_COPY);
for(int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
{ {
......
...@@ -1614,6 +1614,8 @@ void APIENTRY glDisable(GLenum cap) ...@@ -1614,6 +1614,8 @@ void APIENTRY glDisable(GLenum cap)
case GL_LIGHT7: context->setLight(7, false); break; case GL_LIGHT7: context->setLight(7, false); break;
case GL_COLOR_MATERIAL: context->setColorMaterial(false); break; case GL_COLOR_MATERIAL: context->setColorMaterial(false); break;
case GL_RESCALE_NORMAL: context->setNormalizeNormals(false); break; case GL_RESCALE_NORMAL: context->setNormalizeNormals(false); break;
case GL_COLOR_LOGIC_OP: context->setColorLogicOpEnable(false); break;
case GL_INDEX_LOGIC_OP: UNIMPLEMENTED();
default: default:
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
...@@ -1761,6 +1763,8 @@ void APIENTRY glEnable(GLenum cap) ...@@ -1761,6 +1763,8 @@ void APIENTRY glEnable(GLenum cap)
case GL_LIGHT6: context->setLight(6, true); break; case GL_LIGHT6: context->setLight(6, true); break;
case GL_LIGHT7: context->setLight(7, true); break; case GL_LIGHT7: context->setLight(7, true); break;
case GL_RESCALE_NORMAL: context->setNormalizeNormals(true); break; case GL_RESCALE_NORMAL: context->setNormalizeNormals(true); break;
case GL_COLOR_LOGIC_OP: context->setColorLogicOpEnable(true); break;
case GL_INDEX_LOGIC_OP: UNIMPLEMENTED();
default: default:
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
...@@ -3520,6 +3524,8 @@ GLboolean APIENTRY glIsEnabled(GLenum cap) ...@@ -3520,6 +3524,8 @@ GLboolean APIENTRY glIsEnabled(GLenum cap)
case GL_DEPTH_TEST: return context->isDepthTestEnabled(); case GL_DEPTH_TEST: return context->isDepthTestEnabled();
case GL_BLEND: return context->isBlendEnabled(); case GL_BLEND: return context->isBlendEnabled();
case GL_DITHER: return context->isDitherEnabled(); case GL_DITHER: return context->isDitherEnabled();
case GL_COLOR_LOGIC_OP: return context->isColorLogicOpEnabled();
case GL_INDEX_LOGIC_OP: UNIMPLEMENTED();
default: default:
return error(GL_INVALID_ENUM, false); return error(GL_INVALID_ENUM, false);
} }
...@@ -6623,7 +6629,42 @@ void APIENTRY glLoadName(GLuint name) ...@@ -6623,7 +6629,42 @@ void APIENTRY glLoadName(GLuint name)
void APIENTRY glLogicOp(GLenum opcode) void APIENTRY glLogicOp(GLenum opcode)
{ {
UNIMPLEMENTED(); TRACE("(GLenum opcode = 0x%X)", opcode);
switch(opcode)
{
case GL_CLEAR:
case GL_SET:
case GL_COPY:
case GL_COPY_INVERTED:
case GL_NOOP:
case GL_INVERT:
case GL_AND:
case GL_NAND:
case GL_OR:
case GL_NOR:
case GL_XOR:
case GL_EQUIV:
case GL_AND_REVERSE:
case GL_AND_INVERTED:
case GL_OR_REVERSE:
case GL_OR_INVERTED:
break;
default:
return error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getContext();
if(context)
{
if(context->getListIndex() != 0)
{
UNIMPLEMENTED();
}
context->setLogicalOperation(opcode);
}
} }
void APIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points) void APIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)
......
...@@ -509,6 +509,32 @@ namespace es2sw ...@@ -509,6 +509,32 @@ namespace es2sw
return sw::BLENDOP_ADD; return sw::BLENDOP_ADD;
} }
sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation)
{
switch(logicalOperation)
{
case GL_CLEAR: return sw::LOGICALOP_CLEAR;
case GL_SET: return sw::LOGICALOP_SET;
case GL_COPY: return sw::LOGICALOP_COPY;
case GL_COPY_INVERTED: return sw::LOGICALOP_COPY_INVERTED;
case GL_NOOP: return sw::LOGICALOP_NOOP;
case GL_INVERT: return sw::LOGICALOP_INVERT;
case GL_AND: return sw::LOGICALOP_AND;
case GL_NAND: return sw::LOGICALOP_NAND;
case GL_OR: return sw::LOGICALOP_OR;
case GL_NOR: return sw::LOGICALOP_NOR;
case GL_XOR: return sw::LOGICALOP_XOR;
case GL_EQUIV: return sw::LOGICALOP_EQUIV;
case GL_AND_REVERSE: return sw::LOGICALOP_AND_REVERSE;
case GL_AND_INVERTED: return sw::LOGICALOP_AND_INVERTED;
case GL_OR_REVERSE: return sw::LOGICALOP_OR_REVERSE;
case GL_OR_INVERTED: return sw::LOGICALOP_OR_INVERTED;
default: UNREACHABLE(logicalOperation);
}
return sw::LOGICALOP_COPY;
}
sw::StencilOperation ConvertStencilOp(GLenum stencilOp) sw::StencilOperation ConvertStencilOp(GLenum stencilOp)
{ {
switch(stencilOp) switch(stencilOp)
......
...@@ -61,6 +61,7 @@ namespace es2sw ...@@ -61,6 +61,7 @@ namespace es2sw
sw::Color<float> ConvertColor(gl::Color color); sw::Color<float> ConvertColor(gl::Color color);
sw::BlendFactor ConvertBlendFunc(GLenum blend); sw::BlendFactor ConvertBlendFunc(GLenum blend);
sw::BlendOperation ConvertBlendOp(GLenum blendOp); sw::BlendOperation ConvertBlendOp(GLenum blendOp);
sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation);
sw::StencilOperation ConvertStencilOp(GLenum stencilOp); sw::StencilOperation ConvertStencilOp(GLenum stencilOp);
sw::AddressingMode ConvertTextureWrap(GLenum wrap); sw::AddressingMode ConvertTextureWrap(GLenum wrap);
sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace); sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace);
......
...@@ -86,6 +86,8 @@ Context::Context(const egl::Config *config, const Context *shareContext) ...@@ -86,6 +86,8 @@ Context::Context(const egl::Config *config, const Context *shareContext)
mState.shadeModel = GL_SMOOTH; mState.shadeModel = GL_SMOOTH;
mState.generateMipmapHint = GL_DONT_CARE; mState.generateMipmapHint = GL_DONT_CARE;
mState.perspectiveCorrectionHint = GL_DONT_CARE; mState.perspectiveCorrectionHint = GL_DONT_CARE;
mState.colorLogicOp = false;
mState.logicalOperation = GL_COPY;
mState.lineWidth = 1.0f; mState.lineWidth = 1.0f;
......
...@@ -236,6 +236,8 @@ struct State ...@@ -236,6 +236,8 @@ struct State
bool scissorTest; bool scissorTest;
bool dither; bool dither;
GLenum shadeModel; GLenum shadeModel;
bool colorLogicOp;
GLenum logicalOperation;
GLfloat lineWidth; GLfloat lineWidth;
......
...@@ -87,6 +87,8 @@ namespace es1 ...@@ -87,6 +87,8 @@ namespace es1
setDestBlendFactorAlpha(BLEND_ZERO); setDestBlendFactorAlpha(BLEND_ZERO);
setBlendOperationAlpha(BLENDOP_ADD); setBlendOperationAlpha(BLENDOP_ADD);
setPointSpriteEnable(true); setPointSpriteEnable(true);
setColorLogicOpEnabled(false);
setLogicalOperation(LOGICALOP_COPY);
for(int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
{ {
......
...@@ -52,6 +52,7 @@ namespace es2sw ...@@ -52,6 +52,7 @@ namespace es2sw
sw::Color<float> ConvertColor(es1::Color color); sw::Color<float> ConvertColor(es1::Color color);
sw::BlendFactor ConvertBlendFunc(GLenum blend); sw::BlendFactor ConvertBlendFunc(GLenum blend);
sw::BlendOperation ConvertBlendOp(GLenum blendOp); sw::BlendOperation ConvertBlendOp(GLenum blendOp);
sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation);
sw::StencilOperation ConvertStencilOp(GLenum stencilOp); sw::StencilOperation ConvertStencilOp(GLenum stencilOp);
sw::AddressingMode ConvertTextureWrap(GLenum wrap); sw::AddressingMode ConvertTextureWrap(GLenum wrap);
sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace); sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace);
......
...@@ -306,6 +306,8 @@ struct State ...@@ -306,6 +306,8 @@ struct State
bool dither; bool dither;
bool primitiveRestartFixedIndex; bool primitiveRestartFixedIndex;
bool rasterizerDiscard; bool rasterizerDiscard;
bool colorLogicOp;
GLenum logicalOperation;
GLfloat lineWidth; GLfloat lineWidth;
......
...@@ -87,6 +87,8 @@ namespace es2 ...@@ -87,6 +87,8 @@ namespace es2
setDestBlendFactorAlpha(BLEND_ZERO); setDestBlendFactorAlpha(BLEND_ZERO);
setBlendOperationAlpha(BLENDOP_ADD); setBlendOperationAlpha(BLENDOP_ADD);
setPointSpriteEnable(true); setPointSpriteEnable(true);
setColorLogicOpEnabled(false);
setLogicalOperation(LOGICALOP_COPY);
for(int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
{ {
......
...@@ -61,6 +61,7 @@ namespace es2sw ...@@ -61,6 +61,7 @@ namespace es2sw
sw::Color<float> ConvertColor(es2::Color color); sw::Color<float> ConvertColor(es2::Color color);
sw::BlendFactor ConvertBlendFunc(GLenum blend); sw::BlendFactor ConvertBlendFunc(GLenum blend);
sw::BlendOperation ConvertBlendOp(GLenum blendOp); sw::BlendOperation ConvertBlendOp(GLenum blendOp);
sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation);
sw::StencilOperation ConvertStencilOp(GLenum stencilOp); sw::StencilOperation ConvertStencilOp(GLenum stencilOp);
sw::AddressingMode ConvertTextureWrap(GLenum wrap); sw::AddressingMode ConvertTextureWrap(GLenum wrap);
sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace); sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace);
......
...@@ -302,6 +302,9 @@ namespace sw ...@@ -302,6 +302,9 @@ namespace sw
writeSRGB = false; writeSRGB = false;
sampleMask = 0xFFFFFFFF; sampleMask = 0xFFFFFFFF;
colorLogicOpEnabled = false;
logicalOperation = LogicalOperation::LOGICALOP_COPY;
} }
const float &Context::exp2Bias() const float &Context::exp2Bias()
...@@ -446,6 +449,20 @@ namespace sw ...@@ -446,6 +449,20 @@ namespace sw
return modified; return modified;
} }
bool Context::setColorLogicOpEnabled(bool enabled)
{
bool modified = (Context::colorLogicOpEnabled != enabled);
Context::colorLogicOpEnabled = enabled;
return modified;
}
bool Context::setLogicalOperation(LogicalOperation logicalOperation)
{
bool modified = (Context::logicalOperation != logicalOperation);
Context::logicalOperation = logicalOperation;
return modified;
}
void Context::setColorVertexEnable(bool colorVertexEnable) void Context::setColorVertexEnable(bool colorVertexEnable)
{ {
Context::colorVertexEnable = colorVertexEnable; Context::colorVertexEnable = colorVertexEnable;
...@@ -731,6 +748,11 @@ namespace sw ...@@ -731,6 +748,11 @@ namespace sw
return colorBlend || alphaBlend; return colorBlend || alphaBlend;
} }
LogicalOperation Context::colorLogicOp()
{
return colorLogicOpEnabled ? logicalOperation : LogicalOperation::LOGICALOP_COPY;
}
BlendFactor Context::sourceBlendFactor() BlendFactor Context::sourceBlendFactor()
{ {
if(!alphaBlendEnable) return BLEND_ONE; if(!alphaBlendEnable) return BLEND_ONE;
......
...@@ -205,6 +205,28 @@ namespace sw ...@@ -205,6 +205,28 @@ namespace sw
BLENDOP_LAST = BLENDOP_NULL BLENDOP_LAST = BLENDOP_NULL
}; };
enum LogicalOperation : unsigned int
{
LOGICALOP_CLEAR,
LOGICALOP_SET,
LOGICALOP_COPY,
LOGICALOP_COPY_INVERTED,
LOGICALOP_NOOP,
LOGICALOP_INVERT,
LOGICALOP_AND,
LOGICALOP_NAND,
LOGICALOP_OR,
LOGICALOP_NOR,
LOGICALOP_XOR,
LOGICALOP_EQUIV,
LOGICALOP_AND_REVERSE,
LOGICALOP_AND_INVERTED,
LOGICALOP_OR_REVERSE,
LOGICALOP_OR_INVERTED,
LOGICALOP_LAST = LOGICALOP_OR_INVERTED
};
enum MaterialSource : unsigned int enum MaterialSource : unsigned int
{ {
MATERIAL_MATERIAL, MATERIAL_MATERIAL,
...@@ -297,6 +319,9 @@ namespace sw ...@@ -297,6 +319,9 @@ namespace sw
bool setColorWriteMask(int index, int colorWriteMask); bool setColorWriteMask(int index, int colorWriteMask);
bool setWriteSRGB(bool sRGB); bool setWriteSRGB(bool sRGB);
bool setColorLogicOpEnabled(bool colorLogicOpEnabled);
bool setLogicalOperation(LogicalOperation logicalOperation);
// Active fixed-function pixel pipeline states // Active fixed-function pixel pipeline states
bool fogActive(); bool fogActive();
bool pointSizeActive(); bool pointSizeActive();
...@@ -335,6 +360,9 @@ namespace sw ...@@ -335,6 +360,9 @@ namespace sw
BlendFactor destBlendFactorAlpha(); BlendFactor destBlendFactorAlpha();
BlendOperation blendOperationAlpha(); BlendOperation blendOperationAlpha();
LogicalOperation colorLogicOp();
LogicalOperation indexLogicOp();
bool indexedVertexBlendActive(); bool indexedVertexBlendActive();
int vertexBlendMatrixCountActive(); int vertexBlendMatrixCountActive();
bool localViewerActive(); bool localViewerActive();
...@@ -483,6 +511,9 @@ namespace sw ...@@ -483,6 +511,9 @@ namespace sw
bool writeSRGB; bool writeSRGB;
unsigned int sampleMask; unsigned int sampleMask;
unsigned int multiSampleMask; unsigned int multiSampleMask;
bool colorLogicOpEnabled;
LogicalOperation logicalOperation;
}; };
} }
......
...@@ -420,6 +420,16 @@ namespace sw ...@@ -420,6 +420,16 @@ namespace sw
context->setWriteSRGB(sRGB); context->setWriteSRGB(sRGB);
} }
void PixelProcessor::setColorLogicOpEnabled(bool colorLogicOpEnabled)
{
context->setColorLogicOpEnabled(colorLogicOpEnabled);
}
void PixelProcessor::setLogicalOperation(LogicalOperation logicalOperation)
{
context->setLogicalOperation(logicalOperation);
}
void PixelProcessor::setDepthBufferEnable(bool depthBufferEnable) void PixelProcessor::setDepthBufferEnable(bool depthBufferEnable)
{ {
context->setDepthBufferEnable(depthBufferEnable); context->setDepthBufferEnable(depthBufferEnable);
...@@ -883,7 +893,9 @@ namespace sw ...@@ -883,7 +893,9 @@ namespace sw
state.destBlendFactorAlpha = context->destBlendFactorAlpha(); state.destBlendFactorAlpha = context->destBlendFactorAlpha();
state.blendOperationAlpha = context->blendOperationAlpha(); state.blendOperationAlpha = context->blendOperationAlpha();
} }
state.logicalOperation = context->colorLogicOp();
state.colorWriteMask = (context->colorWriteActive(0) << 0) | state.colorWriteMask = (context->colorWriteActive(0) << 0) |
(context->colorWriteActive(1) << 4) | (context->colorWriteActive(1) << 4) |
(context->colorWriteActive(2) << 8) | (context->colorWriteActive(2) << 8) |
......
...@@ -80,6 +80,8 @@ namespace sw ...@@ -80,6 +80,8 @@ namespace sw
TransparencyAntialiasing transparencyAntialiasing : BITS(TRANSPARENCY_LAST); TransparencyAntialiasing transparencyAntialiasing : BITS(TRANSPARENCY_LAST);
bool centroid : 1; bool centroid : 1;
LogicalOperation logicalOperation : BITS(LOGICALOP_LAST);
Sampler::State sampler[TEXTURE_IMAGE_UNITS]; Sampler::State sampler[TEXTURE_IMAGE_UNITS];
TextureStage::State textureStage[8]; TextureStage::State textureStage[8];
...@@ -233,6 +235,9 @@ namespace sw ...@@ -233,6 +235,9 @@ namespace sw
virtual void setCullMode(CullMode cullMode); virtual void setCullMode(CullMode cullMode);
virtual void setColorWriteMask(int index, int rgbaMask); virtual void setColorWriteMask(int index, int rgbaMask);
virtual void setColorLogicOpEnabled(bool colorLogicOpEnabled);
virtual void setLogicalOperation(LogicalOperation logicalOperation);
virtual void setStencilEnable(bool stencilEnable); virtual void setStencilEnable(bool stencilEnable);
virtual void setStencilCompare(StencilCompareMode stencilCompareMode); virtual void setStencilCompare(StencilCompareMode stencilCompareMode);
virtual void setStencilReference(int stencilReference); virtual void setStencilReference(int stencilReference);
......
...@@ -2200,6 +2200,7 @@ namespace sw ...@@ -2200,6 +2200,7 @@ namespace sw
if(state.multiSampleMask & (1 << q)) if(state.multiSampleMask & (1 << q))
{ {
alphaBlend(r, 0, buffer, color, x); alphaBlend(r, 0, buffer, color, x);
logicOperation(r, 0, buffer, color, x);
writeColor(r, 0, buffer, x, color, sMask[q], zMask[q], cMask[q]); writeColor(r, 0, buffer, x, color, sMask[q], zMask[q], cMask[q]);
} }
} }
...@@ -2271,6 +2272,7 @@ namespace sw ...@@ -2271,6 +2272,7 @@ namespace sw
if(state.multiSampleMask & (1 << q)) if(state.multiSampleMask & (1 << q))
{ {
alphaBlend(r, index, buffer, color, x); alphaBlend(r, index, buffer, color, x);
logicOperation(r, index, buffer, color, x);
writeColor(r, index, buffer, x, color, sMask[q], zMask[q], cMask[q]); writeColor(r, index, buffer, x, color, sMask[q], zMask[q], cMask[q]);
} }
} }
...@@ -2427,26 +2429,18 @@ namespace sw ...@@ -2427,26 +2429,18 @@ namespace sw
} }
} }
void PixelRoutine::alphaBlend(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x) void PixelRoutine::readPixel(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x, Vector4s &pixel)
{ {
if(!state.alphaBlendActive)
{
return;
}
Pointer<Byte> buffer;
Vector4s pixel;
Short4 c01; Short4 c01;
Short4 c23; Short4 c23;
Pointer<Byte> buffer;
// Read pixel
switch(state.targetFormat[index]) switch(state.targetFormat[index])
{ {
case FORMAT_R5G6B5: case FORMAT_R5G6B5:
buffer = cBuffer + 2 * x; buffer = cBuffer + 2 * x;
c01 = As<Short4>(Insert(As<Int2>(c01), *Pointer<Int>(buffer), 0)); c01 = As<Short4>(Insert(As<Int2>(c01), *Pointer<Int>(buffer), 0));
buffer += *Pointer<Int>(r.data + OFFSET(DrawData,colorPitchB[index])); buffer += *Pointer<Int>(r.data + OFFSET(DrawData, colorPitchB[index]));
c01 = As<Short4>(Insert(As<Int2>(c01), *Pointer<Int>(buffer), 1)); c01 = As<Short4>(Insert(As<Int2>(c01), *Pointer<Int>(buffer), 1));
pixel.x = c01 & Short4(0xF800u); pixel.x = c01 & Short4(0xF800u);
...@@ -2457,7 +2451,7 @@ namespace sw ...@@ -2457,7 +2451,7 @@ namespace sw
case FORMAT_A8R8G8B8: case FORMAT_A8R8G8B8:
buffer = cBuffer + 4 * x; buffer = cBuffer + 4 * x;
c01 = *Pointer<Short4>(buffer); c01 = *Pointer<Short4>(buffer);
buffer += *Pointer<Int>(r.data + OFFSET(DrawData,colorPitchB[index])); buffer += *Pointer<Int>(r.data + OFFSET(DrawData, colorPitchB[index]));
c23 = *Pointer<Short4>(buffer); c23 = *Pointer<Short4>(buffer);
pixel.z = c01; pixel.z = c01;
pixel.y = c01; pixel.y = c01;
...@@ -2476,7 +2470,7 @@ namespace sw ...@@ -2476,7 +2470,7 @@ namespace sw
case FORMAT_A8B8G8R8: case FORMAT_A8B8G8R8:
buffer = cBuffer + 4 * x; buffer = cBuffer + 4 * x;
c01 = *Pointer<Short4>(buffer); c01 = *Pointer<Short4>(buffer);
buffer += *Pointer<Int>(r.data + OFFSET(DrawData,colorPitchB[index])); buffer += *Pointer<Int>(r.data + OFFSET(DrawData, colorPitchB[index]));
c23 = *Pointer<Short4>(buffer); c23 = *Pointer<Short4>(buffer);
pixel.z = c01; pixel.z = c01;
pixel.y = c01; pixel.y = c01;
...@@ -2495,7 +2489,7 @@ namespace sw ...@@ -2495,7 +2489,7 @@ namespace sw
case FORMAT_A8: case FORMAT_A8:
buffer = cBuffer + 1 * x; buffer = cBuffer + 1 * x;
pixel.w = Insert(pixel.w, *Pointer<Short>(buffer), 0); pixel.w = Insert(pixel.w, *Pointer<Short>(buffer), 0);
buffer += *Pointer<Int>(r.data + OFFSET(DrawData,colorPitchB[index])); buffer += *Pointer<Int>(r.data + OFFSET(DrawData, colorPitchB[index]));
pixel.w = Insert(pixel.w, *Pointer<Short>(buffer), 1); pixel.w = Insert(pixel.w, *Pointer<Short>(buffer), 1);
pixel.w = UnpackLow(As<Byte8>(pixel.w), As<Byte8>(pixel.w)); pixel.w = UnpackLow(As<Byte8>(pixel.w), As<Byte8>(pixel.w));
pixel.x = Short4(0x0000); pixel.x = Short4(0x0000);
...@@ -2505,7 +2499,7 @@ namespace sw ...@@ -2505,7 +2499,7 @@ namespace sw
case FORMAT_X8R8G8B8: case FORMAT_X8R8G8B8:
buffer = cBuffer + 4 * x; buffer = cBuffer + 4 * x;
c01 = *Pointer<Short4>(buffer); c01 = *Pointer<Short4>(buffer);
buffer += *Pointer<Int>(r.data + OFFSET(DrawData,colorPitchB[index])); buffer += *Pointer<Int>(r.data + OFFSET(DrawData, colorPitchB[index]));
c23 = *Pointer<Short4>(buffer); c23 = *Pointer<Short4>(buffer);
pixel.z = c01; pixel.z = c01;
pixel.y = c01; pixel.y = c01;
...@@ -2523,7 +2517,7 @@ namespace sw ...@@ -2523,7 +2517,7 @@ namespace sw
case FORMAT_X8B8G8R8: case FORMAT_X8B8G8R8:
buffer = cBuffer + 4 * x; buffer = cBuffer + 4 * x;
c01 = *Pointer<Short4>(buffer); c01 = *Pointer<Short4>(buffer);
buffer += *Pointer<Int>(r.data + OFFSET(DrawData,colorPitchB[index])); buffer += *Pointer<Int>(r.data + OFFSET(DrawData, colorPitchB[index]));
c23 = *Pointer<Short4>(buffer); c23 = *Pointer<Short4>(buffer);
pixel.z = c01; pixel.z = c01;
pixel.y = c01; pixel.y = c01;
...@@ -2541,32 +2535,32 @@ namespace sw ...@@ -2541,32 +2535,32 @@ namespace sw
break; break;
case FORMAT_A8G8R8B8Q: case FORMAT_A8G8R8B8Q:
UNIMPLEMENTED(); UNIMPLEMENTED();
// pixel.z = UnpackLow(As<Byte8>(pixel.z), *Pointer<Byte8>(cBuffer + 8 * x + 0)); // pixel.z = UnpackLow(As<Byte8>(pixel.z), *Pointer<Byte8>(cBuffer + 8 * x + 0));
// pixel.x = UnpackHigh(As<Byte8>(pixel.x), *Pointer<Byte8>(cBuffer + 8 * x + 0)); // pixel.x = UnpackHigh(As<Byte8>(pixel.x), *Pointer<Byte8>(cBuffer + 8 * x + 0));
// pixel.y = UnpackLow(As<Byte8>(pixel.y), *Pointer<Byte8>(cBuffer + 8 * x + 8)); // pixel.y = UnpackLow(As<Byte8>(pixel.y), *Pointer<Byte8>(cBuffer + 8 * x + 8));
// pixel.w = UnpackHigh(As<Byte8>(pixel.w), *Pointer<Byte8>(cBuffer + 8 * x + 8)); // pixel.w = UnpackHigh(As<Byte8>(pixel.w), *Pointer<Byte8>(cBuffer + 8 * x + 8));
break; break;
case FORMAT_X8G8R8B8Q: case FORMAT_X8G8R8B8Q:
UNIMPLEMENTED(); UNIMPLEMENTED();
// pixel.z = UnpackLow(As<Byte8>(pixel.z), *Pointer<Byte8>(cBuffer + 8 * x + 0)); // pixel.z = UnpackLow(As<Byte8>(pixel.z), *Pointer<Byte8>(cBuffer + 8 * x + 0));
// pixel.x = UnpackHigh(As<Byte8>(pixel.x), *Pointer<Byte8>(cBuffer + 8 * x + 0)); // pixel.x = UnpackHigh(As<Byte8>(pixel.x), *Pointer<Byte8>(cBuffer + 8 * x + 0));
// pixel.y = UnpackLow(As<Byte8>(pixel.y), *Pointer<Byte8>(cBuffer + 8 * x + 8)); // pixel.y = UnpackLow(As<Byte8>(pixel.y), *Pointer<Byte8>(cBuffer + 8 * x + 8));
// pixel.w = Short4(0xFFFFu); // pixel.w = Short4(0xFFFFu);
break; break;
case FORMAT_A16B16G16R16: case FORMAT_A16B16G16R16:
buffer = cBuffer; buffer = cBuffer;
pixel.x = *Pointer<Short4>(buffer + 8 * x); pixel.x = *Pointer<Short4>(buffer + 8 * x);
pixel.y = *Pointer<Short4>(buffer + 8 * x + 8); pixel.y = *Pointer<Short4>(buffer + 8 * x + 8);
buffer += *Pointer<Int>(r.data + OFFSET(DrawData,colorPitchB[index])); buffer += *Pointer<Int>(r.data + OFFSET(DrawData, colorPitchB[index]));
pixel.z = *Pointer<Short4>(buffer + 8 * x); pixel.z = *Pointer<Short4>(buffer + 8 * x);
pixel.w = *Pointer<Short4>(buffer + 8 * x + 8); pixel.w = *Pointer<Short4>(buffer + 8 * x + 8);
transpose4x4(pixel.x, pixel.y, pixel.z, pixel.w); transpose4x4(pixel.x, pixel.y, pixel.z, pixel.w);
break; break;
case FORMAT_G16R16: case FORMAT_G16R16:
buffer = cBuffer; buffer = cBuffer;
pixel.x = *Pointer<Short4>(buffer + 4 * x); pixel.x = *Pointer<Short4>(buffer + 4 * x);
buffer += *Pointer<Int>(r.data + OFFSET(DrawData,colorPitchB[index])); buffer += *Pointer<Int>(r.data + OFFSET(DrawData, colorPitchB[index]));
pixel.y = *Pointer<Short4>(buffer + 4 * x); pixel.y = *Pointer<Short4>(buffer + 4 * x);
pixel.z = pixel.x; pixel.z = pixel.x;
pixel.x = As<Short4>(UnpackLow(pixel.x, pixel.y)); pixel.x = As<Short4>(UnpackLow(pixel.x, pixel.y));
pixel.z = As<Short4>(UnpackHigh(pixel.z, pixel.y)); pixel.z = As<Short4>(UnpackHigh(pixel.z, pixel.y));
...@@ -2584,6 +2578,20 @@ namespace sw ...@@ -2584,6 +2578,20 @@ namespace sw
{ {
sRGBtoLinear16_12_16(r, pixel); sRGBtoLinear16_12_16(r, pixel);
} }
}
void PixelRoutine::alphaBlend(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x)
{
if(!state.alphaBlendActive)
{
return;
}
Vector4s pixel;
Short4 c01;
Short4 c23;
readPixel(r, index, cBuffer, current, x, pixel);
// Final Color = ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor // Final Color = ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor
Vector4s sourceFactor; Vector4s sourceFactor;
...@@ -2694,6 +2702,103 @@ namespace sw ...@@ -2694,6 +2702,103 @@ namespace sw
} }
} }
void PixelRoutine::logicOperation(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x)
{
if(state.logicalOperation == LogicalOperation::LOGICALOP_COPY)
{
return;
}
Vector4s pixel;
// Read pixel
readPixel(r, index, cBuffer, current, x, pixel);
switch(state.logicalOperation)
{
case LOGICALOP_CLEAR:
current.x = 0;
current.y = 0;
current.z = 0;
break;
case LOGICALOP_SET:
current.x = 0xFFFF;
current.y = 0xFFFF;
current.z = 0xFFFF;
break;
case LOGICALOP_COPY:
ASSERT(false); // Optimized out
break;
case LOGICALOP_COPY_INVERTED:
current.x = ~current.x;
current.y = ~current.y;
current.z = ~current.z;
break;
case LOGICALOP_NOOP:
current.x = pixel.x;
current.y = pixel.y;
current.z = pixel.z;
break;
case LOGICALOP_INVERT:
current.x = ~pixel.x;
current.y = ~pixel.y;
current.z = ~pixel.z;
break;
case LOGICALOP_AND:
current.x = pixel.x & current.x;
current.y = pixel.y & current.y;
current.z = pixel.z & current.z;
break;
case LOGICALOP_NAND:
current.x = ~(pixel.x & current.x);
current.y = ~(pixel.y & current.y);
current.z = ~(pixel.z & current.z);
break;
case LOGICALOP_OR:
current.x = pixel.x | current.x;
current.y = pixel.y | current.y;
current.z = pixel.z | current.z;
break;
case LOGICALOP_NOR:
current.x = ~(pixel.x | current.x);
current.y = ~(pixel.y | current.y);
current.z = ~(pixel.z | current.z);
break;
case LOGICALOP_XOR:
current.x = pixel.x ^ current.x;
current.y = pixel.y ^ current.y;
current.z = pixel.z ^ current.z;
break;
case LOGICALOP_EQUIV:
current.x = ~(pixel.x ^ current.x);
current.y = ~(pixel.y ^ current.y);
current.z = ~(pixel.z ^ current.z);
break;
case LOGICALOP_AND_REVERSE:
current.x = ~pixel.x & current.x;
current.y = ~pixel.y & current.y;
current.z = ~pixel.z & current.z;
break;
case LOGICALOP_AND_INVERTED:
current.x = pixel.x & ~current.x;
current.y = pixel.y & ~current.y;
current.z = pixel.z & ~current.z;
break;
case LOGICALOP_OR_REVERSE:
current.x = ~pixel.x | current.x;
current.y = ~pixel.y | current.y;
current.z = ~pixel.z | current.z;
break;
case LOGICALOP_OR_INVERTED:
current.x = pixel.x | ~current.x;
current.y = pixel.y | ~current.y;
current.z = pixel.z | ~current.z;
break;
default:
ASSERT(false);
}
}
void PixelRoutine::writeColor(Registers &r, int index, Pointer<Byte> &cBuffer, Int &x, Vector4s &current, Int &sMask, Int &zMask, Int &cMask) void PixelRoutine::writeColor(Registers &r, int index, Pointer<Byte> &cBuffer, Int &x, Vector4s &current, Int &sMask, Int &zMask, Int &cMask)
{ {
if(postBlendSRGB && state.writeSRGB) if(postBlendSRGB && state.writeSRGB)
...@@ -3292,7 +3397,6 @@ namespace sw ...@@ -3292,7 +3397,6 @@ namespace sw
Short4 c01; Short4 c01;
Short4 c23; Short4 c23;
// Read pixel
switch(state.targetFormat[index]) switch(state.targetFormat[index])
{ {
case FORMAT_R32F: case FORMAT_R32F:
......
...@@ -179,7 +179,9 @@ namespace sw ...@@ -179,7 +179,9 @@ namespace sw
void rasterOperation(Vector4f oC[4], Registers &r, Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]); void rasterOperation(Vector4f oC[4], Registers &r, Float4 &fog, Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4]);
void blendFactor(Registers &r, const Vector4s &blendFactor, const Vector4s &current, const Vector4s &pixel, BlendFactor blendFactorActive); void blendFactor(Registers &r, const Vector4s &blendFactor, const Vector4s &current, const Vector4s &pixel, BlendFactor blendFactorActive);
void blendFactorAlpha(Registers &r, const Vector4s &blendFactor, const Vector4s &current, const Vector4s &pixel, BlendFactor blendFactorAlphaActive); void blendFactorAlpha(Registers &r, const Vector4s &blendFactor, const Vector4s &current, const Vector4s &pixel, BlendFactor blendFactorAlphaActive);
void readPixel(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x, Vector4s &pixel);
void alphaBlend(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x); void alphaBlend(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x);
void logicOperation(Registers &r, int index, Pointer<Byte> &cBuffer, Vector4s &current, Int &x);
void writeColor(Registers &r, int index, Pointer<Byte> &cBuffer, Int &i, Vector4s &current, Int &sMask, Int &zMask, Int &cMask); void writeColor(Registers &r, int index, Pointer<Byte> &cBuffer, Int &i, Vector4s &current, Int &sMask, Int &zMask, Int &cMask);
void blendFactor(Registers &r, const Vector4f &blendFactor, const Vector4f &oC, const Vector4f &pixel, BlendFactor blendFactorActive); void blendFactor(Registers &r, const Vector4f &blendFactor, const Vector4f &oC, const Vector4f &pixel, BlendFactor blendFactorActive);
void blendFactorAlpha(Registers &r, const Vector4f &blendFactor, const Vector4f &oC, const Vector4f &pixel, BlendFactor blendFactorAlphaActive); void blendFactorAlpha(Registers &r, const Vector4f &blendFactor, const Vector4f &oC, const Vector4f &pixel, BlendFactor blendFactorAlphaActive);
......
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