2017-02-25 00:38:48 +00:00
|
|
|
#include "ppsspp_config.h"
|
|
|
|
|
2017-02-08 17:07:34 +00:00
|
|
|
#include <cstdint>
|
2018-03-22 21:14:19 +00:00
|
|
|
#include <cfloat>
|
2017-02-08 17:07:34 +00:00
|
|
|
#include <vector>
|
2020-09-29 10:19:22 +00:00
|
|
|
#include <string>
|
2017-02-08 17:07:34 +00:00
|
|
|
#include <d3d11.h>
|
|
|
|
#include <D3Dcompiler.h>
|
2017-02-09 23:01:56 +00:00
|
|
|
|
2017-02-25 00:38:48 +00:00
|
|
|
#if PPSSPP_PLATFORM(UWP)
|
|
|
|
#define ptr_D3DCompile D3DCompile
|
|
|
|
#else
|
2020-10-04 21:24:14 +00:00
|
|
|
#include "Common/GPU/D3D11/D3D11Loader.h"
|
2017-02-25 00:38:48 +00:00
|
|
|
#endif
|
|
|
|
|
2020-08-16 12:11:56 +00:00
|
|
|
#include "Common/CommonFuncs.h"
|
2020-08-15 10:25:39 +00:00
|
|
|
#include "Common/Log.h"
|
2020-09-29 10:19:22 +00:00
|
|
|
#include "Common/StringUtils.h"
|
|
|
|
|
2020-08-16 12:11:56 +00:00
|
|
|
#include "D3D11Util.h"
|
2017-02-08 17:07:34 +00:00
|
|
|
|
2020-10-19 18:38:43 +00:00
|
|
|
std::vector<uint8_t> CompileShaderToBytecodeD3D11(const char *code, size_t codeSize, const char *target, UINT flags) {
|
2017-02-08 17:07:34 +00:00
|
|
|
ID3DBlob *compiledCode = nullptr;
|
|
|
|
ID3DBlob *errorMsgs = nullptr;
|
2017-02-23 10:26:16 +00:00
|
|
|
HRESULT result = ptr_D3DCompile(code, codeSize, nullptr, nullptr, nullptr, "main", target, flags, 0, &compiledCode, &errorMsgs);
|
2017-02-09 12:57:24 +00:00
|
|
|
std::string errors;
|
2017-02-08 17:07:34 +00:00
|
|
|
if (errorMsgs) {
|
2017-02-09 12:57:24 +00:00
|
|
|
errors = std::string((const char *)errorMsgs->GetBufferPointer(), errorMsgs->GetBufferSize());
|
2022-09-11 11:27:17 +00:00
|
|
|
std::string numberedCode = LineNumberString(code);
|
2020-11-01 10:06:52 +00:00
|
|
|
if (SUCCEEDED(result)) {
|
|
|
|
WARN_LOG(G3D, "%s: %s", "warnings", errors.c_str());
|
|
|
|
} else {
|
2022-09-11 11:27:17 +00:00
|
|
|
ERROR_LOG(G3D, "%s: %s\n\n%s", "errors", errors.c_str(), numberedCode.c_str());
|
2020-11-01 10:06:52 +00:00
|
|
|
}
|
|
|
|
OutputDebugStringA(errors.c_str());
|
2022-09-11 11:27:17 +00:00
|
|
|
OutputDebugStringA(numberedCode.c_str());
|
2017-02-08 17:07:34 +00:00
|
|
|
errorMsgs->Release();
|
|
|
|
}
|
|
|
|
if (compiledCode) {
|
2020-10-19 18:38:43 +00:00
|
|
|
// Success!
|
2017-02-08 17:07:34 +00:00
|
|
|
const uint8_t *buf = (const uint8_t *)compiledCode->GetBufferPointer();
|
|
|
|
std::vector<uint8_t> compiled = std::vector<uint8_t>(buf, buf + compiledCode->GetBufferSize());
|
2020-10-19 18:38:43 +00:00
|
|
|
_assert_(compiled.size() != 0);
|
2017-02-08 17:07:34 +00:00
|
|
|
compiledCode->Release();
|
|
|
|
return compiled;
|
|
|
|
}
|
|
|
|
return std::vector<uint8_t>();
|
|
|
|
}
|
|
|
|
|
2017-03-05 11:26:46 +00:00
|
|
|
ID3D11VertexShader *CreateVertexShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, std::vector<uint8_t> *byteCodeOut, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
|
|
|
|
const char *profile = featureLevel <= D3D_FEATURE_LEVEL_9_3 ? "vs_4_0_level_9_1" : "vs_4_0";
|
2020-10-19 18:38:43 +00:00
|
|
|
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, profile, flags);
|
2017-02-08 17:07:34 +00:00
|
|
|
if (byteCode.empty())
|
|
|
|
return nullptr;
|
2017-02-14 12:04:14 +00:00
|
|
|
|
2017-02-08 17:07:34 +00:00
|
|
|
ID3D11VertexShader *vs;
|
|
|
|
device->CreateVertexShader(byteCode.data(), byteCode.size(), nullptr, &vs);
|
|
|
|
if (byteCodeOut)
|
|
|
|
*byteCodeOut = byteCode;
|
|
|
|
return vs;
|
|
|
|
}
|
|
|
|
|
2017-03-05 11:26:46 +00:00
|
|
|
ID3D11PixelShader *CreatePixelShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
|
|
|
|
const char *profile = featureLevel <= D3D_FEATURE_LEVEL_9_3 ? "ps_4_0_level_9_1" : "ps_4_0";
|
2020-10-19 18:38:43 +00:00
|
|
|
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, profile, flags);
|
2017-02-08 17:07:34 +00:00
|
|
|
if (byteCode.empty())
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
ID3D11PixelShader *ps;
|
|
|
|
device->CreatePixelShader(byteCode.data(), byteCode.size(), nullptr, &ps);
|
|
|
|
return ps;
|
|
|
|
}
|
|
|
|
|
2017-03-05 11:26:46 +00:00
|
|
|
ID3D11ComputeShader *CreateComputeShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
|
|
|
|
if (featureLevel <= D3D_FEATURE_LEVEL_9_3)
|
|
|
|
return nullptr;
|
2020-10-19 18:38:43 +00:00
|
|
|
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, "cs_4_0", flags);
|
2017-02-14 12:04:14 +00:00
|
|
|
if (byteCode.empty())
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
ID3D11ComputeShader *cs;
|
|
|
|
device->CreateComputeShader(byteCode.data(), byteCode.size(), nullptr, &cs);
|
|
|
|
return cs;
|
|
|
|
}
|
|
|
|
|
2017-03-05 11:26:46 +00:00
|
|
|
ID3D11GeometryShader *CreateGeometryShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
|
|
|
|
if (featureLevel <= D3D_FEATURE_LEVEL_9_3)
|
|
|
|
return nullptr;
|
2020-10-19 18:38:43 +00:00
|
|
|
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, "gs_5_0", flags);
|
2017-02-23 10:26:16 +00:00
|
|
|
if (byteCode.empty())
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
ID3D11GeometryShader *gs;
|
|
|
|
device->CreateGeometryShader(byteCode.data(), byteCode.size(), nullptr, &gs);
|
|
|
|
return gs;
|
|
|
|
}
|
|
|
|
|
2017-02-08 17:07:34 +00:00
|
|
|
void StockObjectsD3D11::Create(ID3D11Device *device) {
|
|
|
|
D3D11_BLEND_DESC blend_desc{};
|
2017-02-12 17:29:58 +00:00
|
|
|
blend_desc.RenderTarget[0].BlendEnable = false;
|
|
|
|
blend_desc.IndependentBlendEnable = false;
|
2017-02-08 17:07:34 +00:00
|
|
|
for (int i = 0; i < 16; i++) {
|
|
|
|
blend_desc.RenderTarget[0].RenderTargetWriteMask = i;
|
2017-03-05 09:33:35 +00:00
|
|
|
ASSERT_SUCCESS(device->CreateBlendState(&blend_desc, &blendStateDisabledWithColorMask[i]));
|
2017-02-08 17:07:34 +00:00
|
|
|
}
|
2017-02-12 10:20:55 +00:00
|
|
|
|
2017-02-08 17:07:34 +00:00
|
|
|
D3D11_DEPTH_STENCIL_DESC depth_desc{};
|
2017-02-09 12:57:24 +00:00
|
|
|
depth_desc.DepthEnable = FALSE;
|
2017-03-05 09:33:35 +00:00
|
|
|
ASSERT_SUCCESS(device->CreateDepthStencilState(&depth_desc, &depthStencilDisabled));
|
2017-02-08 17:07:34 +00:00
|
|
|
depth_desc.StencilEnable = TRUE;
|
|
|
|
depth_desc.StencilReadMask = 0xFF;
|
|
|
|
depth_desc.StencilWriteMask = 0xFF;
|
|
|
|
depth_desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
|
2017-02-09 12:27:45 +00:00
|
|
|
depth_desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_REPLACE;
|
|
|
|
depth_desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE;
|
2017-02-08 17:07:34 +00:00
|
|
|
depth_desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
2017-02-12 17:29:58 +00:00
|
|
|
depth_desc.BackFace = depth_desc.FrontFace;
|
2017-03-05 09:33:35 +00:00
|
|
|
ASSERT_SUCCESS(device->CreateDepthStencilState(&depth_desc, &depthDisabledStencilWrite));
|
2017-02-12 10:20:55 +00:00
|
|
|
|
2017-02-08 17:07:34 +00:00
|
|
|
D3D11_RASTERIZER_DESC raster_desc{};
|
|
|
|
raster_desc.FillMode = D3D11_FILL_SOLID;
|
|
|
|
raster_desc.CullMode = D3D11_CULL_NONE;
|
|
|
|
raster_desc.ScissorEnable = FALSE;
|
2017-03-05 09:33:35 +00:00
|
|
|
raster_desc.DepthClipEnable = TRUE; // the default! FALSE is unsupported on D3D11 level 9
|
|
|
|
ASSERT_SUCCESS(device->CreateRasterizerState(&raster_desc, &rasterStateNoCull));
|
2017-02-12 10:20:55 +00:00
|
|
|
|
2017-02-08 17:07:34 +00:00
|
|
|
D3D11_SAMPLER_DESC sampler_desc{};
|
|
|
|
sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
|
|
|
sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
|
|
|
sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
|
|
|
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
2017-03-05 10:59:40 +00:00
|
|
|
sampler_desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
sampler_desc.BorderColor[i] = 1.0f;
|
|
|
|
sampler_desc.MinLOD = -FLT_MAX;
|
|
|
|
sampler_desc.MaxLOD = FLT_MAX;
|
|
|
|
sampler_desc.MipLODBias = 0.0f;
|
2020-09-29 10:19:22 +00:00
|
|
|
sampler_desc.MaxAnisotropy = 1;
|
2017-03-05 09:33:35 +00:00
|
|
|
ASSERT_SUCCESS(device->CreateSamplerState(&sampler_desc, &samplerPoint2DWrap));
|
|
|
|
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
|
|
|
|
ASSERT_SUCCESS(device->CreateSamplerState(&sampler_desc, &samplerLinear2DWrap));
|
2017-02-12 10:20:55 +00:00
|
|
|
sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
|
|
|
sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
|
|
|
sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
|
|
|
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
2017-03-05 09:33:35 +00:00
|
|
|
ASSERT_SUCCESS(device->CreateSamplerState(&sampler_desc, &samplerPoint2DClamp));
|
|
|
|
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
|
|
|
|
ASSERT_SUCCESS(device->CreateSamplerState(&sampler_desc, &samplerLinear2DClamp));
|
2017-02-08 17:07:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void StockObjectsD3D11::Destroy() {
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
|
|
blendStateDisabledWithColorMask[i]->Release();
|
|
|
|
}
|
|
|
|
depthStencilDisabled->Release();
|
|
|
|
depthDisabledStencilWrite->Release();
|
|
|
|
rasterStateNoCull->Release();
|
|
|
|
samplerPoint2DWrap->Release();
|
|
|
|
samplerLinear2DWrap->Release();
|
2017-02-17 18:22:41 +00:00
|
|
|
samplerPoint2DClamp->Release();
|
|
|
|
samplerLinear2DClamp->Release();
|
2017-02-08 17:07:34 +00:00
|
|
|
}
|
|
|
|
|
2018-03-22 21:14:19 +00:00
|
|
|
StockObjectsD3D11 stockD3D11;
|