2016-05-05 42 views
6

Ho un vertex con un blocco di spinta costante contenente un galleggiante:Utilizzando differenti flessioni costanti in differenti Shader stadi

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

E shader frammento con un altro blocco di spinta costante con un valore float diversa:

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

test1 e test2 si suppone di essere diversi.

Le gamme di spinta costante per il layout tubazione sono definite in questo modo:

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

Le costanti reali vengono quindi spinte durante il rendering simili:

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

Tuttavia, durante il controllo i valori all'interno gli shader hanno entrambi il valore 123. Sembra che gli offset siano completamente ignorati. Sto usando in modo errato?

risposta

8

Nel layout della pipeline, hai dichiarato che il vertex shader avrebbe accesso all'intervallo di dati da [0, 4) byte nella gamma di costante di spinta. Hai affermato che il tuo shader di frammenti avrebbe accesso all'intervallo di dati da [4, 8) nell'intervallo costante di spinta.

Ma i tuoi shader raccontano una storia diversa.

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

Questa definizione dice molto chiaramente che l'intervallo di spinta costante inizia con [0, 4). Ma hai detto a Vulkan che usa [4, 8). Quale dovrebbe credere Vulkan: il tuo shader o il tuo layout del gasdotto?

Una regola empirica generale da ricordare è questa: lo shader indica ciò che dice che significa. I parametri forniti per la creazione della pipeline non possono modificare il significato del codice.

Se avete intenzione di avere shader frammento davvero usare [4, 8), poi lo shader frammento deve davvero usarlo:

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

Dal momento che ha una definizione diversa dalla versione VS, si dovrebbe avere anche un nome di blocco diverso Il layout offset specifica l'offset della variabile in questione. È roba standard da GLSL, e compiling for Vulkan non lo cambia.