Clean up indentation / add comments for assembly functions
authorJustin Weiss <justin@justinweiss.com>
Sun, 19 Apr 2020 17:18:54 +0000 (10:18 -0700)
committerJustin Weiss <justin@justinweiss.com>
Mon, 20 Apr 2020 15:14:12 +0000 (08:14 -0700)
plugins/gpu_unai/gpu_inner.h
plugins/gpu_unai/gpu_inner_blend_arm.h
plugins/gpu_unai/gpu_inner_light_arm.h

index 8314790..76479f9 100644 (file)
@@ -357,10 +357,10 @@ static void gpuSpriteSpanFn(u16 *pDst, u32 count, u8* pTxt, u32 u0)
        // Blend func can save an operation if it knows uSrc MSB is unset.
        //  Untextured prims can always skip (source color always comes with MSB=0).
        //  For textured prims, the generic lighting funcs always return it unset. (bonus!)
-  const bool skip_uSrc_mask = MSB_PRESERVED ? (!CF_TEXTMODE) : (!CF_TEXTMODE) || CF_LIGHT;
+       const bool skip_uSrc_mask = MSB_PRESERVED ? (!CF_TEXTMODE) : (!CF_TEXTMODE) || CF_LIGHT;
 
        uint_fast16_t uSrc, uDst, srcMSB;
-  bool should_blend;
+       bool should_blend;
        u32 u0_mask = gpu_unai.TextureWindow[2];
 
        u8 r5, g5, b5;
@@ -402,7 +402,7 @@ static void gpuSpriteSpanFn(u16 *pDst, u32 count, u8* pTxt, u32 u0)
                if (CF_LIGHT)
                        uSrc = gpuLightingTXT(uSrc, r5, g5, b5);
 
-    should_blend = MSB_PRESERVED ? uSrc & 0x8000 : srcMSB;
+               should_blend = MSB_PRESERVED ? uSrc & 0x8000 : srcMSB;
 
                if (CF_BLEND && should_blend)
                        uSrc = gpuBlending<CF_BLENDMODE, skip_uSrc_mask>(uSrc, uDst);
@@ -487,8 +487,8 @@ static void gpuPolySpanFn(const gpu_unai_t &gpu_unai, u16 *pDst, u32 count)
        // Blend func can save an operation if it knows uSrc MSB is unset.
        //  Untextured prims can always skip this (src color MSB is always 0).
        //  For textured prims, the generic lighting funcs always return it unset. (bonus!)
-  const bool skip_uSrc_mask = MSB_PRESERVED ? (!CF_TEXTMODE) : (!CF_TEXTMODE) || CF_LIGHT;
-  bool should_blend;
+       const bool skip_uSrc_mask = MSB_PRESERVED ? (!CF_TEXTMODE) : (!CF_TEXTMODE) || CF_LIGHT;
+       bool should_blend;
 
        u32 bMsk; if (CF_BLITMASK) bMsk = gpu_unai.blit_mask;
 
@@ -653,7 +653,7 @@ endpolynotextgou:
                                                uSrc = gpuLightingTXT(uSrc, r5, g5, b5);
                                }
 
-        should_blend = MSB_PRESERVED ? uSrc & 0x8000 : srcMSB;
+                               should_blend = MSB_PRESERVED ? uSrc & 0x8000 : srcMSB;
                                if (CF_BLEND && should_blend)
                                        uSrc = gpuBlending<CF_BLENDMODE, skip_uSrc_mask>(uSrc, uDst);
                        }
index 5ddbdbb..6413527 100644 (file)
@@ -22,79 +22,80 @@ GPU_INLINE uint_fast16_t gpuBlendingARM(uint_fast16_t uSrc, uint_fast16_t uDst)
        //  http://blargg.8bitalley.com/info/rgb_clamped_add.html
        //  http://blargg.8bitalley.com/info/rgb_clamped_sub.html
 
-  
        uint_fast16_t mix;
 
-  asm ("bic %[uDst], %[uDst], #0x8000" : [uDst] "+r" (uDst));
+       // Clear preserved msb
+       asm ("bic %[uDst], %[uDst], #0x8000" : [uDst] "+r" (uDst));
+
+       if (BLENDMODE == 3) {
+               // Prepare uSrc for blending ((0.25 * uSrc) & (0.25 * mask))
+               asm ("and %[uSrc], %[mask], %[uSrc], lsr #0x2" : [uSrc] "+r" (uSrc) : [mask] "r" (0x1ce7));
+       } else if (!SKIP_USRC_MSB_MASK) {
+               asm ("bic %[uSrc], %[uSrc], #0x8000" : [uSrc] "+r" (uSrc));
+       }
 
