我有個像素着色器,寫在HLSL,聲明如下常量緩衝區:性能動態常數緩衝索引的像素着色器
cbuffer RenderParametersData : register(b2)
{
float4 LineColor[16];
};
在着色器的功能之一,我期待基於輸出顏色在指數的「顏色」(這是不是一個真正的色彩,只是一個方便的地方把索引LineColors的陣列):
output.Color = Colors[input.Color.b * 255];
這導致在指令槽的數量急劇增加生成彙編代碼。保持一切不變,而是執行一個常量數組查找 - output.Color = LineColor[0];
- 算術運算的數量變爲10至37幾乎所有的附加操作是這樣的:
cmp r2, -r1.x, c0, r0.w
cmp r2, -r1.y, c1, r2
cmp r2, -r1.z, c2, r2
cmp r1, -r1.w, c3, r2
其中c增大到15,匹配LineColor中的元素數量。將LineColor大小調整爲8個元素導致代碼非常類似於第二種情況,但c只會變爲7,再次匹配數組中的元素數量。回到不斷的查詢,操作的數量回落到10.
所以看起來,動態常量緩衝區數組查找帶有相當大的額外開銷,在數組中添加一個比較指令,每個元素加上一些開銷。我真的很驚訝這個數組的查找是多麼昂貴,並且考慮到我的數組大小很快就會增加一個數量級,這會使我超過64個算術指令的限制。
這是預期的行爲?我在這裏做錯了什麼,或者這是動態數組索引的必然結果?
謝謝!
編輯:只需添加一些額外的細節,我後面的效果是根據來自頂點着色器和紋理座標的數據爲一些四邊形着色。我會在頂點着色器中做這項工作,但紋理座標的插值必須首先進行。
編輯2:我解決了這個問題。我正在向FXC指定我的目標是ps_4_0_level_9_1,這導致它爲着色器模型2.0和4.0生成裝配。我發現每個元素的附加比較問題只發生在2.0型彙編代碼中。將編譯器目標器切換到PS_4_0只會獲得模型4.0代碼,並且由於我不受限於9_1級,所以現在情況已經很好了。
出於好奇:爲什麼在輸入中使用浮點型索引而不僅僅是一個專用的整數部分?這至少會消除縮放浮點數並將其轉換回整數的成本。考慮使用包含顏色的紋理資源,而不是一個常量緩衝區。 – Lucius
@Lucius - 如果我可以在着色器中得到一個int,並用這個做索引,我會的。你知不知道怎麼?對於DX9,它看起來像我可用的語義是COLOR(所有UNORMS)或TEXCOORD(全部浮動)。還有其他選擇嗎?關於你的第二點,如果我目前的方法不起作用,我將不得不切換到紋理資源,我只是認爲一個cbuffer可能會在這裏更好地工作,並避免瑕疵問題(如閃閃發光)。 –
**「[..]任意語義允許沒有特殊含義。」[MSDN]中的**(http://msdn.microsoft.com/zh-cn/library/windows/desktop/bb509647(v = vs.85)的.aspx)。我想這意味着你可以想出自定義的語義。因爲我不知道你在做什麼樣的效果,我不能說這裏的紋理是否適合。但我會試一試,看看它在性能方面的表現如何。畢竟他們是*製作*查找顏色。 – Lucius