Jump to content

harold

Members
  • Posts

    366
  • Joined

  • Last visited

Posts posted by harold

  1. "Content Aware Resize" is a little effect I've written in a couple of hours that uses Seam Carving to make an image less wide in a way that somewhat respects the content.

    It probably shouldn't really be an effect because it effectively changes the size of the picture, but there is little choice.. so it just leaves some transparent space, which works well enough.

    As you can see in the source, I use an ugly hack to render only once. It's fundamentally impossible to render it in parts - it has to calculate the globally least-energy seam, which means it has to look at the entire image all at once (well the entire selection really, but I had no idea how to do that). Once it knows the seam it could theoretically build the output row by row, I suppose.

    Is there a good way to render just once, preferrably in a way that handles rectangular selections?

    edit: I know the code is lame and I recalculate far too much for every seam, I'll fix that later..

    ContentAwareResize.zip

  2. OpenCL automatically comes with the graphics driver in nvidia's case (very recently only, older drivers offer no support)

    ATI and Intel etc seem to be running behind, wikipedia says ATI has their OpenCL support in beta and that they would supposedly support R700/R800 GPUs and SSE3 capable CPUs

    So that's pretty much a lose.

    Can we still use it in effects though?

  3. :(

    It can fall back to CPU though

    I'm not sure what ATI is doing with OpenCL atm, do their drivers support it already? If I could get my hands on their OpenCL.dll then I could try to make it work

    edit: I don't have an ATI gpu so I couldn't test it, oh well.. btw making an actual effect from this is not very easy - is there an easy way to get the entire render region instead of those small 2pixel-high rectangles?

  4. So we were recently given OpenCL, and nVidia was so nice as to provide both a 32bit and a 64bit version.

    Since GPU programming is cool I made a nice wrapper for it (currently unfinished but (and this is the best part) workable) in C#, and did a couple of tests with it.

    I found out that (on at least my GPU) there is a smallish limit on the output size, which is a shame, but we could of course come up with some clever tiling scheme.

    A 1024x1024 mandelbrot render with 250 max iterations takes approximately 23 milliseconds - depending of course on what part you are looking at and your GPU (GTX260 in my case) etc etc, but 23 milliseconds is so incredibly fast that none of the details really matter here. Copying the result back to normal ram took an other 20 milliseconds which is pretty much instantaneously.

    These kinds of speed won't be beaten by your average CPU.

    Compiling the OpenCL code takes a while, but this only needs to be done once per session.

    The wrapper is written in pure C# and works in both 32bit and 64bit modes (although it currently only supports nvidia GPU's and requires their OpenCL capable drivers), and will be released into the public domain as soon as I feel comfortable with it (ironed out some bugs and added some more functionality etc) for now you can link to the binary in your project (but you really shouldn't as it is not finished) and edit the source as long as you don't make it available (but honestly, what's going to happen if you do it anyway?)

    The reason I'm posting here is that this wrapper may be interesting to plugin writers, at least until Paint.NET exposes something like DirectCompute/OpenCL itself (any plans, Rick?)

    In the mean time you can all get a copy of the temporary wrapper + test project (mandelbrot) here (mediafire) (too big to upload it to the forum)

    And yes, most of the error codes are translated to throw new Exception() which sucks, it is not finished.

    ps: sorry if this is the wrong forum

    small status update: it looks to me like there is a bug in clEnqueueNDRangeKernel when called with a dimension of 2 (haven't tested 3), it throws a division by zero exception seemingly for no reason (I gave it reasonable arguments), so for now I'm cheating and using code like

    int id = get_global_id(0);
    int ix = id % pxwidth;
    int iy = id / pxwidth;

    Which works fine but probably costs some extra time (well that's an extra % and / you normally wouldn't have, and since their argument is not a constant they can not be free)

    It looks like a hack and that's exactly what it is, but until I find out where that odd division by zero is coming from you/I won't be able to use multidimensional kernels.

  5. I tried writing a FileType plugin for it, but I got that darned "WindowsBase version 3.0.0.0" error

    I'll get back to you after I fix that

    edit: Ok here you go, I couldn't find any way to make PDN use this plugin for 32bit BMP's other than giving it a different extension, so you'll have to rename your BMP's to bmpx if you want to open them with this plugin.

    It's not very well tested, but it worked with the 32bit BMP's from visual studio - at least for as much as I tested. It shouldn't work on any other type of bmp.

    Edit: Removed zip. Please post in Plugins section instead.

  6. Well I didn't really expect you to, but I was hoping you might implement something (as in, the pattern) similar, because it's really quite easy to use - just write a LINQ query and it Just Works, all gory details well-hidden, details that could very well be just about multithreading instead of executing on the GPU

    An effect of that type also can't really do anything "bad", it could just operate on the pixels.

  7. Ok I guess I've been unclear then... :(

    I never expected 32bit dll's to be loaded form 64bit processes - it wouldn't even make sense if it were possible.

    The "bug" is that PDN crashes badly - obviously that would made the offending plugin bad and therefore likely banned but it can't hurt to not-crash..

    Of course I'm not blaming it on the GPU stuff or anything - I just want to find a way to use the GPU in 64bit code. I mailed the Brahma programmer to ask if he could make it 64bit compatible but it's a bit early to expect results yet. The reason I brought that up was that maybe such an architecture would help plugin writers if (or when?) there will be GPU support in PDN. Which means later, not now.

  8. yet

    I hope that means it will be :)

    But does "this" refer to "using a 32bit dll as plugin in 64bit mode"? (I'd be surprised if that's possible at all)

    Or to "using the GPU" ? Well I did that already, it's just that it completely fails to work on 64bit and writing a plugin that doesn't work on x64 is just unacceptable for me. The good news (in so far as it's news) is that for complex effects it was very much faster than the CPU version.

    By the way, Rick, maybe you could have a look at Brahma (or even just their intro) someday? It's something like "Linq to GPU". Something comparable to that system would allow plugin writers to write GPU-executed effects without writing any code in HLSL or other shading/GPGPU languages. It translates a LambdaExpression into HLSL - in a way that allows you to use normal C# syntax, variables, and even the functions from System.Math.

  9. Yes.. but it killed my plugin. Does anyone know a way to talk with the GPU in a way that works on both 32bit and 64bit?

    I haven't found any such way yet.

    XNA: no good, 32bit only

    DirectX: both versions available but the API is different so that still leaves you with nothing.

    Tao (OpenGL binding): no good, 32bit only unless you recompile which is just impossible.

    CsGL: same.

    CUDA: the C# bindings don't even work at all as far as I've been able to test.

  10. That it wouldn't work was to be expected.

    Still, should it crash a horrible death?

    I got here trying to code up a mandelbrot effect that would use GPGPU (using Brahma), unfortunately the dependencies are 32bit only.

    This text file was created because Paint.NET crashed.
    Please e-mail this file to crashlog@getpaint.net so we can diagnose and fix the problem.
    
    Application version: Paint.NET v3.36 (Final Release build 3.36.3158.38068)
    Time of crash: 07-02-2009 18:57:01
    Application uptime: 00:00:13.2500000
    OS Version: 5.2.3790.131072 Service Pack 2 Workstation x64
    .NET version: CLR 2.0.50727.3082 x64, FX 2.0 2.0SP1 2.0SP2 3.0 3.0SP1 3.0SP2 3.5 3.5SP1 3.5SP1_Client 
    Processor: 4x "Intel(R) Core(TM)2 Extreme CPU Q6850  @ 3.00GHz" @ ~3333MHz (DEP, SSE, SSE2)
    Physical memory: 4094 MB
    UI DPI: 96.00 dpi (1.00x scale)
    Tablet PC: no
    Updates: true, 02-02-2009
    Locale: pdnr.c: en-US, hklm: en-US, hkcu: en-US, cc: en-GB, cuic: en-US
    Features log: PopulateFonts(), UpdatesState(StartupState), SetTool(PaintDotNet.Tools.PaintBrushTool), UpdatesState(ReadyToCheckState), HM(NullHistoryMemento), ShowDialog(PaintDotNet.ToolsForm), ShowDialog(PaintDotNet.ColorsForm), ShowDialog(PaintDotNet.HistoryForm), ShowDialog(PaintDotNet.LayerForm), ShowDialog(PaintDotNet.MainForm), Menu.Effects, Effect(MandelEffect.EffectPlugin), ShowDialog(MandelEffect.EffectPluginConfigDialog), HM(BitmapHistoryMemento), ShowDialog(PaintDotNet.ProgressDialog)
    Loaded assemblies: 
       mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @ C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\mscorlib.dll
       PaintDotNet, Version=3.36.3158.38068, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.exe
       System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @ C:\WINDOWS\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll
       System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @ C:\WINDOWS\assembly\GAC_MSIL\System\2.0.0.0__b77a5c561934e089\System.dll
       System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @ C:\WINDOWS\assembly\GAC_MSIL\System.Drawing\2.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll
       PaintDotNet.Core, Version=3.36.3158.38063, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.Core.dll
       PaintDotNet.Base, Version=3.36.3158.38062, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.Base.dll
       PaintDotNet.SystemLayer, Version=3.36.3158.38062, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.SystemLayer.dll
       PaintDotNet.Resources, Version=3.36.3158.38063, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.Resources.dll
       PaintDotNet.Data, Version=3.36.3158.38064, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.Data.dll
       PaintDotNet.Effects, Version=3.36.3158.38065, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\PaintDotNet.Effects.dll
       Brahma.DirectX, Version=0.0.3325.31501, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\Effects\Brahma.DirectX.dll
       Brahma, Version=0.0.3325.31501, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\Effects\Brahma.dll
       MandelEffect, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null @ C:\Program Files\Paint.NET\Effects\MandelEffect.dll
       System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @ C:\WINDOWS\assembly\GAC_MSIL\System.Core\3.5.0.0__b77a5c561934e089\System.Core.dll
    
    Exception details:
    System.BadImageFormatException:  is not a valid Win32 application. (Exception from HRESULT: 0x800700C1)
      at Brahma.DirectX.ComputationProvider.DisposeUnmanaged()
      at Brahma.ComputationProviderBase.Dispose(Boolean disposing)
      at Brahma.ComputationProviderBase.Finalize()
    ------------------------------------------------------------------------------
    

  11. So much discussion about what "int x = rect.Left" does lol

    Well let's try to say exactly what it does..

    It tells the C# compiler to emit:

    A slot for a local variable of the type "int32" in the .locals init part of the function

    ldloca.s rectangle //where "rectangle" refers to a local variable slot index at which the current rois is stored

    call instance int32 [system.Drawing]System.Drawing.Rectangle::get_Left() //call the get part of the Left property

    stloc.s num8 //where num8 refers to the local variable slot index for the variable x

    Then what the JIT compiler (or NGEN) does with this is probably along the lines of:

    During the register allocation phase, find that the variable x is:

    case 1: important - it will be held in a register (and might still get some stack space allocated for it, but maybe not?)

    case 2: not so important - it will get a place on the stack (will add 4 to the stack reservation value, possibly affecting alignment so might cause up to 12 extra bytes to be allocated on 64bit)

    The 64bit JIT will probably give different results than the 32bit JIT since it has more available registers and 64bit calling conventions are very different (fastcall by default). NGEN will give different results also, and 64bit NGEN yet other results.

    The get_Left() code is likely to be inlined since it's body is small, thus turning x=rect.Left into something like mov x,rect.x if x is in a register, rect.x refers to a place on the stack. Or 2 mov's if x is not in a register (first into a temporary register). But who knows? I can't test this.

    So. "int x = rect.Left" turned into something quite .. different.

    note: I don't guarantee I made no mistakes. Please correct me - I like to learn :)

  12. Have a look at File and FileStream - and then don't use that, there are easier ways.

    (quick idea)

    You could easily load the image and resize it like so: new Bitmap(new Bitmap("path/to/file"), width, height)

    Then copy the bitmap onto the current layer of course (I wouldn't use unsafe code just yet, do that when you're familiar with it)

    (/quick idea)

×
×
  • Create New...