-  if (BLENDMODE == 3) {
-    asm ("and %[uSrc], %[mask], %[uSrc], lsr #0x2" : [uSrc] "+r" (uSrc) : [mask] "r" (0x1ce7));
-  } else if (!SKIP_USRC_MSB_MASK) {
-    asm ("bic %[uSrc], %[uSrc], #0x8000" : [uSrc] "+r" (uSrc));
-  }
 
-  
        // 0.5 x Back + 0.5 x Forward
        if (BLENDMODE==0) {
-    // mix = ((uSrc + uDst) - ((uSrc ^ uDst) & 0x0421)) >> 1;
-    asm ("eor %[mix], %[uSrc], %[uDst]\n\t"
-         "and %[mix], %[mix], %[mask]\n\t"
-         "sub %[mix], %[uDst], %[mix]\n\t"
-         "add %[mix], %[uSrc], %[mix]\n\t"
-         "mov %[mix], %[mix], lsr #0x1\n\t"
-         : [mix] "=&r" (mix)
-         : [uSrc] "r" (uSrc), [uDst] "r" (uDst), [mask] "r" (0x0421));
-  }
+               // mix = ((uSrc + uDst) - ((uSrc ^ uDst) & 0x0421)) >> 1;
+               asm ("eor %[mix], %[uSrc], %[uDst]\n\t" // uSrc ^ uDst
+                    "and %[mix], %[mix], %[mask]\n\t"  // ... & 0x0421
+                    "sub %[mix], %[uDst], %[mix]\n\t"  // uDst - ...
+                    "add %[mix], %[uSrc], %[mix]\n\t"  // uSrc + ...
+                    "mov %[mix], %[mix], lsr #0x1\n\t" // ... >> 1
+                    : [mix] "=&r" (mix)
+                    : [uSrc] "r" (uSrc), [uDst] "r" (uDst), [mask] "r" (0x0421));
+       }
 
-  if (BLENDMODE == 1 || BLENDMODE == 3) {
-    // u32 sum      = uSrc + uDst;
+       if (BLENDMODE == 1 || BLENDMODE == 3) {
+               // u32 sum      = uSrc + uDst;
                // u32 low_bits = (uSrc ^ uDst) & 0x0421;
                // u32 carries  = (sum - low_bits) & 0x8420;
                // u32 modulo   = sum - carries;
                // u32 clamp    = carries - (carries >> 5);
                // mix = modulo | clamp;
 
-    u32 sum;
+               u32 sum;
 
-    asm ("add %[sum], %[uSrc], %[uDst]\n\t"
-         "eor %[mix], %[uSrc], %[uDst]\n\t"
-         "and %[mix], %[mix], %[mask]\n\t"
-         "sub %[mix], %[sum], %[mix]\n\t"
-         "and %[mix], %[mix], %[mask], lsl #0x05\n\t"
-         "sub %[sum], %[sum], %[mix] \n\t"
-         "sub %[mix], %[mix], %[mix], lsr #0x05\n\t"
-         "orr %[mix], %[sum], %[mix]"
-         : [sum] "=&r" (sum), [mix] "=&r" (mix)
-         : [uSrc] "r" (uSrc), [uDst] "r" (uDst), [mask] "r" (0x0421));
-  }
+               asm ("add %[sum], %[uSrc], %[uDst]\n\t" // sum = uSrc + uDst
+                    "eor %[mix], %[uSrc], %[uDst]\n\t" // uSrc ^ uDst
+                    "and %[mix], %[mix], %[mask]\n\t"  // low_bits = (... & 0x0421)
+                    "sub %[mix], %[sum], %[mix]\n\t"   // sum - low_bits
+                    "and %[mix], %[mix], %[mask], lsl #0x05\n\t"  // carries = ... & 0x8420
+                    "sub %[sum], %[sum], %[mix] \n\t"  // modulo = sum - carries
+                    "sub %[mix], %[mix], %[mix], lsr #0x05\n\t" // clamp = carries - (carries >> 5)
+                    "orr %[mix], %[sum], %[mix]"       // mix = modulo | clamp
+                    : [sum] "=&r" (sum), [mix] "=&r" (mix)
+                    : [uSrc] "r" (uSrc), [uDst] "r" (uDst), [mask] "r" (0x0421));
+       }
     
        // 1.0 x Back - 1.0 x Forward
        if (BLENDMODE==2) {
-    u32 diff;
-    // u32 diff     = uDst - uSrc + 0x8420;
+               u32 diff;
+               // u32 diff     = uDst - uSrc + 0x8420;
                // u32 low_bits = (uDst ^ uSrc) & 0x8420;
                // u32 borrows  = (diff - low_bits) & 0x8420;
                // u32 modulo   = diff - borrows;
                // u32 clamp    = borrows - (borrows >> 5);
                // mix = modulo & clamp;
-    asm ("sub %[diff], %[uDst], %[uSrc]\n\t"
-         "add %[diff], %[diff], %[mask]\n\t"
-         "eor %[mix], %[uDst], %[uSrc]\n\t"
-         "and %[mix], %[mix], %[mask]\n\t"
-         "sub %[mix], %[diff], %[mix]\n\t"
-         "and %[mix], %[mix], %[mask]\n\t"
-         "sub %[diff], %[diff], %[mix]\n\t"
-         "sub %[mix], %[mix], %[mix], lsr #0x05\n\t"
-         "and %[mix], %[diff], %[mix]"
-         : [diff] "=&r" (diff), [mix] "=&r" (mix)
-         : [uSrc] "r" (uSrc), [uDst] "r" (uDst), [mask] "r" (0x8420));
+               asm ("sub %[diff], %[uDst], %[uSrc]\n\t"  // uDst - uSrc
+                    "add %[diff], %[diff], %[mask]\n\t"  // diff = ... + 0x8420
+                    "eor %[mix], %[uDst], %[uSrc]\n\t"   // uDst ^ uSrc
+                    "and %[mix], %[mix], %[mask]\n\t"    // low_bits = ... & 0x8420
+                    "sub %[mix], %[diff], %[mix]\n\t"    // diff - low_bits
+                    "and %[mix], %[mix], %[mask]\n\t"    // borrows = ... & 0x8420
+                    "sub %[diff], %[diff], %[mix]\n\t"   // modulo = diff - borrows
+                    "sub %[mix], %[mix], %[mix], lsr #0x05\n\t"  // clamp = borrows - (borrows >> 5)
+                    "and %[mix], %[diff], %[mix]"        // mix = modulo & clamp
+                    : [diff] "=&r" (diff), [mix] "=&r" (mix)
+                    : [uSrc] "r" (uSrc), [uDst] "r" (uDst), [mask] "r" (0x8420));
        }
 
