Advertisement Jump to content
Sign in to follow this  
Sturmh

Increment texture values using render to texture

This topic is 1856 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

As I understand it you cant bind the a texture as a render target and a shaderresource at the same time. How does one typically handle the situation where you want to render to a texture but sample that same texture in the render to texture operation. The reasoning would be if you need to use the previous value in the texture in the new value being written.The only way I could think of was to duplicate your texture and use one as the render target every frame and the other as the resource. Once the render is complete, copy the render target to the resource view.

 

Thought?

 

Share this post


Link to post
Share on other sites
Advertisement

Yes, that is what you do. To be clear, though: you don't have to duplicate the texture, but you do have to have two separate textures. One for the render target and one for the shader resource. That is, you don't have to copy the data from the shader resource to the render target prior to drawing. That would be redundant, obviously, as the rendering operation is going to overwrite everything that is in that render target texture anyway (assuming the viewport that you render into covers the entire render target).

 

EDIT: Also, you probably don't need to have one texture always be the render target and one texture always be the shader resource. A common technique is to "ping-pong" between textures, swapping which texture is the render target and which is the shader resource with each pass. Say you have multiple passes, and two textures TexA and TexB. TexA is your original shader resource. Then in Pass-1 you render using TexA as the shader resource and TexB as the render target. Now TexB has the processed TexA, so you can use TexB as a shader resource. In Pass-2 you use TexB as the shader resource and TexA as the render target. Now TexA has the composite results of Pass1 and Pass2, and can be used as a shader resource again. Pass-3 uses TexA to render into TexB, and so forth.

Edited by Samith

Share this post


Link to post
Share on other sites

Just want to make sure I understand what you are describing so I'll write up a bit of pseudo code.

 

Texture2D texA = CreateTexture();
Texture2D texB = CreateTexture();
RenderTarget texARTV = CreateRenderTarget(texA);
ShaderResource texASRV = CreateShaderResource(texA);
RenderTarget texBRTV = CreateRenderTarget(texB);
ShaderResource texBSRV = CreateShaderResource(texB);


// then when rendering


// pass 1
SetRenderTarget(texARTV);
SetShaderResource(texBSRV);


draw()


//pass 2
SetRenderTarget(texBRTV);
SetShaderResource(texASRV);


draw()
... and so on?
Edited by Sturmh

Share this post


Link to post
Share on other sites

 

Just want to make sure I understand what you are describing so I'll write up a bit of pseudo code.

 

Texture2D texA = CreateTexture();
Texture2D texB = CreateTexture();
RenderTarget texARTV = CreateRenderTarget(texA);
ShaderResource texASRV = CreateShaderResource(texA);
RenderTarget texBRTV = CreateRenderTarget(texB);
ShaderResource texBSRV = CreateShaderResource(texB);


// then when rendering


// pass 1
SetRenderTarget(texARTV);
SetShaderResource(texBSRV);


draw()


//pass 2
SetRenderTarget(texBRTV);
SetShaderResource(texASRV);


draw()
... and so on?

 

 

Yep, that looks right. Probably should have given some pseudo-code myself, it's much clearer than a paragraph of text describing the technique happy.png

Share this post


Link to post
Share on other sites

For the specific case of incrementing the values of a render target, you could use additive blending.

Share this post


Link to post
Share on other sites

For the specific case of incrementing the values of a render target, you could use additive blending.

 

This will be slower than the other way. Blending is never worthwhile.

Share this post


Link to post
Share on other sites

It is worthwhile if it saves one frame of latency by not requiring to ping-pong between buffers. Depends on the goal, really.

Share this post


Link to post
Share on other sites

For the specific case of incrementing the values of a render target, you could use additive blending.

This will be slower than the other way. Blending is never worthwhile.

This depends entirely on the GPU.

GPU's don't allow you to sample from and write pixels to the same texture at the same time, because it would be a race condition (what if one pixel-shader instance tried to read a texel that another pixel-shader instance was writing to?).
However, blending is a special-case of this -- with blending, each pixel-shader instance reads and writes one specific pixel, so there's no races with other pixel-shader instances.
This might mean that the cost of blending is the same as adding one extra texture fetch into your shader code -- if your code is ALU-bound, then this extra instruction might be 'free'... Or if you're already bottlenecked by memory bandwidth, it might be expensive.
Other GPU's might only allow render-targets to exist in special dedicated RAM chips, separate from the main GPU-RAM, which would mean that the additional bandwidth from blending doesn't end up contributing to a bottleneck and is 'free'...

As with any optimisation question, it depends on the situation wink.png

Share this post


Link to post
Share on other sites

I would assume the pixel shaders which you have a lot of, doing a nearest texel lookup vs the few ROP's performing an extra additive blend operation seems not right.

I'm thinking potentially you can drop the second texture fetch (base value fetch + add value fetch) to be inside of 1 texture with 2 float components. Each time you write into a 2 component texture  vec2(new base value, new add value). This way 1 fetch each time to get your 2 numbers to add. new values = computed # to use for this frame, new add is what the new value to be added next fram will be.

Edited by dpadam450

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!