2016-06-17 15 views
5

La mia domanda è simile a this one ma parte della risposta data (utile) non è compatibile con la compilazione GLSL per vulkan basato su ESPL ESSL 3.10 di OpenGL.Compilare GLSL scritto per OpenGL ES versioni per Vulkan

Per utilizzare una sezione separata della memoria costante di spinta nel vertex shader e nello shader di frammenti, la soluzione suggerita è di utilizzare il layout (offset = #) prima del primo membro della struttura costante di spinta.

Il tentativo di eseguire questa operazione nel codice GLSL ES 310 porta all'errore "'offset sul membro del blocco': non supportato con questo profilo: es".

Esiste un modo supportato per dichiarare tale offset compatibile con es?

L'unica soluzione che ho trovato è dichiarare un gruppo di variabili fittizie nello shader di frammenti. Quando lo faccio, ottengo errori di livello di convalida se non dichiaro l'intervallo completo del buffer di costante di push del frammento shader in VkPipelineLayoutCreateInfo. Dopo aver corretto ciò, ricevo avvisi di livello di convalida sulla "chiamata vkCreatePipelineLayout() ha costanti push con intervalli sovrapposti".

Ovviamente posso ignorare gli avvisi, ma se c'è una soluzione più ordinata, sarebbe molto più preferibile.

Semplice esempio, questo compila con successo con VulkanSDK \ 1.0.13.0 \ Bin \ glslangValidator.exe:

#version 430 
#extension GL_ARB_enhanced_layouts: enable 

layout(std140, push_constant) uniform PushConstants 
{ 
     layout(offset=64) mat4 matWorldViewProj; 
} ubuf; 

layout(location = 0) in vec4 i_Position; 

void main() { 
    gl_Position = ubuf.matWorldViewProj * i_Position; 
} 

considerando che il presente non è così:

#version 310 es 
#extension GL_ARB_enhanced_layouts: enable 

layout(std140, push_constant) uniform PushConstants 
{ 
     layout(offset=64) mat4 matWorldViewProj; 
} ubuf; 

layout(location = 0) in vec4 i_Position; 

void main() { 
    gl_Position = ubuf.matWorldViewProj * i_Position; 
} 

la conversione di tutti il ​​mio codice 310 ES shader per 430 risolverebbe il mio problema, ma non sarebbe l'ideale. GL_ARB_enhanced_layouts non si applica al codice 310 ES, quindi la mia domanda non riguarda il motivo per cui non funziona, ma piuttosto, ho qualche opzione in ES per raggiungere lo stesso obiettivo?

+0

"* Convertire tutto il mio codice shader 310 ES in 430 risolverebbe il mio problema, ma non sarebbe l'ideale. *" I tuoi shader sono scritti per essere consumati da * Vulkan *, non OpenGL ES. Quindi, perché non è "ideale" che devi apportare modifiche per far sì che funzioni? Perché sei collegato ai tuoi shader usando ES version 3.10? –

+0

Dato che questa domanda continua ad avere visualizzazioni occasionali e upvotes, ho pensato di seguire. Mi rivolgo ai dispositivi mobili, compresi i dispositivi OpenGLES2 e Metal, e ho voluto utilizzare SPIR-V cross per compilare in cross-down un singolo set di shader su tutte le piattaforme di destinazione. Mi sono bloccato con 310 ES + GL_KHR_vulkan_glsl e ho hacked glslang e SPIRV-Cross per consentire entrambi gli offset di layout (per Vulkan) e lowp (per GLES2). Glslang e SPIRV-Cross sono entrambi open source e sono stati relativamente facili da modificare per soddisfare le mie esigenze: YMMV. – Columbo

risposta

1

Se si compila SPIR-V per Vulkan c'è un "VULKAN" definiscono impostare nei vostri shaders (vedi GL_KHR_VULKAN_glsl), così si potrebbe fare qualcosa di simile:

#ifdef VULKAN 
    layout(push_constant) uniform pushConstants { 
     vec4 (offset = 12) pos; 
    } pushConstBlock; 
#else 
    // GLES stuff 
#endif 
+0

Grazie per la risposta. Non sto cercando di compilare lo shader per GLES, sto provando a compilare lo shader per vulkan usando il dialetto 310 ES + GL_KHR_vulkan_glsl. Ho aggiunto un paio di esempi alla mia domanda per rendere il problema più chiaro. Quello che sto cercando di fare funziona con 430 + GL_KHR_vulkan_glsl, ma non con 310 ES + GL_KHR_vulkan_glsl. – Columbo

3

Secondo me è un errore il compilatore GLSL.

Quello che sta succedendo è questo. Ci sono alcune cose che la compilazione di GLSL per Vulkan aggiunge alla lingua, come defined by KHR_vulkan_glsl. Il layout push_constant, ad esempio, è esplicitamente aggiunto alla sintassi GLSL.

Tuttavia, ci sono alcune cose che è non aggiungere alla lingua. Importante per il tuo caso d'uso è la possibilità di applicare offset ai membri di blocchi uniformi. Oh sì, KHR_vulkan_glsl utilizza le informazioni durante la creazione del layout del blocco dello shader. Ma la grammatica che consente di dire layout(offset=#) è definita da GLSL, non da KHR_vulkan_glsl.

E quella grammatica non fa parte della versione di GLSL-ES. Né è fornito da alcuna estensione ES di cui sono a conoscenza. Quindi non puoi usarlo.

direi che il compilatore di riferimento dovrebbe, durante la compilazione di uno shader per Vulkan, non riuscire a compilare qualsiasi versione GLSL-ES-based, o in silenzio ignorare eventuali dichiarazioni di versione e di estensione, e dare per scontato GLSL desktop di 4,50.

Per quanto riguarda quello che puoi fare al riguardo ... niente. A parte l'hacking di questa soluzione nel compilatore stesso, la soluzione principale è scrivere il codice contro le versioni di OpenGL desktop. Come 4,50.

+0

Potrei essere fraintendere la tua risposta, ma sembra che tu stia dicendo che è solo un bug che GLSL-ES 310 è autorizzato dal compilatore di riferimento. Tuttavia, GL_KHR_vulkan_glsl specifica che può essere applicato a GLSL-ES 310 (nella sezione delle dipendenze). Tuttavia, senza alcuno strumento per ottenere l'offset del layout, GLSL-ES 310 sembra essere un cittadino di seconda classe, quindi probabilmente seguirò il tuo consiglio e passerò a una versione desktop. – Columbo

+0

@Columbo: considererei un bug nella "specifica". VKSL dovrebbe essere una lingua, una sorta di pseudo-estensione che può o non può supportare tutte le sue funzionalità. –

+0

Sì, forse è stato un passo falso per GL_KHR_vulkan_glsl cercare di supportare un insieme troppo ampio di versioni GLSL. Sicuramente per me sarebbe stato meglio se GL_KHR_vulkan_glsl non avesse mai supportato GLSL-ES. Quindi non avrei passato molto tempo a lavorare con molti shader in un dialetto prima di scoprire che avevo sostenuto il cavallo sbagliato. Tuttavia, probabilmente non troppa fatica per rielaborarli. A chiunque voglia provare a decidere quale lingua basare il proprio codice di vulcan shader, ti consiglio di scegliere il GLSL desktop. – Columbo