-  // There's not a case where we can get into this function,
-  // SKIP_USRC_MSB_MASK is false, and the msb of uSrc is unset.
-  if (!SKIP_USRC_MSB_MASK) {
-    asm ("orr %[mix], %[mix], #0x8000" : [mix] "+r" (mix));
-  }
+       // There's not a case where we can get into this function,
+       // SKIP_USRC_MSB_MASK is false, and the msb of uSrc is unset.
+       if (!SKIP_USRC_MSB_MASK) {
+               asm ("orr %[mix], %[mix], #0x8000" : [mix] "+r" (mix));
+       }
   
        return mix;
 }
index a1c3628..7bd5890 100644 (file)
 ////////////////////////////////////////////////////////////////////////////////
 GPU_INLINE uint_fast16_t gpuLightingRGBARM(u32 gCol)
 {
-  uint_fast16_t out = 0x03E0; // don't need the mask after starting to write output
-  u32 tmp;
+       uint_fast16_t out = 0x03E0; // don't need the mask after starting to write output
+       u32 tmp;
   
-  asm ("and %[tmp], %[gCol], %[out]\n\t"              // tmp holds 0x000000bbbbb00000
-       "and %[out], %[out],  %[gCol], lsr #0x0B\n\t"  // out holds 0x000000ggggg00000
-       "orr %[tmp], %[out],  %[tmp],  lsl #0x05\n\t"  // tmp holds 0x0bbbbbggggg00000
-       "orr %[out], %[tmp],  %[gCol], lsr #0x1B\n\t"  // out holds 0x0bbbbbgggggrrrrr
-       : [out] "+&r" (out), [tmp] "=&r" (tmp)
-       : [gCol] "r"  (gCol)
-  );
+       asm ("and %[tmp], %[gCol], %[out]\n\t"              // tmp holds 0x000000bbbbb00000
+            "and %[out], %[out],  %[gCol], lsr #0x0B\n\t"  // out holds 0x000000ggggg00000
+            "orr %[tmp], %[out],  %[tmp],  lsl #0x05\n\t"  // tmp holds 0x0bbbbbggggg00000
+            "orr %[out], %[tmp],  %[gCol], lsr #0x1B\n\t"  // out holds 0x0bbbbbgggggrrrrr
+            : [out] "+&r" (out), [tmp] "=&r" (tmp)
+            : [gCol] "r"  (gCol)
+            );
 
-  return out;
+       return out;
 }
 
