transfer byte[] to effect

Started by
27 comments, last by begemot 11 years, 11 months ago
It is also possible that the hardware supports YUV texture formats natively. You will want to check this at runtime, though.

Niko Suni

Advertisement
Which of ways of creating texture you suppose is the fastest?

Texture.FromMemory
Texture.FromStream
new Texture() and copy data
It varies based on system architecture, and the source of the stream in FromStream (and a number of other things). A stream could be a disk file or a network socket, which are generally way slower than a local memory buffer.

FromMemory and FromStream differ from your third method in that they read and decode whole image file contents whereas in manual copying, you generally only handle the actual pixel data.

You are not supposed to create new textures each frame anyway; if you use a texture in more than one frame (which is very, very common), you allocate it outside the render loop when you initialize your objects and update it as needed.

Niko Suni

You might also want to look at Suface.FromMemory() which will do all the copying for you from a byte[] array.
I tested creating texture from memory using Texture.FromMemory () (Nik02 was right in data format - it must contain BITMAPINFOHEADER),but it is very slow..
Now I do CopyMemory -this way a little bit faster when unsafe copying.

Working with video memory throw surfaces is faster then throw textures?
Texture.FromMemory allocates a new texture each time. Allocations are always much slower than updates.

A surface is a block of video memory. A texture is a collection of 1...n surfaces. If you are updating one level of a texture, you are effectively updating a surface.

Niko Suni

But I don't understand how I pass my surface to shader..
I can create texture, Get surface as
[font="Consolas"][size="2"][font="Consolas"][size="2"]Texture.GetSurfaceLevel(0)[/font][/font],
[font="Consolas"][size="2"][font="Consolas"][size="2"]update surface using line per line CopyMemory and pass to shader texture. Is it right?[/font][/font]
You pass textures to the shader.

You can create a texture with only one surface, by setting the mipLevels field of the texture descriptor to 1.

Niko Suni

I have texture and can do next operation

[font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"]using[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"] ([/font][/font][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]Surface[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"] surface = t.GetSurfaceLevel(0))[/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"]{[/font][/font]
[font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]DataRectangle[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"] dr = surface.LockRectangle([/font][/font][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]LockFlags[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"].Discard);[/font][/font]
[font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"]int[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"] d_pit = dr.Pitch;[/font][/font]
[font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"]for[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"] ([/font][/font][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"]int[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"] j = 0; j < heightdef; j++)[/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"]CopyMemory(dr.Data.DataPointer.ToInt32() + j*d_pit,[/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]ptr.ToInt32() + [/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]j*pit,[/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]d_pit);[/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"]surface.UnlockRectangle();[/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"]}[/font][/font]

[font="Consolas"][size="2"][font="Consolas"][size="2"]then I pass it to shader.[/font][/font]

[font="Consolas"][size="2"][font="Consolas"][size="2"]Is it the fastest way? [/font][/font]
In general, line by line copy is the fastest robust method with which you can copy stuff to surfaces. To optimize, you could check whether the destination pitch equals width*number of bytes per pixel, and if it happens to be the same, copy all the data in one call. If not, just copy line per line like you do now.

The texture usage flags and lock flags are very important for performance. Discard is often the desired behavior, when you want to overwrite the entire destination data.

I previously mentioned double buffering; have you tried it?

And finally, have you profiled your application? Do you have actual knowledge of where your performance bottleneck is?

Niko Suni

This topic is closed to new replies.

Advertisement