Professional Documents
Culture Documents
Loader
Layer
缩写:ICDs。每一个支持一个或者多个设备(VkPhysicalDevice ).loader 负责找出可用的
DiligentEngine 分析:
2 注册创建窗口。
3 动态加载渲染 api :
合并出动态 dll
sprintf_s(LibName, StringBufferSize, "%s%s%s.dll", EngineName, Arch, Conf);
hModuel = LoadLibraryA(LibName); //windows 32 加载 dll 库
GetFactoryFunc = GetProcAddress(hModuel ,GetFactoryFuncName)
4 创建 比较重要的类 渲染 API 工厂
5 创建 contetx 和 运行设备
运行时候检查错误:
#define VERIFY (EXPr,Message,...)
If(!EXPr)
ASSERTION_FAILED(Message, ##_VA__ARGS__);
创建内存分配器
SetRawAllocator(EngineCI.pRawMemAllocator);
//创建 shader
RefCntAutoPtr<IShaderSourceInputStreamFactory> pShaderSourceFactory;
m_pEngineFactory->CreateDefaultShaderSourceStreamFactory(nullptr,
&pShaderSourceFactory);
ShaderCI.pShaderSourceStreamFactory = pShaderSourceFactory;
通过创建 IShaderSourceInputStreamFactory 实现跨平台访问 shader 文件。
SRB
Shader resouces binding 必须创建一个用来绑定 shader 资源。Mutable 资源通过 SRB 进行设
置。SRB 包含了一个物体所有的资源。
1pCtx->PSSetShaderResources(0, NumSRVs, ppSRVs);
2pCtx->PSSetConstantBuffers(0, NumBuffers, ppCBs);
3pCtx->PSSetSamplers(0, NumSamplers, ppSamplers);
4pCtx->CSSetUnorderedAccessViews(0, NumUAVs, ppUAVs, nullptr);
杂项:待整理
...
進行到
判断數量計算錯誤。
来做库平台区分:
Hlsl 转 glsl 用
1 左值 右值 将亡值 存右值
//https://stackoverflow.com/questions/25312225/c-why-decltype-this-returns-a-
reference decltype(x) 如果 x 是左值,会返回&x 左值引用,如果 x 是 xvalue,就会返回
&&x 可移动。 左值就是驻留在内存中的,可以取出地址的表达式。
//xvlue 是将亡值,可以被移动的表达式 ,prvalue 纯右值。
所以 Allocator 是一个左值,会返回一个引用,因此当类型使用时候需要解除引用。
Diligent 引擎中创建一个 object 时候用法。
#define NEW_RC_OBJ(Allocator, Desc, Type, ...) MakeNewRCObj<Type, typename
std::remove_reference<decltype(Allocator)>::type>(Allocator, Desc, __FILE__,
__LINE__, ##__VA_ARGS__)
} // namespace Diligent
1)++i 是左值,i++是右值。
前者,对 i 加 1 后再赋给 i,最终的返回值就是 i,所以,++i 的结果是具名的,名字就
是 i;而对于 i++而言,是先对 i 进行一次拷贝,将得到的副本作为返回结果,然后再对 i
加 1,由于 i++的结果是对 i 加 1 前 i 的一份拷贝,所以它是不具名的。假设自增前 i 的值是
6,那么,++i 得到的结果是 7,这个 7 有个名字,就是 i;而 i++得到的结果是 6,这个 6
是 i 加 1 前的一个副本,它没有名字,i 不是它的名字,i 的值此时也是 7。可见,++i 和 i+
+都达到了使 i 加 1 的目的,但两个表达式的结果不同。
2)所以++i 效率更高、
2 lambda 表达式作模板参数,不需要再函数做声明,会自动把 lamda 看作为模板参数:
SPirv 生成:
主要方法:CompileShaderInternal
经过一系列处理后真正解析的位置:
Spirv 添加逻辑
前面 5 个字符表示
// Header, before first instructions:
out.push_back(MagicNumber);
out.push_back(spvVersion);
out.push_back(builderNumber);
out.push_back(uniqueId + 1);
out.push_back(0);
Spirv 解析:
接下来解析指令:
Stream 的 作 用 是 返 回 当 前 指 令 开 始 的 地 址 。 并 保 证 指 令 数 不 会 越 界 , 否 则 抛 出
std::runtimeError。
String result;
从当前指令的偏移地址算起:直到整个指令结束为止:
取出当前指令
For( j=0; j<4; ++j, 当前指令值右移 8 位 )
{
Char 指令字符 = 当前指令 & 255
如果 指令字符为空 返回 result
否则 累加指令支付到字符串 result
}
经过两层循环,外层取出指令,内层循环对当前指令做四次字符取值,这样直到返回空格
该次解析终止。
代码解析
具体执行位置:
解析完毕后执行反射
具体参考 https://github.com/KhronosGroup/SPIRV-Cross/wiki/Reflection-API-user-guide
Spirv:调试判断
Spirv 如果想调试成功必须开启:device 必须开启 SPV_KHR_non_semantic_info 扩展
开启成功后编译的 spirv 代码:里面有黄色的内容字样。 hello 是我打印的字符串。
先会统一执行:
然后 走判断是否保护字符
接着把
实际在使用过程中会进行各种优化:如果发现灭有打印成功,那么就得检查一下是否开启
了优化:
最终打印成功:
创建新的控制台窗口:
如 DX 中间编译语言 DXIL
其中最重要的是:
Error:
检查内存泄露创建 runtime 类
通过 NEW_RC_OBJ 创建出需要的类对象,传递进去要创建的对象类型,以及一些参数。
RenderDeviceVkImpl:要创建目标类
RawMemAllocator:内存分配器对象。
NEW_RC_OBJ:
代码为
//https://stackoverflow.com/questions/25312225/c-why-decltype-this-returns-a-reference
decltype(x) 如果 x 是左值,会返回 &x 左值引用,如果 x 是 xvalue,就会返回&&x 可移动。 左值就是驻留在
内存中的,可以取出地址的表达式。
//xvlue 是将亡值,可以被移动的表达式 ,prvalue 纯右值。
#defineNEW_RC_OBJ(Allocator,Desc,Type,...)MakeNewRCObj<Type,typename
std::remove_reference<decltype(Allocator)>::type>(Allocator,Desc,__FILE__,__LINE__, ##__VA_ARGS__)
这些参数。
:
根据 operator new 方法中会自动计算出当前对象的 size,也可以可以用来打印当前对象的
大小。
class car
{
string name;
int num;
public:
car(string a, int n)
{
cout << "Constructor called" << endl;
this->name = a;
this->num = n;
}
void display()
{
cout << "Name: " << name << endl;
cout << "Num: " << num << endl;
}
void* operator new(size_t size)
{
cout << "new operator overloaded" << endl;
void* p = malloc(size);
return p;
}
void operator delete(void* ptr)
{
cout << "delete operator overloaded" << endl;
free(ptr);
}
};
ar* p = new car("HYUNDAI", 2012);
修改向 operator new 添加参数 int
void* operator new(size_t size,int id)
{
cout << "new operator overloaded" << endl;
void* p = malloc(size);
return p;
}
调用方式在 new char 中间添加参数即可 car* p = new (1)car("HYUNDAI", 2012);
UE4 资源注册方式:
声明全局的资源
TGlobalResource<FFilterVertexDeclaration> GFilterVertexDeclaration;
InitResouce 里 面
把资源添加到
static