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
MacKraken
Greg Thomas
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.
Sasco
Tomasz Janczuk - MSFT
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
Golf_Novice
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.
Tony Loton
hstiles
It's only really slow, when you run with debugging. That was not the case in VS2003 though.
Alicia Rose
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.
SHWoo
-Jeremy
Subodh Pai
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);
Lina María Villa
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);
Dan Fisherman
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.
Nahum
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.
JUSTFUN
-Jeremy