Understanding texture registers and samplers with optimising in mind
I have 3 different xna effects, one开发者_StackOverflow中文版 called initialise, one called iterate and one called finalise.
Initialise takes no texture inputs, and renders to 3 targets. Iterate takes those 3 as texture inputs, and renders to 3 targets, iterate runs multiple times. Finalise takes 1 texture input and renders to one target.
I've got a few helper classes, but it should be obvious what's going on from my render loop below:
int i = 0;
FractalInitRenderer.DefineOutputs(IterationsAndControl[i], Variables1And2[i], Variables3And4[i]);
FractalInitRenderer.Draw();
for (; i < 50; i++)
{
FractalIterateRenderer.ClearInputTextures();
FractalIterateRenderer.AddInput("IterationsAndControl", IterationsAndControl[i % 2]);
FractalIterateRenderer.AddInput("Variables1And2", Variables1And2[i % 2]);
FractalIterateRenderer.AddInput("Variables3And4", Variables3And4[i % 2]);
FractalIterateRenderer.DefineOutputs(IterationsAndControl[(i + 1) % 2], Variables1And2[(i + 1) % 2], Variables3And4[(i + 1) % 2]);
FractalIterateRenderer.Draw();
}
FractalFinaliseRenderer.ClearInputTextures();
FractalFinaliseRenderer.AddInput("IterationsAndControl", IterationsAndControl[i % 2]);
FractalFinaliseRenderer.Draw();
My texture declarations are using the following macro, and are defined as follows, along with my output struct:
#define DECLARE_TEXTURE(Name, index) \
Texture2D<float4> Name : register(t##index); \
sampler Name##Sampler : register(s##index);
struct FRACTAL_OUTPUT
{
float4 IterationsAndControl : COLOR0;
float4 Variables1And2 : COLOR1;
float4 Variables3And4 : COLOR2;
};
What i'm wondering is, can i put input and output render targets in different texture registers, then maybe run 2 iteration pixel shaders alternately one of them reading from the first 3 registers, writing to the last 3, and the other reading from the last 3 and writing to the first 3?
I'm guessing there's a cost associated with setting render targets and input textures many times, which i'd no longer have to do. Would this avoid it, and would it be worth it?
Note, i can optimise code within the shaders seperately, and if needed i'll ask a seperate question.
As the documentation states:
At draw time, a texture cannot be simultaneously set as a render target and a texture at a stage.
Basically the concept of what you are doing is fine. Having three input textures and three output textures, and then switching them on each pass. But you have to explicitly switch them.
The good news, however, is that I am pretty sure that, on Windows, changing the textures and render targets is a relatively inexpensive operation. You may want to mess with RenderTargetUsage
(probably setting PreserveContents
) to only create a single surface. (I not entirely sure what XNA 4.0 does, because the behaviour was only documented in earlier versions and it may have changed; you might try and find out with PIX).
Xbox 360, on the other hand, is a different story.
精彩评论