--- id: wiki-2026-0508-render-state title: Render State category: 10_Wiki/Topics status: verified canonical_id: self aliases: [GPU Render State, Pipeline State, Graphics State] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [graphics, gpu, rendering, pipeline] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: hlsl/glsl framework: vulkan/d3d12 --- # Render State ## 매 한 줄 > **"매 GPU 명령마다 어떤 컨텍스트에서 그릴지 결정하는 파라미터 묶음"**. 매 blend mode, depth test, rasterizer setup, shader binding 의 collection. 매 modern Vulkan/D3D12 에서는 PSO (Pipeline State Object) 의 immutable bake — state change cost 의 minimization. ## 매 핵심 ### 매 구성 요소 - **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. ### 매 진화 - **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. ### 매 응용 1. Forward / deferred 의 pass 별 PSO 분리. 2. Shadow pass 의 depth-only PSO. 3. UI overlay 의 alpha-blend PSO. ## 💻 패턴 ### 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); ``` ### 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(...); } ``` ### 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() ``` ### 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)); ``` ### 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; ``` ### Bindless descriptor + PSO 단순화 ```cpp // Descriptor heap 1개 + bindless indexing → PSO 변경 거의 없음 ConstantBuffer meshIdx; Texture2D textures[] : register(t0, space0); float4 color = textures[NonUniformResourceIndex(materialId)].Sample(...); ``` ## 매 결정 기준 | 상황 | 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]] - 응용: [[Deferred Rendering]] - Adjacent: [[Vulkan]] · [[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 |