Skip to content

Commit

Permalink
Extensions translate into Korean (#245)
Browse files Browse the repository at this point in the history
* Add files via upload

Add in the Korean translation from twoo0220(Tae-Woo Lee)

* Add files via upload

REAME Modify

* move files kor to lang/kor

* Revert "Add files via upload"

This reverts commit fa14342.

* remove duplicated REAME-kor.adoc
reset README.adoc and 2line modify

* kor/chapters/extensions translate
  • Loading branch information
twoo0220 authored Jan 22, 2024
1 parent 3fbb1fd commit 4734f59
Show file tree
Hide file tree
Showing 17 changed files with 1,856 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lang/kor/README-kor.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ Vulkan에서 사용하는 특수한 용어에 대한 혼란을 막기 위해 명

// include::{chapters}hlsl.adoc[]

= 확장 기능을 사용하응 시점과 이유
= 확장 기능을 사용하는 시점과 이유

[NOTE]
====
Expand Down
112 changes: 112 additions & 0 deletions lang/kor/chapters/extensions/VK_EXT_descriptor_indexing.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright 2019-2021 The Khronos Group, Inc.
// SPDX-License-Identifier: CC-BY-4.0

ifndef::chapters[:chapters: ../]
ifndef::images[:images: ../images/]

[[VK_EXT_descriptor_indexing]]
= VK_EXT_descriptor_indexing

[NOTE]
====
Vulkan 1.2에서 코어로 승격됨
link:https://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/EXT/SPV_EXT_descriptor_indexing.html[SPV_EXT_descriptor_indexing]
link:https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GL_EXT_nonuniform_qualifier.txt[GLSL - GL_EXT_nonuniform_qualifier]
Montreal Developer Day 의 프레젠테이션 (link:https://www.youtube.com/watch?v=tXipcoeuNh4[video] 및 link:https://www.khronos.org/assets/uploads/developers/library/2018-vulkan-devday/11-DescriptorUpdateTemplates.pdf[slides])
====

이 확장 기능은 가능한 경우 구현에서 각 기능에 대한 지원을 추가할 수 있도록 몇 가지 작은 기능으로 세분화하도록 설계되었습니다.

== 바인드 후의 업데이트

이 확장 기능이 없으면 커맨드 버퍼 기록과 실행 사이에 애플리케이션의 디스크립터는 업데이트할 수 없습니다. 이 확장 기능을 통해 애플리케이션이 사용 중인 디스크립터 유형에 대해 `descriptorBinding*UpdateAfterBind` 지원을 쿼리하여 애플리케이션이 기록과 실행 사이에 업데이트할 수 있도록 할 수 있습니다.

[NOTE]
.Example
====
애플리케이션에 `StorageBuffer` 디스크립터가 있는 경우, `descriptorBindingStorageBufferUpdateAfterBind` 지원 여부를 쿼리합니다.
====

바인드 후 업데이트 기능을 활성화한 후 애플리케이션에서 바인드 후 업데이트할 수 있는 디스크립터를 사용하려면 다음과 같은 설정을 해야 합니다:

* 디스크립터가 할당된 모든 `VkDescriptorPool` 에 대한 `VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT` 플래그가 설정됩니다.
* 디스크립터의 출처가 되는 모든 `VkDescriptorSetLayout` 에 대한 `VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT` 플래그가 설정됩니다.
* 디스크립터가 사용할 `VkDescriptorSetLayout` 의 각 바인딩에 대한 `VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT` 를 설정합니다.

다음 코드 예시는 바인딩 후 업데이트를 활성화할 때와 그렇지 않을 때의 차이점을 보여줍니다:

image::../../../../chapters/images/extensions/VK_EXT_descriptor_indexing_update_after_bind.png[VK_EXT_descriptor_indexing_update_after_bind.png]

== 부분적으로 바인딩

`descriptorBindingPartiallyBound` 기능을 사용하고 `VkDescriptorSetLayoutBindingFlagsCreateInfo::pBindingFlags` 에서 `VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT` 를 사용하면 애플리케이션 개발자가 사용 시 모든 디스크립터를 업데이트할 필요가 없습니다.

예를 들어 애플리케이션의 GLSL이 다음과 같은 경우입니다.

[source,glsl]
----
layout(set = 0, binding = 0) uniform sampler2D textureSampler[64];
----

여기서 배열의 첫 32 슬롯만 바인딩합니다. 이것은 배열의 바인딩되지 않은 슬롯에 인덱싱되지 않는다는 것을 애플리케이션이 알고 있어야 합니다.

== 동적 인덱싱

일반적으로 애플리케이션이 바인딩된 디스크립터의 배열로 인덱싱할 때 인덱스는 컴파일 시점에 알 수 있어야 합니다. `shader*ArrayDynamicIndexing` 기능을 사용하면 특정 유형의 디스크립터를 "`동적으로 유니폼한(dynamically uniform)`" 정수로 인덱싱할 수 있습니다. 이 기능은 이미 대부분의 디스크립터에 대해 `VkPhysicalDeviceFeatures` 로 지원되었지만, 이번 확장 기능에서는 `VkPhysicalDeviceDescriptorIndexingFeatures` 구조체를 추가하여 입력 첨부, 유니폼 텍셀 버퍼 및 스토리지 텍셀 버퍼의 동적 유니폼 인덱싱을 구현할 수 있도록 지원합니다.

여기서 핵심 단어는 "`유니폼(uniform)`" 으로, SPIR-V 호출 그룹의 모든 호출이 모두 동일한 동적 인덱스를 사용해야 함을 의미합니다. 이는 단일 `vkCmdDraw*` 호출의 모든 호출 또는 단일 `vkCmdDispatch*` 호출의 단일 워크그룹으로 변환됩니다.

GLSL의 동적 유니폼 인덱싱 예시

[source,glsl]
----
layout(set = 0, binding = 0) uniform sampler2D mySampler[64];
layout(set = 0, binding = 1) uniform UniformBufferObject {
int textureId;
} ubo;
// ...
void main() {
// ...
vec4 samplerColor = texture(mySampler[ubo.textureId], uvCoords);
// ...
}
----

이 예제는 `ubo.textureId` 값을 실행할 때까지 알 수 없기 때문에 "`동적(dynamic)`" 문입니다. 또한 이 쉐이더에서는 모든 호출에서 `ubo.textureId` 가 사용되기 때문에 "`유니폼(uniform)`" 입니다.

== 동적 비유니폼 인덱싱

동적으로 **비유니폼(non-uniform)**하다는 것은 호출이 디스크립터 배열에 다르게 인덱싱될 수 있다는 것을 의미하지만, 런타임까지는 알 수 없습니다. 이 확장 기능은 `VkPhysicalDeviceDescriptorIndexingFeatures` 에서 `shader*ArrayNonUniformIndexing` 기능 비트 세트를 공개하여 구현이 동적 비균일 인덱싱을 지원하는 디스크립터 유형을 표시합니다. SPIR-V 확장은 `NonUniform` 수식을 추가하며, 이 수식은 `nonuniformEXT` 키워드를 추가하여 GLSL에서 설정할 수 있습니다.

GLSL에서 동적 비유니폼 인덱싱의 예시

[source,glsl]
----
#version450
#extension GL_EXT_nonuniform_qualifier : enable
layout(set = 0, binding = 0) uniform sampler2D mySampler[64];
layout(set = 0, binding = 1) uniform UniformBufferObject {
int textureId;
} ubo;
// ...
void main() {
// ...
if (uvCoords.x > runtimeThreshold) {
index = 0;
} else {
index = 1;
}
vec4 samplerColor = texture(mySampler[nonuniformEXT(index)], uvCoords);
// ...
}
----

이 예제에서 일부 호출은 `mySampler[0]` 에서 인덱싱하고 일부는 `mySampler[1]` 에서 인덱싱하므로 비유니폼(non-uniform)입니다. 이 경우 `nonuniformEXT()` 가 필요합니다.
26 changes: 26 additions & 0 deletions lang/kor/chapters/extensions/VK_EXT_inline_uniform_block.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2019-2022 The Khronos Group, Inc.
// SPDX-License-Identifier: CC-BY-4.0

ifndef::chapters[:chapters: ../]
ifndef::images[:images: ../images/]

[[VK_EXT_inline_uniform_block]]
= VK_EXT_inline_uniform_block

[NOTE]
====
Vulkan 1.3에서 코어로 승격됨
====

일반적인 구현에서 디스크립터는 커맨드 버퍼를 기록하는 동안 바인딩된 데이터를 간접적으로 가리키는 테이블일 뿐입니다. 문제는 모든 디스크립터가 동일하게 생성되는 것은 아니며, 예를 들어 하나의 디스크립터 크기가 몇 DWORDS에 불과할 수도 있다는 것입니다.

image::../../../../chapters/images/extensions/VK_EXT_inline_uniform_block_before.png[VK_EXT_inline_uniform_block_before.png]

`VK_EXT_inline_uniform_block` 을 사용하면 몇 개의 값만 사용하는 경우 구현이 유니폼 값에 접근하기 위해 취하는 간접 처리 횟수를 줄일 수 있습니다. 푸시 상수와 달리 이 데이터는 여러 개의 분리된 드로우/디스패치 세트에서 재사용할 수 있습니다.

image::../../../../chapters/images/extensions/VK_EXT_inline_uniform_block_after.png[VK_EXT_inline_uniform_block_after.png]

== 제안(Suggestions)

* `VkPhysicalDeviceInlineUniformBlockPropertiesEXT` 구조체를 확인하여 인라인 유니폼 블록 사용에 대한 구현 제한 사항을 확인하세요.
* 인라인화를 과도하게 사용하면 드라이버가 버퍼에 다시 패킹해야 하므로 CPU 오버헤드가 증가하고 간접 참조의 이점을 잃을 수 있으므로 몇 DWORDS 이하를 기준으로 하세요.
34 changes: 34 additions & 0 deletions lang/kor/chapters/extensions/VK_EXT_memory_priority.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2019-2021 The Khronos Group, Inc.
// SPDX-License-Identifier: CC-BY-4.0

ifndef::chapters[:chapters: ../]
ifndef::images[:images: ../images/]

[[VK_EXT_memory_priority]]
= VK_EXT_memory_priority

메모리 관리는 Vulkan에서 중요한 부분입니다. `VK_EXT_memory_priority` 확장 기능은 애플리케이션이 중요한 할당이 느린 메모리로 이동하는 것을 방지할 수 있도록 설계되었습니다.

이 확장 기능은 두 개의 애플리케이션(기본 애플리케이션과 호스트 머신의 다른 프로세스)을 예로 들어 설명할 수 있습니다. 시간이 지남에 따라 두 애플리케이션 모두 제한된 장치 힙 메모리를 사용하려고 시도합니다.

image::../../../../chapters/images/extensions/VK_EXT_memory_priority_overview.png[VK_EXT_memory_priority_overview]

이 상황에서는 메인 애플리케이션의 할당이 아직 존재하지만 느린 메모리에 있을 가능성이 있습니다(구현에서 다시 필요할 때까지 호스트 가시 메모리로 이동했을 수 있음).

**어떤 메모리**를 옮길지는 구현에 따라 결정됩니다. 이제 메인 애플리케이션의 메모리 사용량이 다음과 같다고 가정해 보겠습니다.

image::../../../../chapters/images/extensions/VK_EXT_memory_priority_app.png[VK_EXT_memory_priority_app]

보시다시피, 애플리케이션이 항상 빠른 메모리에 보관하는 것이 더 중요하다고 생각하는 메모리가 있었습니다.

`VK_EXT_memory_priority` 확장 기능을 사용하면 이 작업을 매우 쉽게 수행할 수 있습니다. 메모리를 할당할 때, 애플리케이션은 `VkMemoryAllocateInfoEXT` 를 `VkMemoryAllocateInfo::pNext` 에 추가하기만 하면 됩니다. 여기에서 `VkMemoryPriorityAllocateInfoEXT::priority` 값을 `0.0` 에서 `1.0` 사이의 값으로 설정할 수 있습니다(기본값은 `0.5`). 이를 통해 위와 같은 상황이 발생했을 때 애플리케이션이 더 나은 추측을 할 수 있도록 도와줍니다.

== 제안(Suggestions)

* 확장 기능이 지원되는지 확인하세요.
* 이것은 구현에 대한 **힌트**이며, 애플리케이션은 이를 사용하기 전에 적절한 비용(budgets)을 책정해야 한다는 점을 기억하세요.
* 가능하면 가정하지 말고 항상 메모리 병목 현상을 측정하세요.
* 기록되는 모든 메모리는 우선순위가 높은 메모리가 될 가능성이 높습니다.
** 렌더 타켓(예: 프레임버퍼의 출력 첨부)은 일반적으로 높은 우선순위로 설정하는 것이 중요합니다.
* 우선 순위가 높은 메모리는 "`고빈도 접근(high frequency access)`" 와 "`낮은 지연시간 허용(low latency tolerance)`" 을 갖는 것으로 간주하세요.
** 예: 정점 버퍼는 여러 프레임에 걸쳐 안정적이며, 각 값이 한 번만 액세스되며, 보통 접근 지연에 관대하기 때문에 일반적으로 우선순위를 낮추기에 좋은 후보입니다.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2019-2021 The Khronos Group, Inc.
// SPDX-License-Identifier: CC-BY-4.0

ifndef::chapters[:chapters: ../]
ifndef::images[:images: ../images/]

[[VK_KHR_descriptor_update_template]]
= VK_KHR_descriptor_update_template

[NOTE]
====
Vulkan 1.1에서 코어로 승격됨
link:https://www.khronos.org/assets/uploads/developers/library/2018-vulkan-devday/11-DescriptorUpdateTemplates.pdf[Presentation from Montreal Developer Day]
====

이 확장 기능은 일부 애플리케이션이 초기화 단계에서 많은 `VkDescriptorSet` 을 생성하고 업데이트하는 방식을 중심으로 설계되었습니다. 많은 업데이트가 동일한 `VkDescriptorLayout` 을 갖게 되고 동일한 바인딩이 업데이트될 가능성은 거의 없으므로 디스크립터 업데이트 템플릿은 업데이트 정보를 한 번만 전달하도록 설계되었습니다.

디스크립터 자체는 `VkDescriptorUpdateTemplate` 에 지정되지 않고, 호스트 메모리로의 포인터 오프셋 지정됩니다. 이 오프셋은 `vkUpdateDescriptorSetWithTemplate` 또는 `vkCmdPushDescriptorSetWithTemplateKHR` 에 전달된 포인터와 결합됩니다. 이를 통해 애플리케이션 데이터 구조를 엄격하게 정의된 Vulkan 데이터 구조로 변환하지 않고도 대량의 업데이트를 실행할 수 있습니다.
25 changes: 25 additions & 0 deletions lang/kor/chapters/extensions/VK_KHR_draw_indirect_count.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2019-2021 The Khronos Group, Inc.
// SPDX-License-Identifier: CC-BY-4.0

ifndef::chapters[:chapters: ../]
ifndef::images[:images: ../images/]

[[VK_KHR_draw_indirect_count]]
= VK_KHR_draw_indirect_count

[NOTE]
====
Vulkan 1.2에서 코어로 승격됨
====

`vkCmdDraw` 를 호출할 때마다 드로우콜을 기술하는 매개변수 세트를 사용합니다. 드로우콜을 일괄 처리하기 위해 동일한 매개변수가 `VkDrawIndirectCommand` 블록의 `VkBuffer` 에 저장됩니다. `vkCmdDrawIndirect` 를 사용하면 `drawCount` 드로우 횟수를 호출할 수 있지만, `drawCount` 는 기록 시점에 필요합니다. 새로운 `vkCmdDrawIndirectCount` 호출을 사용하면 `drawCount` 가 `VkBuffer` 에도 포함될 수 있습니다. 이를 통해 드로우콜이 실행될 때 `drawCount` 의 값이 동적으로 결정될 수 있습니다.

[NOTE]
====
확장 기능이 지원되거나 `VkPhysicalDeviceVulkan12Features::drawIndirectCount` 기능 비트가 `true` 인 경우 `vkCmdDrawIndirectCount` 및 `vkCmdDrawIndexedIndirectCount` 함수를 사용할 수 있습니다.
====

다음 다이어그램은 `vkCmdDraw` , `vkCmdDrawIndirect` , `vkCmdDrawIndirectCount` 의 차이를 시각화한 것입니다.

image::../../../../chapters/images/extensions/VK_KHR_draw_indirect_count_example.png[VK_KHR_draw_indirect_count example]

17 changes: 17 additions & 0 deletions lang/kor/chapters/extensions/VK_KHR_image_format_list.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2019-2021 The Khronos Group, Inc.
// SPDX-License-Identifier: CC-BY-4.0

ifndef::chapters[:chapters: ../]
ifndef::images[:images: ../images/]

[[VK_KHR_image_format_list]]
= VK_KHR_image_format_list

[NOTE]
====
Vulkan 1.2에서 코어로 승격됨
====

일부 구현에서, `VkImage` 생성 시 `VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT` 를 설정하면, `VkImage` 에 대한 액세스 성능이 `VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT` 없이 만든 동등한 `VkImage` 보다 저하될 수 있습니다. 구현이 `VkImage` 에 어떤 `VkImageView` 포맷이 짝이 될지 모르기 때문입니다. 이로 인해 구현이 무손실 이미지 압축과 같은 포맷별 최적화를 (`VkImageView`) 강제로 비활성화할 수 있습니다. `VkImageFormatListCreateInfo` 구조체를 이용해 `VkImage` 가 짝을 이룰 수 있는 `VkImageView` 포맷을 명시적으로 나열하면, 구현이 추가적인 경우에 포맷별 최적화를 활성화할 수 있습니다.

애플리케이션이 이미지를 생성할 때 `VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT` 을 사용하지 않는다면 이 확장 기능에 대해 고민할 필요가 없습니다.
55 changes: 55 additions & 0 deletions lang/kor/chapters/extensions/VK_KHR_imageless_framebuffer.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2019-2021 The Khronos Group, Inc.
// SPDX-License-Identifier: CC-BY-4.0

ifndef::chapters[:chapters: ../]
ifndef::images[:images: ../images/]

[[VK_KHR_imageless_framebuffer]]
= VK_KHR_imageless_framebuffer

[NOTE]
====
Vulkan 1.2에서 코어로 승격됨
====

`VkFramebuffer` 를 생성할 때 일반적으로 `VkFramebufferCreateInfo::pAttachments` 에서 사용 중인 `VkImageView`s`` 를 전달해야 합니다. `VkImageView` 가 필요하면 애플리케이션이 각 스왑체인 이미지에 대한 프레임버퍼를 만들어야 합니다. `VK_KHR_imageless_framebuffer` 를 사용하면 `vkCmdBeginRenderPass` 시점에 `VkImageView` 정보가 대신 제공됩니다. 이는 모든 스왑체인 이미지에 대해 `VkFramebuffer` 하나만 필요하다는 것을 의미합니다. 주의할 점은 스왑체인의 크기가 변경되더라도 `VkFramebuffer`는 `높이(height)`와 `폭(width)`과 같은 정보를 조정하기 위해 다시 생성되어야 한다는 것입니다.

이미지 없는 `VkFramebuffer` 를 이용하려면

* `VkPhysicalDeviceImagelessFramebufferFeatures::imagelessFramebuffer` 또는 `VkPhysicalDeviceVulkan12Features::imagelessFramebuffer` 를 쿼리하여 구현이 지원되는지 확인합니다.
* `VkFramebufferCreateInfo::flags` 에서 `VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT` 를 설정합니다.
* `VkFramebufferCreateInfo::pNext`에다가 `VkFramebufferAttachmentsCreateInfo` 구조체를 포함시킵니다.
* 렌더 패스를 시작할 때, 호환되는 첨부와 함께 `VkRenderPassAttachmentBeginInfo` 구조체를 `VkRenderPassBeginInfo::pNext` 에 전달합니다.

[source,cpp]
----
// 첨부에 관한 정보 채우기
VkFramebufferAttachmentImageInfo attachments_image_info = {};
// ...
VkFramebufferAttachmentsCreateInfo attachments_create_info = {};
// ...
attachments_create_info.attachmentImageInfoCount = 1;
attachments_create_info.pAttachmentImageInfos = &attachments_image_info;
// FrameBuffer 를 imageless 상태로 생성
VkFramebufferCreateInfo framebuffer_info = {};
framebuffer_info.pNext = &attachments_create_info;
framebuffer_info.flags |= VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT;
// ...
framebffer_info.pAttachments = NULL; // 여기선 pAttachments는 무시됩니다
vkCreateFramebuffer(device, &framebuffer_info, NULL, &framebuffer_object);
// ...
// 커맨드 버퍼 기록 시작
VkRenderPassAttachmentBeginInfo attachment_begin_info = {};
// attachment_begin_info.pAttachments 에는 VkImageView 객체가 포함됩니다
VkRenderPassBeginInfo begin_info = {};
begin_info.pNext = &attachment_begin_info;
// ...
vkCmdBeginRenderPass(command_buffer, &begin_info, VK_SUBPASS_CONTENTS_INLINE);
----
Loading

0 comments on commit 4734f59

Please sign in to comment.