CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/GPU/D3D11/D3D11Util.cpp
Views: 1401
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
22
std::vector<uint8_t> CompileShaderToBytecodeD3D11(const char *code, size_t codeSize, const char *target, UINT flags) {
23
ID3DBlob *compiledCode = nullptr;
24
ID3DBlob *errorMsgs = nullptr;
25
HRESULT result = ptr_D3DCompile(code, codeSize, nullptr, nullptr, nullptr, "main", target, flags, 0, &compiledCode, &errorMsgs);
26
std::string errors;
27
if (errorMsgs) {
28
errors = std::string((const char *)errorMsgs->GetBufferPointer(), errorMsgs->GetBufferSize());
29
std::string numberedCode = LineNumberString(code);
30
if (SUCCEEDED(result)) {
31
std::vector<std::string_view> lines;
32
SplitString(errors, '\n', lines);
33
for (auto &line : lines) {
34
auto trimmed = StripSpaces(line);
35
// Ignore the useless warning about taking the power of negative numbers.
36
if (trimmed.find("pow(f, e) will not work for negative f") != std::string::npos) {
37
continue;
38
}
39
if (trimmed.size() > 1) { // ignore single nulls, not sure how they appear.
40
WARN_LOG(Log::G3D, "%.*s", (int)trimmed.length(), trimmed.data());
41
}
42
}
43
} else {
44
ERROR_LOG(Log::G3D, "%s: %s\n\n%s", "errors", errors.c_str(), numberedCode.c_str());
45
}
46
OutputDebugStringA(errors.c_str());
47
OutputDebugStringA(numberedCode.c_str());
48
errorMsgs->Release();
49
}
50
if (compiledCode) {
51
// Success!
52
const uint8_t *buf = (const uint8_t *)compiledCode->GetBufferPointer();
53
std::vector<uint8_t> compiled = std::vector<uint8_t>(buf, buf + compiledCode->GetBufferSize());
54
_assert_(compiled.size() != 0);
55
compiledCode->Release();
56
return compiled;
57
}
58
return std::vector<uint8_t>();
59
}
60
61
ID3D11VertexShader *CreateVertexShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, std::vector<uint8_t> *byteCodeOut, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
62
const char *profile = featureLevel <= D3D_FEATURE_LEVEL_9_3 ? "vs_4_0_level_9_1" : "vs_4_0";
63
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, profile, flags);
64
if (byteCode.empty())
65
return nullptr;
66
67
ID3D11VertexShader *vs;
68
device->CreateVertexShader(byteCode.data(), byteCode.size(), nullptr, &vs);
69
if (byteCodeOut)
70
*byteCodeOut = byteCode;
71
return vs;
72
}
73
74
ID3D11PixelShader *CreatePixelShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
75
const char *profile = featureLevel <= D3D_FEATURE_LEVEL_9_3 ? "ps_4_0_level_9_1" : "ps_4_0";
76
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, profile, flags);
77
if (byteCode.empty())
78
return nullptr;
79
80
ID3D11PixelShader *ps;
81
device->CreatePixelShader(byteCode.data(), byteCode.size(), nullptr, &ps);
82
return ps;
83
}
84
85
ID3D11ComputeShader *CreateComputeShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
86
if (featureLevel <= D3D_FEATURE_LEVEL_9_3)
87
return nullptr;
88
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, "cs_4_0", flags);
89
if (byteCode.empty())
90
return nullptr;
91
92
ID3D11ComputeShader *cs;
93
device->CreateComputeShader(byteCode.data(), byteCode.size(), nullptr, &cs);
94
return cs;
95
}
96
97
ID3D11GeometryShader *CreateGeometryShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
98
if (featureLevel <= D3D_FEATURE_LEVEL_9_3)
99
return nullptr;
100
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, "gs_5_0", flags);
101
if (byteCode.empty())
102
return nullptr;
103
104
ID3D11GeometryShader *gs;
105
device->CreateGeometryShader(byteCode.data(), byteCode.size(), nullptr, &gs);
106
return gs;
107
}
108
109
void StockObjectsD3D11::Create(ID3D11Device *device) {
110
D3D11_BLEND_DESC blend_desc{};
111
blend_desc.RenderTarget[0].BlendEnable = false;
112
blend_desc.IndependentBlendEnable = false;
113
for (int i = 0; i < 16; i++) {
114
blend_desc.RenderTarget[0].RenderTargetWriteMask = i;
115
ASSERT_SUCCESS(device->CreateBlendState(&blend_desc, &blendStateDisabledWithColorMask[i]));
116
}
117
118
D3D11_DEPTH_STENCIL_DESC depth_desc{};
119
depth_desc.DepthEnable = FALSE;
120
ASSERT_SUCCESS(device->CreateDepthStencilState(&depth_desc, &depthStencilDisabled));
121
depth_desc.StencilEnable = TRUE;
122
depth_desc.StencilReadMask = 0xFF;
123
depth_desc.StencilWriteMask = 0xFF;
124
depth_desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
125
depth_desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_REPLACE;
126
depth_desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE;
127
depth_desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
128
depth_desc.BackFace = depth_desc.FrontFace;
129
ASSERT_SUCCESS(device->CreateDepthStencilState(&depth_desc, &depthDisabledStencilWrite));
130
131
D3D11_RASTERIZER_DESC raster_desc{};
132
raster_desc.FillMode = D3D11_FILL_SOLID;
133
raster_desc.CullMode = D3D11_CULL_NONE;
134
raster_desc.ScissorEnable = FALSE;
135
raster_desc.DepthClipEnable = TRUE; // the default! FALSE is unsupported on D3D11 level 9
136
ASSERT_SUCCESS(device->CreateRasterizerState(&raster_desc, &rasterStateNoCull));
137
138
D3D11_SAMPLER_DESC sampler_desc{};
139
sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
140
sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
141
sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
142
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
143
sampler_desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
144
for (int i = 0; i < 4; i++)
145
sampler_desc.BorderColor[i] = 1.0f;
146
sampler_desc.MinLOD = -FLT_MAX;
147
sampler_desc.MaxLOD = FLT_MAX;
148
sampler_desc.MipLODBias = 0.0f;
149
sampler_desc.MaxAnisotropy = 1;
150
ASSERT_SUCCESS(device->CreateSamplerState(&sampler_desc, &samplerPoint2DWrap));
151
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
152
ASSERT_SUCCESS(device->CreateSamplerState(&sampler_desc, &samplerLinear2DWrap));
153
sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
154
sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
155
sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
156
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
157
ASSERT_SUCCESS(device->CreateSamplerState(&sampler_desc, &samplerPoint2DClamp));
158
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
159
ASSERT_SUCCESS(device->CreateSamplerState(&sampler_desc, &samplerLinear2DClamp));
160
}
161
162
void StockObjectsD3D11::Destroy() {
163
for (int i = 0; i < 16; i++) {
164
blendStateDisabledWithColorMask[i]->Release();
165
}
166
depthStencilDisabled->Release();
167
depthDisabledStencilWrite->Release();
168
rasterStateNoCull->Release();
169
samplerPoint2DWrap->Release();
170
samplerLinear2DWrap->Release();
171
samplerPoint2DClamp->Release();
172
samplerLinear2DClamp->Release();
173
}
174
175
StockObjectsD3D11 stockD3D11;
176
177