2016-05-05 13 views
6

I einen Vertex-Shader mit einem Push-Konstantenblock habe, die einen Schwimmer:verschiedene Druckkonstanten in verschiedenen Shader Verwendung Stufen

layout(push_constant) uniform pushConstants { 
    float test1; 
} u_pushConstants; 

und einen Fragment-Shader mit einem anderen Druckkonstant Block mit einem anderen Gleitkommawert:

layout(push_constant) uniform pushConstants { 
    float test2; 
} u_pushConstants; 

test1 und test2 sollen, anders sein.

Die Push-konstante Bereiche für die Pipeline-Layout sind wie folgt definiert:

std::array<vk::PushConstantRange,2> ranges = { 
    vk::PushConstantRange{ 
     vk::ShaderStageFlagBits::eVertex, 
     0, 
     sizeof(float) 
    }, 
    vk::PushConstantRange{ 
     vk::ShaderStageFlagBits::eFragment, 
     sizeof(float), // Push-constant range offset (Start after vertex push constants) 
     sizeof(float) 
    } 
}; 

Die tatsächlichen Konstanten werden dann während der Wiedergabe wie folgt gedrückt:

std::array<float,1> constants = {123.f}; 
commandBufferDraw.pushConstants(
    pipelineLayout, 
    vk::ShaderStageFlagBits::eVertex, 
    0, 
    sizeof(float), 
    constants.data() 
); 
std::array<float,1> constants = {456.f}; 
commandBufferDraw.pushConstants(
    pipelineLayout, 
    vk::ShaderStageFlagBits::eFragment, 
    sizeof(float), // Offset in bytes 
    sizeof(float), 
    constants.data() 
); 

Wenn jedoch die Werte innerhalb Überprüfung Die Shader, beide haben den Wert 123. Es scheint, dass die Offsets vollständig ignoriert werden. Benutze ich sie falsch?

Antwort

8

In Ihrem Pipeline-Layout haben Sie angegeben, dass Ihr Vertex-Shader auf den Datenbereich von [0, 4) Bytes im Schubkonstantenbereich zugreifen würde. Sie haben angegeben, dass Ihr Fragment-Shader auf den Datenbereich von [4, 8] im Push-Konstantenbereich zugreifen würde.

Aber Ihre Shader erzählen eine andere Geschichte.

Diese Definition besagt sehr deutlich, dass die Push-Konstanten-Range verwendet [0, 4]. Aber du hast Vulkan gesagt, dass es [4, 8] benutzt. Was sollte Vulkan glauben: Ihr Shader oder Ihr Pipeline-Layout?

Als allgemeine Faustregel gilt: Ihr Shader bedeutet, was er bedeutet. Parameter, die der Pipelineerzeugung zugewiesen werden, können die die Bedeutung Ihres Codes nicht ändern.

Wenn Sie beabsichtigen, die Fragment-Shader wirklich haben mit [4, 8), dann muss der Fragment-Shader es wirklich verwenden:

layout(push_constant) uniform fragmentPushConstants { 
    layout(offset = 4) float test2; 
} u_pushConstants; 

Da es eine andere Definition aus der VS-Version hat, es sollte auch einen anderen Blocknamen haben. Das Layout offset gibt den Offset der betreffenden Variablen an. Das ist Standardmaterial von GLSL, und compiling for Vulkan ändert das nicht.