internal CPUFractalEngine(CPUDeviceEntry devEntry) { int fractalSize, branchesSize, variWeightsSize; Fractal.GetNativeFractalSizes(out fractalSize, out branchesSize, out variWeightsSize); //these are allocated from unmanaged memory so we don't have to worry about pinning them all the time fractal = (NativeFractal *)Marshal.AllocHGlobal(fractalSize); branches = (NativeBranch *)Marshal.AllocHGlobal(branchesSize); variWeights = (float *)Marshal.AllocHGlobal(variWeightsSize); int iterCount = Util.Clamp(2 * devEntry.NumCores, 2, MaxUseableIterators); iterators = new Iterator[iterCount]; int dotBufferSize = Marshal.SizeOf(typeof(Dot)) * DotsPerCycle; dots = (Dot *)Marshal.AllocHGlobal(dotBufferSize); int dotIndiciesSize = Marshal.SizeOf(typeof(ushort)) * DotsPerCycle; dotIndicies = (ushort *)Marshal.AllocHGlobal(dotIndiciesSize); for (int i = 0; i < DotsPerCycle; i++) { dotIndicies[i] = (ushort)i; } for (int i = 0; i < IteratorCount; i++) { iterators[i] = new Iterator(i); iterators[i].SetFractal(this.fractal, branches, variWeights); iterators[i].SetOutput(dots); } globalStats = new NativeGlobalStatEntry(); tonemapVertShader = GLUtil.MakeShader("tonemap_vert_glsl", Kernels.KernelResources.tonemap_vert_glsl, ShaderType.VertexShader); tonemapFragShader = GLUtil.MakeShader("tonemap_frag_glsl", Kernels.KernelResources.tonemap_frag_glsl, ShaderType.FragmentShader); tonemapProgram = GLUtil.MakeProgram("tonemap_program", tonemapVertShader, tonemapFragShader); accumSamplerLocation = GL.GetUniformLocation(tonemapProgram, "accumSampler"); scaleConstantLocation = GL.GetUniformLocation(tonemapProgram, "scaleConstant"); brightnessLocation = GL.GetUniformLocation(tonemapProgram, "brightness"); invGammaLocation = GL.GetUniformLocation(tonemapProgram, "invGamma"); vibrancyLocation = GL.GetUniformLocation(tonemapProgram, "vibrancy"); upScaleFactorLocation = GL.GetUniformLocation(tonemapProgram, "upScaleFactor"); subStepXLocation = GL.GetUniformLocation(tonemapProgram, "subStepX"); subStepYLocation = GL.GetUniformLocation(tonemapProgram, "subStepY"); #if DEBUG FractalManager.Blip += delegate(object obj, EventArgs ea){ iterators[0].GetStuck(); }; #endif }
public override void Destroy() { Deallocate(); foreach (Iterator iter in iterators) { iter.Shutdown(); } if (fractal != null) { Marshal.FreeHGlobal((IntPtr)fractal); fractal = null; } if (branches != null) { Marshal.FreeHGlobal((IntPtr)branches); branches = null; } if (variWeights != null) { Marshal.FreeHGlobal((IntPtr)variWeights); variWeights = null; } if (tonemapVertShader != 0) { GL.DeleteShader(tonemapVertShader); tonemapVertShader = 0; } if (tonemapFragShader != 0) { GL.DeleteShader(tonemapFragShader); tonemapFragShader = 0; } if (tonemapProgram != 0) { GL.DeleteProgram(tonemapProgram); tonemapProgram = 0; } if (paletteTexID != 0) { GL.DeleteTexture(paletteTexID); paletteTexID = 0; } }
unsafe public void FillNativeFractal(int xRes, int yRes, NativeFractal *nFractal, NativeBranch *nBranches, float *nVariWeights) { Int32 branchCount = Math.Min(NativeFractal.MaxBranches, this.Branches.Count); nFractal->BranchCount = (uint)branchCount; float invAspectRatio = (xRes > 0) ? ((float)yRes / (float)xRes) : 0.0f; Affine2D viewTransform = this.CameraTransform.Inverse; Affine2D projTransform = new Affine2D(invAspectRatio, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f); float xHalf = (float)xRes / 2.0f; float yHalf = (float)yRes / 2.0f; Affine2D screenTransform = new Affine2D(xHalf, 0.0f, 0.0f, yHalf, xHalf, yHalf); nFractal->VpsTransform = screenTransform * projTransform * viewTransform; nFractal->Brightness = this.Brightness; nFractal->InvGamma = 1.0f / this.Gamma; nFractal->Vibrancy = this.Vibrancy; nFractal->BgColor = this.BackgroundColor; for (int bi = 0; bi < branchCount; bi++) { nBranches[bi].NormWeight = (UInt32)0x00010000; } float branchWeightSum = 0.0f; for (int bi = 0; bi < branchCount; bi++) { branchWeightSum += this.Branches[bi].Weight; } for (int i = 0; i < NativeFractal.MaxBranches * NativeFractal.MaxVariations; i++) { nVariWeights[i] = 0.0f; } UInt32 runningSum = 0; for (int bi = 0; bi < branchCount; bi++) { Branch branch = this.Branches[bi]; runningSum += (UInt32)(branch.Weight / branchWeightSum * 65536.0f); if (bi < branchCount - 1) { nBranches[bi].NormWeight = runningSum; } else { nBranches[bi].NormWeight = 0x00010000; } nBranches[bi].ColorWeight = branch.ColorWeight; nBranches[bi].Chroma = branch.Chroma; nBranches[bi].PreTransform = branch.PreTransform; nBranches[bi].PostTransform = branch.PostTransform; foreach (Branch.VariEntry ve in branch.Variations) { if (ve.Index >= 0 && ve.Index < NativeFractal.MaxVariations) { nVariWeights[bi * NativeFractal.MaxVariations + ve.Index] += ve.Weight; } } } }
public void SetFractal(NativeFractal *fractal, NativeBranch *branches, float *variWeights) { lock (syncRoot){ set_iterator_fractal(iterHandle, fractal, branches, variWeights); } }
extern private static void set_iterator_fractal(IntPtr iter, NativeFractal *fractal, NativeBranch *branches, float *variWeights);