Commit 1edcd8b6 by Alexis Hetu Committed by Alexis Hétu

Multiple draw buffers implementation

Implemented the missing pieces for multiple draw buffers support: - Fixed Context::getScissoredImage() to use the drawbuffer parameter properly - Enabled setting multiple render targets - Added dynamic indexing of gl_FragData using a new dynOut flag to figure out which channels are being written to. Change-Id: Id3d95c46a980a698f71e99f7781cc6287e880e9d Reviewed-on: https://swiftshader-review.googlesource.com/4220Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent f59ad06e
...@@ -89,6 +89,7 @@ enum ...@@ -89,6 +89,7 @@ enum
MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 4, MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 4,
MAX_UNIFORM_BUFFER_BINDINGS = 36, MAX_UNIFORM_BUFFER_BINDINGS = 36,
MAX_CLIP_PLANES = 6, MAX_CLIP_PLANES = 6,
RENDERTARGETS = 4,
}; };
#endif // sw_Config_hpp #endif // sw_Config_hpp
...@@ -1718,7 +1718,7 @@ bool Context::applyRenderTarget() ...@@ -1718,7 +1718,7 @@ bool Context::applyRenderTarget()
} }
Image *renderTarget = framebuffer->getRenderTarget(); Image *renderTarget = framebuffer->getRenderTarget();
device->setRenderTarget(renderTarget); device->setRenderTarget(0, renderTarget);
if(renderTarget) renderTarget->release(); if(renderTarget) renderTarget->release();
Image *depthStencil = framebuffer->getDepthStencil(); Image *depthStencil = framebuffer->getDepthStencil();
......
...@@ -443,7 +443,7 @@ namespace gl ...@@ -443,7 +443,7 @@ namespace gl
scissorEnable = enable; scissorEnable = enable;
} }
void Device::setRenderTarget(Image *renderTarget) void Device::setRenderTarget(int index, Image *renderTarget)
{ {
if(renderTarget) if(renderTarget)
{ {
...@@ -457,7 +457,7 @@ namespace gl ...@@ -457,7 +457,7 @@ namespace gl
this->renderTarget = renderTarget; this->renderTarget = renderTarget;
Renderer::setRenderTarget(0, renderTarget); Renderer::setRenderTarget(index, renderTarget);
} }
void Device::setScissorRect(const sw::Rect &rect) void Device::setScissorRect(const sw::Rect &rect)
......
...@@ -59,7 +59,7 @@ namespace gl ...@@ -59,7 +59,7 @@ namespace gl
virtual void setPixelShader(sw::PixelShader *shader); virtual void setPixelShader(sw::PixelShader *shader);
virtual void setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count); virtual void setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
virtual void setScissorEnable(bool enable); virtual void setScissorEnable(bool enable);
virtual void setRenderTarget(Image *renderTarget); virtual void setRenderTarget(int index, Image *renderTarget);
virtual void setScissorRect(const sw::Rect &rect); virtual void setScissorRect(const sw::Rect &rect);
virtual void setVertexShader(sw::VertexShader *shader); virtual void setVertexShader(sw::VertexShader *shader);
virtual void setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count); virtual void setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
......
...@@ -1705,7 +1705,7 @@ bool Context::applyRenderTarget() ...@@ -1705,7 +1705,7 @@ bool Context::applyRenderTarget()
} }
egl::Image *renderTarget = framebuffer->getRenderTarget(); egl::Image *renderTarget = framebuffer->getRenderTarget();
device->setRenderTarget(renderTarget); device->setRenderTarget(0, renderTarget);
if(renderTarget) renderTarget->release(); if(renderTarget) renderTarget->release();
egl::Image *depthStencil = framebuffer->getDepthStencil(); egl::Image *depthStencil = framebuffer->getDepthStencil();
......
...@@ -380,7 +380,7 @@ namespace es1 ...@@ -380,7 +380,7 @@ namespace es1
scissorEnable = enable; scissorEnable = enable;
} }
void Device::setRenderTarget(egl::Image *renderTarget) void Device::setRenderTarget(int index, egl::Image *renderTarget)
{ {
if(renderTarget) if(renderTarget)
{ {
...@@ -394,7 +394,7 @@ namespace es1 ...@@ -394,7 +394,7 @@ namespace es1
this->renderTarget = renderTarget; this->renderTarget = renderTarget;
Renderer::setRenderTarget(0, renderTarget); Renderer::setRenderTarget(index, renderTarget);
} }
void Device::setScissorRect(const sw::Rect &rect) void Device::setScissorRect(const sw::Rect &rect)
......
...@@ -60,7 +60,7 @@ namespace es1 ...@@ -60,7 +60,7 @@ namespace es1
virtual void drawPrimitive(PrimitiveType primitiveType, unsigned int primiveCount); virtual void drawPrimitive(PrimitiveType primitiveType, unsigned int primiveCount);
virtual void setDepthStencilSurface(egl::Image *newDepthStencil); virtual void setDepthStencilSurface(egl::Image *newDepthStencil);
virtual void setScissorEnable(bool enable); virtual void setScissorEnable(bool enable);
virtual void setRenderTarget(egl::Image *renderTarget); virtual void setRenderTarget(int index, egl::Image *renderTarget);
virtual void setScissorRect(const sw::Rect &rect); virtual void setScissorRect(const sw::Rect &rect);
virtual void setViewport(const Viewport &viewport); virtual void setViewport(const Viewport &viewport);
......
...@@ -2702,8 +2702,8 @@ void Context::applyScissor(int width, int height) ...@@ -2702,8 +2702,8 @@ void Context::applyScissor(int width, int height)
egl::Image *Context::getScissoredImage(GLint drawbuffer, int &x0, int &y0, int &width, int &height, bool depthStencil) egl::Image *Context::getScissoredImage(GLint drawbuffer, int &x0, int &y0, int &width, int &height, bool depthStencil)
{ {
Framebuffer* framebuffer = getFramebuffer(drawbuffer); Framebuffer* framebuffer = getDrawFramebuffer();
egl::Image* image = depthStencil ? framebuffer->getDepthStencil() : framebuffer->getRenderTarget(0); egl::Image* image = depthStencil ? framebuffer->getDepthStencil() : framebuffer->getRenderTarget(drawbuffer);
applyScissor(image->getWidth(), image->getHeight()); applyScissor(image->getWidth(), image->getHeight());
...@@ -2723,9 +2723,12 @@ bool Context::applyRenderTarget() ...@@ -2723,9 +2723,12 @@ bool Context::applyRenderTarget()
return error(GL_INVALID_FRAMEBUFFER_OPERATION, false); return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
} }
egl::Image *renderTarget = framebuffer->getRenderTarget(0); for(int i = 0; i < MAX_DRAW_BUFFERS; ++i)
device->setRenderTarget(renderTarget); {
egl::Image *renderTarget = framebuffer->getRenderTarget(i);
device->setRenderTarget(i, renderTarget);
if(renderTarget) renderTarget->release(); if(renderTarget) renderTarget->release();
}
egl::Image *depthStencil = framebuffer->getDepthStencil(); egl::Image *depthStencil = framebuffer->getDepthStencil();
device->setDepthStencilSurface(depthStencil); device->setDepthStencilSurface(depthStencil);
...@@ -3279,7 +3282,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, ...@@ -3279,7 +3282,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
} }
} }
egl::Image *renderTarget = framebuffer->getRenderTarget(0); egl::Image *renderTarget = framebuffer->getReadRenderTarget();
if(!renderTarget) if(!renderTarget)
{ {
......
...@@ -79,7 +79,7 @@ enum ...@@ -79,7 +79,7 @@ enum
MAX_VERTEX_TEXTURE_IMAGE_UNITS = VERTEX_TEXTURE_IMAGE_UNITS, MAX_VERTEX_TEXTURE_IMAGE_UNITS = VERTEX_TEXTURE_IMAGE_UNITS,
MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS, MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS,
MAX_FRAGMENT_UNIFORM_VECTORS = FRAGMENT_UNIFORM_VECTORS - 3, // Reserve space for gl_DepthRange MAX_FRAGMENT_UNIFORM_VECTORS = FRAGMENT_UNIFORM_VECTORS - 3, // Reserve space for gl_DepthRange
MAX_DRAW_BUFFERS = 1, MAX_DRAW_BUFFERS = RENDERTARGETS,
MAX_ELEMENT_INDEX = 0x7FFFFFFF, MAX_ELEMENT_INDEX = 0x7FFFFFFF,
MAX_ELEMENTS_INDICES = 0x7FFFFFFF, MAX_ELEMENTS_INDICES = 0x7FFFFFFF,
MAX_ELEMENTS_VERTICES = 0x7FFFFFFF, MAX_ELEMENTS_VERTICES = 0x7FFFFFFF,
......
...@@ -31,8 +31,8 @@ namespace es2 ...@@ -31,8 +31,8 @@ namespace es2
Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context) Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context)
{ {
depthStencil = 0; depthStencil = nullptr;
renderTarget = 0; for(int i = 0; i < RENDERTARGETS; ++i) { renderTarget[i] = nullptr; }
setDepthBufferEnable(true); setDepthBufferEnable(true);
setFillMode(FILL_SOLID); setFillMode(FILL_SOLID);
...@@ -119,8 +119,8 @@ namespace es2 ...@@ -119,8 +119,8 @@ namespace es2
setClipPlane(i, plane); setClipPlane(i, plane);
} }
pixelShader = 0; pixelShader = nullptr;
vertexShader = 0; vertexShader = nullptr;
pixelShaderDirty = true; pixelShaderDirty = true;
pixelShaderConstantsFDirty = 0; pixelShaderConstantsFDirty = 0;
...@@ -147,13 +147,16 @@ namespace es2 ...@@ -147,13 +147,16 @@ namespace es2
if(depthStencil) if(depthStencil)
{ {
depthStencil->release(); depthStencil->release();
depthStencil = 0; depthStencil = nullptr;
} }
if(renderTarget) for(int i = 0; i < RENDERTARGETS; ++i)
{
if(renderTarget[i])
{ {
renderTarget->release(); renderTarget[i]->release();
renderTarget = 0; renderTarget[i] = nullptr;
}
} }
delete context; delete context;
...@@ -177,15 +180,16 @@ namespace es2 ...@@ -177,15 +180,16 @@ 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(!renderTarget) for(int i = 0; i < RENDERTARGETS; ++i)
{
if(renderTarget[i])
{ {
return;
}
int x0(0), y0(0), width(0), height(0); int x0(0), y0(0), width(0), height(0);
getScissoredRegion(renderTarget, x0, y0, width, height); getScissoredRegion(renderTarget[i], x0, y0, width, height);
renderTarget->clearColorBuffer(red, green, blue, alpha, rgbaMask, x0, y0, width, height); renderTarget[i]->clearColorBuffer(red, green, blue, alpha, rgbaMask, x0, y0, width, height);
}
}
} }
void Device::clearDepth(float z) void Device::clearDepth(float z)
...@@ -409,21 +413,21 @@ namespace es2 ...@@ -409,21 +413,21 @@ namespace es2
scissorEnable = enable; scissorEnable = enable;
} }
void Device::setRenderTarget(egl::Image *renderTarget) void Device::setRenderTarget(int index, egl::Image *renderTarget)
{ {
if(renderTarget) if(renderTarget)
{ {
renderTarget->addRef(); renderTarget->addRef();
} }
if(this->renderTarget) if(this->renderTarget[index])
{ {
this->renderTarget->release(); this->renderTarget[index]->release();
} }
this->renderTarget = renderTarget; this->renderTarget[index] = renderTarget;
Renderer::setRenderTarget(0, renderTarget); Renderer::setRenderTarget(index, renderTarget);
} }
void Device::setScissorRect(const sw::Rect &rect) void Device::setScissorRect(const sw::Rect &rect)
...@@ -816,12 +820,15 @@ namespace es2 ...@@ -816,12 +820,15 @@ namespace es2
scissor.y0 = viewport.y0; scissor.y0 = viewport.y0;
scissor.y1 = viewport.y0 + viewport.height; scissor.y1 = viewport.y0 + viewport.height;
if(renderTarget) for(int i = 0; i < RENDERTARGETS; ++i)
{
if(renderTarget[i])
{ {
scissor.x0 = max(scissor.x0, 0); scissor.x0 = max(scissor.x0, 0);
scissor.x1 = min(scissor.x1, renderTarget->getWidth()); scissor.x1 = min(scissor.x1, renderTarget[i]->getWidth());
scissor.y0 = max(scissor.y0, 0); scissor.y0 = max(scissor.y0, 0);
scissor.y1 = min(scissor.y1, renderTarget->getHeight()); scissor.y1 = min(scissor.y1, renderTarget[i]->getHeight());
}
} }
if(depthStencil) if(depthStencil)
......
...@@ -62,7 +62,7 @@ namespace es2 ...@@ -62,7 +62,7 @@ namespace es2
virtual void setPixelShader(sw::PixelShader *shader); virtual void setPixelShader(sw::PixelShader *shader);
virtual void setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count); virtual void setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
virtual void setScissorEnable(bool enable); virtual void setScissorEnable(bool enable);
virtual void setRenderTarget(egl::Image *renderTarget); virtual void setRenderTarget(int index, egl::Image *renderTarget);
virtual void setScissorRect(const sw::Rect &rect); virtual void setScissorRect(const sw::Rect &rect);
virtual void setVertexShader(sw::VertexShader *shader); virtual void setVertexShader(sw::VertexShader *shader);
virtual void setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count); virtual void setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
...@@ -100,7 +100,7 @@ namespace es2 ...@@ -100,7 +100,7 @@ namespace es2
float pixelShaderConstantF[FRAGMENT_UNIFORM_VECTORS][4]; float pixelShaderConstantF[FRAGMENT_UNIFORM_VECTORS][4];
float vertexShaderConstantF[VERTEX_UNIFORM_VECTORS][4]; float vertexShaderConstantF[VERTEX_UNIFORM_VECTORS][4];
egl::Image *renderTarget; egl::Image *renderTarget[RENDERTARGETS];
egl::Image *depthStencil; egl::Image *depthStencil;
}; };
} }
......
...@@ -218,10 +218,10 @@ namespace sw ...@@ -218,10 +218,10 @@ namespace sw
localViewer = true; localViewer = true;
normalizeNormals = false; normalizeNormals = false;
renderTarget[0] = 0; for(int i = 0; i < RENDERTARGETS; ++i)
renderTarget[1] = 0; {
renderTarget[2] = 0; renderTarget[i] = 0;
renderTarget[3] = 0; }
depthStencil = 0; depthStencil = 0;
stencilEnable = false; stencilEnable = false;
......
...@@ -450,7 +450,7 @@ namespace sw ...@@ -450,7 +450,7 @@ namespace sw
int textureTransformCount[8]; int textureTransformCount[8];
bool textureTransformProject[8]; bool textureTransformProject[8];
Surface *renderTarget[4]; Surface *renderTarget[RENDERTARGETS];
Surface *depthStencil; Surface *depthStencil;
// Fog // Fog
......
...@@ -938,7 +938,7 @@ namespace sw ...@@ -938,7 +938,7 @@ namespace sw
(context->colorWriteActive(2) << 8) | (context->colorWriteActive(2) << 8) |
(context->colorWriteActive(3) << 12); (context->colorWriteActive(3) << 12);
for(int i = 0; i < 4; i++) for(int i = 0; i < RENDERTARGETS; i++)
{ {
state.targetFormat[i] = context->renderTargetInternalFormat(i); state.targetFormat[i] = context->renderTargetInternalFormat(i);
} }
......
...@@ -73,7 +73,7 @@ namespace sw ...@@ -73,7 +73,7 @@ namespace sw
BlendOperation blendOperationAlpha : BITS(BLENDOP_LAST); BlendOperation blendOperationAlpha : BITS(BLENDOP_LAST);
unsigned int colorWriteMask : 16; // (four times four component bit mask) unsigned int colorWriteMask : 16; // (four times four component bit mask)
Format targetFormat[4]; Format targetFormat[RENDERTARGETS];
bool writeSRGB : 1; bool writeSRGB : 1;
unsigned int multiSample : 3; unsigned int multiSample : 3;
unsigned int multiSampleMask : 4; unsigned int multiSampleMask : 4;
......
...@@ -111,11 +111,11 @@ namespace sw ...@@ -111,11 +111,11 @@ namespace sw
void QuadRasterizer::rasterize(Registers &r, Int &yMin, Int &yMax) void QuadRasterizer::rasterize(Registers &r, Int &yMin, Int &yMax)
{ {
Pointer<Byte> cBuffer[4]; Pointer<Byte> cBuffer[RENDERTARGETS];
Pointer<Byte> zBuffer; Pointer<Byte> zBuffer;
Pointer<Byte> sBuffer; Pointer<Byte> sBuffer;
for(int index = 0; index < 4; index++) for(int index = 0; index < RENDERTARGETS; index++)
{ {
if(state.colorWriteActive(index)) if(state.colorWriteActive(index))
{ {
...@@ -310,7 +310,7 @@ namespace sw ...@@ -310,7 +310,7 @@ namespace sw
} }
} }
for(int index = 0; index < 4; index++) for(int index = 0; index < RENDERTARGETS; index++)
{ {
if(state.colorWriteActive(index)) if(state.colorWriteActive(index))
{ {
......
...@@ -567,7 +567,7 @@ namespace sw ...@@ -567,7 +567,7 @@ namespace sw
// Target // Target
{ {
for(int index = 0; index < 4; index++) for(int index = 0; index < RENDERTARGETS; index++)
{ {
draw->renderTarget[index] = context->renderTarget[index]; draw->renderTarget[index] = context->renderTarget[index];
...@@ -916,7 +916,7 @@ namespace sw ...@@ -916,7 +916,7 @@ namespace sw
draw.queries = 0; draw.queries = 0;
} }
for(int i = 0; i < 4; i++) for(int i = 0; i < RENDERTARGETS; i++)
{ {
if(draw.renderTarget[i]) if(draw.renderTarget[i])
{ {
...@@ -2052,7 +2052,7 @@ namespace sw ...@@ -2052,7 +2052,7 @@ namespace sw
bool Renderer::isReadWriteTexture(int sampler) bool Renderer::isReadWriteTexture(int sampler)
{ {
for(int index = 0; index < 4; index++) for(int index = 0; index < RENDERTARGETS; index++)
{ {
if(context->renderTarget[index] && context->texture[sampler] == context->renderTarget[index]->getResource()) if(context->renderTarget[index] && context->texture[sampler] == context->renderTarget[index]->getResource())
{ {
......
...@@ -172,9 +172,9 @@ namespace sw ...@@ -172,9 +172,9 @@ namespace sw
float depthNear; float depthNear;
Plane clipPlane[6]; Plane clipPlane[6];
unsigned int *colorBuffer[4]; unsigned int *colorBuffer[RENDERTARGETS];
int colorPitchB[4]; int colorPitchB[RENDERTARGETS];
int colorSliceB[4]; int colorSliceB[RENDERTARGETS];
float *depthBuffer; float *depthBuffer;
int depthPitchB; int depthPitchB;
int depthSliceB; int depthSliceB;
...@@ -215,7 +215,7 @@ namespace sw ...@@ -215,7 +215,7 @@ namespace sw
Resource *vertexStream[VERTEX_ATTRIBUTES]; Resource *vertexStream[VERTEX_ATTRIBUTES];
Resource *indexBuffer; Resource *indexBuffer;
Surface *renderTarget[4]; Surface *renderTarget[RENDERTARGETS];
Surface *depthStencil; Surface *depthStencil;
Resource *texture[TOTAL_IMAGE_UNITS]; Resource *texture[TOTAL_IMAGE_UNITS];
......
...@@ -72,7 +72,13 @@ namespace sw ...@@ -72,7 +72,13 @@ namespace sw
r.enableLeave = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); r.enableLeave = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
} }
bool out[4][4] = { false }; for(int i = 0; i < RENDERTARGETS; i++)
{
if(state.targetFormat[i] != FORMAT_NULL)
{
r.oC[i] = Vector4f(0.0f, 0.0f, 0.0f, 0.0f);
}
}
// Create all call site return blocks up front // Create all call site return blocks up front
for(size_t i = 0; i < shader->getLength(); i++) for(size_t i = 0; i < shader->getLength(); i++)
...@@ -362,11 +368,22 @@ namespace sw ...@@ -362,11 +368,22 @@ namespace sw
} }
break; break;
case Shader::PARAMETER_COLOROUT: case Shader::PARAMETER_COLOROUT:
ASSERT(dst.rel.type == Shader::PARAMETER_VOID); if(dst.rel.type == Shader::PARAMETER_VOID)
{
if(dst.x) pDst.x = r.oC[dst.index].x; if(dst.x) pDst.x = r.oC[dst.index].x;
if(dst.y) pDst.y = r.oC[dst.index].y; if(dst.y) pDst.y = r.oC[dst.index].y;
if(dst.z) pDst.z = r.oC[dst.index].z; if(dst.z) pDst.z = r.oC[dst.index].z;
if(dst.w) pDst.w = r.oC[dst.index].w; if(dst.w) pDst.w = r.oC[dst.index].w;
}
else
{
Int a = relativeAddress(r, dst) + dst.index;
if(dst.x) pDst.x = r.oC[a].x;
if(dst.y) pDst.y = r.oC[a].y;
if(dst.z) pDst.z = r.oC[a].z;
if(dst.w) pDst.w = r.oC[a].w;
}
break; break;
case Shader::PARAMETER_PREDICATE: case Shader::PARAMETER_PREDICATE:
if(dst.x) pDst.x = r.p0.x; if(dst.x) pDst.x = r.p0.x;
...@@ -445,11 +462,22 @@ namespace sw ...@@ -445,11 +462,22 @@ namespace sw
} }
break; break;
case Shader::PARAMETER_COLOROUT: case Shader::PARAMETER_COLOROUT:
ASSERT(dst.rel.type == Shader::PARAMETER_VOID); if(dst.rel.type == Shader::PARAMETER_VOID)
if(dst.x) { r.oC[dst.index].x = d.x; out[dst.index][0] = true; } {
if(dst.y) { r.oC[dst.index].y = d.y; out[dst.index][1] = true; } if(dst.x) { r.oC[dst.index].x = d.x; }
if(dst.z) { r.oC[dst.index].z = d.z; out[dst.index][2] = true; } if(dst.y) { r.oC[dst.index].y = d.y; }
if(dst.w) { r.oC[dst.index].w = d.w; out[dst.index][3] = true; } if(dst.z) { r.oC[dst.index].z = d.z; }
if(dst.w) { r.oC[dst.index].w = d.w; }
}
else
{
Int a = relativeAddress(r, dst) + dst.index;
if(dst.x) { r.oC[a].x = d.x; }
if(dst.y) { r.oC[a].y = d.y; }
if(dst.z) { r.oC[a].z = d.z; }
if(dst.w) { r.oC[a].w = d.w; }
}
break; break;
case Shader::PARAMETER_PREDICATE: case Shader::PARAMETER_PREDICATE:
if(dst.x) r.p0.x = d.x; if(dst.x) r.p0.x = d.x;
...@@ -471,15 +499,9 @@ namespace sw ...@@ -471,15 +499,9 @@ namespace sw
Nucleus::setInsertBlock(returnBlock); Nucleus::setInsertBlock(returnBlock);
} }
for(int i = 0; i < 4; i++) for(int i = 0; i < RENDERTARGETS; i++)
{ {
if(state.targetFormat[i] != FORMAT_NULL) r.c[i] = r.oC[i];
{
if(!out[i][0]) r.oC[i].x = Float4(0.0f);
if(!out[i][1]) r.oC[i].y = Float4(0.0f);
if(!out[i][2]) r.oC[i].z = Float4(0.0f);
if(!out[i][3]) r.oC[i].w = Float4(0.0f);
}
} }
} }
...@@ -487,7 +509,7 @@ namespace sw ...@@ -487,7 +509,7 @@ namespace sw
{ {
Registers& r = *static_cast<Registers*>(&rBase); Registers& r = *static_cast<Registers*>(&rBase);
clampColor(r.oC); clampColor(r.c);
if(!state.alphaTestActive()) if(!state.alphaTestActive())
{ {
...@@ -498,7 +520,7 @@ namespace sw ...@@ -498,7 +520,7 @@ namespace sw
if(state.transparencyAntialiasing == TRANSPARENCY_NONE) if(state.transparencyAntialiasing == TRANSPARENCY_NONE)
{ {
Short4 alpha = RoundShort4(r.oC[0].w * Float4(0x1000)); Short4 alpha = RoundShort4(r.c[0].w * Float4(0x1000));
PixelRoutine::alphaTest(r, aMask, alpha); PixelRoutine::alphaTest(r, aMask, alpha);
...@@ -509,7 +531,7 @@ namespace sw ...@@ -509,7 +531,7 @@ namespace sw
} }
else if(state.transparencyAntialiasing == TRANSPARENCY_ALPHA_TO_COVERAGE) else if(state.transparencyAntialiasing == TRANSPARENCY_ALPHA_TO_COVERAGE)
{ {
alphaToCoverage(r, cMask, r.oC[0].w); alphaToCoverage(r, cMask, r.c[0].w);
} }
else ASSERT(false); else ASSERT(false);
...@@ -527,7 +549,7 @@ namespace sw ...@@ -527,7 +549,7 @@ namespace sw
{ {
Registers& r = *static_cast<Registers*>(&rBase); Registers& r = *static_cast<Registers*>(&rBase);
for(int index = 0; index < 4; index++) for(int index = 0; index < RENDERTARGETS; index++)
{ {
if(!state.colorWriteActive(index)) if(!state.colorWriteActive(index))
{ {
...@@ -536,14 +558,14 @@ namespace sw ...@@ -536,14 +558,14 @@ namespace sw
if(!postBlendSRGB && state.writeSRGB) if(!postBlendSRGB && state.writeSRGB)
{ {
r.oC[index].x = linearToSRGB(r.oC[index].x); r.c[index].x = linearToSRGB(r.c[index].x);
r.oC[index].y = linearToSRGB(r.oC[index].y); r.c[index].y = linearToSRGB(r.c[index].y);
r.oC[index].z = linearToSRGB(r.oC[index].z); r.c[index].z = linearToSRGB(r.c[index].z);
} }
if(index == 0) if(index == 0)
{ {
fogBlend(r, r.oC[index], fog); fogBlend(r, r.c[index], fog);
} }
switch(state.targetFormat[index]) switch(state.targetFormat[index])
...@@ -561,10 +583,10 @@ namespace sw ...@@ -561,10 +583,10 @@ namespace sw
Pointer<Byte> buffer = cBuffer[index] + q * *Pointer<Int>(r.data + OFFSET(DrawData, colorSliceB[index])); Pointer<Byte> buffer = cBuffer[index] + q * *Pointer<Int>(r.data + OFFSET(DrawData, colorSliceB[index]));
Vector4s color; Vector4s color;
color.x = convertFixed16(r.oC[index].x, false); color.x = convertFixed16(r.c[index].x, false);
color.y = convertFixed16(r.oC[index].y, false); color.y = convertFixed16(r.c[index].y, false);
color.z = convertFixed16(r.oC[index].z, false); color.z = convertFixed16(r.c[index].z, false);
color.w = convertFixed16(r.oC[index].w, false); color.w = convertFixed16(r.c[index].w, false);
if(state.multiSampleMask & (1 << q)) if(state.multiSampleMask & (1 << q))
{ {
...@@ -580,7 +602,7 @@ namespace sw ...@@ -580,7 +602,7 @@ namespace sw
for(unsigned int q = 0; q < state.multiSample; q++) for(unsigned int q = 0; q < state.multiSample; q++)
{ {
Pointer<Byte> buffer = cBuffer[index] + q * *Pointer<Int>(r.data + OFFSET(DrawData, colorSliceB[index])); Pointer<Byte> buffer = cBuffer[index] + q * *Pointer<Int>(r.data + OFFSET(DrawData, colorSliceB[index]));
Vector4f color = r.oC[index]; Vector4f color = r.c[index];
if(state.multiSampleMask & (1 << q)) if(state.multiSampleMask & (1 << q))
{ {
...@@ -647,9 +669,9 @@ namespace sw ...@@ -647,9 +669,9 @@ namespace sw
#endif #endif
} }
void PixelProgram::clampColor(Vector4f oC[4]) void PixelProgram::clampColor(Vector4f oC[RENDERTARGETS])
{ {
for(int index = 0; index < 4; index++) for(int index = 0; index < RENDERTARGETS; index++)
{ {
if(!state.colorWriteActive(index) && !(index == 0 && state.alphaTestActive())) if(!state.colorWriteActive(index) && !(index == 0 && state.alphaTestActive()))
{ {
...@@ -779,7 +801,16 @@ namespace sw ...@@ -779,7 +801,16 @@ namespace sw
case Shader::PARAMETER_CONSTBOOL: return reg; // Dummy case Shader::PARAMETER_CONSTBOOL: return reg; // Dummy
case Shader::PARAMETER_LOOP: return reg; // Dummy case Shader::PARAMETER_LOOP: return reg; // Dummy
case Shader::PARAMETER_COLOROUT: case Shader::PARAMETER_COLOROUT:
if(src.rel.type == Shader::PARAMETER_VOID) // Not relative
{
reg = r.oC[i]; reg = r.oC[i];
}
else
{
Int a = relativeAddress(r, src);
reg = r.oC[i + a];
}
break; break;
case Shader::PARAMETER_DEPTHOUT: case Shader::PARAMETER_DEPTHOUT:
reg.x = r.oDepth; reg.x = r.oDepth;
......
...@@ -60,7 +60,8 @@ namespace sw ...@@ -60,7 +60,8 @@ namespace sw
RegisterArray<4096> r; RegisterArray<4096> r;
// Color outputs // Color outputs
Vector4f oC[4]; Vector4f c[RENDERTARGETS];
RegisterArray<RENDERTARGETS, true> oC;
// Shader variables // Shader variables
Vector4f vPos; Vector4f vPos;
...@@ -88,7 +89,7 @@ namespace sw ...@@ -88,7 +89,7 @@ namespace sw
void sampleTexture(Registers &r, Vector4f &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project = false, bool bias = false, bool gradients = false, bool lodProvided = false); void sampleTexture(Registers &r, Vector4f &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, bool project = false, bool bias = false, bool gradients = false, bool lodProvided = false);
// Raster operations // Raster operations
void clampColor(Vector4f oC[4]); void clampColor(Vector4f oC[RENDERTARGETS]);
Int4 enableMask(Registers &r, const Shader::Instruction *instruction); Int4 enableMask(Registers &r, const Shader::Instruction *instruction);
......
...@@ -55,7 +55,7 @@ namespace sw ...@@ -55,7 +55,7 @@ namespace sw
} }
} }
void PixelRoutine::quad(QuadRasterizer::Registers &rBase, Pointer<Byte> cBuffer[4], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x, Int &y) void PixelRoutine::quad(QuadRasterizer::Registers &rBase, Pointer<Byte> cBuffer[RENDERTARGETS], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x, Int &y)
{ {
Registers& r = *static_cast<Registers*>(&rBase); Registers& r = *static_cast<Registers*>(&rBase);
......
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