Commit 75b650f0 by Alexis Hetu Committed by Alexis Hétu

Blitter clear implementation

The "clear" operation can now be done through the blitter. The few changes are: - The blitter now supports RGBA masking - The blitter now supports RGB565 - When in "clear" mode, the blitter does a one read/multiple writes The old clearing code has been deleted from Surface. Change-Id: I970c3a0323f63ee5c89f02d94a2705e4bcf83866 Reviewed-on: https://swiftshader-review.googlesource.com/4291Tested-by: 's avatarNicolas Capens <capn@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent c8f95e8a
...@@ -435,19 +435,24 @@ namespace D3D9 ...@@ -435,19 +435,24 @@ namespace D3D9
D3DSURFACE_DESC description; D3DSURFACE_DESC description;
renderTarget[index]->GetDesc(&description); renderTarget[index]->GetDesc(&description);
float r = (float)(color & 0x00FF0000) / 0x00FF0000; float rgba[4];
float g = (float)(color & 0x0000FF00) / 0x0000FF00; rgba[0] = (float)(color & 0x00FF0000) / 0x00FF0000;
float b = (float)(color & 0x000000FF) / 0x000000FF; rgba[1] = (float)(color & 0x0000FF00) / 0x0000FF00;
float a = (float)(color & 0xFF000000) / 0xFF000000; rgba[2] = (float)(color & 0x000000FF) / 0x000000FF;
rgba[3] = (float)(color & 0xFF000000) / 0xFF000000;
if(renderState[D3DRS_SRGBWRITEENABLE] != FALSE && index == 0 && Capabilities::isSRGBwritable(description.Format)) if(renderState[D3DRS_SRGBWRITEENABLE] != FALSE && index == 0 && Capabilities::isSRGBwritable(description.Format))
{ {
r = sw::linearToSRGB(r); rgba[0] = sw::linearToSRGB(rgba[0]);
g = sw::linearToSRGB(g); rgba[1] = sw::linearToSRGB(rgba[1]);
b = sw::linearToSRGB(b); rgba[2] = sw::linearToSRGB(rgba[2]);
} }
renderTarget[index]->clearColorBuffer(r, g, b, a, 0xF, rect.x1, rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1); sw::SliceRect sliceRect;
if(renderTarget[index]->getClearRect(rect.x1, rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1, sliceRect))
{
renderer->clear(rgba, sw::FORMAT_A32B32G32R32F, renderTarget[index], sliceRect, 0xF);
}
} }
} }
} }
......
...@@ -180,7 +180,7 @@ namespace gl ...@@ -180,7 +180,7 @@ namespace gl
void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask) void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)
{ {
if(!renderTarget) if(!renderTarget || !rgbaMask)
{ {
return; return;
} }
...@@ -198,7 +198,17 @@ namespace gl ...@@ -198,7 +198,17 @@ namespace gl
if(height > scissorRect.y1 - scissorRect.y0) height = scissorRect.y1 - scissorRect.y0; if(height > scissorRect.y1 - scissorRect.y0) height = scissorRect.y1 - scissorRect.y0;
} }
renderTarget->clearColorBuffer(red, green, blue, alpha, rgbaMask, x0, y0, width, height); float rgba[4];
rgba[0] = red;
rgba[1] = green;
rgba[2] = blue;
rgba[3] = alpha;
sw::SliceRect sliceRect;
if(renderTarget->getClearRect(x0, y0, width, height, sliceRect))
{
clear(rgba, FORMAT_A32B32G32R32F, renderTarget, sliceRect, rgbaMask);
}
} }
void Device::clearDepth(float z) void Device::clearDepth(float z)
......
...@@ -138,7 +138,7 @@ namespace es1 ...@@ -138,7 +138,7 @@ namespace es1
void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask) void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)
{ {
if(!renderTarget) if(!renderTarget || !rgbaMask)
{ {
return; return;
} }
...@@ -156,7 +156,17 @@ namespace es1 ...@@ -156,7 +156,17 @@ namespace es1
if(height > scissorRect.y1 - scissorRect.y0) height = scissorRect.y1 - scissorRect.y0; if(height > scissorRect.y1 - scissorRect.y0) height = scissorRect.y1 - scissorRect.y0;
} }
renderTarget->clearColorBuffer(red, green, blue, alpha, rgbaMask, x0, y0, width, height); float rgba[4];
rgba[0] = red;
rgba[1] = green;
rgba[2] = blue;
rgba[3] = alpha;
sw::SliceRect sliceRect;
if(renderTarget->getClearRect(x0, y0, width, height, sliceRect))
{
clear(rgba, FORMAT_A32B32G32R32F, renderTarget, sliceRect, rgbaMask);
}
} }
void Device::clearDepth(float z) void Device::clearDepth(float z)
......
...@@ -3359,7 +3359,7 @@ void Context::clear(GLbitfield mask) ...@@ -3359,7 +3359,7 @@ void Context::clear(GLbitfield mask)
} }
} }
void Context::clearColorBuffer(GLint drawbuffer, const GLint *value) void Context::clearColorBuffer(GLint drawbuffer, void *value, sw::Format format)
{ {
unsigned int rgbaMask = getColorMask(); unsigned int rgbaMask = getColorMask();
if(device && rgbaMask) if(device && rgbaMask)
...@@ -3367,47 +3367,27 @@ void Context::clearColorBuffer(GLint drawbuffer, const GLint *value) ...@@ -3367,47 +3367,27 @@ void Context::clearColorBuffer(GLint drawbuffer, const GLint *value)
int x0(0), y0(0), width(0), height(0); int x0(0), y0(0), width(0), height(0);
egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, false); egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, false);
float red = clamp01((float)value[0] / 0x7FFFFFFF); sw::SliceRect sliceRect;
float green = clamp01((float)value[1] / 0x7FFFFFFF); if(image->getClearRect(x0, y0, width, height, sliceRect))
float blue = clamp01((float)value[2] / 0x7FFFFFFF); {
float alpha = clamp01((float)value[3] / 0x7FFFFFFF); device->clear(value, format, image, sliceRect, rgbaMask);
}
image->clearColorBuffer(red, green, blue, alpha, rgbaMask, x0, y0, width, height);
} }
} }
void Context::clearColorBuffer(GLint drawbuffer, const GLuint *value) void Context::clearColorBuffer(GLint drawbuffer, const GLint *value)
{ {
unsigned int rgbaMask = getColorMask(); clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32I);
if(device && rgbaMask) }
{
int x0(0), y0(0), width(0), height(0);
egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, false);
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); void Context::clearColorBuffer(GLint drawbuffer, const GLuint *value)
} {
clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32UI);
} }
void Context::clearColorBuffer(GLint drawbuffer, const GLfloat *value) void Context::clearColorBuffer(GLint drawbuffer, const GLfloat *value)
{ {
unsigned int rgbaMask = getColorMask(); clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32F);
if(device && rgbaMask)
{
int x0(0), y0(0), width(0), height(0);
egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, false);
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);
}
} }
void Context::clearDepthBuffer(GLint drawbuffer, const GLfloat *value) void Context::clearDepthBuffer(GLint drawbuffer, const GLfloat *value)
......
...@@ -686,6 +686,7 @@ private: ...@@ -686,6 +686,7 @@ private:
void applyTextures(); void applyTextures();
void applyTextures(sw::SamplerType type); void applyTextures(sw::SamplerType type);
void applyTexture(sw::SamplerType type, int sampler, Texture *texture); void applyTexture(sw::SamplerType type, int sampler, Texture *texture);
void clearColorBuffer(GLint drawbuffer, void *value, sw::Format format);
void detachBuffer(GLuint buffer); void detachBuffer(GLuint buffer);
void detachTexture(GLuint texture); void detachTexture(GLuint texture);
......
...@@ -180,6 +180,17 @@ namespace es2 ...@@ -180,6 +180,17 @@ namespace es2
void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask) void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)
{ {
if(!rgbaMask)
{
return;
}
float rgba[4];
rgba[0] = red;
rgba[1] = green;
rgba[2] = blue;
rgba[3] = alpha;
for(int i = 0; i < RENDERTARGETS; ++i) for(int i = 0; i < RENDERTARGETS; ++i)
{ {
if(renderTarget[i]) if(renderTarget[i])
...@@ -187,7 +198,11 @@ namespace es2 ...@@ -187,7 +198,11 @@ namespace es2
int x0(0), y0(0), width(0), height(0); int x0(0), y0(0), width(0), height(0);
getScissoredRegion(renderTarget[i], x0, y0, width, height); getScissoredRegion(renderTarget[i], x0, y0, width, height);
renderTarget[i]->clearColorBuffer(red, green, blue, alpha, rgbaMask, x0, y0, width, height); sw::SliceRect sliceRect;
if(renderTarget[i]->getClearRect(x0, y0, width, height, sliceRect))
{
clear(rgba, FORMAT_A32B32G32R32F, renderTarget[i], sliceRect, rgbaMask);
}
} }
} }
} }
......
...@@ -1700,6 +1700,13 @@ namespace sw ...@@ -1700,6 +1700,13 @@ namespace sw
storeValue(integer); storeValue(integer);
} }
UShort::UShort(RValue<Int> cast)
{
Value *integer = Nucleus::createTrunc(cast.value, UShort::getType());
storeValue(integer);
}
UShort::UShort() UShort::UShort()
{ {
} }
......
...@@ -570,6 +570,7 @@ namespace sw ...@@ -570,6 +570,7 @@ namespace sw
explicit UShort(llvm::Argument *argument); explicit UShort(llvm::Argument *argument);
explicit UShort(RValue<UInt> cast); explicit UShort(RValue<UInt> cast);
explicit UShort(RValue<Int> cast);
UShort(); UShort();
UShort(unsigned short x); UShort(unsigned short x);
......
...@@ -22,6 +22,18 @@ namespace sw ...@@ -22,6 +22,18 @@ namespace sw
{ {
class Blitter class Blitter
{ {
enum Options : unsigned char
{
FILTER_POINT = 0x00,
WRITE_RED = 0x01,
WRITE_GREEN = 0x02,
WRITE_BLUE = 0x04,
WRITE_ALPHA = 0x08,
WRITE_RGBA = WRITE_RED | WRITE_GREEN | WRITE_BLUE | WRITE_ALPHA,
FILTER_LINEAR = 0x10,
CLEAR_OPERATION = 0x20
};
struct BlitState struct BlitState
{ {
bool operator==(const BlitState &state) const bool operator==(const BlitState &state) const
...@@ -31,7 +43,7 @@ namespace sw ...@@ -31,7 +43,7 @@ namespace sw
Format sourceFormat; Format sourceFormat;
Format destFormat; Format destFormat;
bool filter; Blitter::Options options;
}; };
struct BlitData struct BlitData
...@@ -60,16 +72,19 @@ namespace sw ...@@ -60,16 +72,19 @@ namespace sw
virtual ~Blitter(); virtual ~Blitter();
void clear(void* pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask);
void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter); void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter);
void blit3D(Surface *source, Surface *dest); void blit3D(Surface *source, Surface *dest);
private: private:
bool read(Float4 &color, Pointer<Byte> element, Format format); bool read(Float4 &color, Pointer<Byte> element, Format format);
bool write(Float4 &color, Pointer<Byte> element, Format format); bool write(Float4 &color, Pointer<Byte> element, Format format, const Blitter::Options& options);
bool read(Int4 &color, Pointer<Byte> element, Format format); bool read(Int4 &color, Pointer<Byte> element, Format format);
bool write(Int4 &color, Pointer<Byte> element, Format format); bool write(Int4 &color, Pointer<Byte> element, Format format, const Blitter::Options& options);
static bool GetScale(float4& scale, Format format); static bool GetScale(float4& scale, Format format);
bool blitReactor(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter); static bool ApplyScaleAndClamp(Float4& value, const BlitState& state);
void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, const Blitter::Options& options);
bool blitReactor(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, const Blitter::Options& options);
Routine *generate(BlitState &state); Routine *generate(BlitState &state);
RoutineCache<BlitState> *blitCache; RoutineCache<BlitState> *blitCache;
......
...@@ -189,6 +189,11 @@ namespace sw ...@@ -189,6 +189,11 @@ namespace sw
delete swiftConfig; delete swiftConfig;
} }
void Renderer::clear(void *pixel, Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask)
{
blitter.clear(pixel, format, dest, dRect, rgbaMask);
}
void Renderer::blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter) void Renderer::blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter)
{ {
blitter.blit(source, sRect, dest, dRect, filter); blitter.blit(source, sRect, dest, dRect, filter);
......
...@@ -303,6 +303,7 @@ namespace sw ...@@ -303,6 +303,7 @@ namespace sw
virtual ~Renderer(); virtual ~Renderer();
virtual void clear(void* pixel, Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask);
virtual void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter); virtual void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter);
virtual void blit3D(Surface *source, Surface *dest); virtual void blit3D(Surface *source, Surface *dest);
virtual void draw(DrawType drawType, unsigned int indexOffset, unsigned int count, bool update = true); virtual void draw(DrawType drawType, unsigned int indexOffset, unsigned int count, bool update = true);
......
...@@ -282,7 +282,8 @@ namespace sw ...@@ -282,7 +282,8 @@ namespace sw
inline int getMultiSampleCount() const; inline int getMultiSampleCount() const;
inline int getSuperSampleCount() const; inline int getSuperSampleCount() const;
void clearColorBuffer(float red, float green, float blue, float alpha, unsigned int rgbaMask, int x0, int y0, int width, int height); bool isEntire(const SliceRect& rect) const;
bool getClearRect(int x0, int y0, int width, int height, SliceRect& rect) const;
void clearDepthBuffer(float depth, 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 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); 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