diff --git a/src/basictypes.h b/src/basictypes.h index 025d119a53..fed81fa1c8 100644 --- a/src/basictypes.h +++ b/src/basictypes.h @@ -37,7 +37,6 @@ union QWORD_UNION #define FRACUNIT (1<GetDest(_x1, _y); _xstep = args.TextureUStep(); _ystep = args.TextureVStep(); - _xbits = args.TextureWidthBits(); - _ybits = args.TextureHeightBits(); + _srcwidth = args.TextureWidth(); + _srcheight = args.TextureHeight(); _srcblend = args.SrcBlend(); _destblend = args.DestBlend(); _color = args.SolidColor(); @@ -2035,10 +2035,10 @@ namespace swrenderer if (thread->line_skipped_by_thread(_y)) return; - dsfixed_t xfrac; - dsfixed_t yfrac; - dsfixed_t xstep; - dsfixed_t ystep; + uint32_t xfrac; + uint32_t yfrac; + uint32_t xstep; + uint32_t ystep; uint8_t *dest; const uint8_t *source = _source; const uint8_t *colormap = _colormap; @@ -2060,7 +2060,7 @@ namespace swrenderer float viewpos_x = _viewpos_x; float step_viewpos_x = _step_viewpos_x; - if (_xbits == 6 && _ybits == 6 && num_dynlights == 0) + if (_srcwidth == 64 && _srcheight == 64 && num_dynlights == 0) { // 64x64 is the most common case by far, so special case it. do @@ -2077,7 +2077,7 @@ namespace swrenderer yfrac += ystep; } while (--count); } - else if (_xbits == 6 && _ybits == 6) + else if (_srcwidth == 64 && _srcheight == 64) { // 64x64 is the most common case by far, so special case it. do @@ -2097,14 +2097,13 @@ namespace swrenderer } else { - uint8_t yshift = 32 - _ybits; - uint8_t xshift = yshift - _xbits; - int xmask = ((1 << _xbits) - 1) << _ybits; + uint8_t srcwidth = _srcwidth; + uint8_t srcheight = _srcheight; do { // Current texture index in u,v. - spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + spot = (((xfrac >> 16) * srcwidth) >> 16) * srcheight + (((yfrac >> 16) * srcheight) >> 16); // Lookup pixel from flat texture tile, // re-index using light/colormap. @@ -2123,10 +2122,10 @@ namespace swrenderer if (thread->line_skipped_by_thread(_y)) return; - dsfixed_t xfrac; - dsfixed_t yfrac; - dsfixed_t xstep; - dsfixed_t ystep; + uint32_t xfrac; + uint32_t yfrac; + uint32_t xstep; + uint32_t ystep; uint8_t *dest; const uint8_t *source = _source; const uint8_t *colormap = _colormap; @@ -2148,7 +2147,7 @@ namespace swrenderer float viewpos_x = _viewpos_x; float step_viewpos_x = _step_viewpos_x; - if (_xbits == 6 && _ybits == 6) + if (_srcwidth == 64 && _srcheight == 64) { // 64x64 is the most common case by far, so special case it. do @@ -2169,14 +2168,14 @@ namespace swrenderer } else { - uint8_t yshift = 32 - _ybits; - uint8_t xshift = yshift - _xbits; - int xmask = ((1 << _xbits) - 1) << _ybits; + uint8_t srcwidth = _srcwidth; + uint8_t srcheight = _srcheight; + do { int texdata; - spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + spot = (((xfrac >> 16) * srcwidth) >> 16) * srcheight + (((yfrac >> 16) * srcheight) >> 16); texdata = source[spot]; if (texdata != 0) { @@ -2195,10 +2194,10 @@ namespace swrenderer if (thread->line_skipped_by_thread(_y)) return; - dsfixed_t xfrac; - dsfixed_t yfrac; - dsfixed_t xstep; - dsfixed_t ystep; + uint32_t xfrac; + uint32_t yfrac; + uint32_t xstep; + uint32_t ystep; uint8_t *dest; const uint8_t *source = _source; const uint8_t *colormap = _colormap; @@ -2226,7 +2225,7 @@ namespace swrenderer if (!r_blendmethod) { - if (_xbits == 6 && _ybits == 6) + if (_srcwidth == 64 && _srcheight == 64) { // 64x64 is the most common case by far, so special case it. do @@ -2245,12 +2244,12 @@ namespace swrenderer } else { - uint8_t yshift = 32 - _ybits; - uint8_t xshift = yshift - _xbits; - int xmask = ((1 << _xbits) - 1) << _ybits; + uint8_t srcwidth = _srcwidth; + uint8_t srcheight = _srcheight; + do { - spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + spot = (((xfrac >> 16) * srcwidth) >> 16) * srcheight + (((yfrac >> 16) * srcheight) >> 16); uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; uint32_t bg = *dest; fg = fg2rgb[fg]; @@ -2265,7 +2264,7 @@ namespace swrenderer } else { - if (_xbits == 6 && _ybits == 6) + if (_srcwidth == 64 && _srcheight == 64) { // 64x64 is the most common case by far, so special case it. do @@ -2285,12 +2284,12 @@ namespace swrenderer } else { - uint8_t yshift = 32 - _ybits; - uint8_t xshift = yshift - _xbits; - int xmask = ((1 << _xbits) - 1) << _ybits; + uint8_t srcwidth = _srcwidth; + uint8_t srcheight = _srcheight; + do { - spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + spot = (((xfrac >> 16) * srcwidth) >> 16) * srcheight + (((yfrac >> 16) * srcheight) >> 16); uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; uint32_t bg = *dest; int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); @@ -2311,10 +2310,10 @@ namespace swrenderer if (thread->line_skipped_by_thread(_y)) return; - dsfixed_t xfrac; - dsfixed_t yfrac; - dsfixed_t xstep; - dsfixed_t ystep; + uint32_t xfrac; + uint32_t yfrac; + uint32_t xstep; + uint32_t ystep; uint8_t *dest; const uint8_t *source = _source; const uint8_t *colormap = _colormap; @@ -2342,7 +2341,7 @@ namespace swrenderer if (!r_blendmethod) { - if (_xbits == 6 && _ybits == 6) + if (_srcwidth == 64 && _srcheight == 64) { // 64x64 is the most common case by far, so special case it. do @@ -2368,14 +2367,14 @@ namespace swrenderer } else { - uint8_t yshift = 32 - _ybits; - uint8_t xshift = yshift - _xbits; - int xmask = ((1 << _xbits) - 1) << _ybits; + uint8_t srcwidth = _srcwidth; + uint8_t srcheight = _srcheight; + do { uint8_t texdata; - spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + spot = (((xfrac >> 16) * srcwidth) >> 16) * srcheight + (((yfrac >> 16) * srcheight) >> 16); texdata = source[spot]; if (texdata != 0) { @@ -2395,7 +2394,7 @@ namespace swrenderer } else { - if (_xbits == 6 && _ybits == 6) + if (_srcwidth == 64 && _srcheight == 64) { // 64x64 is the most common case by far, so special case it. do @@ -2421,14 +2420,14 @@ namespace swrenderer } else { - uint8_t yshift = 32 - _ybits; - uint8_t xshift = yshift - _xbits; - int xmask = ((1 << _xbits) - 1) << _ybits; + uint8_t srcwidth = _srcwidth; + uint8_t srcheight = _srcheight; + do { uint8_t texdata; - spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + spot = (((xfrac >> 16) * srcwidth) >> 16) * srcheight + (((yfrac >> 16) * srcheight) >> 16); texdata = source[spot]; if (texdata != 0) { @@ -2453,10 +2452,10 @@ namespace swrenderer if (thread->line_skipped_by_thread(_y)) return; - dsfixed_t xfrac; - dsfixed_t yfrac; - dsfixed_t xstep; - dsfixed_t ystep; + uint32_t xfrac; + uint32_t yfrac; + uint32_t xstep; + uint32_t ystep; uint8_t *dest; const uint8_t *source = _source; const uint8_t *colormap = _colormap; @@ -2483,7 +2482,7 @@ namespace swrenderer if (!r_blendmethod) { - if (_xbits == 6 && _ybits == 6) + if (_srcwidth == 64 && _srcheight == 64) { // 64x64 is the most common case by far, so special case it. do @@ -2506,12 +2505,12 @@ namespace swrenderer } else { - uint8_t yshift = 32 - _ybits; - uint8_t xshift = yshift - _xbits; - int xmask = ((1 << _xbits) - 1) << _ybits; + uint8_t srcwidth = _srcwidth; + uint8_t srcheight = _srcheight; + do { - spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + spot = (((xfrac >> 16) * srcwidth) >> 16) * srcheight + (((yfrac >> 16) * srcheight) >> 16); uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; uint32_t a = fg2rgb[fg] + bg2rgb[*dest]; uint32_t b = a; @@ -2530,7 +2529,7 @@ namespace swrenderer } else { - if (_xbits == 6 && _ybits == 6) + if (_srcwidth == 64 && _srcheight == 64) { // 64x64 is the most common case by far, so special case it. do @@ -2550,12 +2549,12 @@ namespace swrenderer } else { - uint8_t yshift = 32 - _ybits; - uint8_t xshift = yshift - _xbits; - int xmask = ((1 << _xbits) - 1) << _ybits; + uint8_t srcwidth = _srcwidth; + uint8_t srcheight = _srcheight; + do { - spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + spot = (((xfrac >> 16) * srcwidth) >> 16) * srcheight + (((yfrac >> 16) * srcheight) >> 16); uint32_t fg = num_dynlights != 0 ? AddLights(dynlights, num_dynlights, viewpos_x, colormap[source[spot]], source[spot]) : colormap[source[spot]]; uint32_t bg = *dest; int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); @@ -2576,10 +2575,10 @@ namespace swrenderer if (thread->line_skipped_by_thread(_y)) return; - dsfixed_t xfrac; - dsfixed_t yfrac; - dsfixed_t xstep; - dsfixed_t ystep; + uint32_t xfrac; + uint32_t yfrac; + uint32_t xstep; + uint32_t ystep; uint8_t *dest; const uint8_t *source = _source; const uint8_t *colormap = _colormap; @@ -2606,7 +2605,7 @@ namespace swrenderer if (!r_blendmethod) { - if (_xbits == 6 && _ybits == 6) + if (_srcwidth == 64 && _srcheight == 64) { // 64x64 is the most common case by far, so special case it. do @@ -2636,14 +2635,14 @@ namespace swrenderer } else { - uint8_t yshift = 32 - _ybits; - uint8_t xshift = yshift - _xbits; - int xmask = ((1 << _xbits) - 1) << _ybits; + uint8_t srcwidth = _srcwidth; + uint8_t srcheight = _srcheight; + do { uint8_t texdata; - spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + spot = (((xfrac >> 16) * srcwidth) >> 16) * srcheight + (((yfrac >> 16) * srcheight) >> 16); texdata = source[spot]; if (texdata != 0) { @@ -2667,7 +2666,7 @@ namespace swrenderer } else { - if (_xbits == 6 && _ybits == 6) + if (_srcwidth == 64 && _srcheight == 64) { // 64x64 is the most common case by far, so special case it. do @@ -2693,14 +2692,14 @@ namespace swrenderer } else { - uint8_t yshift = 32 - _ybits; - uint8_t xshift = yshift - _xbits; - int xmask = ((1 << _xbits) - 1) << _ybits; + uint8_t srcwidth = _srcwidth; + uint8_t srcheight = _srcheight; + do { uint8_t texdata; - spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + spot = (((xfrac >> 16) * srcwidth) >> 16) * srcheight + (((yfrac >> 16) * srcheight) >> 16); texdata = source[spot]; if (texdata != 0) { diff --git a/src/swrenderer/drawers/r_draw_pal.h b/src/swrenderer/drawers/r_draw_pal.h index 813825f2ba..e3b2b95726 100644 --- a/src/swrenderer/drawers/r_draw_pal.h +++ b/src/swrenderer/drawers/r_draw_pal.h @@ -101,16 +101,16 @@ namespace swrenderer const uint8_t *_source; const uint8_t *_colormap; - dsfixed_t _xfrac; - dsfixed_t _yfrac; + uint32_t _xfrac; + uint32_t _yfrac; int _y; int _x1; int _x2; uint8_t *_dest; - dsfixed_t _xstep; - dsfixed_t _ystep; - int _xbits; - int _ybits; + uint32_t _xstep; + uint32_t _ystep; + int _srcwidth; + int _srcheight; uint32_t *_srcblend; uint32_t *_destblend; int _color; diff --git a/src/swrenderer/drawers/r_draw_rgba.h b/src/swrenderer/drawers/r_draw_rgba.h index c13eb51621..6cafb2f1e2 100644 --- a/src/swrenderer/drawers/r_draw_rgba.h +++ b/src/swrenderer/drawers/r_draw_rgba.h @@ -286,7 +286,7 @@ namespace swrenderer { public: // calculates the light constant passed to the shade_pal_index function - FORCEINLINE static uint32_t calc_light_multiplier(dsfixed_t light) + FORCEINLINE static uint32_t calc_light_multiplier(uint32_t light) { return 256 - (light >> (FRACBITS - 8)); } diff --git a/src/swrenderer/drawers/r_draw_span32.h b/src/swrenderer/drawers/r_draw_span32.h index a48ec844b6..dfbfb813e2 100644 --- a/src/swrenderer/drawers/r_draw_span32.h +++ b/src/swrenderer/drawers/r_draw_span32.h @@ -61,15 +61,14 @@ namespace swrenderer struct TextureData { - uint32_t xbits; - uint32_t ybits; + uint32_t width; + uint32_t height; + uint32_t xone; + uint32_t yone; uint32_t xstep; uint32_t ystep; uint32_t xfrac; uint32_t yfrac; - uint32_t yshift; - uint32_t xshift; - uint32_t xmask; const uint32_t *source; }; @@ -80,8 +79,8 @@ namespace swrenderer if (thread->line_skipped_by_thread(args.DestY())) return; TextureData texdata; - texdata.xbits = args.TextureWidthBits(); - texdata.ybits = args.TextureHeightBits(); + texdata.width = args.TextureWidth(); + texdata.height = args.TextureHeight(); texdata.xstep = args.TextureUStep(); texdata.ystep = args.TextureVStep(); texdata.xfrac = args.TextureUPos(); @@ -98,22 +97,21 @@ namespace swrenderer int level = (int)lod; while (level > 0) { - if (texdata.xbits <= 2 || texdata.ybits <= 2) + if (texdata.width <= 2 || texdata.height <= 2) break; - texdata.source += (1 << (texdata.xbits)) * (1 << (texdata.ybits)); - texdata.xbits -= 1; - texdata.ybits -= 1; + texdata.source += texdata.width * texdata.height; + texdata.width = MAX(texdata.width / 2, 1); + texdata.height = MAX(texdata.height / 2, 1); level--; } } - texdata.yshift = 32 - texdata.ybits; - texdata.xshift = texdata.yshift - texdata.xbits; - texdata.xmask = ((1 << texdata.xbits) - 1) << texdata.ybits; + texdata.xone = (0x80000000u / texdata.width) << 1; + texdata.yone = (0x80000000u / texdata.height) << 1; bool is_nearest_filter = (magnifying && !r_magfilter) || (!magnifying && !r_minfilter); - bool is_64x64 = texdata.xbits == 6 && texdata.ybits == 6; + bool is_64x64 = texdata.width == 64 && texdata.height == 64; auto shade_constants = args.ColormapConstants(); if (shade_constants.simple_shade) @@ -198,8 +196,8 @@ namespace swrenderer if (FilterModeT::Mode == (int)FilterModes::Linear) { - texdata.xfrac -= 1 << (31 - texdata.xbits); - texdata.yfrac -= 1 << (31 - texdata.ybits); + texdata.xfrac -= texdata.xone / 2; + texdata.yfrac -= texdata.yone / 2; } uint32_t srcalpha = args.SrcAlpha() >> (FRACBITS - 8); @@ -217,7 +215,7 @@ namespace swrenderer bgcolor = 0; } - uint32_t ifgcolor = Sample(texdata.xbits, texdata.ybits, texdata.xstep, texdata.ystep, texdata.xfrac, texdata.yfrac, texdata.yshift, texdata.xshift, texdata.xmask, texdata.source); + uint32_t ifgcolor = Sample(texdata.width, texdata.height, texdata.xone, texdata.yone, texdata.xstep, texdata.ystep, texdata.xfrac, texdata.yfrac, texdata.source); BgraColor fgcolor = Shade(ifgcolor, light, desaturate, inv_desaturate, shade_fade, shade_light, lights, num_lights, viewpos_x); BgraColor outcolor = Blend(fgcolor, bgcolor, srcalpha, destalpha, ifgcolor); @@ -231,7 +229,7 @@ namespace swrenderer } template - FORCEINLINE uint32_t Sample(uint32_t xbits, uint32_t ybits, uint32_t xstep, uint32_t ystep, uint32_t xfrac, uint32_t yfrac, uint32_t yshift, uint32_t xshift, uint32_t xmask, const uint32_t *source) + FORCEINLINE uint32_t Sample(uint32_t width, uint32_t height, uint32_t xone, uint32_t yone, uint32_t xstep, uint32_t ystep, uint32_t xfrac, uint32_t yfrac, const uint32_t *source) { using namespace DrawSpan32TModes; @@ -242,37 +240,44 @@ namespace swrenderer } else if (FilterModeT::Mode == (int)FilterModes::Nearest) { - int sample_index = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + uint32_t x = ((xfrac >> 16) * width) >> 16; + uint32_t y = ((yfrac >> 16) * height) >> 16; + int sample_index = x * height + y; return source[sample_index]; } else { - uint32_t xxbits, yybits; + uint32_t p00, p01, p10, p11; + uint32_t frac_x, frac_y; if (TextureSizeT::Mode == (int)SpanTextureSize::Size64x64) { - xxbits = 26; - yybits = 26; + frac_x = xfrac >> 16 << 6; + frac_y = yfrac >> 16 << 6; + uint32_t x0 = frac_x >> 16; + uint32_t y0 = frac_y >> 16; + uint32_t x1 = (x0 + 1) & 0x3f; + uint32_t y1 = (y0 + 1) & 0x3f; + p00 = source[(y0 + (x0 << 6))]; + p01 = source[(y1 + (x0 << 6))]; + p10 = source[(y0 + (x1 << 6))]; + p11 = source[(y1 + (x1 << 6))]; } else { - xxbits = 32 - xbits; - yybits = 32 - ybits; + frac_x = (xfrac >> 16) * width; + frac_y = (yfrac >> 16) * height; + uint32_t x0 = frac_x >> 16; + uint32_t y0 = frac_y >> 16; + uint32_t x1 = (((xfrac + xone) >> 16) * width) >> 16; + uint32_t y1 = (((yfrac + yone) >> 16) * height) >> 16; + p00 = source[y0 + x0 * height]; + p01 = source[y1 + x0 * height]; + p10 = source[y0 + x1 * height]; + p11 = source[y1 + x1 * height]; } - uint32_t xxshift = (32 - xxbits); - uint32_t yyshift = (32 - yybits); - uint32_t xxmask = (1 << xxshift) - 1; - uint32_t yymask = (1 << yyshift) - 1; - uint32_t x = xfrac >> xxbits; - uint32_t y = yfrac >> yybits; - - uint32_t p00 = source[((y & yymask) + ((x & xxmask) << yyshift))]; - uint32_t p01 = source[(((y + 1) & yymask) + ((x & xxmask) << yyshift))]; - uint32_t p10 = source[((y & yymask) + (((x + 1) & xxmask) << yyshift))]; - uint32_t p11 = source[(((y + 1) & yymask) + (((x + 1) & xxmask) << yyshift))]; - - uint32_t inv_b = (xfrac >> (xxbits - 4)) & 15; - uint32_t inv_a = (yfrac >> (yybits - 4)) & 15; + uint32_t inv_b = (frac_x >> 12) & 15; + uint32_t inv_a = (frac_y >> 12) & 15; uint32_t a = 16 - inv_a; uint32_t b = 16 - inv_b; diff --git a/src/swrenderer/drawers/r_draw_span32_sse2.h b/src/swrenderer/drawers/r_draw_span32_sse2.h index 8a4e28608a..8d7cc28c47 100644 --- a/src/swrenderer/drawers/r_draw_span32_sse2.h +++ b/src/swrenderer/drawers/r_draw_span32_sse2.h @@ -61,15 +61,14 @@ namespace swrenderer struct TextureData { - uint32_t xbits; - uint32_t ybits; + uint32_t width; + uint32_t height; + uint32_t xone; + uint32_t yone; uint32_t xstep; uint32_t ystep; uint32_t xfrac; uint32_t yfrac; - uint32_t yshift; - uint32_t xshift; - uint32_t xmask; const uint32_t *source; }; @@ -80,8 +79,8 @@ namespace swrenderer if (thread->line_skipped_by_thread(args.DestY())) return; TextureData texdata; - texdata.xbits = args.TextureWidthBits(); - texdata.ybits = args.TextureHeightBits(); + texdata.width = args.TextureWidth(); + texdata.height = args.TextureHeight(); texdata.xstep = args.TextureUStep(); texdata.ystep = args.TextureVStep(); texdata.xfrac = args.TextureUPos(); @@ -98,22 +97,21 @@ namespace swrenderer int level = (int)lod; while (level > 0) { - if (texdata.xbits <= 2 || texdata.ybits <= 2) + if (texdata.width <= 2 || texdata.height <= 2) break; - texdata.source += (1 << (texdata.xbits)) * (1 << (texdata.ybits)); - texdata.xbits -= 1; - texdata.ybits -= 1; + texdata.source += texdata.width * texdata.height; + texdata.width = MAX(texdata.width / 2, 1); + texdata.height = MAX(texdata.height / 2, 1); level--; } } - texdata.yshift = 32 - texdata.ybits; - texdata.xshift = texdata.yshift - texdata.xbits; - texdata.xmask = ((1 << texdata.xbits) - 1) << texdata.ybits; + texdata.xone = (0x80000000u / texdata.width) << 1; + texdata.yone = (0x80000000u / texdata.height) << 1; bool is_nearest_filter = (magnifying && !r_magfilter) || (!magnifying && !r_minfilter); - bool is_64x64 = texdata.xbits == 6 && texdata.ybits == 6; + bool is_64x64 = texdata.width == 64 && texdata.height == 64; auto shade_constants = args.ColormapConstants(); if (shade_constants.simple_shade) @@ -194,8 +192,8 @@ namespace swrenderer if (FilterModeT::Mode == (int)FilterModes::Linear) { - texdata.xfrac -= 1 << (31 - texdata.xbits); - texdata.yfrac -= 1 << (31 - texdata.ybits); + texdata.xfrac -= texdata.xone / 2; + texdata.yfrac -= texdata.yone / 2; } uint32_t srcalpha = args.SrcAlpha() >> (FRACBITS - 8); @@ -217,11 +215,11 @@ namespace swrenderer } unsigned int ifgcolor[2]; - ifgcolor[0] = Sample(texdata.xbits, texdata.ybits, texdata.xstep, texdata.ystep, texdata.xfrac, texdata.yfrac, texdata.yshift, texdata.xshift, texdata.xmask, texdata.source); + ifgcolor[0] = Sample(texdata.width, texdata.height, texdata.xone, texdata.yone, texdata.xstep, texdata.ystep, texdata.xfrac, texdata.yfrac, texdata.source); texdata.xfrac += texdata.xstep; texdata.yfrac += texdata.ystep; - ifgcolor[1] = Sample(texdata.xbits, texdata.ybits, texdata.xstep, texdata.ystep, texdata.xfrac, texdata.yfrac, texdata.yshift, texdata.xshift, texdata.xmask, texdata.source); + ifgcolor[1] = Sample(texdata.width, texdata.height, texdata.xone, texdata.yone, texdata.xstep, texdata.ystep, texdata.xfrac, texdata.yfrac, texdata.source); texdata.xfrac += texdata.xstep; texdata.yfrac += texdata.ystep; @@ -251,7 +249,7 @@ namespace swrenderer // Sample unsigned int ifgcolor[2]; - ifgcolor[0] = Sample(texdata.xbits, texdata.ybits, texdata.xstep, texdata.ystep, texdata.xfrac, texdata.yfrac, texdata.yshift, texdata.xshift, texdata.xmask, texdata.source); + ifgcolor[0] = Sample(texdata.width, texdata.height, texdata.xone, texdata.yone, texdata.xstep, texdata.ystep, texdata.xfrac, texdata.yfrac, texdata.source); ifgcolor[1] = 0; __m128i fgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)ifgcolor), _mm_setzero_si128()); @@ -265,7 +263,7 @@ namespace swrenderer } template - FORCEINLINE unsigned int VECTORCALL Sample(uint32_t xbits, uint32_t ybits, uint32_t xstep, uint32_t ystep, uint32_t xfrac, uint32_t yfrac, uint32_t yshift, uint32_t xshift, uint32_t xmask, const uint32_t *source) + FORCEINLINE unsigned int VECTORCALL Sample(uint32_t width, uint32_t height, uint32_t xone, uint32_t yone, uint32_t xstep, uint32_t ystep, uint32_t xfrac, uint32_t yfrac, const uint32_t *source) { using namespace DrawSpan32TModes; @@ -276,37 +274,44 @@ namespace swrenderer } else if (FilterModeT::Mode == (int)FilterModes::Nearest) { - int sample_index = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + uint32_t x = ((xfrac >> 16) * width) >> 16; + uint32_t y = ((yfrac >> 16) * height) >> 16; + int sample_index = x * height + y; return source[sample_index]; } else { - uint32_t xxbits, yybits; + uint32_t p00, p01, p10, p11; + uint32_t frac_x, frac_y; if (TextureSizeT::Mode == (int)SpanTextureSize::Size64x64) { - xxbits = 26; - yybits = 26; + frac_x = xfrac >> 16 << 6; + frac_y = yfrac >> 16 << 6; + uint32_t x0 = frac_x >> 16; + uint32_t y0 = frac_y >> 16; + uint32_t x1 = (x0 + 1) & 0x3f; + uint32_t y1 = (y0 + 1) & 0x3f; + p00 = source[(y0 + (x0 << 6))]; + p01 = source[(y1 + (x0 << 6))]; + p10 = source[(y0 + (x1 << 6))]; + p11 = source[(y1 + (x1 << 6))]; } else { - xxbits = 32 - xbits; - yybits = 32 - ybits; + frac_x = (xfrac >> 16) * width; + frac_y = (yfrac >> 16) * height; + uint32_t x0 = frac_x >> 16; + uint32_t y0 = frac_y >> 16; + uint32_t x1 = (((xfrac + xone) >> 16) * width) >> 16; + uint32_t y1 = (((yfrac + yone) >> 16) * height) >> 16; + p00 = source[y0 + x0 * height]; + p01 = source[y1 + x0 * height]; + p10 = source[y0 + x1 * height]; + p11 = source[y1 + x1 * height]; } - uint32_t xxshift = (32 - xxbits); - uint32_t yyshift = (32 - yybits); - uint32_t xxmask = (1 << xxshift) - 1; - uint32_t yymask = (1 << yyshift) - 1; - uint32_t x = xfrac >> xxbits; - uint32_t y = yfrac >> yybits; - - uint32_t p00 = source[((y & yymask) + ((x & xxmask) << yyshift))]; - uint32_t p01 = source[(((y + 1) & yymask) + ((x & xxmask) << yyshift))]; - uint32_t p10 = source[((y & yymask) + (((x + 1) & xxmask) << yyshift))]; - uint32_t p11 = source[(((y + 1) & yymask) + (((x + 1) & xxmask) << yyshift))]; - - uint32_t inv_b = (xfrac >> (xxbits - 4)) & 15; - uint32_t inv_a = (yfrac >> (yybits - 4)) & 15; + uint32_t inv_b = (frac_x >> 12) & 15; + uint32_t inv_a = (frac_y >> 12) & 15; uint32_t a = 16 - inv_a; uint32_t b = 16 - inv_b; diff --git a/src/swrenderer/plane/r_flatplane.cpp b/src/swrenderer/plane/r_flatplane.cpp index bbc6f2871a..be0546d7f6 100644 --- a/src/swrenderer/plane/r_flatplane.cpp +++ b/src/swrenderer/plane/r_flatplane.cpp @@ -171,27 +171,11 @@ namespace swrenderer double distance = viewport->PlaneDepth(y, planeheight); - if (drawerargs.TextureWidthBits() != 0) - { - drawerargs.SetTextureUStep(xs_ToFixed(32 - drawerargs.TextureWidthBits(), distance * xstepscale)); - drawerargs.SetTextureUPos(xs_ToFixed(32 - drawerargs.TextureWidthBits(), distance * curxfrac + pviewx)); - } - else - { - drawerargs.SetTextureUStep(0); - drawerargs.SetTextureUPos(0); - } + drawerargs.SetTextureUStep(distance * xstepscale / drawerargs.TextureWidth()); + drawerargs.SetTextureUPos((distance * curxfrac + pviewx) / drawerargs.TextureWidth()); - if (drawerargs.TextureHeightBits() != 0) - { - drawerargs.SetTextureVStep(xs_ToFixed(32 - drawerargs.TextureHeightBits(), distance * ystepscale)); - drawerargs.SetTextureVPos(xs_ToFixed(32 - drawerargs.TextureHeightBits(), distance * curyfrac + pviewy)); - } - else - { - drawerargs.SetTextureVStep(0); - drawerargs.SetTextureVPos(0); - } + drawerargs.SetTextureVStep(distance * ystepscale / drawerargs.TextureHeight()); + drawerargs.SetTextureVPos((distance * curyfrac + pviewy) / drawerargs.TextureHeight()); if (viewport->RenderTarget->IsBgra()) { diff --git a/src/swrenderer/r_swcanvas.cpp b/src/swrenderer/r_swcanvas.cpp index 1c29fca45e..087d0ca87c 100644 --- a/src/swrenderer/r_swcanvas.cpp +++ b/src/swrenderer/r_swcanvas.cpp @@ -285,26 +285,12 @@ void SWCanvas::FillSimplePoly(DCanvas *canvas, FTexture *tex, FVector2 *points, drawerargs.SetLight(colormap, 0, clamp(shade >> FRACBITS, 0, NUMCOLORMAPS - 1)); else drawerargs.SetLight(&identitycolormap, 0, 0); - if (drawerargs.TextureWidthBits() != 0) - { - scalex = double(1u << (32 - drawerargs.TextureWidthBits())) / scalex; - drawerargs.SetTextureUStep(xs_RoundToInt(cosrot * scalex)); - } - else - { // Texture is one pixel wide. - scalex = 0; - drawerargs.SetTextureUStep(0); - } - if (drawerargs.TextureHeightBits() != 0) - { - scaley = double(1u << (32 - drawerargs.TextureHeightBits())) / scaley; - drawerargs.SetTextureVStep(xs_RoundToInt(sinrot * scaley)); - } - else - { // Texture is one pixel tall. - scaley = 0; - drawerargs.SetTextureVStep(0); - } + + scalex /= drawerargs.TextureWidth(); + scaley /= drawerargs.TextureHeight(); + + drawerargs.SetTextureUStep(cosrot * scalex); + drawerargs.SetTextureVStep(sinrot * scaley); int width = canvas->GetWidth(); @@ -382,8 +368,8 @@ void SWCanvas::FillSimplePoly(DCanvas *canvas, FTexture *tex, FVector2 *points, tex.X = t * cosrot - tex.Y * sinrot; tex.Y = tex.Y * cosrot + t * sinrot; } - drawerargs.SetTextureUPos(xs_RoundToInt(tex.X * scalex)); - drawerargs.SetTextureVPos(xs_RoundToInt(tex.Y * scaley)); + drawerargs.SetTextureUPos(tex.X * scalex); + drawerargs.SetTextureVPos(tex.Y * scaley); drawerargs.DrawSpan(&thread); #endif diff --git a/src/swrenderer/viewport/r_spandrawer.cpp b/src/swrenderer/viewport/r_spandrawer.cpp index fd81d60fd0..245cac2abf 100644 --- a/src/swrenderer/viewport/r_spandrawer.cpp +++ b/src/swrenderer/viewport/r_spandrawer.cpp @@ -34,7 +34,8 @@ namespace swrenderer { thread->PrepareTexture(tex); - tex->GetWidth(); + ds_texwidth = tex->GetWidth(); + ds_texheight = tex->GetHeight(); ds_xbits = tex->WidthBits; ds_ybits = tex->HeightBits; if ((1 << ds_xbits) > tex->GetWidth()) diff --git a/src/swrenderer/viewport/r_spandrawer.h b/src/swrenderer/viewport/r_spandrawer.h index 4cb131b374..2dd9a959aa 100644 --- a/src/swrenderer/viewport/r_spandrawer.h +++ b/src/swrenderer/viewport/r_spandrawer.h @@ -21,10 +21,10 @@ namespace swrenderer void SetDestX2(int x) { ds_x2 = x; } void SetTexture(RenderThread *thread, FTexture *tex); void SetTextureLOD(double lod) { ds_lod = lod; } - void SetTextureUPos(dsfixed_t xfrac) { ds_xfrac = xfrac; } - void SetTextureVPos(dsfixed_t yfrac) { ds_yfrac = yfrac; } - void SetTextureUStep(dsfixed_t xstep) { ds_xstep = xstep; } - void SetTextureVStep(dsfixed_t vstep) { ds_ystep = vstep; } + void SetTextureUPos(double u) { ds_xfrac = (uint32_t)(int64_t)(u * 4294967296.0); } + void SetTextureVPos(double v) { ds_yfrac = (uint32_t)(int64_t)(v * 4294967296.0); } + void SetTextureUStep(double ustep) { ds_xstep = (uint32_t)(int64_t)(ustep * 4294967296.0); } + void SetTextureVStep(double vstep) { ds_ystep = (uint32_t)(int64_t)(vstep * 4294967296.0); } void SetSolidColor(int colorIndex) { ds_color = colorIndex; } void DrawSpan(RenderThread *thread); @@ -39,11 +39,13 @@ namespace swrenderer int DestY() const { return ds_y; } int DestX1() const { return ds_x1; } int DestX2() const { return ds_x2; } - dsfixed_t TextureUPos() const { return ds_xfrac; } - dsfixed_t TextureVPos() const { return ds_yfrac; } - dsfixed_t TextureUStep() const { return ds_xstep; } - dsfixed_t TextureVStep() const { return ds_ystep; } + uint32_t TextureUPos() const { return ds_xfrac; } + uint32_t TextureVPos() const { return ds_yfrac; } + uint32_t TextureUStep() const { return ds_xstep; } + uint32_t TextureVStep() const { return ds_ystep; } int SolidColor() const { return ds_color; } + int TextureWidth() const { return ds_texwidth; } + int TextureHeight() const { return ds_texheight; } int TextureWidthBits() const { return ds_xbits; } int TextureHeightBits() const { return ds_ybits; } const uint8_t *TexturePixels() const { return ds_source; } @@ -64,14 +66,16 @@ namespace swrenderer int ds_y; int ds_x1; int ds_x2; + int ds_texwidth; + int ds_texheight; int ds_xbits; int ds_ybits; const uint8_t *ds_source; bool ds_source_mipmapped; - dsfixed_t ds_xfrac; - dsfixed_t ds_yfrac; - dsfixed_t ds_xstep; - dsfixed_t ds_ystep; + uint32_t ds_xfrac; + uint32_t ds_yfrac; + uint32_t ds_xstep; + uint32_t ds_ystep; uint32_t *dc_srcblend; uint32_t *dc_destblend; fixed_t dc_srcalpha;