transfer byte[] to effect

Started by
27 comments, last by begemot 11 years, 11 months ago
I have byte array of image's data (or pointer).
I have effect with pixel shader to fill result texture. I want to work with my image data in pixel shader without unnecessary transformations.
How I can transfer bytes array to my Effect and how I must define it in HLSL program?
I'm using SlimDX and C#.
Help me,please!!!
Advertisement
Usually this kind of thing is done via textures.

A "texture" is essentially (and in somewhat simplified terms) "a handle to video memory area that contains texels for the purpose of sampling filtered image-type data by the gpu".

Typically, hardware supports several texture formats so "unnecessary transforms" are seldom needed. If you are targeting hardware with D3D10 and up, you can also load data from custom structured buffers in the pixel shader (but you have to do your own filtering).

Actual texture objects are usually faster than custom buffers since hardware tends to have dedicated circuits for the specific purpose of taking filtered samples from known common format textures.

Niko Suni

I need to use D3D9..

Now I create texture as

[font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"]new[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"] [/font][/font][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]Texture[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"](device, w[/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"], h[/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"], 1, [/font][/font][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]Usage[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"].Dynamic, [/font][/font][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]Format[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"].A8R8G8B8,[/font][/font][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]Pool[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"].Default);[/font][/font]

[font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"]and then fill it [/font][/font]

[font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"][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"] a_ = t.LockRectangle(0, [/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"].None);[/font][/font][/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"][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"] pitch = (([/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"])a_.Pitch / [/font][/font][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"]sizeof[/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"]ushort[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]));[/font][/font][/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]DataStream[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"] a = a_.Data;[/font][/font][/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"]unsafe[/font][/font][/font][/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"][font="Consolas"][size="2"][font="Consolas"][size="2"]{[/font][/font][/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"]ushort[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]* to = ([/font][/font][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"]ushort[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]*)a.DataPointer;[/font][/font][/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"]ushort[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]* from = ([/font][/font][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"]ushort[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]*)ptr.ToPointer();[/font][/font][/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"][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][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"][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"] i = 0; i < pit; i++)[/font][/font][/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"][font="Consolas"][size="2"][font="Consolas"][size="2"]to[i + j * pitch] = from[i + j * pit];[/font][/font][/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"][font="Consolas"][size="2"][font="Consolas"][size="2"]}[/font][/font][/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"][font="Consolas"][size="2"][font="Consolas"][size="2"]t.UnlockRectangle(0);[/font][/font][/font][/font]

[font="Consolas"][size="2"][font="Consolas"][size="2"] [/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"] [/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"]then I can set it to my effect to texture parameter: effect.SetTexture("Tex",t). [/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"] Is exist any faster way to update texture in effect?[/font][/font]
May be creating parameters are not optimized? or code to fill?
It is faster to perform block copies of the data (CopyMemory or Marshal.Copy) than copying pixel per pixel.

You may also want to use double buffering; keep a pair of textures and update the other when you use the another in rendering the current frame. This helps to prevent stalling (condition where either CPU or GPU waits for access because other side has a resource locked).

Setting effect variables is not particularly slow; internally, when you apply an effect pass, the framework sets the texture for you using IDirect3DDevice9::SetTexture.

If you don't have to lock the texture each frame, then don't lock it each frame :) I assume that you have a video source or something like that here, though.

Niko Suni

It seems to me, that I can not use Marshal.Copy so as pitch of source image not equals texture's pitch at times..
I'm dreaming to remove this copying process..


Yes. I need get and display frames from video file in realtime mode)))
May be, those copying code can be exclude in the following ways:
1. My idea to put bytes to shader/effect
2. Create texture from memory. In this case I have error in code

[font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]Texture[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"].FromMemory(device, imageBytes,widthdef,heightdef,1,[/font][/font][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]Usage[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"].None,[/font][/font][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]Format[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"].A8R8G8B8,[/font][/font][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]Pool[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"].Default,[/font][/font][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]Filter[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"].None,[/font][/font][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]Filter[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"].None,[/font][/font][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"][font="Consolas"][size="2"][color="#2b91af"]Color[/font][/font][/font][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"].White.ToArgb())[/font][/font]
[font="Consolas"][size="2"][font="Consolas"][size="2"][color="#000000"]In what I'm mistake?[/font][/font]

3. Create one - dimension texture and pass it to shader/effect
You can use Marshal.Copy to copy one line at a time. This is still far more efficient than doing byte-per-byte copies.

I believe that Texture.FromMemory expects to find image file contents from the source array, not just the image pixel data.

Niko Suni

Also pay attention to the lock flags. If you don't need to read back the texture, be sure to request write only access and discard behavior.

Niko Suni

One trick that can often be done with video data is to get the pixel shader to do the YUV->RGB conversion. You'll probably want to use three 8-bit textures for this (e.g. D3DFMT_A8). That method has several benefits:

- The GPU can do the conversion much quicker than the CPU.
- You need to upload less data (because U and V are a quarter of the size of Y).
- Saves a fair bit of memory too.

Ideally you would get your video codec to output directly to your texture too, but that's not always so easy.

This topic is closed to new replies.

Advertisement