Commit 66747262 by Nicolas Capens

Improve color clear precision.

Change-Id: Ib9dadf3d8fee0f63deb10e6754856c0530c928ab Reviewed-on: https://swiftshader-review.googlesource.com/3995Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent 64750b5b
......@@ -435,24 +435,19 @@ namespace D3D9
D3DSURFACE_DESC description;
renderTarget[index]->GetDesc(&description);
float r = (float)(color & 0x00FF0000) / 0x00FF0000;
float g = (float)(color & 0x0000FF00) / 0x0000FF00;
float b = (float)(color & 0x000000FF) / 0x000000FF;
float a = (float)(color & 0xFF000000) / 0xFF000000;
if(renderState[D3DRS_SRGBWRITEENABLE] != FALSE && index == 0 && Capabilities::isSRGBwritable(description.Format))
{
float r = (float)(color & 0x00FF0000) / 0x00FF0000;
float g = (float)(color & 0x0000FF00) / 0x0000FF00;
float b = (float)(color & 0x000000FF) / 0x000000FF;
float a = (float)(color & 0xFF000000) / 0xFF000000;
r = sw::linearToSRGB(r);
g = sw::linearToSRGB(g);
b = sw::linearToSRGB(b);
color = ((int)(a * 255) << 24) |
((int)(r * 255) << 16) |
((int)(g * 255) << 8) |
((int)(b * 255) << 0);
}
renderTarget[index]->clearColorBuffer(color, 0xF, rect.x1, rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1);
renderTarget[index]->clearColorBuffer(r, g, b, a, 0xF, rect.x1, rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1);
}
}
}
......
......@@ -2454,11 +2454,7 @@ void Context::clear(GLbitfield mask)
{
return;
}
unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) |
(unorm<8>(mState.colorClearValue.red) << 16) |
(unorm<8>(mState.colorClearValue.green) << 8) |
(unorm<8>(mState.colorClearValue.blue) << 0);
float depth = clamp01(mState.depthClearValue);
int stencil = mState.stencilClearValue & 0x000000FF;
......@@ -2471,7 +2467,7 @@ void Context::clear(GLbitfield mask)
if(rgbaMask != 0)
{
device->clearColor(color, rgbaMask);
device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
}
}
......
......@@ -178,7 +178,7 @@ namespace gl
delete context;
}
void Device::clearColor(unsigned int color, unsigned int rgbaMask)
void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)
{
if(!renderTarget)
{
......@@ -198,7 +198,7 @@ namespace gl
if(height > scissorRect.y1 - scissorRect.y0) height = scissorRect.y1 - scissorRect.y0;
}
renderTarget->clearColorBuffer(color, rgbaMask, x0, y0, width, height);
renderTarget->clearColorBuffer(red, green, blue, alpha, rgbaMask, x0, y0, width, height);
}
void Device::clearDepth(float z)
......
......@@ -48,7 +48,7 @@ namespace gl
virtual ~Device();
virtual void clearColor(unsigned int color, unsigned int rgbaMask);
virtual void clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask);
virtual void clearDepth(float z);
virtual void clearStencil(unsigned int stencil, unsigned int mask);
virtual Image *createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
......
......@@ -2659,10 +2659,6 @@ void Context::clear(GLbitfield mask)
return;
}
unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) |
(unorm<8>(mState.colorClearValue.red) << 16) |
(unorm<8>(mState.colorClearValue.green) << 8) |
(unorm<8>(mState.colorClearValue.blue) << 0);
float depth = clamp01(mState.depthClearValue);
int stencil = mState.stencilClearValue & 0x000000FF;
......@@ -2675,7 +2671,7 @@ void Context::clear(GLbitfield mask)
if(rgbaMask != 0)
{
device->clearColor(color, rgbaMask);
device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
}
}
......
......@@ -136,7 +136,7 @@ namespace es1
delete context;
}
void Device::clearColor(unsigned int color, unsigned int rgbaMask)
void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)
{
if(!renderTarget)
{
......@@ -156,7 +156,7 @@ namespace es1
if(height > scissorRect.y1 - scissorRect.y0) height = scissorRect.y1 - scissorRect.y0;
}
renderTarget->clearColorBuffer(color, rgbaMask, x0, y0, width, height);
renderTarget->clearColorBuffer(red, green, blue, alpha, rgbaMask, x0, y0, width, height);
}
void Device::clearDepth(float z)
......
......@@ -51,7 +51,7 @@ namespace es1
virtual ~Device();
virtual void clearColor(unsigned int color, unsigned int rgbaMask);
virtual void clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask);
virtual void clearDepth(float z);
virtual void clearStencil(unsigned int stencil, unsigned int mask);
virtual egl::Image *createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
......
......@@ -3538,11 +3538,7 @@ void Context::clear(GLbitfield mask)
if(rgbaMask != 0)
{
unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) |
(unorm<8>(mState.colorClearValue.red) << 16) |
(unorm<8>(mState.colorClearValue.green) << 8) |
(unorm<8>(mState.colorClearValue.blue) << 0);
device->clearColor(color, rgbaMask);
device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
}
}
......@@ -3573,11 +3569,12 @@ void Context::clearColorBuffer(GLint drawbuffer, const GLint *value)
int x0(0), y0(0), width(0), height(0);
egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, false);
unsigned int color = (value[0] < 0 ? 0 : (value[0] & 0x7F800000) << 1) |
(value[1] < 0 ? 0 : (value[1] & 0x7F800000) >> 7) |
(value[2] < 0 ? 0 : (value[2] & 0x7F800000) >> 15) |
(value[3] < 0 ? 0 : (value[3] & 0x7F800000) >> 23);
image->clearColorBuffer(color, rgbaMask, x0, y0, width, height);
float red = clamp01((float)value[0] / 0x7FFFFFFF);
float green = clamp01((float)value[1] / 0x7FFFFFFF);
float blue = clamp01((float)value[2] / 0x7FFFFFFF);
float alpha = clamp01((float)value[3] / 0x7FFFFFFF);
image->clearColorBuffer(red, green, blue, alpha, rgbaMask, x0, y0, width, height);
}
}
......@@ -3589,11 +3586,12 @@ void Context::clearColorBuffer(GLint drawbuffer, const GLuint *value)
int x0(0), y0(0), width(0), height(0);
egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, false);
unsigned int color = (value[0] & 0xFF000000) >> 0 |
(value[1] & 0xFF000000) >> 8 |
(value[2] & 0xFF000000) >> 16 |
(value[3] & 0xFF000000) >> 24;
image->clearColorBuffer(color, rgbaMask, x0, y0, width, height);
float red = (float)value[0] / 0xFFFFFFFF;
float green = (float)value[1] / 0xFFFFFFFF;
float blue = (float)value[2] / 0xFFFFFFFF;
float alpha = (float)value[3] / 0xFFFFFFFF;
image->clearColorBuffer(red, green, blue, alpha, rgbaMask, x0, y0, width, height);
}
}
......@@ -3605,11 +3603,12 @@ void Context::clearColorBuffer(GLint drawbuffer, const GLfloat *value)
int x0(0), y0(0), width(0), height(0);
egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, false);
unsigned int color = (unorm<8>(value[0]) << 24) |
(unorm<8>(value[1]) << 16) |
(unorm<8>(value[2]) << 8) |
(unorm<8>(value[3]) << 0);
image->clearColorBuffer(color, rgbaMask, x0, y0, width, height);
float red = clamp01(value[0]);
float green = clamp01(value[1]);
float blue = clamp01(value[2]);
float alpha = clamp01(value[3]);
image->clearColorBuffer(red, green, blue, alpha, rgbaMask, x0, y0, width, height);
}
}
......
......@@ -175,7 +175,7 @@ namespace es2
}
}
void Device::clearColor(unsigned int color, unsigned int rgbaMask)
void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)
{
if(!renderTarget)
{
......@@ -185,7 +185,7 @@ namespace es2
int x0(0), y0(0), width(0), height(0);
getScissoredRegion(renderTarget, x0, y0, width, height);
renderTarget->clearColorBuffer(color, rgbaMask, x0, y0, width, height);
renderTarget->clearColorBuffer(red, green, blue, alpha, rgbaMask, x0, y0, width, height);
}
void Device::clearDepth(float z)
......
......@@ -51,7 +51,7 @@ namespace es2
virtual ~Device();
virtual void clearColor(unsigned int color, unsigned int rgbaMask);
virtual void clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask);
virtual void clearDepth(float z);
virtual void clearStencil(unsigned int stencil, unsigned int mask);
virtual egl::Image *createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
......
......@@ -2797,7 +2797,7 @@ namespace sw
}
}
void Surface::clearColorBuffer(unsigned int colorARGB, unsigned int rgbaMask, int x0, int y0, int width, int height)
void Surface::clearColorBuffer(float red, float green, float blue, float alpha, unsigned int rgbaMask, int x0, int y0, int width, int height)
{
// FIXME: Also clear buffers in other formats?
......@@ -2837,30 +2837,39 @@ namespace sw
case FORMAT_A8R8G8B8:
// case FORMAT_X8G8R8B8Q: // FIXME
// case FORMAT_A8G8R8B8Q: // FIXME
if(rgbaMask == 0xF || (internal.format == FORMAT_X8R8G8B8 && rgbaMask == 0x7))
{
memfill4(target, colorARGB, 4 * (x1 - x0));
}
else
{
unsigned int bgraMask = (rgbaMask & 0x1 ? 0x00FF0000 : 0) | (rgbaMask & 0x2 ? 0x0000FF00 : 0) | (rgbaMask & 0x4 ? 0x000000FF : 0) | (rgbaMask & 0x8 ? 0xFF000000 : 0);
unsigned int invMask = ~bgraMask;
unsigned int maskedColor = colorARGB & bgraMask;
unsigned int *target32 = (unsigned int*)target;
for(int x = 0; x < width; x++)
unsigned char r8 = iround(red * 0xFF);
unsigned char g8 = iround(green * 0xFF);
unsigned char b8 = iround(blue * 0xFF);
unsigned char a8 = iround(alpha * 0xFF);
unsigned char a8r8g8b8[4] = {b8, g8, r8, a8};
unsigned int colorARGB = (unsigned int&)a8r8g8b8;
if(rgbaMask == 0xF || (internal.format == FORMAT_X8R8G8B8 && rgbaMask == 0x7))
{
target32[x] = maskedColor | (target32[x] & invMask);
memfill4(target, colorARGB, 4 * (x1 - x0));
}
else
{
unsigned int bgraMask = (rgbaMask & 0x1 ? 0x00FF0000 : 0) | (rgbaMask & 0x2 ? 0x0000FF00 : 0) | (rgbaMask & 0x4 ? 0x000000FF : 0) | (rgbaMask & 0x8 ? 0xFF000000 : 0);
unsigned int invMask = ~bgraMask;
unsigned int maskedColor = colorARGB & bgraMask;
unsigned int *target32 = (unsigned int*)target;
for(int x = 0; x < width; x++)
{
target32[x] = maskedColor | (target32[x] & invMask);
}
}
}
break;
case FORMAT_X8B8G8R8:
case FORMAT_A8B8G8R8:
{
unsigned char r8 = (colorARGB & 0x00FF0000) >> 16;
unsigned char g8 = (colorARGB & 0x0000FF00) >> 8;
unsigned char b8 = (colorARGB & 0x000000FF) >> 0;
unsigned char a8 = (colorARGB & 0xFF000000) >> 24;
unsigned char r8 = iround(red * 0xFF);
unsigned char g8 = iround(green * 0xFF);
unsigned char b8 = iround(blue * 0xFF);
unsigned char a8 = iround(alpha * 0xFF);
unsigned char a8b8g8r8[4] = {r8, g8, b8, a8};
unsigned int colorABGR = (unsigned int&)a8b8g8r8;
......@@ -2884,8 +2893,8 @@ namespace sw
break;
case FORMAT_G8R8:
{
unsigned char r8 = (colorARGB & 0x00FF0000) >> 16;
unsigned char g8 = (colorARGB & 0x0000FF00) >> 8;
unsigned char r8 = iround(red * 0xFF);
unsigned char g8 = iround(green * 0xFF);
unsigned char g8r8[4] = {r8, g8, r8, g8};
if((rgbaMask & 0x3) == 0x3)
......@@ -2908,10 +2917,8 @@ namespace sw
break;
case FORMAT_G16R16:
{
unsigned char r8 = (colorARGB & 0x00FF0000) >> 16;
unsigned char g8 = (colorARGB & 0x0000FF00) >> 8;
unsigned short r16 = (r8 << 8) | r8;
unsigned short g16 = (g8 << 8) | g8;
unsigned char r16 = iround(red * 0xFFFF);
unsigned char g16 = iround(green * 0xFFFF);
unsigned short g16r16[2] = {r16, g16};
if((rgbaMask & 0x3) == 0x3)
......@@ -2934,14 +2941,10 @@ namespace sw
break;
case FORMAT_A16B16G16R16:
{
unsigned char r8 = (colorARGB & 0x00FF0000) >> 16;
unsigned char g8 = (colorARGB & 0x0000FF00) >> 8;
unsigned char b8 = (colorARGB & 0x000000FF) >> 0;
unsigned char a8 = (colorARGB & 0xFF000000) >> 24;
unsigned short r16 = (r8 << 8) | r8;
unsigned short g16 = (g8 << 8) | g8;
unsigned short b16 = (b8 << 8) | b8;
unsigned short a16 = (a8 << 8) | a8;
unsigned char r16 = iround(red * 0xFFFF);
unsigned char g16 = iround(green * 0xFFFF);
unsigned char b16 = iround(blue * 0xFFFF);
unsigned char a16 = iround(alpha * 0xFFFF);
if(rgbaMask == 0xF)
{
......@@ -2965,63 +2968,52 @@ namespace sw
case FORMAT_R32F:
if(rgbaMask & 0x1)
{
float r32f = (float)(colorARGB & 0x00FF0000) / 0x00FF0000;
for(int x = 0; x < width; x++)
{
((float*)target)[x] = r32f;
((float*)target)[x] = red;
}
}
break;
case FORMAT_G32R32F:
if((rgbaMask & 0x3) == 0x3)
{
float r32f = (float)(colorARGB & 0x00FF0000) / 0x00FF0000;
float g32f = (float)(colorARGB & 0x0000FF00) / 0x0000FF00;
if((rgbaMask & 0x3) == 0x3)
{
for(int x = 0; x < width; x++)
{
((float*)target)[2 * x + 0] = r32f;
((float*)target)[2 * x + 1] = g32f;
}
}
else
for(int x = 0; x < width; x++)
{
if(rgbaMask & 0x1) for(int x = 0; x < width; x++) ((float*)target)[2 * x + 0] = r32f;
if(rgbaMask & 0x2) for(int x = 0; x < width; x++) ((float*)target)[2 * x + 1] = g32f;
((float*)target)[2 * x + 0] = red;
((float*)target)[2 * x + 1] = green;
}
}
else
{
if(rgbaMask & 0x1) for(int x = 0; x < width; x++) ((float*)target)[2 * x + 0] = red;
if(rgbaMask & 0x2) for(int x = 0; x < width; x++) ((float*)target)[2 * x + 1] = green;
}
break;
case FORMAT_A32B32G32R32F:
if(rgbaMask == 0xF)
{
float r32f = (float)(colorARGB & 0x00FF0000) / 0x00FF0000;
float g32f = (float)(colorARGB & 0x0000FF00) / 0x0000FF00;
float b32f = (float)(colorARGB & 0x000000FF) / 0x000000FF;
float a32f = (float)(colorARGB & 0xFF000000) / 0xFF000000;
if(rgbaMask == 0xF)
{
for(int x = 0; x < width; x++)
{
((float*)target)[4 * x + 0] = r32f;
((float*)target)[4 * x + 1] = g32f;
((float*)target)[4 * x + 2] = b32f;
((float*)target)[4 * x + 3] = a32f;
}
}
else
for(int x = 0; x < width; x++)
{
if(rgbaMask & 0x1) for(int x = 0; x < width; x++) ((float*)target)[4 * x + 0] = r32f;
if(rgbaMask & 0x2) for(int x = 0; x < width; x++) ((float*)target)[4 * x + 1] = g32f;
if(rgbaMask & 0x4) for(int x = 0; x < width; x++) ((float*)target)[4 * x + 2] = b32f;
if(rgbaMask & 0x8) for(int x = 0; x < width; x++) ((float*)target)[4 * x + 3] = a32f;
((float*)target)[4 * x + 0] = red;
((float*)target)[4 * x + 1] = green;
((float*)target)[4 * x + 2] = blue;
((float*)target)[4 * x + 3] = alpha;
}
}
else
{
if(rgbaMask & 0x1) for(int x = 0; x < width; x++) ((float*)target)[4 * x + 0] = red;
if(rgbaMask & 0x2) for(int x = 0; x < width; x++) ((float*)target)[4 * x + 1] = green;
if(rgbaMask & 0x4) for(int x = 0; x < width; x++) ((float*)target)[4 * x + 2] = blue;
if(rgbaMask & 0x8) for(int x = 0; x < width; x++) ((float*)target)[4 * x + 3] = alpha;
}
break;
case FORMAT_R5G6B5:
{
unsigned int r5g6b5 = ((colorARGB >> 8) & 0xF800) | ((colorARGB >> 5) & 0x07E0) | ((colorARGB >> 3) & 0x001F);
unsigned int r5 = iround(red * 0x1F);
unsigned int g6 = iround(green * 0x3F);
unsigned int b5 = iround(blue * 0x1F);
unsigned int r5g6b5 = (r5 << 11) | (g6 << 5) | b5;
if((rgbaMask & 0x7) == 0x7)
{
......
......@@ -254,7 +254,7 @@ namespace sw
inline int getMultiSampleCount() const;
inline int getSuperSampleCount() const;
void clearColorBuffer(unsigned int colorARGB, unsigned int rgbaMask, int x0, int y0, int width, int height);
void clearColorBuffer(float red, float green, float blue, float alpha, unsigned int rgbaMask, int x0, int y0, int width, int height);
void clearDepthBuffer(float depth, int x0, int y0, int width, int height);
void clearStencilBuffer(unsigned char stencil, unsigned char mask, int x0, int y0, int width, int height);
void fill(const Color<float> &color, int x0, int y0, int width, int height);
......
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