GPUμμ μ½λ μ€ννκΈ°
μ΄μ λ λλ§ λ£¨νκ° κ΅¬νλμμΌλ, λ€μ λ¨κ³λ μ€μ λ‘ λ¬΄μΈκ°λ₯Ό 그리λ κ²μ λλ€.
λνμ λ°λ‘ 그리λ κ²λ³΄λ€λ μ»΄ν¨νΈ μ °μ΄λλ₯Ό μ¬μ©ν΄ μ΄λ―Έμ§μ λ°μ΄ν°λ₯Ό κΈ°λ‘νκ³ , μ΄λ₯Ό νλ©΄μ νμν΄λ³΄κ² μ΅λλ€. μ΄λ―Έμ§λ₯Ό κ³μ°νλ μ©λμ μ»΄ν¨νΈ μ °μ΄λλ μμ§μ 볡μ‘ν νμ²λ¦¬μμ νν λ³Ό μ μλ μ¬μ© μ¬λ‘μ λλ€. λν κ°λ°μκ° λ μ΄νΈλ μ΄μ±μ΄λ λνμ΄ μλ λ€λ₯Έ κ²μ 그릴 λμλ νν λ³Ό μ μμ΅λλ€.
VkPipeline
Vulkanμμλ GPUμμ μ½λλ₯Ό μ€ννκΈ° μν΄ νμ΄νλΌμΈμ μ€μ ν΄μΌ ν©λλ€. κ·Έλν½μ€μ μ»΄ν¨νΈ λ μ’ λ₯μ νμ΄νλΌμΈμ΄ μμ΅λλ€. μ»΄ν¨νΈ νμ΄νλΌμΈμ κ½€ λ¨μν©λλ€. μ °μ΄λ μ½λμ μ λ¬ν λ°μ΄ν°, λ°μ΄ν° λ°μΈλ©μ μ¬μ©ν λμ€ν¬λ¦½ν° λ μ΄μμλ§ νμν©λλ€. λ°λ©΄ κ·Έλν½μ€ νμ΄νλΌμΈμ λΈλ λ©, κΉμ΄ ν μ€νΈ, λν ν¬λ§· λ± GPUμ λͺ¨λ κ³ μ κΈ°λ₯ νλμ¨μ΄λ₯Ό μν μλΉν μνλ₯Ό ꡬμ±ν΄μΌ ν©λλ€. κ·Έλν½μ€ νμ΄νλΌμΈμ λ€μ μ₯μμ λ€λ£° μμ μ λλ€.
λ νμ΄νλΌμΈμ μ °μ΄λ λͺ¨λκ³Ό λ μ΄μμμ λμΌν λ°©μμΌλ‘ μμ±νλ©°, μ΄λ₯Ό 곡μ ν μ μμ΅λλ€.
VkShaderModule
VkShaderModule
μ μ μ²λ¦¬λ μ
°μ΄λ νμΌμ
λλ€. μ»΄νμΌλ SpirV νμΌμ ν΅ν΄ μμ±ν μ μμ΅λλ€. OpenGLκ³Ό λ¬λ¦¬ Vulkanμμλ GLSL μ
°μ΄λ μ½λλ₯Ό μ§μ μ λ¬ν μ μμ΅λλ€. μ΄λ₯Ό κ°λ₯μΌνλ νμ₯λ μ‘΄μ¬νκΈ°λ νμ§λ§ νμ€μ μλλλ€. λ°λΌμ GLSL νμΌμ 미리 μ»΄νμΌνμ¬ SpirVνμΌλ‘ λ§λ€μ΄μΌ ν©λλ€. Vulkan SDKμλ glslangValidatorκ° ν¬ν¨λμ΄ μμΌλ©°, μ΄λ₯Ό μ¬μ©ν΄ GLSLμ SpirVλ‘ μ»΄νμΌν μ μμ΅λλ€. vkguide μ½λμμ λ©μΈ νλ‘μ νΈμ CMakeLists.txtλ₯Ό 보면 /shaders/ ν΄λμμ λͺ¨λ μ
°μ΄λ νμΌμ κ°μ Έμ μ»΄νμΌ νκ²μΌλ‘ μΆκ°νλ 컀μ€ν
λͺ
λ Ήμ λ³Ό μ μμ΅λλ€.
μ΄ νν 리μΌμμ μ °μ΄λλ₯Ό μ»΄νμΌνλ €λ©΄ μ °μ΄λ νκ²μ λΉλν΄μΌ ν©λλ€. μ΄λ μμ μ λͺ¨λ μ °μ΄λ νμΌμ μ»΄νμΌ ν©λλ€. CMakeμ νκ³λ‘ μΈν΄ μλ‘μ΄ μ °μ΄λ νμΌμ μΆκ°νλ©΄ CMake μ€μ λ¨κ³λ₯Ό μ¬μ€ννμ¬ CMakeκ° ν΄λΉ μ °μ΄λ νμΌμ κ°μ Έμ¬ μ μλλ‘ ν΄μΌ ν©λλ€. λ€λ₯Έ μμ§μμλ μ °μ΄λ μ»΄νμΌμ μλννκΈ° μν΄ μμ§μ΄ μμλ λ μλμΌλ‘ μ€νκ°λ₯ν νμΌ νΉμ .bat, νΉμ λ€λ₯Έ μ€ν¬λ¦½νΈ νμΌμ μ¬μ©νλ κ²μ΄ μΌλ°μ μ λλ€.
Vulkan μ °μ΄λμ μ½λλ‘ GLSL λμ HLSLμ μ¬μ©νλ κ²λ κ°λ₯ν©λλ€. λ§μ νλ‘μ νΈκ° μ΄λ¬ν λ°©μμ μ νΈνμ§λ§, μ΄ νν 리μΌμμλ λ€λ£¨μ§ μμ΅λλ€. λ§μ½ HLSLμ Vulkanμμ μ¬μ©νλ λ°©λ²μ λν΄ λ μκ³ μΆλ€λ©΄, HLSL In Vulkanλ₯Ό μ°Έκ³ ν΄λ³΄μΈμ.
Descriptor sets
μ
°μ΄λμ λ°μ΄ν°λ₯Ό μ λ¬νλ €λ©΄ λ°μΈλ©μ μ€μ ν΄μΌ ν©λλ€. Vulkanμμλ μ΄λ―Έμ§λ λ²νΌ κ°μ κ°μ²΄λ₯Ό μ
°μ΄λλ‘ λ°μΈλ©νκΈ° μν΄ λμ€ν¬λ¦½ν° μ
(DescriptorSet)μ΄ νμν©λλ€. νλμ λμ€ν¬λ¦½ν°λ μμ(λ²νΌλ μ΄λ―Έμ§ λ±)μ λν νΈλ€ νΉμ ν¬μΈν°λΌκ³ μκ°νλ©΄ λ©λλ€. μ΄λ λ²νΌμ ν¬κΈ°λ μ΄λ―Έμ§μ μνλ¬(sampler) νμ
κ³Ό κ°μ μ 보λ λ΄κ³ μμ΅λλ€. VkDescriptorSet
μ μ΄λ¬ν ν¬μΈν°λ€μ λ¬Άμ΄λμ μ§ν©μ
λλ€. Vulkanμ μ
°μ΄λλ‘ κ°λ³ 리μμ€λ₯Ό μ§μ λ°μΈλ©νλ κ²μ νμ©νμ§ μμ΅λλ€. λμ€ν¬λ¦½ν° μ
μ VkDescriptorSetLayout
μ κΈ°λ°μΌλ‘ VkDescriptorPool
μμ ν λΉλ©λλ€. VkDescriptorSetLayout
μ λμ€ν¬λ¦½ν° μ
μ΄ μ΄λ€ μμμ λ΄λμ§λ₯Ό μ μν©λλ€.(μ : μ΄λ―Έμ§ 2κ°) λμ€ν¬λ¦½ν° μ
μ΄ ν λΉλλ©΄ vkUpdateDescriptorSets
λ₯Ό μ¬μ©ν΄ λ°μ΄ν°λ₯Ό κ°±μ ν μ μμΌλ©°, μ΄λ VkWriteDescriptorSet
μ λ°°μ΄μ λκΉλλ€. λμ€ν¬λ¦½ν° μ
μ ꡬμ±μ΄ μλ£λλ©΄ νμ΄νλΌμΈμ VkBindDescriptorSets
λ₯Ό μ¬μ©ν΄ λ°μΈλ©ν μ μμΌλ©° μ
°μ΄λμμ λ°μ΄ν°λ₯Ό μ¬μ©ν μ μμ΅λλ€.
μ΄ μ±ν°μμλ λ λλ§ν μ΄λ―Έμ§λ₯Ό μ»΄ν¨νΈ μ °μ΄λμ μ°κ²°νμ¬ μ °μ΄λκ° ν΄λΉ μ΄λ―Έμ§μ μ§μ μΈ μ μλλ‘ νκ² μ΅λλ€. νν λ¦¬μΌ μ λ°μ κ±Έμ³ μ΄λ¬ν νλ¦μ λ¨μννλ μΆμνλ₯Ό μμ±ν κ²μ λλ€. νμ΄νλΌμΈμ μ¬λ¬ κ°μ λμ€ν¬λ¦½ν° μ μ λ°μΈλ©ν μ μλ μ¬λ‘―μ κ°μ΅λλ€. Vulkan λͺ μΈμμλ μ μ΄λ 4κ°μ λμ€ν¬λ¦½ν° μ μ 보μ₯νλ©°, μ΄ νν 리μΌμμλ μ΄ μλ₯Ό κΈ°μ€μΌλ‘ μΌκ² μ΅λλ€. GPU μ μ‘°μ¬μ λ°λ₯΄λ©΄ κ° λμ€ν¬λ¦½ν° μ μ¬λ‘―μ μΌμ ν λΉμ©μ΄ λ€ μ μμΌλ―λ‘, κ°λ₯ν ν μ κ² μ¬μ©νλ κ²μ΄ μ’μ΅λλ€. μ΄νμ νν 리μΌμμλ λμ€ν¬λ¦½ν° μ 0λ²μλ μ λνΌ λ²νΌμ μΌλΆ νΉμ ν μ€μ³λ₯Ό ν¬ν¨νλ μ μ μ¬ λ°μ΄ν°λ₯Ό λ°μΈλ©ν κ²μ΄κ³ , λμ€ν¬λ¦½ν° μ 1λ²μλ κ°λ³ μ€λΈμ νΈ λ°μ΄ν°λ₯Ό λ°μΈλ©νλ μ©λλ‘ μ¬μ©νκ² μ΅λλ€.
νΈμ μμ
μ °μ΄λμ λ²νΌμ μ΄λ―Έμ§λ₯Ό μ λ¬νλ λ° μ¬μ©λλ λμ€ν¬λ¦½ν° μ μΈμλ, Vulkanμ 컀맨λ λ²νΌλ₯Ό κΈ°λ‘νλ κ³Όμ μ€μ μ§μ λͺ λ°μ΄νΈμ λ°μ΄ν°λ₯Ό μΈ μ μλ κΈ°λ₯μ μ 곡ν©λλ€. μ΄λ νΈμ μμ(Push Constants)λΌ λΆλ¦¬λ©°, Vulkanμλ§ μ‘΄μ¬νλ λ νΉν λ°©μμ λλ€. μ °μ΄λμ μ§μ λ°μΈλ©λλ μμ£Ό μλμ λ©λͺ¨λ¦¬ 곡κ°μ μμ½νλ ꡬ쑰λ‘, μλλ λΉ λ₯΄μ§λ§ λ§€μ° μ νλ μ©λλ§ μ¬μ©ν μ μμΌλ©°, λͺ λ Ήμ μΈμ½λ©νλ μμ μ μμ±λμ΄μΌλ§ ν©λλ€. μ£Όλ‘ κ°μ²΄κ° λ§μ λ°μ΄ν°λ₯Ό μꡬνμ§μμ λ, κ°μ²΄λ³ λ°μ΄ν° μ λ¬μ μ¬μ©ν μ μμ΅λλ€. GPU μ μ‘°μ¬μ λ°λ₯΄λ©΄ μ΄μμ μΈ μ©λ‘λ μ °μ΄λλ‘ μΈλ±μ€λ₯Ό μ λ¬ν΄ λ ν° λ°μ΄ν° λ²νΌμ μ κ·Όν λ μ¬μ©νλ κ²μ λλ€.
νμ΄νλΌμΈ λ μ΄μμ
μ
°μ΄λλ λ€μν μ
λ ₯μ΄ νμνλ©°, μ΄λ¬ν μ
λ ₯ ꡬ쑰λ VkPipelineLayout
μ΄ μ μν©λλ€. νμ΄νλΌμΈ λ μ΄μμμ μμ±νκΈ° μν΄ VkDescriptorSetLayout
κ³Ό νΈμ μμμ μ¬μ©λλ PushConstantRange
μ μκ° νμν©λλ€. κ·Έλν½μ€ νμ΄νλΌμΈκ³Ό μ»΄ν¨νΈ νμ΄νλΌμΈμ νμ΄νλΌμΈ λ μ΄μμμ κ°μ λ°©μμΌλ‘ λ μ΄μμμ μμ±νλ©°, μ€μ νμ΄νλΌμΈμ΄ μμ±λκΈ° μ μ λ¨Όμ μμ±λμ΄μΌ ν©λλ€.
μ»΄ν¨νΈ νμ΄νλΌμΈ
μ»΄ν¨νΈ νμ΄νλΌμΈμ ꡬμ±νκΈ° μν΄μλ νμ΄νλΌμΈ λ μ΄μμμ λ¨Όμ μμ±νκ³ , μ
°μ΄λ λͺ¨λμ μ°κ²°ν΄μΌ ν©λλ€. νμ΄νλΌμΈμ΄ λ§λ€μ΄μ§λ©΄ μ»΄ν¨νΈ μ
°μ΄λλ₯Ό VkCmdBindPipeline
λ₯Ό νΈμΆν΄ λ°μΈλ©νκ³ VkCmdDispatch
λ₯Ό νΈμΆν΄ μ€νν μ μμ΅λλ€.
μ»΄ν¨νΈ μ
°μ΄λλ νΉμν νλ‘κ·Έλλ° λͺ¨λΈμ λ°λ¦
λλ€. VkCmdDispatch
νΈμΆ μ, Vulkanμκ² X, Y, Z ννλ‘ μμ
κ·Έλ£Ήμ μλ₯Ό μ§μ ν©λλ€. μ΄ νν 리μΌμμλ μ΄λ―Έμ§λ₯Ό μ²λ¦¬ν κ²μ΄λ―λ‘ 2κ°μ μ°¨μλ§ μ¬μ©ν©λλ€. μ΄λ―Έμ§μ κ° ν½μ
κ·Έλ£Ήλ§λ€ νλμ μμ
κ·Έλ£Ήμ΄ μ€νλλλ‘ μ€μ ν©λλ€.
μ
°μ΄λ λ΄λΆμμλ λ€μκ³Ό κ°μ μ½λκ° λ³΄μ
λλ€. layout (local_size_x = 16, local_size_y = 16) in;
. μ΄λ κ° μμ
κ·Έλ£Ήμ΄ 16 * 16 μ°λ λλ‘ κ΅¬μ±λ¨μ μλ―Έν©λλ€. μ¦, vkCmdDispatchλ‘ ν μμ
κ·Έλ£Ήμ΄ νΈμΆλλ©΄, 16 * 16κ°μ μ°λ λκ° λ³λ ¬λ‘ μ€νλμ΄ 16 * 16 ν½μ
μ¬κ°νμ μ²λ¦¬ν μ μμ΅λλ€.
μ
°μ΄λ μ½λμμλ gl_LocalInvocationID
λ³μλ₯Ό ν΅ν΄ νμ¬ μ°λ λ μΈλ±μ€μ μ κ·Όν μ μμ΅λλ€. gl_GlobalInvocationID
μ gl_WorkGroupID
λ μμ΅λλ€. μ΄λ¬ν λ³μλ€μ μ¬μ©νμ¬ κ° μ°λ λκ° μ΄λ€ ν½μ
μ μ²λ¦¬ν μ§ μ νν μ°Ύμ μ μμ΅λλ€.
μ΄μ μ€μ μ½λλ₯Ό μ΄ν΄λ³΄λ©° μ΄λ»κ² μ °μ΄λκ° μλνλ μ§ μμλ³΄κ² μ΅λλ€.
Next: Vulkan Shaders - Code