static unsafe void DrawSegments( NativeArray <SegmentData> segments, World *worldLODs, CameraData camera, int screenWidth, int screenHeight, float2 vanishingPointScreenSpace, RayBuffer.Native rayBufferTopDown, RayBuffer.Native rayBufferLeftRight, RayBuffer rayBufferTopDownManaged, RayBuffer rayBufferLeftRightManaged ) { float2 screen = new float2(screenWidth, screenHeight); Profiler.BeginSample("Segment setup overhead"); DrawSegmentRayJob.DrawContext drawContext = new DrawSegmentRayJob.DrawContext { camera = camera, screen = screen, worldLODs = worldLODs }; NativeArray <DrawSegmentRayJob.SegmentContext> segmentContexts = new NativeArray <DrawSegmentRayJob.SegmentContext>(4, Allocator.TempJob, NativeArrayOptions.ClearMemory); DrawSegmentRayJob.SegmentContext *segmentContextPtr = (DrawSegmentRayJob.SegmentContext *)segmentContexts.GetUnsafePtr(); int totalRays = 0; for (int segmentIndex = 0; segmentIndex < segments.Length; segmentIndex++) { DrawSegmentRayJob.SegmentContext *context = segmentContextPtr + segmentIndex; context->segment = segments[segmentIndex]; totalRays += segments[segmentIndex].RayCount; if (segments[segmentIndex].RayCount <= 0) { continue; } context->axisMappedToY = (segmentIndex > 1) ? 0 : 1; context->segmentRayIndexOffset = 0; if (segmentIndex == 1) { context->segmentRayIndexOffset = segments[0].RayCount; } if (segmentIndex == 3) { context->segmentRayIndexOffset = segments[2].RayCount; } int2 nextFreePixel; if (segmentIndex < 2) { context->activeRayBufferFull = rayBufferTopDown; if (segmentIndex == 0) // top segment { nextFreePixel = int2(clamp(Mathf.RoundToInt(vanishingPointScreenSpace.y), 0, screenHeight - 1), screenHeight - 1); } else // bottom segment { nextFreePixel = int2(0, clamp(Mathf.RoundToInt(vanishingPointScreenSpace.y), 0, screenHeight - 1)); } } else { context->activeRayBufferFull = rayBufferLeftRight; if (segmentIndex == 3) // left segment { nextFreePixel = int2(0, clamp(Mathf.RoundToInt(vanishingPointScreenSpace.x), 0, screenWidth - 1)); } else // right segment { nextFreePixel = int2(clamp(Mathf.RoundToInt(vanishingPointScreenSpace.x), 0, screenWidth - 1), screenWidth - 1); } } context->originalNextFreePixelMin = nextFreePixel.x; context->originalNextFreePixelMax = nextFreePixel.y; context->seenPixelCacheLength = (int)ceil(drawContext.screen[context->axisMappedToY]); } Profiler.EndSample(); rayBufferTopDownManaged.Prepare(segments[0].RayCount + segments[1].RayCount); rayBufferLeftRightManaged.Prepare(segments[2].RayCount + segments[3].RayCount); NativeArray <DrawSegmentRayJob.RayContext> rayContext = new NativeArray <DrawSegmentRayJob.RayContext>( totalRays, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <DrawSegmentRayJob.RayDDAContext> rayDDAContext = new NativeArray <DrawSegmentRayJob.RayDDAContext>( totalRays, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeList <DrawSegmentRayJob.RayContinuation> rayContinuations = new NativeList <DrawSegmentRayJob.RayContinuation>( totalRays, Allocator.TempJob); DrawSegmentRayJob.RaySetupJob raySetupJob = new DrawSegmentRayJob.RaySetupJob() { contexts = segmentContexts, rays = rayContext }; DrawSegmentRayJob.DDASetupJob ddaSetupJob = new DrawSegmentRayJob.DDASetupJob() { raysInput = rayContext, raysOutput = rayDDAContext, drawContext = drawContext, }; DrawSegmentRayJob.TraceToFirstColumnJob firstColumnJob = new DrawSegmentRayJob.TraceToFirstColumnJob { drawContext = drawContext, inRays = rayDDAContext, outRays = rayContinuations.AsParallelWriter() }; DrawSegmentRayJob.RenderJob renderJob = new DrawSegmentRayJob.RenderJob { rays = rayContinuations, DrawingContext = drawContext, }; JobHandle setup = raySetupJob.Schedule(totalRays, 64); JobHandle ddaSetup = ddaSetupJob.Schedule(totalRays, 64, setup); JobHandle firstColumn = firstColumnJob.Schedule(totalRays, 4, ddaSetup); JobHandle render = renderJob.Schedule(totalRays, 1, firstColumn); render.Complete(); rayContext.Dispose(); segmentContexts.Dispose(); rayDDAContext.Dispose(); rayContinuations.Dispose(); rayBufferTopDownManaged.UploadCompletes(); rayBufferLeftRightManaged.UploadCompletes(); }