@@ -142,15 +142,15 @@ int CalculateMipmapCount(bool forceAutoCount = false) {
142142 return mipmapCount ;
143143 }
144144
145- Vector2Int CalculateMipmapDimensions ( int mipmapLevel ) {
145+ int2 CalculateMipmapDimensions ( int mipmapLevel ) {
146146 // Base level
147147 if ( mipmapLevel == 0 ) {
148- return new Vector2Int ( _width , _height ) ;
148+ return int2 ( _width , _height ) ;
149149 } else {
150150 var mipmapFactor = Mathf . Pow ( 2f , - mipmapLevel ) ;
151151 var mipmapWidth = Mathf . Max ( 1 , Mathf . FloorToInt ( mipmapFactor * _width ) ) ;
152152 var mipmapHeight = Mathf . Max ( 1 , Mathf . FloorToInt ( mipmapFactor * _height ) ) ;
153- return new Vector2Int ( mipmapWidth , mipmapHeight ) ;
153+ return int2 ( mipmapWidth , mipmapHeight ) ;
154154 }
155155 }
156156
@@ -213,36 +213,26 @@ void ProcessRawTextureData(NativeArray<byte> rawTextureView, int mipmapCount) {
213213 var mipmapSlice = new NativeSlice < byte > ( rawTextureView , 0 , _pixelSize * mipmapSize ) ;
214214 var mipmapIndex = _pixelSize * mipmapSize ;
215215
216- _finalJob = _textureFormat == TextureFormat . RGBA32 ?
217- new SwapGBRA32ToRGBA32Job {
218- mipmapSlice = mipmapSlice
219- } . Schedule ( mipmapSize , 8192 ) :
220- new SwapGBR24ToRGB24Job {
221- mipmapSlice = mipmapSlice
222- } . Schedule ( mipmapSize , 8192 ) ;
216+ _finalJob = new BGRToRGBJob {
217+ textureData = mipmapSlice ,
218+ processFunction = _textureFormat == TextureFormat . RGBA32 ?
219+ BGRToRGBJob . BGRA32ToRGBA32FP : BGRToRGBJob . BGR24ToRGB24FP
220+ } . Schedule ( mipmapSize , 8192 ) ;
223221
224222 for ( int mipmapLevel = 1 ; mipmapLevel < mipmapCount ; mipmapLevel ++ ) {
225223 var nextMipmapDimensions = CalculateMipmapDimensions ( mipmapLevel ) ;
226224 mipmapSize = nextMipmapDimensions . x * nextMipmapDimensions . y ;
227225 var nextMipmapSlice = new NativeSlice < byte > ( rawTextureView , mipmapIndex , _pixelSize * mipmapSize ) ;
228226 mipmapIndex += _pixelSize * mipmapSize ;
229- _finalJob = _textureFormat == TextureFormat . RGBA32 ?
230- new FilterMipmapRGBA32Job {
231- inputWidth = mipmapDimensions . x ,
232- inputHeight = mipmapDimensions . y ,
233- inputMipmap = mipmapSlice . SliceConvert < uint > ( ) ,
234- outputWidth = nextMipmapDimensions . x ,
235- outputHeight = nextMipmapDimensions . y ,
236- outputMipmap = nextMipmapSlice . SliceConvert < uint > ( ) ,
237- } . Schedule ( mipmapSize , 1024 , _finalJob ) :
238- new FilterMipmapRGB24Job {
239- inputWidth = mipmapDimensions . x ,
240- inputHeight = mipmapDimensions . y ,
241- inputMipmap = mipmapSlice ,
242- outputWidth = nextMipmapDimensions . x ,
243- outputHeight = nextMipmapDimensions . y ,
244- outputMipmap = nextMipmapSlice ,
245- } . Schedule ( mipmapSize , 1024 , _finalJob ) ;
227+
228+ _finalJob = new FilterMipmapJob {
229+ inputMipmap = mipmapSlice ,
230+ inputDimensions = mipmapDimensions ,
231+ outputMipmap = nextMipmapSlice ,
232+ outputDimensions = nextMipmapDimensions ,
233+ processFunction = _textureFormat == TextureFormat . RGBA32 ?
234+ FilterMipmapJob . FilterMipmapRGBA32FP : FilterMipmapJob . FilterMipmapRGB24FP
235+ } . Schedule ( mipmapSize , 1024 , _finalJob ) ;
246236
247237 mipmapDimensions = nextMipmapDimensions ;
248238 mipmapSlice = nextMipmapSlice ;
@@ -251,98 +241,97 @@ void ProcessRawTextureData(NativeArray<byte> rawTextureView, int mipmapCount) {
251241 }
252242
253243 [ BurstCompile ( CompileSynchronously = true ) ]
254- struct SwapGBR24ToRGB24Job : IJobParallelFor {
255- [ NativeDisableParallelForRestriction ]
256- public NativeSlice < byte > mipmapSlice ;
244+ struct BGRToRGBJob : IJobParallelFor {
245+ public delegate void BGRToRGBDelegate ( ref NativeSlice < byte > textureData , int index ) ;
257246
258- public void Execute ( int index ) {
259- var temp = mipmapSlice [ 3 * index ] ;
260- mipmapSlice [ 3 * index ] = mipmapSlice [ 3 * index + 2 ] ;
261- mipmapSlice [ 3 * index + 2 ] = temp ;
247+ public static readonly FunctionPointer < BGRToRGBDelegate > BGR24ToRGB24FP = BurstCompiler . CompileFunctionPointer < BGRToRGBDelegate > ( BGR24ToRGB24 ) ;
248+ public static readonly FunctionPointer < BGRToRGBDelegate > BGRA32ToRGBA32FP = BurstCompiler . CompileFunctionPointer < BGRToRGBDelegate > ( BGRA32ToRGBA32 ) ;
249+
250+ [ BurstCompile ( CompileSynchronously = true ) ]
251+ static void BGR24ToRGB24 ( ref NativeSlice < byte > textureData , int index ) {
252+ var temp = textureData [ mad ( 3 , index , 0 ) ] ;
253+ textureData [ mad ( 3 , index , 0 ) ] = textureData [ mad ( 3 , index , 2 ) ] ;
254+ textureData [ mad ( 3 , index , 2 ) ] = temp ;
255+ }
256+
257+ [ BurstCompile ( CompileSynchronously = true ) ]
258+ static void BGRA32ToRGBA32 ( ref NativeSlice < byte > textureData , int index ) {
259+ var temp = textureData [ mad ( 4 , index , 0 ) ] ;
260+ textureData [ mad ( 4 , index , 0 ) ] = textureData [ mad ( 4 , index , 2 ) ] ;
261+ textureData [ mad ( 4 , index , 2 ) ] = temp ;
262262 }
263- }
264263
265- [ BurstCompile ( CompileSynchronously = true ) ]
266- struct SwapGBRA32ToRGBA32Job : IJobParallelFor {
267264 [ NativeDisableParallelForRestriction ]
268- public NativeSlice < byte > mipmapSlice ;
265+ public NativeSlice < byte > textureData ;
266+ public FunctionPointer < BGRToRGBDelegate > processFunction ;
269267
270- public void Execute ( int index ) {
271- var temp = mipmapSlice [ 4 * index ] ;
272- mipmapSlice [ 4 * index ] = mipmapSlice [ 4 * index + 2 ] ;
273- mipmapSlice [ 4 * index + 2 ] = temp ;
274- }
268+ public void Execute ( int index ) => processFunction . Invoke ( ref textureData , index ) ;
275269 }
276270
277271 [ BurstCompile ( CompileSynchronously = true ) ]
278- struct FilterMipmapRGB24Job : IJobParallelFor {
279- public int inputWidth ;
280- public int inputHeight ;
281- [ ReadOnly ]
282- public NativeSlice < byte > inputMipmap ;
272+ struct FilterMipmapJob : IJobParallelFor {
273+ public delegate void FilterMipmapDelegate ( ref FilterMipmapJob job , int outputIndex ) ;
283274
284- public int outputWidth ;
285- public int outputHeight ;
286- [ WriteOnly , NativeDisableParallelForRestriction ]
287- public NativeSlice < byte > outputMipmap ;
275+ public static readonly FunctionPointer < FilterMipmapDelegate > FilterMipmapRGB24FP = BurstCompiler . CompileFunctionPointer < FilterMipmapDelegate > ( FilterMipmapRGB24 ) ;
276+ public static readonly FunctionPointer < FilterMipmapDelegate > FilterMipmapRGBA32FP = BurstCompiler . CompileFunctionPointer < FilterMipmapDelegate > ( FilterMipmapRGBA32 ) ;
288277
289- public void Execute ( int index ) {
290- var outputX = index % outputWidth ;
291- var outputY = index / outputWidth ;
278+ [ BurstCompile ( CompileSynchronously = true ) ]
279+ static void FilterMipmapRGB24 ( ref FilterMipmapJob job , int outputIndex ) {
280+ var outputX = outputIndex % job . outputDimensions . x ;
281+ var outputY = outputIndex / job . outputDimensions . x ;
292282 var outputColor = new uint3 ( ) ;
293283
294- for ( var offsetX = 0 ; offsetX < 2 ; offsetX ++ ) {
295- for ( var offsetY = 0 ; offsetY < 2 ; offsetY ++ ) {
296- var inputX = min ( mad ( 2 , outputX , offsetX ) , inputWidth - 1 ) ;
297- var inputY = min ( mad ( 2 , outputY , offsetY ) , inputHeight - 1 ) ;
298- var inputIndex = mad ( inputWidth , inputY , inputX ) ;
299- outputColor . x += ( uint ) inputMipmap [ mad ( 3 , inputIndex , 0 ) ] >> 2 ;
300- outputColor . y += ( uint ) inputMipmap [ mad ( 3 , inputIndex , 1 ) ] >> 2 ;
301- outputColor . z += ( uint ) inputMipmap [ mad ( 3 , inputIndex , 2 ) ] >> 2 ;
284+ for ( var offsetY = 0 ; offsetY < 2 ; offsetY ++ ) {
285+ for ( var offsetX = 0 ; offsetX < 2 ; offsetX ++ ) {
286+ var inputX = min ( mad ( 2 , outputX , offsetX ) , job . inputDimensions . x - 1 ) ;
287+ var inputY = min ( mad ( 2 , outputY , offsetY ) , job . inputDimensions . y - 1 ) ;
288+ var inputIndex = mad ( job . inputDimensions . x , inputY , inputX ) ;
289+ outputColor . x += ( uint ) job . inputMipmap [ mad ( 3 , inputIndex , 0 ) ] >> 2 ;
290+ outputColor . y += ( uint ) job . inputMipmap [ mad ( 3 , inputIndex , 1 ) ] >> 2 ;
291+ outputColor . z += ( uint ) job . inputMipmap [ mad ( 3 , inputIndex , 2 ) ] >> 2 ;
302292 }
303293 }
304294
305- outputMipmap [ mad ( 3 , index , 0 ) ] = ( byte ) outputColor . x ;
306- outputMipmap [ mad ( 3 , index , 1 ) ] = ( byte ) outputColor . y ;
307- outputMipmap [ mad ( 3 , index , 2 ) ] = ( byte ) outputColor . z ;
295+ job . outputMipmap [ mad ( 3 , outputIndex , 0 ) ] = ( byte ) outputColor . x ;
296+ job . outputMipmap [ mad ( 3 , outputIndex , 1 ) ] = ( byte ) outputColor . y ;
297+ job . outputMipmap [ mad ( 3 , outputIndex , 2 ) ] = ( byte ) outputColor . z ;
308298 }
309- }
310299
311- [ BurstCompile ( CompileSynchronously = true ) ]
312- struct FilterMipmapRGBA32Job : IJobParallelFor {
313- public int inputWidth ;
314- public int inputHeight ;
315- [ ReadOnly ]
316- public NativeSlice < uint > inputMipmap ;
317-
318- public int outputWidth ;
319- public int outputHeight ;
320- [ WriteOnly ]
321- public NativeSlice < uint > outputMipmap ;
322-
323- public void Execute ( int index ) {
324- var outputX = index % outputWidth ;
325- var outputY = index / outputWidth ;
300+ [ BurstCompile ( CompileSynchronously = true ) ]
301+ static void FilterMipmapRGBA32 ( ref FilterMipmapJob job , int outputIndex ) {
302+ var outputX = outputIndex % job . outputDimensions . x ;
303+ var outputY = outputIndex / job . outputDimensions . x ;
326304 var outputColor = new uint4 ( ) ;
327305
328- for ( var offsetX = 0 ; offsetX < 2 ; offsetX ++ ) {
329- for ( var offsetY = 0 ; offsetY < 2 ; offsetY ++ ) {
330- var inputX = min ( mad ( 2 , outputX , offsetX ) , inputWidth - 1 ) ;
331- var inputY = min ( mad ( 2 , outputY , offsetY ) , inputHeight - 1 ) ;
332- var inputColor = inputMipmap [ mad ( inputWidth , inputY , inputX ) ] ;
333- outputColor . x += ( inputColor & 0x000000FFu ) >> 2 ;
334- outputColor . y += ( inputColor & 0x0000FF00u ) >> 10 ;
335- outputColor . z += ( inputColor & 0x00FF0000u ) >> 18 ;
336- outputColor . w += ( inputColor & 0xFF000000u ) >> 26 ;
306+ for ( var offsetY = 0 ; offsetY < 2 ; offsetY ++ ) {
307+ for ( var offsetX = 0 ; offsetX < 2 ; offsetX ++ ) {
308+ var inputX = min ( mad ( 2 , outputX , offsetX ) , job . inputDimensions . x - 1 ) ;
309+ var inputY = min ( mad ( 2 , outputY , offsetY ) , job . inputDimensions . y - 1 ) ;
310+ var inputIndex = mad ( job . inputDimensions . x , inputY , inputX ) ;
311+ outputColor . x += ( uint ) job . inputMipmap [ mad ( 4 , inputIndex , 0 ) ] >> 2 ;
312+ outputColor . y += ( uint ) job . inputMipmap [ mad ( 4 , inputIndex , 1 ) ] >> 2 ;
313+ outputColor . z += ( uint ) job . inputMipmap [ mad ( 4 , inputIndex , 2 ) ] >> 2 ;
314+ outputColor . w += ( uint ) job . inputMipmap [ mad ( 4 , inputIndex , 3 ) ] >> 2 ;
337315 }
338316 }
339317
340- outputMipmap [ index ] =
341- ( outputColor . x << 0 ) |
342- ( outputColor . y << 8 ) |
343- ( outputColor . z << 16 ) |
344- ( outputColor . w << 24 ) ;
318+ job . outputMipmap [ mad ( 4 , outputIndex , 0 ) ] = ( byte ) outputColor . x ;
319+ job . outputMipmap [ mad ( 4 , outputIndex , 1 ) ] = ( byte ) outputColor . y ;
320+ job . outputMipmap [ mad ( 4 , outputIndex , 2 ) ] = ( byte ) outputColor . z ;
321+ job . outputMipmap [ mad ( 4 , outputIndex , 3 ) ] = ( byte ) outputColor . w ;
345322 }
323+
324+ [ ReadOnly ]
325+ public NativeSlice < byte > inputMipmap ;
326+ public int2 inputDimensions ;
327+
328+ [ WriteOnly , NativeDisableParallelForRestriction ]
329+ public NativeSlice < byte > outputMipmap ;
330+ public int2 outputDimensions ;
331+
332+ public FunctionPointer < FilterMipmapDelegate > processFunction ;
333+
334+ public void Execute ( int outputIndex ) => processFunction . Invoke ( ref this , outputIndex ) ;
346335 }
347336 }
348337}
0 commit comments