I reduced program boot time (when running from within the IDE) from 12 seconds to less than 1 second by re-writing Texture.FromBitmap using unsafe code. For me it was easy because I'm only using 32 bit textures and 32 bit bitmaps. It would be nice to see this function optimized in future releases of the SDK. BTW, Texture.FromStream has the same problem.
-Jeremy

Performance problem with Texture.FromBitmap
drS
-Jeremy
.Net Believer
This one works for me:
texture = new Texture(device, bitmap.Width, bitmap.Height, 1, Usage.Dynamic, Format.A8R8G8B8, Pool.Default);
int pitch;
Microsoft.DirectX.GraphicsStream a = texture.LockRectangle(0, LockFlags.None, out pitch);
System.Drawing.Imaging.BitmapData bd = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
unsafe
{
byte* to = (byte*) a.InternalDataPointer;
byte* from = (byte*) bd.Scan0.ToPointer();
for (int y = 0; y < bd.Height; ++y)
for (int x = 0; x < bd.Width * 4; ++x)
to[pitch * y + x] = from[y * bd.Stride + x];
}
texture.UnlockRectangle(0);
bitmap.UnlockBits(bd);
DBurke
The bug
http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx feedbackid=0dda86da-a83f-475d-8610-d3a08a14cc7f
now has 2 workarounds added, I've not tried them yet myself.
Branch
texture = new Texture(device, bitmap.Width, bitmap.Height, 1, Usage.Dynamic, Format.A8R8G8B8, Pool.Default);
Microsoft.DirectX.GraphicsStream a = texture.LockRectangle(0, LockFlags.None);
System.Drawing.Imaging.BitmapData bd = bitmapitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
unsafe
{
uint* to = (uint*) a.InternalDataPointer;
uint* from = (uint*) bd.Scan0.ToPointer();
for (int i = 0; i < bd.Height * bd.Width; ++i) to[ i] = from[ i];
}
texture.UnlockRectangle(0);
bitmap.UnlockBits(bd);
Doesn't work for all textures though, but I'm sure somebody around here can correct that.
tchen
Trying_another_name
MelGrubb
-Jeremy
crazy4sims
It's only really slow, when you run with debugging. That was not the case in VS2003 though.
Muhammad Hashim
From the MDX perspective, Texture from bitmap calls bitmap.GetPixel X*Y times, and as RoKo has shown there is some perf degredation when you run with the debugger attached. But its not an MDX problem directly, we are just seeing the effects.
Noah6782
I actually wrapped System.Drawing.Bitmap in my own class, which caches Width and Height, so I'm never tempted to call those properties more than once.
Elzorro
Mir Mahmood Ali Khan
Here's what I used:
Texture texture = new Texture(dx, bitmap.Width, bitmap.Height, 1,
Usage.AutoGenerateMipMap, Format.A8R8G8B8, Pool.Managed);
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
int pitch;
GraphicsStream textureData = texture.LockRectangle(0, LockFlags.None, out pitch);
Debug.Assert(bitmap.PixelFormat == PixelFormat.Format32bppArgb);
Debug.Assert(sizeof(int) == 4 && (bitmapData.Stride & 3) == 0 && (pitch & 3) == 0);
unsafe
{
int *texturePointer = (int*)textureData.InternalDataPointer;
for (int y = 0; y < bitmap.Height; y++)
{
int *bitmapLinePointer = (int*)bitmapData.Scan0 + y*(bitmapData.Stride/sizeof(int));
int *textureLinePointer = texturePointer + y*(pitch/sizeof(int));
int length = bitmap.Width;
while (--length >= 0)
*textureLinePointer++ = *bitmapLinePointer++;
}
}
bitmap.UnlockBits(bitmapData);
texture.UnlockRectangle(0);
-Melon-
It's essentially the same of course...but mine is much faster, at least in VS2005's debug mode. You're using bitmap.Width and bitmap.Height in a loop. Don't do that, it's just as slow as everything else you can do with the Bitmap. Please don't ask me why.
Scorponok
It was recommended that a bug was raised. If you want to follow this bug, or add your validation or vote then you can find it here:
http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx feedbackid=0dda86da-a83f-475d-8610-d3a08a14cc7f