internal color interp state
This commit is contained in:
parent
5da656df5c
commit
d5e66da17c
1 changed files with 290 additions and 171 deletions
461
src/external/rlsw.h
vendored
461
src/external/rlsw.h
vendored
|
|
@ -791,6 +791,18 @@ SWAPI void swGetFramebufferAttachmentParameteriv(SWattachment attachment, SWatta
|
|||
#define SW_ALIGN(x) // Do nothing if not available
|
||||
#endif
|
||||
|
||||
#if defined(NDEBUG)
|
||||
#if defined(_MSC_VER)
|
||||
#define SW_FORCE_INLINE __forceinline
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
#define SW_FORCE_INLINE inline __attribute__((always_inline))
|
||||
#else
|
||||
#define SW_FORCE_INLINE inline
|
||||
#endif
|
||||
#else
|
||||
#define SW_FORCE_INLINE inline
|
||||
#endif
|
||||
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
#define SW_ARCH_X86_64
|
||||
#elif defined(_M_IX86) || defined(__i386__)
|
||||
|
|
@ -908,10 +920,11 @@ SWAPI void swGetFramebufferAttachmentParameteriv(SWattachment attachment, SWatta
|
|||
|
||||
#define SW_STATE_NONE 0 /* Pseudo state used for the rasterizer variant with no pipeline state enabled */
|
||||
#define SW_STATE_SCISSOR_TEST (1 << 0)
|
||||
#define SW_STATE_TEXTURE_2D (1 << 1)
|
||||
#define SW_STATE_DEPTH_TEST (1 << 2)
|
||||
#define SW_STATE_CULL_FACE (1 << 3)
|
||||
#define SW_STATE_BLEND (1 << 4)
|
||||
#define SW_STATE_COLOR_INTERP (1 << 1)
|
||||
#define SW_STATE_TEXTURE_2D (1 << 2)
|
||||
#define SW_STATE_DEPTH_TEST (1 << 3)
|
||||
#define SW_STATE_CULL_FACE (1 << 4)
|
||||
#define SW_STATE_BLEND (1 << 5)
|
||||
|
||||
#define SW_BLEND_FLAG_NOOP (1 << 0)
|
||||
#define SW_BLEND_FLAG_NEEDS_ALPHA (1 << 1)
|
||||
|
|
@ -1244,16 +1257,15 @@ static inline float sw_fract(float x)
|
|||
return (x - floorf(x));
|
||||
}
|
||||
|
||||
// Xtensa architecture optimization
|
||||
// Fast reciprocal: 1-ULP accurate in ~7 instructions using the
|
||||
// hardware `recip0.s` seed + two Newton-Raphson refinement steps
|
||||
// All work stays in FPU registers — no `__divsf3` software call
|
||||
// Hot-path divisions in the rasterizer (span/triangle setup, perspective divide, etc.) call this
|
||||
// On non-Xtensa targets it transparently expands to `1.0f / x`, so generated code is identical to before
|
||||
#if defined(__XTENSA__)
|
||||
__attribute__((always_inline))
|
||||
static inline float sw_rcp(float x)
|
||||
static SW_FORCE_INLINE float sw_rcp(float x)
|
||||
{
|
||||
#if defined(__XTENSA__)
|
||||
// Xtensa architecture optimization
|
||||
// Fast reciprocal: 1-ULP accurate in ~7 instructions using the
|
||||
// hardware `recip0.s` seed + two Newton-Raphson refinement steps
|
||||
// All work stays in FPU registers — no `__divsf3` software call
|
||||
// Hot-path divisions in the rasterizer (span/triangle setup, perspective divide, etc.) call this
|
||||
// On non-Xtensa targets it transparently expands to `1.0f / x`, so generated code is identical to before
|
||||
float result, temp;
|
||||
__asm__(
|
||||
"recip0.s %0, %2\n"
|
||||
|
|
@ -1266,10 +1278,10 @@ static inline float sw_rcp(float x)
|
|||
: "=&f"(result), "=&f"(temp) : "f"(x)
|
||||
);
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
static inline float sw_rcp(float x) { return 1.0f/x; }
|
||||
return 1.0f/x;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint8_t sw_luminance8(const uint8_t *color)
|
||||
{
|
||||
|
|
@ -1302,108 +1314,6 @@ static inline void sw_lerp_vertex_PCT(sw_vertex_t *SW_RESTRICT out, const sw_ver
|
|||
out->texcoord[1] = a->texcoord[1]*tInv + b->texcoord[1]*t;
|
||||
}
|
||||
|
||||
static inline void sw_get_vertex_grad_PCT(sw_vertex_t *SW_RESTRICT out, const sw_vertex_t *SW_RESTRICT a, const sw_vertex_t *SW_RESTRICT b, float scale)
|
||||
{
|
||||
// Calculate gradients for Position
|
||||
out->position[0] = (b->position[0] - a->position[0])*scale;
|
||||
out->position[1] = (b->position[1] - a->position[1])*scale;
|
||||
out->position[2] = (b->position[2] - a->position[2])*scale;
|
||||
out->position[3] = (b->position[3] - a->position[3])*scale;
|
||||
|
||||
// Calculate gradients for Color
|
||||
out->color[0] = (b->color[0] - a->color[0])*scale;
|
||||
out->color[1] = (b->color[1] - a->color[1])*scale;
|
||||
out->color[2] = (b->color[2] - a->color[2])*scale;
|
||||
out->color[3] = (b->color[3] - a->color[3])*scale;
|
||||
|
||||
// Calculate gradients for Texture coordinates
|
||||
out->texcoord[0] = (b->texcoord[0] - a->texcoord[0])*scale;
|
||||
out->texcoord[1] = (b->texcoord[1] - a->texcoord[1])*scale;
|
||||
}
|
||||
|
||||
static inline void sw_add_vertex_grad_PCT(sw_vertex_t *SW_RESTRICT out, const sw_vertex_t *SW_RESTRICT gradients)
|
||||
{
|
||||
// Add gradients to Position
|
||||
out->position[0] += gradients->position[0];
|
||||
out->position[1] += gradients->position[1];
|
||||
out->position[2] += gradients->position[2];
|
||||
out->position[3] += gradients->position[3];
|
||||
|
||||
// Add gradients to Color
|
||||
out->color[0] += gradients->color[0];
|
||||
out->color[1] += gradients->color[1];
|
||||
out->color[2] += gradients->color[2];
|
||||
out->color[3] += gradients->color[3];
|
||||
|
||||
// Add gradients to Texture coordinates
|
||||
out->texcoord[0] += gradients->texcoord[0];
|
||||
out->texcoord[1] += gradients->texcoord[1];
|
||||
}
|
||||
|
||||
static inline void sw_add_vertex_grad_scaled_PCT(sw_vertex_t *SW_RESTRICT out, const sw_vertex_t *SW_RESTRICT gradients, float scale)
|
||||
{
|
||||
// Add gradients to Position
|
||||
out->position[0] += gradients->position[0]*scale;
|
||||
out->position[1] += gradients->position[1]*scale;
|
||||
out->position[2] += gradients->position[2]*scale;
|
||||
out->position[3] += gradients->position[3]*scale;
|
||||
|
||||
// Add gradients to Color
|
||||
out->color[0] += gradients->color[0]*scale;
|
||||
out->color[1] += gradients->color[1]*scale;
|
||||
out->color[2] += gradients->color[2]*scale;
|
||||
out->color[3] += gradients->color[3]*scale;
|
||||
|
||||
// Add gradients to Texture coordinates
|
||||
out->texcoord[0] += gradients->texcoord[0]*scale;
|
||||
out->texcoord[1] += gradients->texcoord[1]*scale;
|
||||
}
|
||||
|
||||
static inline void sw_get_vertex_grad_PC(sw_vertex_t *SW_RESTRICT out, const sw_vertex_t *SW_RESTRICT a, const sw_vertex_t *SW_RESTRICT b, float scale)
|
||||
{
|
||||
// Calculate gradients for Position
|
||||
out->position[0] = (b->position[0] - a->position[0])*scale;
|
||||
out->position[1] = (b->position[1] - a->position[1])*scale;
|
||||
out->position[2] = (b->position[2] - a->position[2])*scale;
|
||||
out->position[3] = (b->position[3] - a->position[3])*scale;
|
||||
|
||||
// Calculate gradients for Color
|
||||
out->color[0] = (b->color[0] - a->color[0])*scale;
|
||||
out->color[1] = (b->color[1] - a->color[1])*scale;
|
||||
out->color[2] = (b->color[2] - a->color[2])*scale;
|
||||
out->color[3] = (b->color[3] - a->color[3])*scale;
|
||||
}
|
||||
|
||||
static inline void sw_add_vertex_grad_PC(sw_vertex_t *SW_RESTRICT out, const sw_vertex_t *SW_RESTRICT gradients)
|
||||
{
|
||||
// Add gradients to Position
|
||||
out->position[0] += gradients->position[0];
|
||||
out->position[1] += gradients->position[1];
|
||||
out->position[2] += gradients->position[2];
|
||||
out->position[3] += gradients->position[3];
|
||||
|
||||
// Add gradients to Color
|
||||
out->color[0] += gradients->color[0];
|
||||
out->color[1] += gradients->color[1];
|
||||
out->color[2] += gradients->color[2];
|
||||
out->color[3] += gradients->color[3];
|
||||
}
|
||||
|
||||
static inline void sw_add_vertex_grad_scaled_PC(sw_vertex_t *SW_RESTRICT out, const sw_vertex_t *SW_RESTRICT gradients, float scale)
|
||||
{
|
||||
// Add gradients to Position
|
||||
out->position[0] += gradients->position[0]*scale;
|
||||
out->position[1] += gradients->position[1]*scale;
|
||||
out->position[2] += gradients->position[2]*scale;
|
||||
out->position[3] += gradients->position[3]*scale;
|
||||
|
||||
// Add gradients to Color
|
||||
out->color[0] += gradients->color[0]*scale;
|
||||
out->color[1] += gradients->color[1]*scale;
|
||||
out->color[2] += gradients->color[2]*scale;
|
||||
out->color[3] += gradients->color[3]*scale;
|
||||
}
|
||||
|
||||
// Half conversion functions
|
||||
static inline uint16_t sw_float_to_half_ui(uint32_t ui)
|
||||
{
|
||||
|
|
@ -3093,18 +3003,38 @@ static bool sw_polygon_clip(sw_vertex_t polygon[SW_MAX_CLIPPED_POLYGON_VERTICES]
|
|||
[SW_FLAGS(__VA_ARGS__)] = SW_CONCATX(PREFIX, SW_NAME(__VA_ARGS__)),
|
||||
|
||||
// Variant lists: X(STATES...) invoked once per specialization
|
||||
// Triangle/quad: TEXTURE_2D, DEPTH_TEST, BLEND
|
||||
// Triangle/quad: COLOR_INTERP, TEXTURE_2D, DEPTH_TEST, BLEND
|
||||
#define SW_RASTER_VARIANTS_4(X, ...) \
|
||||
X(__VA_ARGS__, NONE) \
|
||||
X(__VA_ARGS__, COLOR_INTERP) \
|
||||
X(__VA_ARGS__, TEXTURE_2D) \
|
||||
X(__VA_ARGS__, DEPTH_TEST) \
|
||||
X(__VA_ARGS__, BLEND) \
|
||||
X(__VA_ARGS__, COLOR_INTERP, TEXTURE_2D) \
|
||||
X(__VA_ARGS__, COLOR_INTERP, DEPTH_TEST) \
|
||||
X(__VA_ARGS__, COLOR_INTERP, BLEND) \
|
||||
X(__VA_ARGS__, TEXTURE_2D, DEPTH_TEST) \
|
||||
X(__VA_ARGS__, TEXTURE_2D, BLEND) \
|
||||
X(__VA_ARGS__, DEPTH_TEST, BLEND) \
|
||||
X(__VA_ARGS__, COLOR_INTERP, TEXTURE_2D, DEPTH_TEST) \
|
||||
X(__VA_ARGS__, COLOR_INTERP, TEXTURE_2D, BLEND) \
|
||||
X(__VA_ARGS__, COLOR_INTERP, DEPTH_TEST, BLEND) \
|
||||
X(__VA_ARGS__, TEXTURE_2D, DEPTH_TEST, BLEND) \
|
||||
X(__VA_ARGS__, COLOR_INTERP, TEXTURE_2D, DEPTH_TEST, BLEND)
|
||||
|
||||
// Variant lists: X(STATES...) invoked once per specialization
|
||||
// Line: COLOR_INTERP, DEPTH_TEST, BLEND
|
||||
#define SW_RASTER_VARIANTS_3(X, ...) \
|
||||
X(__VA_ARGS__, NONE) \
|
||||
X(__VA_ARGS__, TEXTURE_2D) \
|
||||
X(__VA_ARGS__, COLOR_INTERP) \
|
||||
X(__VA_ARGS__, DEPTH_TEST) \
|
||||
X(__VA_ARGS__, BLEND) \
|
||||
X(__VA_ARGS__, TEXTURE_2D, DEPTH_TEST) \
|
||||
X(__VA_ARGS__, TEXTURE_2D, BLEND) \
|
||||
X(__VA_ARGS__, COLOR_INTERP, DEPTH_TEST) \
|
||||
X(__VA_ARGS__, COLOR_INTERP, BLEND) \
|
||||
X(__VA_ARGS__, DEPTH_TEST, BLEND) \
|
||||
X(__VA_ARGS__, TEXTURE_2D, DEPTH_TEST, BLEND)
|
||||
X(__VA_ARGS__, COLOR_INTERP, DEPTH_TEST, BLEND)
|
||||
|
||||
// Line/point: DEPTH_TEST, BLEND
|
||||
// Point: DEPTH_TEST, BLEND
|
||||
#define SW_RASTER_VARIANTS_2(X, ...) \
|
||||
X(__VA_ARGS__, NONE) \
|
||||
X(__VA_ARGS__, DEPTH_TEST) \
|
||||
|
|
@ -3114,12 +3044,16 @@ static bool sw_polygon_clip(sw_vertex_t polygon[SW_MAX_CLIPPED_POLYGON_VERTICES]
|
|||
|
||||
// Triangle rasterizer variant dispatch
|
||||
//-------------------------------------------------------------------------------------------
|
||||
#define SW_RASTER_TRIANGLE_STATE_MASK SW_FLAGS(TEXTURE_2D, DEPTH_TEST, BLEND)
|
||||
#define SW_RASTER_TRIANGLE_STATE_MASK SW_FLAGS(COLOR_INTERP, TEXTURE_2D, DEPTH_TEST, BLEND)
|
||||
|
||||
#define SW_RASTER_TRIANGLE_STATES NONE
|
||||
#include __FILE__ // IWYU pragma: keep
|
||||
#undef SW_RASTER_TRIANGLE_STATES
|
||||
|
||||
#define SW_RASTER_TRIANGLE_STATES COLOR_INTERP
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_TRIANGLE_STATES
|
||||
|
||||
#define SW_RASTER_TRIANGLE_STATES TEXTURE_2D
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_TRIANGLE_STATES
|
||||
|
|
@ -3132,6 +3066,18 @@ static bool sw_polygon_clip(sw_vertex_t polygon[SW_MAX_CLIPPED_POLYGON_VERTICES]
|
|||
#include __FILE__
|
||||
#undef SW_RASTER_TRIANGLE_STATES
|
||||
|
||||
#define SW_RASTER_TRIANGLE_STATES COLOR_INTERP, TEXTURE_2D
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_TRIANGLE_STATES
|
||||
|
||||
#define SW_RASTER_TRIANGLE_STATES COLOR_INTERP, DEPTH_TEST
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_TRIANGLE_STATES
|
||||
|
||||
#define SW_RASTER_TRIANGLE_STATES COLOR_INTERP, BLEND
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_TRIANGLE_STATES
|
||||
|
||||
#define SW_RASTER_TRIANGLE_STATES TEXTURE_2D, DEPTH_TEST
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_TRIANGLE_STATES
|
||||
|
|
@ -3144,27 +3090,46 @@ static bool sw_polygon_clip(sw_vertex_t polygon[SW_MAX_CLIPPED_POLYGON_VERTICES]
|
|||
#include __FILE__
|
||||
#undef SW_RASTER_TRIANGLE_STATES
|
||||
|
||||
#define SW_RASTER_TRIANGLE_STATES COLOR_INTERP, TEXTURE_2D, DEPTH_TEST
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_TRIANGLE_STATES
|
||||
|
||||
#define SW_RASTER_TRIANGLE_STATES COLOR_INTERP, DEPTH_TEST, BLEND
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_TRIANGLE_STATES
|
||||
|
||||
#define SW_RASTER_TRIANGLE_STATES COLOR_INTERP, TEXTURE_2D, BLEND
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_TRIANGLE_STATES
|
||||
|
||||
#define SW_RASTER_TRIANGLE_STATES TEXTURE_2D, DEPTH_TEST, BLEND
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_TRIANGLE_STATES
|
||||
|
||||
// Forward declarations because clangd does not follow #include __FILE__ to avoid infinite recursion
|
||||
// These declarations make all variants visible to static analysis tools without affecting compilation
|
||||
SW_RASTER_VARIANTS_3(SW_RASTER_FWD, sw_raster_triangle_, (const sw_vertex_t*, const sw_vertex_t*, const sw_vertex_t*)) // NOLINT
|
||||
#define SW_RASTER_TRIANGLE_STATES COLOR_INTERP, TEXTURE_2D, DEPTH_TEST, BLEND
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_TRIANGLE_STATES
|
||||
|
||||
// Forward declarations for static analyzer like clangd that do not handle self-inclusion correctly
|
||||
SW_RASTER_VARIANTS_4(SW_RASTER_FWD, sw_raster_triangle_, (const sw_vertex_t*, const sw_vertex_t*, const sw_vertex_t*)) // NOLINT
|
||||
|
||||
static const sw_raster_triangle_f SW_RASTER_TRIANGLE_TABLE[] = {
|
||||
SW_RASTER_VARIANTS_3(SW_RASTER_ENTRY, sw_raster_triangle_)
|
||||
SW_RASTER_VARIANTS_4(SW_RASTER_ENTRY, sw_raster_triangle_)
|
||||
};
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
// Quad rasterizer variant dispatch
|
||||
//-------------------------------------------------------------------------------------------
|
||||
#define SW_RASTER_QUAD_STATE_MASK SW_FLAGS(TEXTURE_2D, DEPTH_TEST, BLEND)
|
||||
#define SW_RASTER_QUAD_STATE_MASK SW_FLAGS(COLOR_INTERP, TEXTURE_2D, DEPTH_TEST, BLEND)
|
||||
|
||||
#define SW_RASTER_QUAD_STATES NONE
|
||||
#include __FILE__ // IWYU pragma: keep
|
||||
#undef SW_RASTER_QUAD_STATES
|
||||
|
||||
#define SW_RASTER_QUAD_STATES COLOR_INTERP
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_QUAD_STATES
|
||||
|
||||
#define SW_RASTER_QUAD_STATES TEXTURE_2D
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_QUAD_STATES
|
||||
|
|
@ -3177,6 +3142,18 @@ static const sw_raster_triangle_f SW_RASTER_TRIANGLE_TABLE[] = {
|
|||
#include __FILE__
|
||||
#undef SW_RASTER_QUAD_STATES
|
||||
|
||||
#define SW_RASTER_QUAD_STATES COLOR_INTERP, TEXTURE_2D
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_QUAD_STATES
|
||||
|
||||
#define SW_RASTER_QUAD_STATES COLOR_INTERP, DEPTH_TEST
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_QUAD_STATES
|
||||
|
||||
#define SW_RASTER_QUAD_STATES COLOR_INTERP, BLEND
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_QUAD_STATES
|
||||
|
||||
#define SW_RASTER_QUAD_STATES TEXTURE_2D, DEPTH_TEST
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_QUAD_STATES
|
||||
|
|
@ -3189,25 +3166,46 @@ static const sw_raster_triangle_f SW_RASTER_TRIANGLE_TABLE[] = {
|
|||
#include __FILE__
|
||||
#undef SW_RASTER_QUAD_STATES
|
||||
|
||||
#define SW_RASTER_QUAD_STATES COLOR_INTERP, TEXTURE_2D, DEPTH_TEST
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_QUAD_STATES
|
||||
|
||||
#define SW_RASTER_QUAD_STATES COLOR_INTERP, TEXTURE_2D, BLEND
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_QUAD_STATES
|
||||
|
||||
#define SW_RASTER_QUAD_STATES COLOR_INTERP, DEPTH_TEST, BLEND
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_QUAD_STATES
|
||||
|
||||
#define SW_RASTER_QUAD_STATES TEXTURE_2D, DEPTH_TEST, BLEND
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_QUAD_STATES
|
||||
|
||||
SW_RASTER_VARIANTS_3(SW_RASTER_FWD, sw_raster_quad_, (const sw_vertex_t*, const sw_vertex_t*, const sw_vertex_t*, const sw_vertex_t*)) // NOLINT
|
||||
#define SW_RASTER_QUAD_STATES COLOR_INTERP, TEXTURE_2D, DEPTH_TEST, BLEND
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_QUAD_STATES
|
||||
|
||||
// Forward declarations for static analyzer like clangd that do not handle self-inclusion correctly
|
||||
SW_RASTER_VARIANTS_4(SW_RASTER_FWD, sw_raster_quad_, (const sw_vertex_t*, const sw_vertex_t*, const sw_vertex_t*, const sw_vertex_t*)) // NOLINT
|
||||
|
||||
static const sw_raster_quad_f SW_RASTER_QUAD_TABLE[] = {
|
||||
SW_RASTER_VARIANTS_3(SW_RASTER_ENTRY, sw_raster_quad_)
|
||||
SW_RASTER_VARIANTS_4(SW_RASTER_ENTRY, sw_raster_quad_)
|
||||
};
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
// Line rasterizer variant dispatch
|
||||
//-------------------------------------------------------------------------------------------
|
||||
#define SW_RASTER_LINE_STATE_MASK SW_FLAGS(DEPTH_TEST, BLEND)
|
||||
#define SW_RASTER_LINE_STATE_MASK SW_FLAGS(COLOR_INTERP, DEPTH_TEST, BLEND)
|
||||
|
||||
#define SW_RASTER_LINE_STATES NONE
|
||||
#include __FILE__ // IWYU pragma: keep
|
||||
#undef SW_RASTER_LINE_STATES
|
||||
|
||||
#define SW_RASTER_LINE_STATES COLOR_INTERP
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_LINE_STATES
|
||||
|
||||
#define SW_RASTER_LINE_STATES DEPTH_TEST
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_LINE_STATES
|
||||
|
|
@ -3216,14 +3214,27 @@ static const sw_raster_quad_f SW_RASTER_QUAD_TABLE[] = {
|
|||
#include __FILE__
|
||||
#undef SW_RASTER_LINE_STATES
|
||||
|
||||
#define SW_RASTER_LINE_STATES COLOR_INTERP, DEPTH_TEST
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_LINE_STATES
|
||||
|
||||
#define SW_RASTER_LINE_STATES COLOR_INTERP, BLEND
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_LINE_STATES
|
||||
|
||||
#define SW_RASTER_LINE_STATES DEPTH_TEST, BLEND
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_LINE_STATES
|
||||
|
||||
SW_RASTER_VARIANTS_2(SW_RASTER_FWD, sw_raster_line_, (const sw_vertex_t*, const sw_vertex_t*)) // NOLINT
|
||||
#define SW_RASTER_LINE_STATES COLOR_INTERP, DEPTH_TEST, BLEND
|
||||
#include __FILE__
|
||||
#undef SW_RASTER_LINE_STATES
|
||||
|
||||
// Forward declarations for static analyzer like clangd that do not handle self-inclusion correctly
|
||||
SW_RASTER_VARIANTS_3(SW_RASTER_FWD, sw_raster_line_, (const sw_vertex_t*, const sw_vertex_t*)) // NOLINT
|
||||
|
||||
static const sw_raster_line_f SW_RASTER_LINE_TABLE[] = {
|
||||
SW_RASTER_VARIANTS_2(SW_RASTER_ENTRY, sw_raster_line_)
|
||||
SW_RASTER_VARIANTS_3(SW_RASTER_ENTRY, sw_raster_line_)
|
||||
};
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -3247,6 +3258,7 @@ static const sw_raster_line_f SW_RASTER_LINE_TABLE[] = {
|
|||
#include __FILE__
|
||||
#undef SW_RASTER_POINT_STATES
|
||||
|
||||
// Forward declarations for static analyzer like clangd that do not handle self-inclusion correctly
|
||||
SW_RASTER_VARIANTS_2(SW_RASTER_FWD, sw_raster_point_, (const sw_vertex_t*)) // NOLINT
|
||||
|
||||
static const sw_raster_point_f SW_RASTER_POINT_TABLE[] = {
|
||||
|
|
@ -5225,17 +5237,80 @@ void swGetFramebufferAttachmentParameteriv(SWattachment attachment, SWattachget
|
|||
#define SW_RASTER_TRIANGLE_SPAN SW_CONCATX(sw_raster_triangle_span_, SW_NAME(SW_RASTER_TRIANGLE_STATES))
|
||||
#define SW_RASTER_TRIANGLE SW_CONCATX(sw_raster_triangle_, SW_NAME(SW_RASTER_TRIANGLE_STATES))
|
||||
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_TEXTURE_2D
|
||||
#define SW_GET_GRAD sw_get_vertex_grad_PCT
|
||||
#define SW_ADD_GRAD sw_add_vertex_grad_PCT
|
||||
#define SW_ADD_GRAD_SCALED sw_add_vertex_grad_scaled_PCT
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
#define SW_SPAN_FLAT_COLOR_PARAM
|
||||
#define SW_SPAN_FLAT_COLOR_ARG
|
||||
#else
|
||||
#define SW_GET_GRAD sw_get_vertex_grad_PC
|
||||
#define SW_ADD_GRAD sw_add_vertex_grad_PC
|
||||
#define SW_ADD_GRAD_SCALED sw_add_vertex_grad_scaled_PC
|
||||
#define SW_SPAN_FLAT_COLOR_PARAM , const float flatColor[4]
|
||||
#define SW_SPAN_FLAT_COLOR_ARG , flatColor
|
||||
#endif
|
||||
|
||||
static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t *end, float dUdy, float dVdy)
|
||||
#define SW_GRAD SW_CONCATX(sw_grad_, SW_NAME(SW_RASTER_TRIANGLE_STATES))
|
||||
#define SW_VADD SW_CONCATX(sw_vadd_, SW_NAME(SW_RASTER_TRIANGLE_STATES))
|
||||
#define SW_VFMA SW_CONCATX(sw_vfma_, SW_NAME(SW_RASTER_TRIANGLE_STATES))
|
||||
|
||||
static SW_FORCE_INLINE void SW_GRAD(sw_vertex_t *SW_RESTRICT out, const sw_vertex_t *SW_RESTRICT a, const sw_vertex_t *SW_RESTRICT b, float scale)
|
||||
{
|
||||
out->position[0] = (b->position[0] - a->position[0])*scale;
|
||||
out->position[1] = (b->position[1] - a->position[1])*scale;
|
||||
out->position[2] = (b->position[2] - a->position[2])*scale;
|
||||
out->position[3] = (b->position[3] - a->position[3])*scale;
|
||||
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
out->color[0] = (b->color[0] - a->color[0])*scale;
|
||||
out->color[1] = (b->color[1] - a->color[1])*scale;
|
||||
out->color[2] = (b->color[2] - a->color[2])*scale;
|
||||
out->color[3] = (b->color[3] - a->color[3])*scale;
|
||||
#endif
|
||||
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_TEXTURE_2D
|
||||
out->texcoord[0] = (b->texcoord[0] - a->texcoord[0])*scale;
|
||||
out->texcoord[1] = (b->texcoord[1] - a->texcoord[1])*scale;
|
||||
#endif
|
||||
}
|
||||
|
||||
static SW_FORCE_INLINE void SW_VADD(sw_vertex_t *SW_RESTRICT out, const sw_vertex_t *SW_RESTRICT gradients)
|
||||
{
|
||||
out->position[0] += gradients->position[0];
|
||||
out->position[1] += gradients->position[1];
|
||||
out->position[2] += gradients->position[2];
|
||||
out->position[3] += gradients->position[3];
|
||||
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
out->color[0] += gradients->color[0];
|
||||
out->color[1] += gradients->color[1];
|
||||
out->color[2] += gradients->color[2];
|
||||
out->color[3] += gradients->color[3];
|
||||
#endif
|
||||
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_TEXTURE_2D
|
||||
out->texcoord[0] += gradients->texcoord[0];
|
||||
out->texcoord[1] += gradients->texcoord[1];
|
||||
#endif
|
||||
}
|
||||
|
||||
static SW_FORCE_INLINE void SW_VFMA(sw_vertex_t *SW_RESTRICT out, const sw_vertex_t *SW_RESTRICT gradients, float scale)
|
||||
{
|
||||
out->position[0] += gradients->position[0]*scale;
|
||||
out->position[1] += gradients->position[1]*scale;
|
||||
out->position[2] += gradients->position[2]*scale;
|
||||
out->position[3] += gradients->position[3]*scale;
|
||||
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
out->color[0] += gradients->color[0]*scale;
|
||||
out->color[1] += gradients->color[1]*scale;
|
||||
out->color[2] += gradients->color[2]*scale;
|
||||
out->color[3] += gradients->color[3]*scale;
|
||||
#endif
|
||||
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_TEXTURE_2D
|
||||
out->texcoord[0] += gradients->texcoord[0]*scale;
|
||||
out->texcoord[1] += gradients->texcoord[1]*scale;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t *end,
|
||||
float dUdy, float dVdy SW_SPAN_FLAT_COLOR_PARAM)
|
||||
{
|
||||
// Gets the start/end coordinates and skip empty lines
|
||||
int xStart = (int)start->position[0];
|
||||
|
|
@ -5256,15 +5331,18 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
|
|||
float dxRcp = sw_rcp(end->position[0] - start->position[0]);
|
||||
|
||||
// Compute the interpolation steps along the X axis
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_DEPTH_TEST
|
||||
float dZdx = (end->position[2] - start->position[2])*dxRcp;
|
||||
#endif
|
||||
float dWdx = (end->position[3] - start->position[3])*dxRcp;
|
||||
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
float dCdx[4] = {
|
||||
(end->color[0] - start->color[0])*dxRcp,
|
||||
(end->color[1] - start->color[1])*dxRcp,
|
||||
(end->color[2] - start->color[2])*dxRcp,
|
||||
(end->color[3] - start->color[3])*dxRcp
|
||||
};
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_DEPTH_TEST
|
||||
float dZdx = (end->position[2] - start->position[2])*dxRcp;
|
||||
#endif
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_TEXTURE_2D
|
||||
float dUdx = (end->texcoord[0] - start->texcoord[0])*dxRcp;
|
||||
|
|
@ -5278,15 +5356,18 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
|
|||
float xOffset = xSubstep + dxStart;
|
||||
|
||||
// Initializing the interpolation starting values
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_DEPTH_TEST
|
||||
float z = start->position[2] + dZdx*xOffset;
|
||||
#endif
|
||||
float w = start->position[3] + dWdx*xOffset;
|
||||
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
float color[4] = {
|
||||
start->color[0] + dCdx[0]*xOffset,
|
||||
start->color[1] + dCdx[1]*xOffset,
|
||||
start->color[2] + dCdx[2]*xOffset,
|
||||
start->color[3] + dCdx[3]*xOffset
|
||||
};
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_DEPTH_TEST
|
||||
float z = start->position[2] + dZdx*xOffset;
|
||||
#endif
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_TEXTURE_2D
|
||||
float u = start->texcoord[0] + dUdx*xOffset;
|
||||
|
|
@ -5316,12 +5397,10 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
|
|||
float wB = w + dWdx*blockLenF;
|
||||
float wRcpB = sw_rcp(wB);
|
||||
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
// Perspective-correct color at both block endpoints, then affine gradient
|
||||
float srcColor[4] = {
|
||||
color[0]*wRcpA,
|
||||
color[1]*wRcpA,
|
||||
color[2]*wRcpA,
|
||||
color[3]*wRcpA
|
||||
color[0]*wRcpA, color[1]*wRcpA, color[2]*wRcpA, color[3]*wRcpA
|
||||
};
|
||||
float dSrcColordx[4] = {
|
||||
((color[0] + dCdx[0]*blockLenF)*wRcpB - srcColor[0])*blockLenRcp,
|
||||
|
|
@ -5329,6 +5408,10 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
|
|||
((color[2] + dCdx[2]*blockLenF)*wRcpB - srcColor[2])*blockLenRcp,
|
||||
((color[3] + dCdx[3]*blockLenF)*wRcpB - srcColor[3])*blockLenRcp
|
||||
};
|
||||
#else
|
||||
// Flat: constant across the whole triangle, no perspective correction needed
|
||||
const float *srcColor = flatColor;
|
||||
#endif
|
||||
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_TEXTURE_2D
|
||||
// Perspective-correct UVs at both endpoints, then affine gradient
|
||||
|
|
@ -5388,10 +5471,12 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
|
|||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_DEPTH_TEST
|
||||
discard:
|
||||
#endif
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
srcColor[0] += dSrcColordx[0];
|
||||
srcColor[1] += dSrcColordx[1];
|
||||
srcColor[2] += dSrcColordx[2];
|
||||
srcColor[3] += dSrcColordx[3];
|
||||
#endif
|
||||
cPtr += SW_FRAMEBUFFER_COLOR_SIZE;
|
||||
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_DEPTH_TEST
|
||||
|
|
@ -5411,10 +5496,12 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
|
|||
|
||||
// Advance perspective-space accumulators by the full block width
|
||||
w = wB;
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
color[0] += dCdx[0]*blockLenF;
|
||||
color[1] += dCdx[1]*blockLenF;
|
||||
color[2] += dCdx[2]*blockLenF;
|
||||
color[3] += dCdx[3]*blockLenF;
|
||||
#endif
|
||||
#if (SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_TEXTURE_2D
|
||||
u += dUdx*blockLenF;
|
||||
v += dVdx*blockLenF;
|
||||
|
|
@ -5450,9 +5537,9 @@ static void SW_RASTER_TRIANGLE(const sw_vertex_t *v0, const sw_vertex_t *v1, con
|
|||
|
||||
// Compute gradients for each side of the triangle
|
||||
sw_vertex_t dVXdy02, dVXdy01, dVXdy12;
|
||||
SW_GET_GRAD(&dVXdy02, v0, v2, h02Rcp);
|
||||
SW_GET_GRAD(&dVXdy01, v0, v1, h01Rcp);
|
||||
SW_GET_GRAD(&dVXdy12, v1, v2, h12Rcp);
|
||||
SW_GRAD(&dVXdy02, v0, v2, h02Rcp);
|
||||
SW_GRAD(&dVXdy01, v0, v1, h01Rcp);
|
||||
SW_GRAD(&dVXdy12, v1, v2, h12Rcp);
|
||||
|
||||
// Y subpixel correction
|
||||
float y0Substep = 1.0f - sw_fract(y0);
|
||||
|
|
@ -5460,8 +5547,18 @@ static void SW_RASTER_TRIANGLE(const sw_vertex_t *v0, const sw_vertex_t *v1, con
|
|||
|
||||
// Get a copy of vertices for interpolation and apply substep correction
|
||||
sw_vertex_t lVert = *v0, rVert = *v0;
|
||||
SW_ADD_GRAD_SCALED(&lVert, &dVXdy02, y0Substep);
|
||||
SW_ADD_GRAD_SCALED(&rVert, &dVXdy01, y0Substep);
|
||||
SW_VFMA(&lVert, &dVXdy02, y0Substep);
|
||||
SW_VFMA(&rVert, &dVXdy01, y0Substep);
|
||||
|
||||
#if !((SW_RASTER_TRIANGLE_FLAGS) & SW_STATE_COLOR_INTERP)
|
||||
float invW = 1.0f / v0->position[3];
|
||||
float flatColor[4] = {
|
||||
v0->color[0]*invW,
|
||||
v0->color[1]*invW,
|
||||
v0->color[2]*invW,
|
||||
v0->color[3]*invW
|
||||
};
|
||||
#endif
|
||||
|
||||
// Y bounds (vertical clipping)
|
||||
int yTop = (int)y0;
|
||||
|
|
@ -5475,14 +5572,14 @@ static void SW_RASTER_TRIANGLE(const sw_vertex_t *v0, const sw_vertex_t *v1, con
|
|||
bool longSideIsLeft = (lVert.position[0] < rVert.position[0]);
|
||||
const sw_vertex_t *a = longSideIsLeft? &lVert : &rVert;
|
||||
const sw_vertex_t *b = longSideIsLeft? &rVert : &lVert;
|
||||
SW_RASTER_TRIANGLE_SPAN(a, b, dVXdy02.texcoord[0], dVXdy02.texcoord[1]);
|
||||
SW_ADD_GRAD(&lVert, &dVXdy02);
|
||||
SW_ADD_GRAD(&rVert, &dVXdy01);
|
||||
SW_RASTER_TRIANGLE_SPAN(a, b, dVXdy02.texcoord[0], dVXdy02.texcoord[1] SW_SPAN_FLAT_COLOR_ARG);
|
||||
SW_VADD(&lVert, &dVXdy02);
|
||||
SW_VADD(&rVert, &dVXdy01);
|
||||
}
|
||||
|
||||
// Get a copy of next right for interpolation and apply substep correction
|
||||
rVert = *v1;
|
||||
SW_ADD_GRAD_SCALED(&rVert, &dVXdy12, y1Substep);
|
||||
SW_VFMA(&rVert, &dVXdy12, y1Substep);
|
||||
|
||||
// Scanline for the lower part of the triangle
|
||||
for (int y = yMid; y < yBot; y++)
|
||||
|
|
@ -5491,15 +5588,14 @@ static void SW_RASTER_TRIANGLE(const sw_vertex_t *v0, const sw_vertex_t *v1, con
|
|||
bool longSideIsLeft = (lVert.position[0] < rVert.position[0]);
|
||||
const sw_vertex_t *a = longSideIsLeft? &lVert : &rVert;
|
||||
const sw_vertex_t *b = longSideIsLeft? &rVert : &lVert;
|
||||
SW_RASTER_TRIANGLE_SPAN(a, b, dVXdy02.texcoord[0], dVXdy02.texcoord[1]);
|
||||
SW_ADD_GRAD(&lVert, &dVXdy02);
|
||||
SW_ADD_GRAD(&rVert, &dVXdy12);
|
||||
SW_RASTER_TRIANGLE_SPAN(a, b, dVXdy02.texcoord[0], dVXdy02.texcoord[1] SW_SPAN_FLAT_COLOR_ARG);
|
||||
SW_VADD(&lVert, &dVXdy02);
|
||||
SW_VADD(&rVert, &dVXdy12);
|
||||
}
|
||||
}
|
||||
|
||||
#undef SW_GET_GRAD
|
||||
#undef SW_ADD_GRAD
|
||||
#undef SW_ADD_GRAD_SCALED
|
||||
#undef SW_SPAN_FLAT_COLOR_PARAM
|
||||
#undef SW_SPAN_FLAT_COLOR_ARG
|
||||
|
||||
#endif // SW_RASTER_TRIANGLE_STATES
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
|
@ -5555,6 +5651,7 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
|
|||
float xSubstep = 1.0f - sw_fract(tl->position[0]);
|
||||
float ySubstep = 1.0f - sw_fract(tl->position[1]);
|
||||
|
||||
#if (SW_RASTER_QUAD_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
// Gradients along X (tl->tr) and Y (tl->bl)
|
||||
float dCdx[4] = {
|
||||
(tr->color[0] - tl->color[0])*wRcp,
|
||||
|
|
@ -5568,6 +5665,9 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
|
|||
(bl->color[2] - tl->color[2])*hRcp,
|
||||
(bl->color[3] - tl->color[3])*hRcp,
|
||||
};
|
||||
#else
|
||||
const float *flatColor = tl->color;
|
||||
#endif
|
||||
|
||||
#if (SW_RASTER_QUAD_FLAGS) & SW_STATE_DEPTH_TEST
|
||||
float dZdx = (tr->position[2] - tl->position[2])*wRcp;
|
||||
|
|
@ -5584,12 +5684,14 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
|
|||
float vRow = tl->texcoord[1] + dVdx*xSubstep + dVdy*ySubstep;
|
||||
#endif
|
||||
|
||||
#if (SW_RASTER_QUAD_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
float cRow[4] = {
|
||||
tl->color[0] + dCdx[0]*xSubstep + dCdy[0]*ySubstep,
|
||||
tl->color[1] + dCdx[1]*xSubstep + dCdy[1]*ySubstep,
|
||||
tl->color[2] + dCdx[2]*xSubstep + dCdy[2]*ySubstep,
|
||||
tl->color[3] + dCdx[3]*xSubstep + dCdy[3]*ySubstep,
|
||||
};
|
||||
#endif
|
||||
|
||||
int stride = RLSW.colorBuffer->width;
|
||||
uint8_t *cPixels = RLSW.colorBuffer->pixels;
|
||||
|
|
@ -5602,10 +5704,12 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
|
|||
float dyMin = (float)(yLoopMin - yMin);
|
||||
|
||||
// Correct our start by how far it's clipped outside the framebuffer
|
||||
#if (SW_RASTER_QUAD_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
cRow[0] += dCdx[0]*dxMin + dCdy[0]*dyMin;
|
||||
cRow[1] += dCdx[1]*dxMin + dCdy[1]*dyMin;
|
||||
cRow[2] += dCdx[2]*dxMin + dCdy[2]*dyMin;
|
||||
cRow[3] += dCdx[3]*dxMin + dCdy[3]*dyMin;
|
||||
#endif
|
||||
#if (SW_RASTER_QUAD_FLAGS) & SW_STATE_DEPTH_TEST
|
||||
zRow += dZdy*dyMin + dZdx*dxMin;
|
||||
#endif
|
||||
|
|
@ -5627,16 +5731,17 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
|
|||
float u = uRow;
|
||||
float v = vRow;
|
||||
#endif
|
||||
float color[4] = {
|
||||
cRow[0],
|
||||
cRow[1],
|
||||
cRow[2],
|
||||
cRow[3]
|
||||
};
|
||||
#if (SW_RASTER_QUAD_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
float color[4] = { cRow[0], cRow[1], cRow[2], cRow[3] };
|
||||
#endif
|
||||
|
||||
for (int x = xLoopMin; x < xLoopMax; x++)
|
||||
{
|
||||
#if (SW_RASTER_QUAD_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
float srcColor[4] = { color[0], color[1], color[2], color[3] };
|
||||
#else
|
||||
float srcColor[4] = { flatColor[0], flatColor[1], flatColor[2], flatColor[3] };
|
||||
#endif
|
||||
|
||||
#if (SW_RASTER_QUAD_FLAGS) & SW_STATE_DEPTH_TEST
|
||||
{
|
||||
|
|
@ -5674,10 +5779,12 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
|
|||
discard:
|
||||
#endif
|
||||
// Move one pixel over without touching the original "start offset"
|
||||
#if (SW_RASTER_QUAD_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
color[0] += dCdx[0];
|
||||
color[1] += dCdx[1];
|
||||
color[2] += dCdx[2];
|
||||
color[3] += dCdx[3];
|
||||
#endif
|
||||
|
||||
#if (SW_RASTER_QUAD_FLAGS) & SW_STATE_DEPTH_TEST
|
||||
{
|
||||
|
|
@ -5699,10 +5806,12 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
|
|||
// The for loop is clamped to the right side of the screen
|
||||
// However, these cursor start vars are still on the left
|
||||
// That's fine, advancing to the next row
|
||||
#if (SW_RASTER_QUAD_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
cRow[0] += dCdy[0];
|
||||
cRow[1] += dCdy[1];
|
||||
cRow[2] += dCdy[2];
|
||||
cRow[3] += dCdy[3];
|
||||
#endif
|
||||
|
||||
#if (SW_RASTER_QUAD_FLAGS) & SW_STATE_DEPTH_TEST
|
||||
{
|
||||
|
|
@ -5764,10 +5873,12 @@ static void SW_RASTER_LINE_THIN(const sw_vertex_t *v0, const sw_vertex_t *v1)
|
|||
#if (SW_RASTER_LINE_FLAGS) & SW_STATE_DEPTH_TEST
|
||||
float zInc = (v1->position[2] - v0->position[2])*stepRcp;
|
||||
#endif
|
||||
#if (SW_RASTER_LINE_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
float rInc = (v1->color[0] - v0->color[0])*stepRcp;
|
||||
float gInc = (v1->color[1] - v0->color[1])*stepRcp;
|
||||
float bInc = (v1->color[2] - v0->color[2])*stepRcp;
|
||||
float aInc = (v1->color[3] - v0->color[3])*stepRcp;
|
||||
#endif
|
||||
|
||||
// Initializing the interpolation starting values
|
||||
float x = x0 + xInc*substep;
|
||||
|
|
@ -5775,10 +5886,12 @@ static void SW_RASTER_LINE_THIN(const sw_vertex_t *v0, const sw_vertex_t *v1)
|
|||
#if (SW_RASTER_LINE_FLAGS) & SW_STATE_DEPTH_TEST
|
||||
float z = v0->position[2] + zInc*substep;
|
||||
#endif
|
||||
#if (SW_RASTER_LINE_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
float r = v0->color[0] + rInc*substep;
|
||||
float g = v0->color[1] + gInc*substep;
|
||||
float b = v0->color[2] + bInc*substep;
|
||||
float a = v0->color[3] + aInc*substep;
|
||||
#endif
|
||||
|
||||
// Start line rasterization
|
||||
const int fbWidth = RLSW.colorBuffer->width;
|
||||
|
|
@ -5811,7 +5924,11 @@ static void SW_RASTER_LINE_THIN(const sw_vertex_t *v0, const sw_vertex_t *v1)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if (SW_RASTER_LINE_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
float srcColor[4] = {r, g, b, a};
|
||||
#else
|
||||
const float *srcColor = v0->color;
|
||||
#endif
|
||||
|
||||
#if (SW_RASTER_LINE_FLAGS) & SW_STATE_BLEND
|
||||
{
|
||||
|
|
@ -5836,10 +5953,12 @@ static void SW_RASTER_LINE_THIN(const sw_vertex_t *v0, const sw_vertex_t *v1)
|
|||
z += zInc;
|
||||
}
|
||||
#endif
|
||||
#if (SW_RASTER_LINE_FLAGS) & SW_STATE_COLOR_INTERP
|
||||
r += rInc;
|
||||
g += gInc;
|
||||
b += bInc;
|
||||
a += aInc;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue