理解纹理寄存器和采样器时要考虑优化

时间:2011-03-31 09:31:52

标签: xna hlsl xna-4.0 render-to-texture

我有3种不同的xna效果,一种叫做初始化,一种叫做迭代,一种叫做终结。

Initialise不接受纹理输入,并渲染到3个目标。 Iterate将这3个作为纹理输入,并渲染到3个目标,迭代运行多次。 Finalize需要1个纹理输入并渲染到一个目标。

我有一些辅助类,但是下面的渲染循环应该很明显:

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();

我的纹理声明使用以下宏,并且与我的输出结构一起定义如下:

#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;
};

我想知道的是,我可以将输入和输出渲染目标放在不同的纹理寄存器中,然后可以交替运行2个迭代像素着色器,其中一个从前3个寄存器读取,写入最后3个,另一个从最后3个读到写入第3个?

我猜测设置渲染目标和输入纹理的成本很多次,我不再需要这样做了。这会避免它吗,它会值得吗?

注意,我可以单独优化着色器中的代码,如果需要,我会问一个单独的问题。

1 个答案:

答案 0 :(得分:0)

正如documentation所述:

  

在绘制时,纹理不能同时设置为渲染目标和舞台上的纹理。

基本上你正在做的事情的概念很好。有三个输入纹理和三个输出纹理,然后在每次传递时切换它们。但是你必须明确地切换它们。

然而,好消息是,我非常确定,在Windows 上,更改纹理和渲染目标是一种相对便宜的操作。你可能想要混淆RenderTargetUsage(可能设置PreserveContents)只创建一个表面。 (我不完全确定XNA 4.0的作用,因为在早期版本中它的行为只有documented并且它may have changed;你可能会试着找出PIX)。

另一方面, Xbox 360是a different story