-
+////////////////////////////////////////////////////////////////////////////////
+// Apply fast (low-precision) 5-bit lighting to bgr555 texture color:
+//
+// INPUT:
+//       'r5','g5','b5' are unsigned 5-bit color values, value of 15
+//         is midpoint that doesn't modify that component of texture
+//       'uSrc' input:  mbbbbbgggggrrrrr
+//                      ^ bit 16
+// RETURNS:
+//         u16 output:  mbbbbbgggggrrrrr
+// Where 'X' are fixed-pt bits.
+////////////////////////////////////////////////////////////////////////////////
 GPU_INLINE uint_fast16_t gpuLightingTXTARM(uint_fast16_t uSrc, u8 r5, u8 g5, u8 b5)
 {
-  uint_fast16_t out = 0x03E0;
-  u32 db, dg;
-  asm ("and    %[dg],  %[out],  %[src]  \n\t"
-       "orr    %[dg],  %[dg],   %[g5]   \n\t"
-       "and    %[db],  %[out],  %[src], lsr #0x05 \n\t"
-       "ldrb   %[dg],  [%[lut], %[dg]]  \n\t" 
-       "and    %[out], %[out],  %[src], lsl #0x05 \n\t"
-       "orr    %[out], %[out],  %[r5]   \n\t"
-       "orr    %[db],  %[db],   %[b5]   \n\t"
-       "ldrb   %[out], [%[lut], %[out]] \n\t"
-       "ldrb   %[db],  [%[lut], %[db]]  \n\t"
-       "tst    %[src], #0x8000\n\t"
-       "orr    %[out], %[out],  %[dg],  lsl #0x05   \n\t"
-       "orrne  %[out], %[out],  #0x8000\n\t"
-       "orr    %[out], %[out],  %[db],  lsl #0x0A   \n\t"
-    : [out] "=&r" (out), [db] "=&r" (db), [dg] "=&r" (dg)
-    : [r5] "r" (r5), [g5] "r" (g5),  [b5] "r" (b5),
-      [lut] "r" (gpu_unai.LightLUT), [src] "r" (uSrc), "0" (out)
-    : "cc");
-  return out;
+       uint_fast16_t out = 0x03E0;
+       u32 db, dg;
+
+       // Using `g` for src, `G` for dest
+       asm ("and    %[dg],  %[out],    %[src]  \n\t"             // dg holds 0x000000ggggg00000
+            "orr    %[dg],  %[dg],     %[g5]   \n\t"             // dg holds 0x000000gggggGGGGG
+            "and    %[db],  %[out],    %[src], lsr #0x05 \n\t"   // db holds 0x000000bbbbb00000
+            "ldrb   %[dg],  [%[lut],   %[dg]]  \n\t"             // dg holds result 0x00000000000ggggg
+            "and    %[out], %[out],    %[src], lsl #0x05 \n\t"   // out holds 0x000000rrrrr00000
+            "orr    %[out], %[out],    %[r5]   \n\t"             // out holds 0x000000rrrrrRRRRR
+            "orr    %[db],  %[db],     %[b5]   \n\t"             // db holds 0x000000bbbbbBBBBB
+            "ldrb   %[out], [%[lut],   %[out]] \n\t"             // out holds result 0x00000000000rrrrr
+            "ldrb   %[db],  [%[lut],   %[db]]  \n\t"             // db holds result 0x00000000000bbbbb
+            "tst    %[src], #0x8000\n\t"                         // check whether msb was set on uSrc
+            "orr    %[out], %[out],    %[dg],  lsl #0x05   \n\t" // out holds 0x000000gggggrrrrr
+            "orrne  %[out], %[out],    #0x8000\n\t"              // add msb to out if set on uSrc
+            "orr    %[out], %[out],    %[db],  lsl #0x0A   \n\t" // out holds 0xmbbbbbgggggrrrrr
+            : [out] "=&r" (out), [db] "=&r" (db), [dg] "=&r" (dg)
+            : [r5] "r" (r5), [g5] "r" (g5),  [b5] "r" (b5),
+              [lut] "r" (gpu_unai.LightLUT), [src] "r" (uSrc), "0" (out)
+            : "cc");
+       return out;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Apply fast (low-precision) 5-bit Gouraud lighting to bgr555 texture color:
+//
+// INPUT:
+//  'gCol' is a packed Gouraud u32 fixed-pt 8.3:8.3:8.2 rgb triplet, value of
+//     15.0 is midpoint that does not modify color of texture
+//        gCol input :  rrrrrXXXXXXgggggXXXXXXbbbbbXXXXX
+//                      ^ bit 31
+//       'uSrc' input:  mbbbbbgggggrrrrr
+//                      ^ bit 16
+// RETURNS:
+//         u16 output:  mbbbbbgggggrrrrr
+// Where 'X' are fixed-pt bits, '0' is zero-padding, and '-' is don't care
+////////////////////////////////////////////////////////////////////////////////
 GPU_INLINE uint_fast16_t gpuLightingTXTGouraudARM(uint_fast16_t uSrc, u32 gCol)
 {
-  uint_fast16_t out = 0x03E0; // don't need the mask after starting to write output
-  u32 db,dg,gtmp;
-  asm ("and    %[dg],  %[out],  %[src]   \n\t"
-       "and    %[gtmp],%[out],  %[gCol], lsr #0x0B \n\t"
-       "and    %[db],  %[out],  %[src],  lsr #0x05 \n\t"
-       "orr    %[dg],  %[dg],   %[gtmp], lsr #0x05 \n\t"
-       "and    %[gtmp],%[out],  %[gCol]  \n\t"
-       "ldrb   %[dg],  [%[lut], %[dg]]   \n\t"
-       "and    %[out], %[out],  %[src],  lsl #0x05 \n\t"
-       "orr    %[out], %[out],  %[gCol], lsr #0x1B \n\t"
-       "orr    %[db],  %[db],   %[gtmp], lsr #0x05 \n\t"
-       "ldrb   %[out], [%[lut], %[out]]  \n\t"
-       "ldrb   %[db],  [%[lut], %[db]]   \n\t"
-       "tst    %[src], #0x8000\n\t"
-       "orr    %[out], %[out],  %[dg],   lsl #0x05 \n\t"
-       "orrne  %[out], %[out],  #0x8000\n\t"
-       "orr    %[out], %[out],  %[db],   lsl #0x0A \n\t"
-       : [out] "=&r" (out), [db] "=&r" (db), [dg] "=&r" (dg),
-         [gtmp] "=&r" (gtmp) \
-       : [gCol] "r" (gCol), [lut] "r" (gpu_unai.LightLUT), "0" (out), [src] "r" (uSrc)
-       : "cc");
+       uint_fast16_t out = 0x03E0; // don't need the mask after starting to write output
+       u32 db,dg,gtmp;
+
+       // Using `g` for src, `G` for dest
+       asm ("and    %[dg],  %[out],  %[src]   \n\t"           // dg holds 0x000000ggggg00000
+            "and    %[gtmp],%[out],  %[gCol], lsr #0x0B \n\t" // gtmp holds 0x000000GGGGG00000
+            "and    %[db],  %[out],  %[src],  lsr #0x05 \n\t" // db holds 0x000000bbbbb00000
+            "orr    %[dg],  %[dg],   %[gtmp], lsr #0x05 \n\t" // dg holds 0x000000gggggGGGGG
+            "and    %[gtmp],%[out],  %[gCol]  \n\t"           // gtmp holds 0x000000BBBBB00000
+            "ldrb   %[dg],  [%[lut], %[dg]]   \n\t"           // dg holds result 0x00000000000ggggg
+            "and    %[out], %[out],  %[src],  lsl #0x05 \n\t" // out holds 0x000000rrrrr00000
+            "orr    %[out], %[out],  %[gCol], lsr #0x1B \n\t" // out holds 0x000000rrrrrRRRRR
+            "orr    %[db],  %[db],   %[gtmp], lsr #0x05 \n\t" // db holds 0x000000bbbbbBBBBB
+            "ldrb   %[out], [%[lut], %[out]]  \n\t"           // out holds result 0x00000000000rrrrr
+            "ldrb   %[db],  [%[lut], %[db]]   \n\t"           // db holds result 0x00000000000bbbbb
+            "tst    %[src], #0x8000\n\t"                      // check whether msb was set on uSrc
+            "orr    %[out], %[out],  %[dg],   lsl #0x05 \n\t" // out holds 0x000000gggggrrrrr
+            "orrne  %[out], %[out],  #0x8000\n\t"             // add msb to out if set on uSrc
+            "orr    %[out], %[out],  %[db],   lsl #0x0A \n\t" // out holds 0xmbbbbbgggggrrrrr
+            : [out] "=&r" (out), [db] "=&r" (db), [dg] "=&r" (dg),
+              [gtmp] "=&r" (gtmp) \
+            : [gCol] "r" (gCol), [lut] "r" (gpu_unai.LightLUT), "0" (out), [src] "r" (uSrc)
+            : "cc");
 
-  return out;
+       return out;
 }
 
 #endif  //_OP_LIGHT_ARM_H_