[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -2,94 +2,147 @@
|
||||
id: wiki-2026-0508-render-state
|
||||
title: Render State
|
||||
category: 10_Wiki/Topics
|
||||
status: needs_review
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [P-Reinforce-AUTO-6A1728]
|
||||
aliases: [GPU Render State, Pipeline State, Graphics State]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
tags: [auto-reinforced]
|
||||
verification_status: applied
|
||||
tags: [graphics, gpu, rendering, pipeline]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-04-20
|
||||
github_commit: "[P-Reinforce] Continuous Worker - Render [[State|State]]"
|
||||
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: unspecified
|
||||
framework: unspecified
|
||||
language: hlsl/glsl
|
||||
framework: vulkan/d3d12
|
||||
---
|
||||
|
||||
# [[Render State|Render State]]
|
||||
# Render State
|
||||
|
||||
## 📌 한 줄 통찰 (The Karpathy Summary)
|
||||
> 렌더링 상태(Render State)란 드로우 콜을 실행하기 위해 CPU가 설정하는 GPU의 내부 설정 및 리소스 상태를 의미합니다 [1, 2]. 셰이더 프로그램 바인딩, 재질 변경, 정점 버퍼 할당 등 렌더 상태를 변경하는 작업은 그래픽 API가 수행하는 연산 중 가장 리소스를 많이 소모하는 작업입니다 [1, 2]. 따라서 드로우 콜과 렌더 상태 변경 횟수를 최소화하는 것은 전체 그래픽 렌더링 성능을 최적화하는 데 매우 중요합니다 [2, 3].
|
||||
## 매 한 줄
|
||||
> **"매 GPU 명령마다 어떤 컨텍스트에서 그릴지 결정하는 파라미터 묶음"**. 매 blend mode, depth test, rasterizer setup, shader binding 의 collection. 매 modern Vulkan/D3D12 에서는 PSO (Pipeline State Object) 의 immutable bake — state change cost 의 minimization.
|
||||
|
||||
## 📖 구조화된 지식 (Synthesized Content)
|
||||
- **렌더 상태의 정의 및 역할:** 화면에 기하학적 구조를 그리기 위해 CPU는 드로우 콜([[Draw Call|Draw Call]])을 발생시키는데, 이를 준비하기 위해 CPU는 리소스를 설정하고 GPU의 내부 설정을 변경하며 이를 총칭하여 렌더 상태(Render State)라고 합니다 [2]. 여기에는 현재 렌더링 상태 설정, 셰이더 프로그램 바인딩, 정점 버퍼 및 텍스처 유닛 할당과 같은 복잡한 준비 과정이 포함됩니다 [1].
|
||||
- **성능에 미치는 영향:** 재질(Material)을 변경하는 등 렌더 상태를 변경하는 것은 그래픽 API 연산 중 리소스를 가장 많이 소모하는 작업입니다 [2]. 드로우 콜을 위한 렌더 상태 설정과 같은 준비 과정(오버헤드)은 실제 GPU가 정점을 처리하고 픽셀을 그리는 시간보다 훨씬 더 많은 CPU 자원을 소모하는 경우가 많습니다 [1].
|
||||
- **최적화 전략:** 렌더 상태 변경을 최적화하는 핵심은 변경 횟수 자체를 줄이는 것입니다 [2]. 이를 위한 두 가지 주요 방법은 다음과 같습니다:
|
||||
1. **드로우 콜 수 감소:** 전체 드로우 콜 수를 줄이면 드로우 콜 사이에 발생하는 렌더 상태 변경 횟수도 자연스럽게 감소합니다 [3].
|
||||
2. **드로우 콜 구성 최적화:** 그래픽 API가 여러 드로우 콜을 수행할 때 동일한 렌더 상태를 유지할 수 있도록 드로우 콜을 효율적으로 구성하면, 드로우 콜을 그룹화하여 잦은 렌더 상태 변경을 방지할 수 있습니다 [3].
|
||||
- **최적화의 이점:** 렌더 상태 변경과 드로우 콜을 최적화하면 일차적으로 프레임 렌더링 시간이 향상됩니다 [4]. 또한, 애플리케이션의 전력 소비를 줄여 배터리 소모와 기기 발열을 감소시킬 수 있으며, 이후 프로젝트에 더 많은 오브젝트(GameObject)를 추가하더라도 큰 성능 저하를 방지하여 장기적인 유지보수성을 높여줍니다 [4].
|
||||
## 매 핵심
|
||||
|
||||
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
|
||||
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
|
||||
- **정책 변화:** Programming & Language 분야의 자동 자산화 수행.
|
||||
### 매 구성 요소
|
||||
- **Rasterizer state**: cull mode, fill mode, depth bias.
|
||||
- **Depth-stencil state**: depth test, stencil ops, write masks.
|
||||
- **Blend state**: src/dst factors, blend op, write mask.
|
||||
- **Input layout**: vertex attribute format.
|
||||
- **Shader stages**: VS / PS / GS / HS / DS / CS bindings.
|
||||
- **Descriptor sets / root signature**: resource bindings.
|
||||
|
||||
## 🔗 지식 연결 (Graph)
|
||||
- **Related Topics:** [[Draw Call|Draw Call]], CPU, [[GPU|GPU]]
|
||||
- **Projects/Contexts:** [[Unity|Unity]], Real-time Rendering
|
||||
- **Contradictions/Notes:** 소스 내에서 렌더 상태에 관한 정보나 최적화 방향성에 대해 상충되는 주장은 존재하지 않습니다.
|
||||
### 매 진화
|
||||
- **OpenGL/D3D9-11**: per-state setter — `glEnable(GL_DEPTH_TEST)` style. Driver 의 lazy validation cost 큼.
|
||||
- **D3D12 / Vulkan / Metal**: PSO bake at create time. Runtime change = bind 1 PSO.
|
||||
- **WebGPU 2025**: Vulkan style PSO + 동일 abstractions.
|
||||
|
||||
---
|
||||
*Last updated: 2026-04-19*
|
||||
### 매 응용
|
||||
1. Forward / deferred 의 pass 별 PSO 분리.
|
||||
2. Shadow pass 의 depth-only PSO.
|
||||
3. UI overlay 의 alpha-blend PSO.
|
||||
|
||||
---
|
||||
## 💻 패턴
|
||||
|
||||
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
|
||||
|
||||
**언제 이 지식을 쓰는가:**
|
||||
- *(TODO)*
|
||||
|
||||
**언제 쓰면 안 되는가:**
|
||||
- *(TODO)*
|
||||
|
||||
## 🧪 검증 상태 (Validation)
|
||||
|
||||
- **정보 상태:** needs_review
|
||||
- **출처 신뢰도:** A
|
||||
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
|
||||
|
||||
## 🧬 중복 검사 (Duplicate Check)
|
||||
|
||||
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
|
||||
- **처리 방식:** UPDATE (자동 정규화)
|
||||
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
|
||||
|
||||
## 🕓 변경 이력 (Changelog)
|
||||
|
||||
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|
||||
|------|-----------|-----------|--------|
|
||||
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
|
||||
|
||||
## 💻 코드 패턴 (Code Patterns)
|
||||
|
||||
**패턴 1:** *(TODO: 이 프로젝트 컨벤션 반영한 구조 스켈레톤)*
|
||||
|
||||
```text
|
||||
# TODO
|
||||
### Vulkan PSO 생성
|
||||
```cpp
|
||||
VkGraphicsPipelineCreateInfo info{};
|
||||
info.stageCount = 2;
|
||||
info.pStages = stages; // VS + PS
|
||||
info.pVertexInputState = &vi;
|
||||
info.pInputAssemblyState = &ia;
|
||||
info.pRasterizationState = &rs; // cull, fill
|
||||
info.pDepthStencilState = &ds; // test, write
|
||||
info.pColorBlendState = &cb; // alpha blend
|
||||
info.layout = pipelineLayout;
|
||||
info.renderPass = rp;
|
||||
vkCreateGraphicsPipelines(dev, cache, 1, &info, nullptr, &pso);
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준 (Decision Criteria)
|
||||
### State sort 의 draw call batching
|
||||
```cpp
|
||||
std::sort(drawables.begin(), drawables.end(), [](auto& a, auto& b){
|
||||
if (a.psoHash != b.psoHash) return a.psoHash < b.psoHash;
|
||||
if (a.materialHash != b.materialHash) return a.materialHash < b.materialHash;
|
||||
return a.depth < b.depth;
|
||||
});
|
||||
for (auto& d : drawables) {
|
||||
if (d.psoHash != lastPso) cmd.bindPipeline(d.pso);
|
||||
if (d.materialHash != lastMat) cmd.bindDescriptorSets(...);
|
||||
cmd.draw(...);
|
||||
}
|
||||
```
|
||||
|
||||
**선택 A를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
### Dynamic state subset
|
||||
```cpp
|
||||
VkPipelineDynamicStateCreateInfo dyn{};
|
||||
VkDynamicState ds[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
|
||||
dyn.dynamicStateCount = 2;
|
||||
dyn.pDynamicStates = ds;
|
||||
// PSO 는 viewport/scissor 없이 bake → runtime 에서 cmd.setViewport()
|
||||
```
|
||||
|
||||
**선택 B를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
### D3D12 root signature + PSO
|
||||
```cpp
|
||||
CD3DX12_PIPELINE_STATE_STREAM_DESC desc;
|
||||
desc.pRootSignature = rootSig;
|
||||
desc.VS = {vsBlob, vsSize};
|
||||
desc.PS = {psBlob, psSize};
|
||||
desc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
|
||||
desc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
|
||||
desc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
|
||||
device->CreateGraphicsPipelineState(&desc, IID_PPV_ARGS(&pso));
|
||||
```
|
||||
|
||||
**기본값:**
|
||||
> *(TODO)*
|
||||
### Shader hot-reload + PSO cache
|
||||
```cpp
|
||||
auto hash = HashShaders(vs, ps) ^ HashState(rs, ds, cb);
|
||||
if (auto it = cache.find(hash); it != cache.end()) return it->second;
|
||||
auto pso = CreatePso(...);
|
||||
cache[hash] = pso;
|
||||
return pso;
|
||||
```
|
||||
|
||||
## ❌ 안티패턴 (Anti-Patterns)
|
||||
### Bindless descriptor + PSO 단순화
|
||||
```cpp
|
||||
// Descriptor heap 1개 + bindless indexing → PSO 변경 거의 없음
|
||||
ConstantBuffer<uint> meshIdx;
|
||||
Texture2D<float4> textures[] : register(t0, space0);
|
||||
float4 color = textures[NonUniformResourceIndex(materialId)].Sample(...);
|
||||
```
|
||||
|
||||
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| AAA 엔진, 수만 draw call | PSO + sort by state hash |
|
||||
| Indie, simple 2D | Dynamic state OK, PSO 1-2개 |
|
||||
| Shader 자주 바뀜 (dev) | PSO cache + hot-reload |
|
||||
| Mobile (tile-based) | Render pass 단위 minimization |
|
||||
|
||||
**기본값**: PSO bake at level load + state-sorted draw queue.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Graphics Pipeline]] · [[GPU]]
|
||||
- 변형: [[PSO]] · [[Pipeline State Object]] · [[Root Signature]]
|
||||
- 응용: [[Forward Rendering]] · [[Deferred Rendering]] · [[Shadow Mapping]]
|
||||
- Adjacent: [[Vulkan]] · [[D3D12]] · [[WebGPU]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: state-sort 알고리즘 작성, PSO cache 설계, Vulkan boilerplate 생성.
|
||||
**언제 X**: GPU vendor 별 micro-optimization (driver 의 black-box).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Per-draw PSO recreation**: stutter 발생. Cache + warmup 필수.
|
||||
- **State leak**: legacy GL 코드 의 `glEnable` 후 disable 누락 → 다음 frame corruption.
|
||||
- **Over-granular PSO**: 1만 PSO → memory + driver overhead.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Vulkan spec, D3D12 docs, GPU Gems).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Render state full coverage |
|
||||
|
||||
Reference in New Issue
Block a user