fix: 修复 DX FL 10 的硬件上编译着色器依然使用ShaderModel 5.0的问题

This commit is contained in:
Xu Liu 2021-12-01 21:25:15 +08:00
commit 4020cd92b8
14 changed files with 138 additions and 847 deletions

View file

@ -6,6 +6,7 @@
#include <charconv>
#include "EffectCache.h"
#include "StrUtils.h"
#include "App.h"
static constexpr const char* META_INDICATOR = "//!";
@ -13,6 +14,38 @@ static constexpr const char* META_INDICATOR = "//!";
extern std::shared_ptr<spdlog::logger> logger;
class PassInclude : public ID3DInclude {
public:
HRESULT CALLBACK Open(
D3D_INCLUDE_TYPE IncludeType,
LPCSTR pFileName,
LPCVOID pParentData,
LPCVOID* ppData,
UINT* pBytes
) override {
std::wstring relativePath = L"effects\\" + StrUtils::UTF8ToUTF16(pFileName);
std::string file;
if (!Utils::ReadTextFile(relativePath.c_str(), file)) {
return E_FAIL;
}
char* result = new char[file.size()];
std::memcpy(result, file.data(), file.size());
*ppData = result;
*pBytes = (UINT)file.size();
return S_OK;
}
HRESULT CALLBACK Close(LPCVOID pData) override {
delete[](char*)pData;
return S_OK;
}
};
static PassInclude passInclude;
UINT RemoveComments(std::string& source) {
// 确保以换行符结尾
@ -729,62 +762,6 @@ UINT ResolveCommon(std::string_view& block) {
return 0;
}
class PassInclude : public ID3DInclude {
public:
HRESULT CALLBACK Open(
D3D_INCLUDE_TYPE IncludeType,
LPCSTR pFileName,
LPCVOID pParentData,
LPCVOID* ppData,
UINT* pBytes
) override {
std::wstring relativePath = L"effects\\" + StrUtils::UTF8ToUTF16(pFileName);
std::string file;
if (!Utils::ReadTextFile(relativePath.c_str(), file)) {
return E_FAIL;
}
char* result = new char[file.size()];
std::memcpy(result, file.data(), file.size());
*ppData = result;
*pBytes = (UINT)file.size();
return S_OK;
}
HRESULT CALLBACK Close(LPCVOID pData) override {
delete[](char*)pData;
return S_OK;
}
};
bool CompilePassPS(std::string_view hlsl, const char* entryPoint, ID3DBlob** blob, UINT passIndex) {
ComPtr<ID3DBlob> errorMsgs = nullptr;
UINT flags = D3DCOMPILE_ENABLE_STRICTNESS;
PassInclude passInclude;
HRESULT hr = D3DCompile(hlsl.data(), hlsl.size(), fmt::format("Pass{}", passIndex).c_str(), nullptr, &passInclude,
entryPoint, "ps_5_0", flags, 0, blob, &errorMsgs);
if (FAILED(hr)) {
if (errorMsgs) {
SPDLOG_LOGGER_ERROR(logger, MakeComErrorMsg(
fmt::format("编译像素着色器失败:{}", (const char*)errorMsgs->GetBufferPointer()), hr));
}
return false;
} else {
if (errorMsgs) {
// 显示警告消息
SPDLOG_LOGGER_WARN(logger,
"编译像素着色器时产生警告:"s + (const char*)errorMsgs->GetBufferPointer());
}
}
return true;
}
struct TPContext {
ULONG index;
std::vector<std::string>& passSources;
@ -794,8 +771,9 @@ struct TPContext {
void NTAPI TPWork(PTP_CALLBACK_INSTANCE, PVOID Context, PTP_WORK) {
TPContext* con = (TPContext*)Context;
ULONG index = InterlockedIncrement(&con->index);
if (!CompilePassPS(con->passSources[index], "__M", con->passes[index].cso.ReleaseAndGetAddressOf(), index + 1)) {
if (!App::GetInstance().GetRenderer().CompileShader(false, con->passSources[index],
"__M", con->passes[index].cso.ReleaseAndGetAddressOf(), fmt::format("Pass{}", index + 1).c_str(), &passInclude)) {
con->passes[index].cso = nullptr;
}
}
@ -1010,8 +988,10 @@ UINT ResolvePasses(const std::vector<std::string_view>& blocks, const std::vecto
// 编译生成的 hlsl
assert(!passSources.empty());
Renderer& renderer = App::GetInstance().GetRenderer();
if (passSources.size() == 1) {
if (!CompilePassPS(passSources[0], "__M", desc.passes[0].cso.ReleaseAndGetAddressOf(), 1)) {
if (!renderer.CompileShader(false, passSources[0], "__M", desc.passes[0].cso.ReleaseAndGetAddressOf(), "Pass1", &passInclude)) {
SPDLOG_LOGGER_ERROR(logger, "编译 Pass1 失败");
return 1;
}
@ -1030,7 +1010,7 @@ UINT ResolvePasses(const std::vector<std::string_view>& blocks, const std::vecto
SubmitThreadpoolWork(work);
}
CompilePassPS(passSources[0], "__M", desc.passes[0].cso.ReleaseAndGetAddressOf(), 1);
renderer.CompileShader(false, passSources[0], "__M", desc.passes[0].cso.ReleaseAndGetAddressOf(), "Pass1", &passInclude);
WaitForThreadpoolWorkCallbacks(work, FALSE);
CloseThreadpoolWork(work);
@ -1046,7 +1026,7 @@ UINT ResolvePasses(const std::vector<std::string_view>& blocks, const std::vecto
// 回退到单线程
for (size_t i = 0; i < passSources.size(); ++i) {
if (!CompilePassPS(passSources[i], "__M", desc.passes[i].cso.ReleaseAndGetAddressOf(), (UINT)i + 1)) {
if (!renderer.CompileShader(false, passSources[i], "__M", desc.passes[i].cso.ReleaseAndGetAddressOf(), fmt::format("Pass{}", i + 1).c_str(), &passInclude)) {
SPDLOG_LOGGER_ERROR(logger, fmt::format("编译 Pass{} 失败", i + 1));
return 1;
}