0

OK, I have a JPG loaded into a WPF Image (I've got a WriteableBitmap which I use as the Image.Source). This JPG is 10,000 x 5,000 pixels. I also have the ability to scale up the image to 200%, so effectively, I'm up to 20,000 x 10,000 pixels, i.e. a 200MP image. For my application, which deals with photographic scans, these sizes are not totally out of the ordinary.

Around my Image, I've got 10 Grids, each of which have an Effect applied. The Effects are compiled as PS 3.0, so should run on the GPU. However, I also have one Effect compiled as PS 2.0, so can only run in software.

Simple thing is, with a 200MP image, my program pretty much stops, it's so slow as to be unusable. The funny thing is, the GPU Effects don't really seem to be any faster than the CPU Effect. I upgraded from my Intel HD 4600 GPU to a GeForce GTX 750 to see if that would help, but again, not really appreciably faster.

The GTX 750 rates about 5 times faster than the Intel 4600 for pixel shading, so I seem to be missing something somewhere.

My CPU is Core i5 4570 @ 3.2GHz. I get that maybe a software shader would run faster on this than on a low-end graphics card, but I'd have thought the GTX 750 should at least be very noticeably faster than the Intel HD 4600.

My GTX 750 has 2GB memory, so can hold a pretty big image in graphics memory, and looking at GPU-Z, it certainly can fill up on opening a big image.

Somewhere along the line though, I feel I'm bottlenecked somewhere. If this graphics card can apply shaders to a 1920x1080 screen 70 frames a second, I'm thinking it should be able to apply shaders to a 20,000 x 10,000 image faster than every minute?

Sorry for the long post, but I wanted to try to articulate exactly what my problem is. Am I missing something? Should I be getting more performance, despite the images being so large?

Thanks

Garry

Code:

sampler2D inputSampler : register(S0);



/// <summary>The gamma correction exponent.</summary>
/// <minValue>0.5</minValue>
/// <maxValue>2</maxValue>
/// <defaultValue>0.8</defaultValue>
float Gamma : register(C3);


float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 c = tex2D(inputSampler, uv);
    c.rgb = pow(c.rgb, Gamma);


    return c;
}
Garry
  • 623
  • 1
  • 7
  • 11
  • We would probably need to see a few things, like the shader code itself and how you are asking it to run on the GPU (are you 100% sure you're on the GPU?) Its hard to help programming questions without code to look at. – Ron Beyer Apr 21 '15 at 01:33
  • Is this happening in Debug or running in normal circumstances? Sometimes the overhead from having the debugger attached can slow down intensive operations. – AllMadHare Apr 21 '15 at 01:52
  • So it is around 40 times slower compared to your peak performance spec of 70 frames/s for something that takes a huge amount of memory and will constantly thrash caches. That is not so bad is it? – Alex Apr 21 '15 at 02:40
  • Thanks for the input guys. OK, Debug vs. Release appears to make no difference. – Garry Apr 21 '15 at 03:27
  • Shader code itself, I've got about 10, but they all run slow, even very simple ones like one I'll paste in below ` sampler2D inputSampler : register(S0); /// The gamma correction exponent. /// 0.5 /// 2 /// 0.8 float Gamma : register(C3); float4 main(float2 uv : TEXCOORD) : COLOR { float4 c = tex2D(inputSampler, uv); c.rgb = pow(c.rgb, Gamma); return c; }` – Garry Apr 21 '15 at 03:29
  • I've put the code into the question, for Alex's comment on performance, yes, I should expect performance to be pretty poor on a 200MP image, but GPU being no better than CPU seems odd, no? For Ron, in terms of being sure it's on GPU, they are PS 3.0 shaders, which as far as I know, *only* run on hardware, and if I render to a bitmap, the effects are gone, which I know is an effect of using hardware shaders, also if I RDP into my desktop, the shaders do not appear either, again, leading me to believe they are indeed definitely in GPU hardware. – Garry Apr 21 '15 at 03:37
  • maybe use Pix (from DirectX SDK) to analyse your shader ? – auburg Apr 21 '15 at 10:40
  • I don't think it's the shader at fault here, I can make a shader which does nothing, just use 'discard', and it's still pretty slow. I think it's because the shader is being run on 200 million pixels or more vs. around 2 million for a regular screen. Really I need to work out how to run the shader only on a section of the image, I can't clip the image, as the shader's behaviour is different based on the size of the image. Really I need the shader to run on the big image, but only on a rect that I specify. – Garry Apr 21 '15 at 11:50
  • So can you create another (smaller) bitmap source from your main image and apply the shader to that ? – auburg Apr 21 '15 at 13:00
  • @auburg, yes, the shaders on images, say, 3000x2000 pixels run in real time, wonderfully fast. Even up to maybe 50MP, they run pretty acceptably. On 100MP, the program is essentially frozen and I have to force exit it. – Garry Apr 22 '15 at 09:18
  • However, say if I want a vignette on a 10000x5000 image, that's going to apply to the corners of that image. If grab a small section of that image, and apply vignette, it'll apply to the corners of the small section, not the overall image. For vignette that I might be able to overcome that, but say for sharpening, maybe not as it depends on sharpening pixels, and that effect looks different to what the user expects if you sharpen what is effectively a zoomed in portion of the image, I've tried it, it looks weird/wrong. – Garry Apr 22 '15 at 09:44

0 Answers0