Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/GPU/D3D11/D3D11Util.cpp
3186 views
1
#include "ppsspp_config.h"
2
3
#include <cstdint>
4
#include <cfloat>
5
#include <vector>
6
#include <string>
7
#include <d3d11.h>
8
#include <D3Dcompiler.h>
9
10
#if PPSSPP_PLATFORM(UWP)
11
#define ptr_D3DCompile D3DCompile
12
#else
13
#include "Common/GPU/D3D11/D3D11Loader.h"
14
#endif
15
16
#include "Common/CommonFuncs.h"
17
#include "Common/Log.h"
18
#include "Common/StringUtils.h"
19
20
#include "D3D11Util.h"
21
#include <wrl/client.h>
22
23
using namespace Microsoft::WRL;
24
25
std::vector<uint8_t> CompileShaderToBytecodeD3D11(const char *code, size_t codeSize, const char *target, UINT flags) {
26
ComPtr<ID3DBlob> compiledCode;
27
ComPtr<ID3DBlob> errorMsgs;
28
HRESULT result = ptr_D3DCompile(code, codeSize, nullptr, nullptr, nullptr, "main", target, flags, 0, &compiledCode, &errorMsgs);
29
std::string errors;
30
if (errorMsgs) {
31
errors = std::string((const char *)errorMsgs->GetBufferPointer(), errorMsgs->GetBufferSize() > 1 ? (errorMsgs->GetBufferSize() - 1) : 0);
32
std::string numberedCode = LineNumberString(code);
33
if (SUCCEEDED(result)) {
34
std::vector<std::string_view> lines;
35
SplitString(errors, '\n', lines);
36
for (auto &line : lines) {
37
auto trimmed = StripSpaces(line);
38
// Ignore the useless warning about taking the power of negative numbers.
39
if (trimmed.find("pow(f, e) will not work for negative f") != std::string::npos) {
40
continue;
41
}
42
if (trimmed.size() > 1) { // ignore single nulls, not sure how they appear.
43
WARN_LOG(Log::G3D, "%.*s", (int)trimmed.length(), trimmed.data());
44
}
45
}
46
} else {
47
ERROR_LOG(Log::G3D, "%s: %s\n\n%s", "errors", errors.c_str(), numberedCode.c_str());
48
OutputDebugStringA(errors.c_str());
49
OutputDebugStringA(numberedCode.c_str());
50
}
51
}
52
if (compiledCode) {
53
// Success!
54
const uint8_t *buf = (const uint8_t *)compiledCode->GetBufferPointer();
55
std::vector<uint8_t> compiled = std::vector<uint8_t>(buf, buf + compiledCode->GetBufferSize());
56
_assert_(compiled.size() != 0);
57
return compiled;
58
}
59
return std::vector<uint8_t>();
60
}
61
62
HRESULT CreateVertexShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, std::vector<uint8_t> *byteCodeOut, D3D_FEATURE_LEVEL featureLevel, UINT flags, ID3D11VertexShader **ppVertexShader) {
63
if (ppVertexShader)
64
*ppVertexShader = nullptr;
65
const char *profile = featureLevel <= D3D_FEATURE_LEVEL_9_3 ? "vs_4_0_level_9_1" : "vs_4_0";
66
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, profile, flags);
67
if (byteCode.empty())
68
return S_FALSE;
69
70
auto hr = device->CreateVertexShader(byteCode.data(), byteCode.size(), nullptr, ppVertexShader);
71
if (byteCodeOut)
72
*byteCodeOut = byteCode;
73
return hr;
74
}
75
76
HRESULT CreatePixelShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags, ID3D11PixelShader **ppPixelShader) {
77
if (ppPixelShader)
78
*ppPixelShader = nullptr;
79
const char *profile = featureLevel <= D3D_FEATURE_LEVEL_9_3 ? "ps_4_0_level_9_1" : "ps_4_0";
80
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, profile, flags);
81
if (byteCode.empty())
82
return S_FALSE;
83
84
return device->CreatePixelShader(byteCode.data(), byteCode.size(), nullptr, ppPixelShader);
85
}
86
87
HRESULT CreateComputeShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags, ID3D11ComputeShader **ppComputeShader) {
88
if (ppComputeShader)
89
*ppComputeShader = nullptr;
90
if (featureLevel <= D3D_FEATURE_LEVEL_9_3)
91
return S_FALSE;
92
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, "cs_4_0", flags);
93
if (byteCode.empty())
94
return S_FALSE;
95
96
return device->CreateComputeShader(byteCode.data(), byteCode.size(), nullptr, ppComputeShader);
97
}
98
99
HRESULT CreateGeometryShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags, ID3D11GeometryShader **ppGeometryShader) {
100
if (ppGeometryShader)
101
*ppGeometryShader = nullptr;
102
if (featureLevel <= D3D_FEATURE_LEVEL_9_3)
103
return S_FALSE;
104
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, "gs_5_0", flags);
105
if (byteCode.empty())
106
return S_FALSE;
107
108
return device->CreateGeometryShader(byteCode.data(), byteCode.size(), nullptr, ppGeometryShader);
109
}
110
111