利用 Direct3D 绘制几何体—9.流水线状态对象
到目前为止展示过编写输入布局描述、创建顶点着色器和像素着色器,以及配置光栅器状态组这 3 个步骤。接下来讲如何将这些对象绑定到图形流水线上,用以实际绘制图形。大多数控制图形流水线状态的对象被统称为流水线状态对象(Pipeline State Object,PSO),用 ID3D12PipelineState 接口来表示。要创建 PSO,我们首先要填写一份描述其细节的 D3D12_GRAPHICS_PIPELINE_STATE_DESC 结构体实例。
typedef struct D3D12_GRAPHICS_PIPELINE_STATE_DESC
{ID3D12RootSignature *pRootSignature;D3D12_SHADER_BYTECODE VS;D3D12_SHADER_BYTECODE PS;D3D12_SHADER_BYTECODE DS;D3D12_SHADER_BYTECODE HS;D3D12_SHADER_BYTECODE GS;D3D12_STREAM_OUTPUT_DESC StreamOutput;D3D12_BLEND_DESC BlendState;UINT SampleMask;D3D12_RASTERIZER_DESC RasterizerState;D3D12_DEPTH_STENCIL_DESC DepthStencilState;D3D12_INPUT_LAYOUT_DESC InputLayout;D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType;UINT NumRenderTargets;DXGI_FORMAT RTVFormats[8];DXGI_FORMAT DSVFormat;DXGI_SAMPLE_DESC SampleDesc;
} D3D12_GRAPHICS_PIPELINE_STATE_DESC;
1. pRootSignature:指向一个与此 PSO 相绑定的根签名的指针。该根签名一定要与此 PSO 指定的着色器相兼容。
2. VS:待绑定的顶点着色器。此成员由结构体 D3D12_SHADER_BYTECODE 表示,这个结构体存有指向已编译好的字节码数据的指针,以及该字节码数据所占的字节大小。
typedef struct D3D12_SHADER_BYTECODE {const void *pShaderBytecode;SIZE_T BytecodeLength;} D3D12_SHADER_BYTECODE;
3. PS:待绑定的像素着色器。
4. DS:待绑定的域着色器(我们将在后续章节中讲解此类型的着色器)。
5. HS:待绑定的外壳着色器(我们将在后续章节中讲解此类型的着色器)。
6. GS:待绑定的几何着色器(我们将在后续章节中讲解此类型的着色器)。
7. StreamOutput:用于实现一种称作流输出(stream-out)的高级技术。目前我们仅将此字段清零。
8. BlendState:指定混合(blending)操作所用的混合状态。我们将在后续章节中讨论此状态组,目前仅将此成员指定为默认的 CD3DX12_BLEND_DESC(D3D12_DEFAULT)。
9. SampleMask:多重采样最多可采集 32 个样本。借此参数的 32 位整数值,即可设置每个采样点的采集情况(采集或禁止采集)。例如,若禁用了第 5 位(将第 5 位设置为 0),则将不会对第 5 个样本进行采样。当然,要禁止采集第 5 个样本的前提是,所用的多重采样至少要有 5 个样本。假如一个应用程序仅使用了单采样(single sampling),那么只能针对该参数的第 1 位进行配置。一般来说,使用的都是默认值 0xffffffff,即表示对所有的采样点都进行采样。
10. RasterizerState:指定用来配置光栅器的光栅化状态。
11. DepthStencilState:指定用于配置深度/模板测试的深度/模板状态。我们将在后续章节中对此状态进行讨论,目前只把它设为默认的 CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT)。
12. InputLayout:输入布局描述,此结构体中有两个成员:一个由 D3D12_INPUT_ELEMENT_DESC 元素构成的数组,以及一个表示此数组中元素数量的无符号整数。
typedef struct D3D12_INPUT_LAYOUT_DESC{const D3D12_INPUT_ELEMENT_DESC *pInputElementDescs;UINT NumElements;} D3D12_INPUT_LAYOUT_DESC;
13. PrimitiveTopologyType:指定图元的拓扑类型。
typedef enum D3D12_PRIMITIVE_TOPOLOGY_TYPE { D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED = 0,D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT = 1,D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE = 2,D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE = 3,D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH = 4} D3D12_PRIMITIVE_TOPOLOGY_TYPE
14. NumRenderTargets:同时所用的渲染目标数量(即 RTVFormats 数组中渲染目标格式的数量)。
15. RTVFormats:渲染目标的格式。利用该数组实现向多渲染目标同时进行写操作。使用此 PSO 的渲染目标的格式设定应当与此参数相匹配。
16. DSVFormat:深度/模板缓冲区的格式。使用此 PSO 的深度/模板缓冲区的格式设定应当与此参数相匹配。
17. SampleDesc:描述多重采样对每个像素采样的数量及其质量级别。此参数应与渲染目标的对应设置相匹配。
在 D3D12_GRAPHICS_PIPELINE_STATE_DESC 实例填写完毕后,我们即可用 ID3D12Device::CreateGraphicsPipelineState 方法来创建 ID3D12PipelineState 对象。
// BoxApp.cpp 58行
ComPtr mRootSignature;
std::vector mInputLayout;
ComPtr mvsByteCode;
ComPtr mpsByteCode;
...
// BoxApp.cpp 436行 BuildPSO()
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc;
ZeroMemory(&psoDesc, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC));
psoDesc.InputLayout = { mInputLayout.data(), (UINT)mInputLayout.size() };
psoDesc.pRootSignature = mRootSignature.Get();
psoDesc.VS =
{ reinterpret_cast(mvsByteCode->GetBufferPointer()),mvsByteCode->GetBufferSize()
};
psoDesc.PS =
{ reinterpret_cast(mpsByteCode->GetBufferPointer()), mpsByteCode->GetBufferSize()
};
psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
psoDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
psoDesc.SampleMask = UINT_MAX;
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
psoDesc.NumRenderTargets = 1;
psoDesc.RTVFormats[0] = mBackBufferFormat;
psoDesc.SampleDesc.Count = m4xMsaaState ? 4 : 1;
psoDesc.SampleDesc.Quality = m4xMsaaState ? (m4xMsaaQuality - 1) : 0;
psoDesc.DSVFormat = mDepthStencilFormat;ComPtr mPSO;
md3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&mPSO)));
ID3D12PipelineState 对象集合了大量的流水线状态信息。为了保证性能,我们将所有这些对象都集总在一起,一并送至渲染流水线。通过这样的一个集合,Direct3D 便可以确定所有的状态是否彼此兼容,而驱动程序则能够据此而提前生成硬件本地指令及其状态。
注意:由于 PSO 的验证和创建操作过于耗时,所以应在初始化期间就生成 PSO。除非有特别的需求,例如,在运行时创建 PSO 伊始就要当即对它进行第一次引用的这种情况。随后,我们就可将它存于如散列表(哈希表)这样的集合里,以便在后续使用时快速获取。
并非所有的渲染状态都封装于 PSO 内,如视口(viewport)和裁剪矩形(scissor rectangle)等属性就独立于 PSO。由于将这些状态的设置与其他的流水线状态分隔开来会更有效,所以把它们强行集中在 PSO 内也并不会为之增添任何优势。
Direct3D 实质上就是一种状态机(state machine),里面的事物会保持它们各自的状态,直到我们将其改变。如果我们以不同的 PSO 去绘制不同物体,则需要像下面那样来组织代码:
// 重置命令列表并指定初始 PSO
mCommandList->Reset(mDirectCmdListAlloc.Get(), mPSO1.Get());
/* ……使用 PSO 1绘制物体…… */// 改变 PSO
mCommandList->SetPipelineState(mPSO2.Get());
/* ……使用 PSO 2绘制物体…… */// 改变 PSO
mCommandList->SetPipelineState(mPSO3.Get());
/* ……使用 PSO 3绘制物体…… */
换句话说,如果把一个 PSO 与命令列表相绑定,那么,在我们设置另一个 PSO 或重置命令列表之前,会一直沿用当前的 PSO 绘制物体。
考虑到程序的性能问题,我们应当尽可能减少改变 PSO 状态的次数。为此,若能以一个 PSO 绘制出所有的物体,绝不用第二个 PSO。切记,不要在每次绘制调用时都修改 PSO。
相关文章:
利用 Direct3D 绘制几何体—9.流水线状态对象
到目前为止展示过编写输入布局描述、创建顶点着色器和像素着色器,以及配置光栅器状态组这 3 个步骤。接下来讲如何将这些对象绑定到图形流水线上,用以实际绘制图形。大多数控制图形流水线状态的对象被统称为流水线状态对象(Pipeline State Ob…...
【开源项目】libfaketime安装、使用——小白教程
项目 Github:GitHub - wolfcw/libfaketime: libfaketime modifies the system time for a single application libfaketime安装 01.切换路径,目标路径:/usr/local (在/usr/local路径下git clone 开源项目) 切换路径指令: cd …...
java.util.concurrent包
java.util.concurrent包是Java中用于并发编程的重要工具集,提供了丰富的并发原语和组件,以简化多线程编程的复杂性,并帮助开发者编写高效、可伸缩和线程安全的并发程序。其主要功能包括以下几个方面: 一、线程池和任务执行框架 …...
Django创建项目模块+创建映射类+视图
确保你的项目已经正确链接数据库 链接数据库的工具有很多,数据库的种类也有很多,我使用的数据库是mysql,工具是pmysql,使用pymysql链接数据库,在settings文件中这么设置: DATABASES {# default: {# ENGINE: dja…...
使用AMD GPU和LangChain构建问答聊天机器人
Question-answering Chatbot with LangChain on an AMD GPU — ROCm Blogs 作者:Phillip Dang 2024年3月11日 LangChain是一个旨在利用语言模型强大功能来构建前沿应用程序的框架。通过将语言模型连接到各种上下文资源并基于给定的上下文提供推理能力,L…...
2024年808数据结构答案
1.已知带头结点单链表,H为头指针。设计一个算法,查找到链表的第m个结点(不包含头结点),并将元 素值为X的结点插入到该结点后,形成一个新的链表。 // 定义单链表节点结构 typedef struct Node {int data;struct Node* next; } Nod…...
Amazon Linux 2023 安装 Docker
Amazon Linux 2023 安装 Docker 1. 简介 在公司需要将代码部属到 Amazon Linux 2023 系统上时,去 Docker 官方文档里面看也没有针对该系统的部属文档。虽然有通用的 Linux 部属方案但不能应用包管理工具。 首先执行yum、dnf、apt,执行yum和dnf都有正确…...
接口测试(八)jmeter——参数化(CSV Data Set Config)
一、CSV Data Set Config 需求:批量注册5个用户,从CSV文件导入用户数据 1. 【线程组】–>【添加】–>【配置元件】–>【CSV Data Set Config】 2. 【CSV数据文件设置】设置如下 3. 设置线程数为5 4. 运行后查看响应结果...
GGD证明推导学习
GGD证明推导学习 这篇文章,建议先看相关的论文。这篇是我读证明的感悟,因此,不会论文的主体内容 首先,给出命题: DGI的sumary向量是一个常数 给定一个图: G { X ∈ R N D , A ∈ R N N } \mathcal{G…...
Flink难点和高频考点:Flink的反压产生原因、排查思路、优化措施和监控方法
目录 反压定义 反压影响 WebUI监控 Metrics指标 backPressureTimeMsPerSecond idleTimeMsPerSecond busyTimeMsPerSecond 反压可视化 资源优化 算子优化 数据倾斜优化 复杂算子优化 背压机制 反压预防 性能调优 内置工具 第三方工具 反压定义 在探讨Flink的性…...
Swarm - Agent 编排工具
文章目录 一、关于 Swarm(实验性、教育性)为什么选择蜂群文档 二、安装使用安装基本用法其它示例 三、Running Swarmclient.run()ArgumentsResponse字段 四、AgentFields Agent指令函数切换和更新上下文变量函数模式 流媒体评估工具 一、关于 Swarm&…...
使用Python中的jieba库进行简单情感分析
在自然语言处理(NLP)领域,情感分析是一项重要的任务,它可以帮助我们理解文本背后的情感倾向。本文将通过一个简单的例子来介绍如何使用Python的jieba库对中文文本进行基本的情感分析。 1. 环境准备 首先,确保已经安装…...
`pip` 下载速度慢
pip 下载速度慢(例如只有 50KB/s)可能由多个因素导致,以下是一些常见原因和解决方法: 1. 使用国内镜像源 国内访问 PyPI 服务器可能会较慢,您可以通过配置国内镜像源来提升下载速度。以下是一些常用的国内镜像源&…...
【WRF数据准备】基于GEE下载静态地理数据-叶面积指数LAI及绿色植被率Fpar
【WRF数据准备】基于GEE下载静态地理数据 准备:WRF所需静态地理数据(Static geographical data)数据范围说明基于GEE下载叶面积指数及绿色植被率GEE数据集介绍数据下载:LAI(叶面积指数)和Fpar(绿色植被率)数据处理:基于Python处理为单波段LAI数据参考GEE的介绍可参见另…...
网管平台(进阶篇):网管软件的配置方式
正确选择网管软件配置方式对于确保网络运行的高效性、稳定性和安全性至关重要,因为它直接影响到网络管理的灵活性、监控的深度以及故障响应的速度,从而保障整体网络环境的顺畅运行和业务连续性。下面我们就分别介绍一下。 一、集中式网络管理配置 在集…...
推荐系统中的AB测试
在现代互联网平台中,推荐系统起着至关重要的作用,无论是视频平台、社交网络还是电商网站,推荐系统都能够帮助用户找到最感兴趣的内容。为了不断优化推荐效果,AB测试(A/B Testing)作为评估新算法或功能改进的…...
.NET 8 Web API 中的身份验证和授权
本次介绍分为3篇文章: 1:.Net 8 Web API CRUD 操作.Net 8 Web API CRUD 操作-CSDN博客 2:在 .Net 8 API 中实现 Entity Framework 的 Code First 方法https://blog.csdn.net/hefeng_aspnet/article/details/143229912 3:.NET …...
Vue弹窗用也可以直接调用Js方法了
问题描述 在前端开发中,弹窗开发是一个不可避免的场景。然而,按照正常的逻辑,通过在template模板中先引用组件,然后通过v-if指令控制显隐,进而达到弹窗的效果。然而,这种方法却有一个严重的缺陷࿰…...
【c语言测试】
1. C语言中,逻辑“真”等价于( ) 题目分析: “逻辑真”在C语言中通常指的是非零数。 A. 大于零的数B. 大于零的整数C. 非零的数 (正确答案)D. 非零的整数 正确答案:C 2. 若定义了数组 int a[3][4];,则对…...
一种将树莓派打造为游戏机的方法——Lakka
什么是Lakka? Lakka是一款Linux发行版,轻量级的,可将小型计算机转变为一台复古游戏机。 图1-Lakka官网,见参考链接[1] Lakka是RetroArch和libretro生态系统下的官方操作系统,前者RetroArch是模拟器、游戏引擎和媒体播…...
从Xilinx 7系列FPGA看架构演进与工程选型实战
1. 项目概述:从一则旧闻看FPGA的演进与选型看到这个标题,很多朋友可能会觉得这是一则十多年前的“旧闻”了。确实,2011年Xilinx宣布其28nm 7系列FPGA在六个月内获得超过200个设计订单,这在当时是半导体行业的一个里程碑。但今天回…...
宠物胰岛素注射剂量安全指南:从单位与毫升混淆到规范操作
1. 从一次惊险的“救援”说起:宠物用药中的剂量迷思昨天早上,我差点目睹了一场因误解而引发的悲剧。走进厨房准备冲杯咖啡时,我看到一位同事(我们暂且称她为“A女士”)正准备给她刚被诊断为糖尿病的小狗注射胰岛素。她…...
Windows APK安装器完整指南:无需安卓手机直接安装应用
Windows APK安装器完整指南:无需安卓手机直接安装应用 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 想要在Windows电脑上直接安装Android应用吗ÿ…...
智能手机如何重塑芯片市场:从基带到SoC的平台化竞争
1. 市场格局的剧变:一部智能手机如何重塑芯片江湖如果你在2007年问一个半导体行业的从业者,手机核心芯片市场的格局会怎样,他大概率会给你描绘一个由德州仪器、飞思卡尔、英飞凌等传统巨头主导的图景。然而,仅仅五年后,…...
rust-rdkafka社区生态与最佳实践:知名项目使用案例分享
rust-rdkafka社区生态与最佳实践:知名项目使用案例分享 【免费下载链接】rust-rdkafka A fully asynchronous, futures-based Kafka client library for Rust based on librdkafka 项目地址: https://gitcode.com/gh_mirrors/ru/rust-rdkafka rust-rdkafka是…...
从零到一:51单片机蓝牙遥控车实战指南(附避坑要点)
1. 项目背景与准备 作为一个非硬件专业的爱好者,我第一次接触51单片机时完全是一头雾水。记得当时因为特殊原因在家闲着,突发奇想做个蓝牙遥控车玩玩。没想到这个简单的想法,让我踩遍了新手能遇到的所有坑。现在回头看,其实用51单…...
长期使用Taotoken后对账单追溯与审计功能的实际评价
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 长期使用Taotoken后对账单追溯与审计功能的实际评价 在持续使用大模型服务进行项目开发与团队协作的过程中,成本的可观…...
码农的职业天花板:30岁前必须突破的5个瓶颈
在软件行业的快速迭代浪潮中,软件测试从业者作为质量保障的核心力量,正面临着愈发严峻的职业挑战。30岁,不仅是人生的重要分水岭,更是测试人职业发展的关键节点。如果不能在这个阶段突破潜藏的瓶颈,很可能会陷入“经验…...
关键词覆盖不足,图标点击率低于行业均值18.7%?Gemini ASO深度调优全链路拆解
更多请点击: https://intelliparadigm.com 第一章:Gemini App Store优化的现状与挑战 生态碎片化加剧分发效率瓶颈 当前 Gemini App Store 尚未建立统一的开发者认证、审核策略与版本兼容性规范,导致应用在不同 Gemini 原生设备(…...
深度解析:PC端即时通讯防撤回功能的技术实现
深度解析:PC端即时通讯防撤回功能的技术实现 【免费下载链接】RevokeMsgPatcher :trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁(我已经看到了,撤回也没用了) 项目地址: https://gitcode.com/GitHub_…...
