affine interpolation per blocks
This commit is contained in:
parent
23efe6decf
commit
a31fecf0b9
179
src/external/rlsw.h
vendored
179
src/external/rlsw.h
vendored
|
|
@ -5259,16 +5259,11 @@ void swGetFramebufferAttachmentParameteriv(SWattachment attachment, SWattachget
|
||||||
|
|
||||||
static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t *end, float dUdy, float dVdy)
|
static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t *end, float dUdy, float dVdy)
|
||||||
{
|
{
|
||||||
// Gets the start and end coordinates
|
// Gets the start/end coordinates and skip empty lines
|
||||||
int xStart = (int)start->coord[0];
|
int xStart = (int)start->coord[0];
|
||||||
int xEnd = (int)end->coord[0];
|
int xEnd = (int)end->coord[0];
|
||||||
|
|
||||||
// Avoid empty lines
|
|
||||||
if (xStart == xEnd) return;
|
if (xStart == xEnd) return;
|
||||||
|
|
||||||
// Compute the subpixel distance to traverse before the first pixel
|
|
||||||
float xSubstep = 1.0f - sw_fract(start->coord[0]);
|
|
||||||
|
|
||||||
// Compute the inverse horizontal distance along the X axis
|
// Compute the inverse horizontal distance along the X axis
|
||||||
float dxRcp = 1.0f/(end->coord[0] - start->coord[0]);
|
float dxRcp = 1.0f/(end->coord[0] - start->coord[0]);
|
||||||
|
|
||||||
|
|
@ -5288,6 +5283,9 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
|
||||||
float dVdx = (end->texcoord[1] - start->texcoord[1])*dxRcp;
|
float dVdx = (end->texcoord[1] - start->texcoord[1])*dxRcp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Compute the subpixel distance to traverse before the first pixel
|
||||||
|
float xSubstep = 1.0f - sw_fract(start->coord[0]);
|
||||||
|
|
||||||
// Initializing the interpolation starting values
|
// Initializing the interpolation starting values
|
||||||
float w = start->coord[3] + dWdx*xSubstep;
|
float w = start->coord[3] + dWdx*xSubstep;
|
||||||
float color[4] = {
|
float color[4] = {
|
||||||
|
|
@ -5312,77 +5310,126 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
|
||||||
uint8_t *dPtr = (uint8_t *)(RLSW.depthBuffer->pixels) + baseOffset*SW_FRAMEBUFFER_DEPTH_SIZE;
|
uint8_t *dPtr = (uint8_t *)(RLSW.depthBuffer->pixels) + baseOffset*SW_FRAMEBUFFER_DEPTH_SIZE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Scanline rasterization
|
#define SW_AFFINE_BLOCK 16
|
||||||
for (int x = xStart; x < xEnd; x++)
|
|
||||||
|
int x = xStart;
|
||||||
|
while (x < xEnd)
|
||||||
{
|
{
|
||||||
float wRcp = 1.0f/w;
|
// Clamp last block to remaining pixels
|
||||||
|
int blockEnd = x + SW_AFFINE_BLOCK;
|
||||||
|
if (blockEnd > xEnd) blockEnd = xEnd;
|
||||||
|
float blockLenF = (float)(blockEnd - x);
|
||||||
|
float blockLenRcp = 1.0f / blockLenF;
|
||||||
|
|
||||||
|
// Only 2 '1/w' here; none inside the pixel loop
|
||||||
|
float wRcpA = 1.0f / w;
|
||||||
|
float wB = w + dWdx*blockLenF;
|
||||||
|
float wRcpB = 1.0f / wB;
|
||||||
|
|
||||||
|
// Perspective-correct color at both block endpoints, then affine gradient
|
||||||
float srcColor[4] = {
|
float srcColor[4] = {
|
||||||
color[0]*wRcp,
|
color[0]*wRcpA,
|
||||||
color[1]*wRcp,
|
color[1]*wRcpA,
|
||||||
color[2]*wRcp,
|
color[2]*wRcpA,
|
||||||
color[3]*wRcp
|
color[3]*wRcpA
|
||||||
|
};
|
||||||
|
float dSrcColordx[4] = {
|
||||||
|
((color[0] + dCdx[0]*blockLenF)*wRcpB - srcColor[0])*blockLenRcp,
|
||||||
|
((color[1] + dCdx[1]*blockLenF)*wRcpB - srcColor[1])*blockLenRcp,
|
||||||
|
((color[2] + dCdx[2]*blockLenF)*wRcpB - srcColor[2])*blockLenRcp,
|
||||||
|
((color[3] + dCdx[3]*blockLenF)*wRcpB - srcColor[3])*blockLenRcp
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef SW_ENABLE_DEPTH_TEST
|
#ifdef SW_ENABLE_TEXTURE
|
||||||
|
// Perspective-correct UVs at both endpoints, then affine gradient
|
||||||
|
float uAffine = u*wRcpA;
|
||||||
|
float vAffine = v*wRcpA;
|
||||||
|
float dUaffine = ((u + dUdx*blockLenF)*wRcpB - uAffine)*blockLenRcp;
|
||||||
|
float dVaffine = ((v + dVdx*blockLenF)*wRcpB - vAffine)*blockLenRcp;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Inner span pixel loop
|
||||||
|
for (; x < blockEnd; x++)
|
||||||
{
|
{
|
||||||
/* TODO: Implement different depth funcs? */
|
#ifdef SW_ENABLE_DEPTH_TEST
|
||||||
float depth = SW_FRAMEBUFFER_DEPTH_GET(dPtr, 0);
|
{
|
||||||
if (z > depth) goto discard;
|
float depth = SW_FRAMEBUFFER_DEPTH_GET(dPtr, 0);
|
||||||
|
if (z > depth) goto discard;
|
||||||
|
SW_FRAMEBUFFER_DEPTH_SET(dPtr, z, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TODO: Implement depth mask */
|
#ifdef SW_ENABLE_TEXTURE
|
||||||
SW_FRAMEBUFFER_DEPTH_SET(dPtr, z, 0);
|
{
|
||||||
|
float texColor[4];
|
||||||
|
sw_texture_sample(texColor, RLSW.boundTexture, uAffine, vAffine, dUdx, dUdy, dVdx, dVdy);
|
||||||
|
float finalColor[4] = {
|
||||||
|
srcColor[0]*texColor[0],
|
||||||
|
srcColor[1]*texColor[1],
|
||||||
|
srcColor[2]*texColor[2],
|
||||||
|
srcColor[3]*texColor[3]
|
||||||
|
};
|
||||||
|
#ifdef SW_ENABLE_BLEND
|
||||||
|
{
|
||||||
|
float dstColor[4];
|
||||||
|
SW_FRAMEBUFFER_COLOR_GET(dstColor, cPtr, 0);
|
||||||
|
RLSW.blendFunc(dstColor, finalColor);
|
||||||
|
SW_FRAMEBUFFER_COLOR_SET(cPtr, dstColor, 0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
SW_FRAMEBUFFER_COLOR_SET(cPtr, finalColor, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
#ifdef SW_ENABLE_BLEND
|
||||||
|
{
|
||||||
|
float dstColor[4];
|
||||||
|
SW_FRAMEBUFFER_COLOR_GET(dstColor, cPtr, 0);
|
||||||
|
RLSW.blendFunc(dstColor, srcColor);
|
||||||
|
SW_FRAMEBUFFER_COLOR_SET(cPtr, dstColor, 0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
SW_FRAMEBUFFER_COLOR_SET(cPtr, srcColor, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
discard:
|
||||||
|
srcColor[0] += dSrcColordx[0];
|
||||||
|
srcColor[1] += dSrcColordx[1];
|
||||||
|
srcColor[2] += dSrcColordx[2];
|
||||||
|
srcColor[3] += dSrcColordx[3];
|
||||||
|
cPtr += SW_FRAMEBUFFER_COLOR_SIZE;
|
||||||
|
|
||||||
|
#ifdef SW_ENABLE_DEPTH_TEST
|
||||||
|
{
|
||||||
|
z += dZdx;
|
||||||
|
dPtr += SW_FRAMEBUFFER_DEPTH_SIZE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SW_ENABLE_TEXTURE
|
||||||
|
{
|
||||||
|
uAffine += dUaffine;
|
||||||
|
vAffine += dVaffine;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
// Advance perspective-space accumulators by the full block width
|
||||||
|
w = wB;
|
||||||
|
color[0] += dCdx[0]*blockLenF;
|
||||||
|
color[1] += dCdx[1]*blockLenF;
|
||||||
|
color[2] += dCdx[2]*blockLenF;
|
||||||
|
color[3] += dCdx[3]*blockLenF;
|
||||||
#ifdef SW_ENABLE_TEXTURE
|
#ifdef SW_ENABLE_TEXTURE
|
||||||
{
|
u += dUdx*blockLenF;
|
||||||
float texColor[4];
|
v += dVdx*blockLenF;
|
||||||
float s = u*wRcp;
|
|
||||||
float t = v*wRcp;
|
|
||||||
sw_texture_sample(texColor, RLSW.boundTexture, s, t, dUdx, dUdy, dVdx, dVdy);
|
|
||||||
srcColor[0] *= texColor[0];
|
|
||||||
srcColor[1] *= texColor[1];
|
|
||||||
srcColor[2] *= texColor[2];
|
|
||||||
srcColor[3] *= texColor[3];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SW_ENABLE_BLEND
|
|
||||||
{
|
|
||||||
float dstColor[4];
|
|
||||||
SW_FRAMEBUFFER_COLOR_GET(dstColor, cPtr, 0);
|
|
||||||
RLSW.blendFunc(dstColor, srcColor);
|
|
||||||
SW_FRAMEBUFFER_COLOR_SET(cPtr, dstColor, 0);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
SW_FRAMEBUFFER_COLOR_SET(cPtr, srcColor, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Increment the interpolation parameter, UVs, and pointers
|
|
||||||
discard:
|
|
||||||
w += dWdx;
|
|
||||||
color[0] += dCdx[0];
|
|
||||||
color[1] += dCdx[1];
|
|
||||||
color[2] += dCdx[2];
|
|
||||||
color[3] += dCdx[3];
|
|
||||||
cPtr += SW_FRAMEBUFFER_COLOR_SIZE;
|
|
||||||
|
|
||||||
#ifdef SW_ENABLE_DEPTH_TEST
|
|
||||||
{
|
|
||||||
z += dZdx;
|
|
||||||
dPtr += SW_FRAMEBUFFER_DEPTH_SIZE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SW_ENABLE_TEXTURE
|
|
||||||
{
|
|
||||||
u += dUdx;
|
|
||||||
v += dVdx;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef SW_AFFINE_BLOCK
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SW_RASTER_TRIANGLE(const sw_vertex_t *v0, const sw_vertex_t *v1, const sw_vertex_t *v2)
|
static void SW_RASTER_TRIANGLE(const sw_vertex_t *v0, const sw_vertex_t *v1, const sw_vertex_t *v2)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user