Merge pull request #20682 from hrydgard/d3d11-fixes

D3D11 resource lifecycle fixes
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2025-08-02 01:04:27 +02:00
commit 9d615cce0e
13 files changed
+170 -151

No files matched your search

-1
View File
@@ -2533,7 +2533,6 @@ void TextureCacheCommon::ApplyTextureDepal(TexCacheEntry *entry) {
void TextureCacheCommon::Clear(bool delete_them) {
textureShaderCache_->Clear();
ForgetLastTexture();
for (TexCache::iterator iter = cache_.begin(); iter != cache_.end(); ++iter) {
ReleaseTexture(iter->second.get(), delete_them);
}
-68
View File
@@ -107,71 +107,3 @@ HRESULT CreateGeometryShaderD3D11(ID3D11Device *device, const char *code, size_t
return device->CreateGeometryShader(byteCode.data(), byteCode.size(), nullptr, ppGeometryShader);
}
void StockObjectsD3D11::Create(ID3D11Device *device) {
D3D11_BLEND_DESC blend_desc{};
blend_desc.RenderTarget[0].BlendEnable = false;
blend_desc.IndependentBlendEnable = false;
for (int i = 0; i < 16; i++) {
blend_desc.RenderTarget[0].RenderTargetWriteMask = i;
ASSERT_SUCCESS(device->CreateBlendState(&blend_desc, &blendStateDisabledWithColorMask[i]));
}
D3D11_DEPTH_STENCIL_DESC depth_desc{};
depth_desc.DepthEnable = FALSE;
ASSERT_SUCCESS(device->CreateDepthStencilState(&depth_desc, &depthStencilDisabled));
depth_desc.StencilEnable = TRUE;
depth_desc.StencilReadMask = 0xFF;
depth_desc.StencilWriteMask = 0xFF;
depth_desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
depth_desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_REPLACE;
depth_desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE;
depth_desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
depth_desc.BackFace = depth_desc.FrontFace;
ASSERT_SUCCESS(device->CreateDepthStencilState(&depth_desc, &depthDisabledStencilWrite));
D3D11_RASTERIZER_DESC raster_desc{};
raster_desc.FillMode = D3D11_FILL_SOLID;
raster_desc.CullMode = D3D11_CULL_NONE;
raster_desc.ScissorEnable = FALSE;
raster_desc.DepthClipEnable = TRUE; // the default! FALSE is unsupported on D3D11 level 9
ASSERT_SUCCESS(device->CreateRasterizerState(&raster_desc, &rasterStateNoCull));
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;
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;
sampler_desc.MaxAnisotropy = 1;
ASSERT_SUCCESS(device->CreateSamplerState(&sampler_desc, &samplerPoint2DWrap));
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
ASSERT_SUCCESS(device->CreateSamplerState(&sampler_desc, &samplerLinear2DWrap));
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;
ASSERT_SUCCESS(device->CreateSamplerState(&sampler_desc, &samplerPoint2DClamp));
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
ASSERT_SUCCESS(device->CreateSamplerState(&sampler_desc, &samplerLinear2DClamp));
}
void StockObjectsD3D11::Destroy() {
for (int i = 0; i < 16; i++) {
blendStateDisabledWithColorMask[i].Reset();
}
depthStencilDisabled.Reset();
depthDisabledStencilWrite.Reset();
rasterStateNoCull.Reset();
samplerPoint2DWrap.Reset();
samplerLinear2DWrap.Reset();
samplerPoint2DClamp.Reset();
samplerLinear2DClamp.Reset();
}
StockObjectsD3D11 stockD3D11;
-17
View File
@@ -80,23 +80,6 @@ HRESULT CreatePixelShaderD3D11(ID3D11Device *device, const char *code, size_t co
HRESULT CreateComputeShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags, ID3D11ComputeShader **);
HRESULT CreateGeometryShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags, ID3D11GeometryShader **);
class StockObjectsD3D11 {
public:
void Create(ID3D11Device *device);
void Destroy();
Microsoft::WRL::ComPtr<ID3D11DepthStencilState> depthStencilDisabled;
Microsoft::WRL::ComPtr<ID3D11DepthStencilState> depthDisabledStencilWrite;
Microsoft::WRL::ComPtr<ID3D11BlendState> blendStateDisabledWithColorMask[16];
Microsoft::WRL::ComPtr<ID3D11RasterizerState> rasterStateNoCull;
Microsoft::WRL::ComPtr<ID3D11SamplerState> samplerPoint2DWrap;
Microsoft::WRL::ComPtr<ID3D11SamplerState> samplerLinear2DWrap;
Microsoft::WRL::ComPtr<ID3D11SamplerState> samplerPoint2DClamp;
Microsoft::WRL::ComPtr<ID3D11SamplerState> samplerLinear2DClamp;
};
#define ASSERT_SUCCESS(x) \
if (!SUCCEEDED((x))) \
Crash();
extern StockObjectsD3D11 stockD3D11;
+57 -18
View File
@@ -90,19 +90,6 @@ void DrawEngineD3D11::InitDeviceObjects() {
draw_->SetInvalidationCallback(std::bind(&DrawEngineD3D11::Invalidate, this, std::placeholders::_1));
}
void DrawEngineD3D11::ClearInputLayoutMap() {
inputLayoutMap_.Iterate([&](const InputLayoutKey &key, ComPtr<ID3D11InputLayout> il) {
if (il)
il.Reset();
});
inputLayoutMap_.Clear();
}
void DrawEngineD3D11::NotifyConfigChanged() {
DrawEngineCommon::NotifyConfigChanged();
ClearInputLayoutMap();
}
void DrawEngineD3D11::DestroyDeviceObjects() {
if (draw_) {
draw_->SetInvalidationCallback(InvalidationCallback());
@@ -114,6 +101,58 @@ void DrawEngineD3D11::DestroyDeviceObjects() {
tessDataTransfer = nullptr;
delete pushVerts_;
delete pushInds_;
pushVerts_ = nullptr;
pushInds_ = nullptr;
// Clear state caches.
blendCache_.Iterate([&](const uint64_t &key, ID3D11BlendState *state) {
state->Release();
});
blendCache_.Clear();
blendCache1_.Iterate([&](const uint64_t &key, ID3D11BlendState1 *state) {
state->Release();
});
blendCache1_.Clear();
depthStencilCache_.Iterate([&](const uint64_t &key, ID3D11DepthStencilState *state) {
state->Release();
});
depthStencilCache_.Clear();
rasterCache_.Iterate([&](const uint32_t &key, ID3D11RasterizerState *state) {
state->Release();
});
rasterCache_.Clear();
inputLayoutMap_.Iterate([&](const InputLayoutKey &key, ID3D11InputLayout *state) {
state->Release();
});
inputLayoutMap_.Clear();
blendState_ = nullptr;
blendState1_ = nullptr;
rasterState_ = nullptr;
depthStencilState_ = nullptr;
}
void DrawEngineD3D11::DeviceLost() {
DestroyDeviceObjects();
draw_ = nullptr;
}
void DrawEngineD3D11::DeviceRestore(Draw::DrawContext *draw) {
draw_ = draw;
InitDeviceObjects();
}
void DrawEngineD3D11::ClearInputLayoutMap() {
inputLayoutMap_.Iterate([&](const InputLayoutKey &key, ComPtr<ID3D11InputLayout> il) {
if (il)
il.Reset();
});
inputLayoutMap_.Clear();
}
void DrawEngineD3D11::NotifyConfigChanged() {
DrawEngineCommon::NotifyConfigChanged();
ClearInputLayoutMap();
}
struct DeclTypeInfo {
@@ -154,9 +193,9 @@ HRESULT DrawEngineD3D11::SetupDecFmtForDraw(D3D11VertexShader *vshader, const De
// TODO: Instead of one for each vshader, we can reduce it to one for each type of shader
// that reads TEXCOORD or not, etc. Not sure if worth it.
const InputLayoutKey key{ vshader, decFmt.id };
ComPtr<ID3D11InputLayout> inputLayout;
ID3D11InputLayout *inputLayout;
if (inputLayoutMap_.Get(key, &inputLayout)) {
*ppInputLayout = inputLayout.Detach();
*ppInputLayout = inputLayout;
return S_OK;
} else {
D3D11_INPUT_ELEMENT_DESC VertexElements[8];
@@ -212,7 +251,7 @@ HRESULT DrawEngineD3D11::SetupDecFmtForDraw(D3D11VertexShader *vshader, const De
// Add it to map
inputLayoutMap_.Insert(key, inputLayout);
*ppInputLayout = inputLayout.Detach();
*ppInputLayout = inputLayout;
return hr;
}
}
@@ -429,12 +468,12 @@ void DrawEngineD3D11::Flush() {
// We really do need a vertex layout for each vertex shader (or at least check its ID bits for what inputs it uses)!
// Some vertex shaders ignore one of the inputs, and then the layout created from it will lack it, which will be a problem for others.
InputLayoutKey key{ vshader, 0xFFFFFFFF }; // Let's use 0xFFFFFFFF to signify TransformedVertex
ComPtr<ID3D11InputLayout> layout;
ID3D11InputLayout *layout;
if (!inputLayoutMap_.Get(key, &layout)) {
ASSERT_SUCCESS(device_->CreateInputLayout(TransformedVertexElements, ARRAY_SIZE(TransformedVertexElements), vshader->bytecode().data(), vshader->bytecode().size(), &layout));
inputLayoutMap_.Insert(key, layout);
}
context_->IASetInputLayout(layout.Get());
context_->IASetInputLayout(layout);
context_->IASetPrimitiveTopology(d3d11prim[prim]);
UINT stride = sizeof(TransformedVertex);
+16 -15
View File
@@ -57,8 +57,8 @@ public:
DrawEngineD3D11(Draw::DrawContext *draw, ID3D11Device *device, ID3D11DeviceContext *context);
~DrawEngineD3D11();
void DeviceLost() override { draw_ = nullptr; }
void DeviceRestore(Draw::DrawContext *draw) override { draw_ = draw; }
void DeviceLost() override;
void DeviceRestore(Draw::DrawContext *draw) override;
void SetShaderManager(ShaderManagerD3D11 *shaderManager) {
shaderManager_ = shaderManager;
@@ -110,7 +110,7 @@ private:
}
};
DenseHashMap<InputLayoutKey, Microsoft::WRL::ComPtr<ID3D11InputLayout>> inputLayoutMap_;
DenseHashMap<InputLayoutKey, ID3D11InputLayout *> inputLayoutMap_;
// Other
ShaderManagerD3D11 *shaderManager_ = nullptr;
@@ -118,27 +118,28 @@ private:
FramebufferManagerD3D11 *framebufferManager_ = nullptr;
// Pushbuffers
PushBufferD3D11 *pushVerts_;
PushBufferD3D11 *pushInds_;
PushBufferD3D11 *pushVerts_ = nullptr;
PushBufferD3D11 *pushInds_ = nullptr;
// D3D11 state object caches.
DenseHashMap<uint64_t, Microsoft::WRL::ComPtr<ID3D11BlendState>> blendCache_;
DenseHashMap<uint64_t, Microsoft::WRL::ComPtr<ID3D11BlendState1>> blendCache1_;
DenseHashMap<uint64_t, Microsoft::WRL::ComPtr<ID3D11DepthStencilState>> depthStencilCache_;
DenseHashMap<uint32_t, Microsoft::WRL::ComPtr<ID3D11RasterizerState>> rasterCache_;
// D3D11 state object caches. Previously had smart pointers but they were harder to deal with.
DenseHashMap<uint64_t, ID3D11BlendState *> blendCache_;
DenseHashMap<uint64_t, ID3D11BlendState1 *> blendCache1_;
DenseHashMap<uint64_t, ID3D11DepthStencilState *> depthStencilCache_;
DenseHashMap<uint32_t, ID3D11RasterizerState *> rasterCache_;
// Keep the depth state between ApplyDrawState and ApplyDrawStateLate
Microsoft::WRL::ComPtr<ID3D11RasterizerState> rasterState_;
Microsoft::WRL::ComPtr<ID3D11BlendState> blendState_;
Microsoft::WRL::ComPtr<ID3D11BlendState1> blendState1_;
Microsoft::WRL::ComPtr<ID3D11DepthStencilState> depthStencilState_;
// These do not hold ownership.
ID3D11BlendState *blendState_ = nullptr;
ID3D11BlendState1 *blendState1_ = nullptr;
ID3D11DepthStencilState *depthStencilState_ = nullptr;
ID3D11RasterizerState *rasterState_ = nullptr;
// State keys
D3D11StateKeys keys_{};
D3D11DynamicState dynState_{};
// Hardware tessellation
TessellationDataTransferD3D11 *tessDataTransferD3D11;
TessellationDataTransferD3D11 *tessDataTransferD3D11 = nullptr;
int lastRenderStepId_ = -1;
};
-8
View File
@@ -75,13 +75,7 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
textureCache_->NotifyConfigChanged();
}
void GPU_D3D11::FinishInitOnMainThread() {
textureCacheD3D11_->InitDeviceObjects();
stockD3D11.Create(device_);
}
GPU_D3D11::~GPU_D3D11() {
stockD3D11.Destroy();
}
u32 GPU_D3D11::CheckGPUFeatures() const {
@@ -111,14 +105,12 @@ void GPU_D3D11::DeviceLost() {
// FBOs appear to survive? Or no?
shaderManager_->ClearShaders();
drawEngine_.ClearInputLayoutMap();
textureCache_->Clear(false);
GPUCommonHW::DeviceLost();
}
void GPU_D3D11::DeviceRestore(Draw::DrawContext *draw) {
GPUCommonHW::DeviceRestore(draw);
// Nothing needed.
}
void GPU_D3D11::BeginHostFrame() {
+1 -3
View File
@@ -34,12 +34,10 @@ public:
GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw);
~GPU_D3D11();
void FinishInitOnMainThread() override;
u32 CheckGPUFeatures() const override;
void GetStats(char *buffer, size_t bufsize) override;
void DeviceLost() override; // Only happens on Android. Drop all textures and shaders.
void DeviceLost() override; // Destroy all device objects.
void DeviceRestore(Draw::DrawContext *draw) override;
protected:
+27 -4
View File
@@ -88,7 +88,18 @@ ShaderManagerD3D11::ShaderManagerD3D11(Draw::DrawContext *draw, ID3D11Device *de
static_assert(sizeof(ub_lights) <= 512, "ub_lights grew too big");
static_assert(sizeof(ub_bones) <= 384, "ub_bones grew too big");
D3D11_BUFFER_DESC desc{sizeof(ub_base), D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE };
InitDeviceObjects();
}
ShaderManagerD3D11::~ShaderManagerD3D11() {
ClearShaders();
delete[] codeBuffer_;
DestroyDeviceObjects();
}
void ShaderManagerD3D11::InitDeviceObjects() {
D3D11_BUFFER_DESC desc{sizeof(ub_base), D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE};
ASSERT_SUCCESS(device_->CreateBuffer(&desc, nullptr, &push_base));
desc.ByteWidth = sizeof(ub_lights);
ASSERT_SUCCESS(device_->CreateBuffer(&desc, nullptr, &push_lights));
@@ -96,9 +107,21 @@ ShaderManagerD3D11::ShaderManagerD3D11(Draw::DrawContext *draw, ID3D11Device *de
ASSERT_SUCCESS(device_->CreateBuffer(&desc, nullptr, &push_bones));
}
ShaderManagerD3D11::~ShaderManagerD3D11() {
ClearShaders();
delete[] codeBuffer_;
void ShaderManagerD3D11::DestroyDeviceObjects() {
push_base.Reset();
push_lights.Reset();
push_bones.Reset();
Clear();
}
void ShaderManagerD3D11::DeviceLost() {
DestroyDeviceObjects();
draw_ = nullptr;
}
void ShaderManagerD3D11::DeviceRestore(Draw::DrawContext *draw) {
draw_ = draw;
InitDeviceObjects();
}
void ShaderManagerD3D11::Clear() {
+5 -2
View File
@@ -90,8 +90,11 @@ public:
void ClearShaders() override;
void DirtyLastShader() override;
void DeviceLost() override { draw_ = nullptr; }
void DeviceRestore(Draw::DrawContext *draw) override { draw_ = draw; }
void InitDeviceObjects();
void DestroyDeviceObjects();
void DeviceLost() override;
void DeviceRestore(Draw::DrawContext *draw) override;
int GetNumVertexShaders() const { return (int)vsCache_.size(); }
int GetNumFragmentShaders() const { return (int)fsCache_.size(); }
+8 -8
View File
@@ -356,7 +356,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
// There might have been interactions between depth and blend above.
if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
if (!device1_) {
ComPtr<ID3D11BlendState> bs;
ID3D11BlendState *bs;
if (!blendCache_.Get(keys_.blend.value, &bs) || !bs) {
D3D11_BLEND_DESC desc{};
D3D11_RENDER_TARGET_BLEND_DESC &rt = desc.RenderTarget[0];
@@ -373,7 +373,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
}
blendState_ = bs;
} else {
ComPtr<ID3D11BlendState1> bs1;
ID3D11BlendState1 *bs1;
if (!blendCache1_.Get(keys_.blend.value, &bs1) || !bs1) {
D3D11_BLEND_DESC1 desc1{};
D3D11_RENDER_TARGET_BLEND_DESC1 &rt = desc1.RenderTarget[0];
@@ -395,7 +395,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
}
if (gstate_c.IsDirty(DIRTY_RASTER_STATE)) {
ComPtr<ID3D11RasterizerState> rs;
ID3D11RasterizerState *rs;
if (!rasterCache_.Get(keys_.raster.value, &rs) || !rs) {
D3D11_RASTERIZER_DESC desc{};
desc.CullMode = (D3D11_CULL_MODE)(keys_.raster.cullMode);
@@ -410,7 +410,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
}
if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE)) {
ComPtr<ID3D11DepthStencilState> ds;
ID3D11DepthStencilState *ds;
if (!depthStencilCache_.Get(keys_.depthStencil.value, &ds) || !ds) {
D3D11_DEPTH_STENCIL_DESC desc{};
desc.DepthEnable = keys_.depthStencil.depthTestEnable;
@@ -446,20 +446,20 @@ void DrawEngineD3D11::ApplyDrawStateLate(bool applyStencilRef, uint8_t stencilRe
draw_->SetScissorRect(dynState_.scissor.left, dynState_.scissor.top, dynState_.scissor.right - dynState_.scissor.left, dynState_.scissor.bottom - dynState_.scissor.top);
}
if (gstate_c.IsDirty(DIRTY_RASTER_STATE)) {
context_->RSSetState(rasterState_.Get());
context_->RSSetState(rasterState_);
}
if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
// Need to do this AFTER ApplyTexture because the process of depalettization can ruin the blend state.
float blendColor[4];
Uint8x4ToFloat4(blendColor, dynState_.blendColor);
if (device1_) {
context1_->OMSetBlendState(blendState1_.Get(), blendColor, 0xFFFFFFFF);
context1_->OMSetBlendState(blendState1_, blendColor, 0xFFFFFFFF);
} else {
context_->OMSetBlendState(blendState_.Get(), blendColor, 0xFFFFFFFF);
context_->OMSetBlendState(blendState_, blendColor, 0xFFFFFFFF);
}
}
if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE) || applyStencilRef) {
context_->OMSetDepthStencilState(depthStencilState_.Get(), applyStencilRef ? stencilRef : dynState_.stencilRef);
context_->OMSetDepthStencilState(depthStencilState_, applyStencilRef ? stencilRef : dynState_.stencilRef);
}
gstate_c.Clean(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_BLEND_STATE);
gstate_c.Dirty(dirtyRequiresRecheck_);
+38 -3
View File
@@ -140,12 +140,47 @@ TextureCacheD3D11::TextureCacheD3D11(Draw::DrawContext *draw, Draw2D *draw2D)
TextureCacheD3D11::~TextureCacheD3D11() {
Clear(true);
DestroyDeviceObjects();
}
void TextureCacheD3D11::InitDeviceObjects() {
D3D11_BUFFER_DESC desc{ sizeof(DepthPushConstants), D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE };
HRESULT hr = device_->CreateBuffer(&desc, nullptr, &depalConstants_);
_dbg_assert_(SUCCEEDED(hr));
D3D11_SAMPLER_DESC sampler_desc{};
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
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;
sampler_desc.MaxAnisotropy = 1;
sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
ASSERT_SUCCESS(device_->CreateSamplerState(&sampler_desc, &samplerPoint2DClamp_));
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
ASSERT_SUCCESS(device_->CreateSamplerState(&sampler_desc, &samplerLinear2DClamp_));
}
void TextureCacheD3D11::DestroyDeviceObjects() {
depalConstants_.Reset();
samplerPoint2DClamp_.Reset();
samplerLinear2DClamp_.Reset();
lastBoundTexture_ = D3D11_INVALID_TEX;
samplerCache_.Destroy();
}
void TextureCacheD3D11::DeviceLost() {
Clear(false);
DestroyDeviceObjects();
draw_ = nullptr;
}
void TextureCacheD3D11::DeviceRestore(Draw::DrawContext *draw) {
draw_ = draw;
InitDeviceObjects();
}
void TextureCacheD3D11::SetFramebufferManager(FramebufferManagerD3D11 *fbManager) {
@@ -222,14 +257,14 @@ void TextureCacheD3D11::BindTexture(TexCacheEntry *entry) {
int maxLevel = (entry->status & TexCacheEntry::STATUS_NO_MIPS) ? 0 : entry->maxLevel;
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry);
ComPtr<ID3D11SamplerState> state;
samplerCache_.GetOrCreateSampler(device_.Get(), samplerKey, &state);
samplerCache_.GetOrCreateSampler(device_, samplerKey, &state);
context_->PSSetSamplers(0, 1, state.GetAddressOf());
gstate_c.SetUseShaderDepal(ShaderDepalMode::OFF);
}
void TextureCacheD3D11::ApplySamplingParams(const SamplerCacheKey &key) {
ComPtr<ID3D11SamplerState> state;
samplerCache_.GetOrCreateSampler(device_.Get(), key, &state);
samplerCache_.GetOrCreateSampler(device_, key, &state);
context_->PSSetSamplers(0, 1, state.GetAddressOf());
}
@@ -240,7 +275,7 @@ void TextureCacheD3D11::Unbind() {
void TextureCacheD3D11::BindAsClutTexture(Draw::Texture *tex, bool smooth) {
ID3D11ShaderResourceView *clutTexture = (ID3D11ShaderResourceView *)draw_->GetNativeObject(Draw::NativeObject::TEXTURE_VIEW, tex);
context_->PSSetShaderResources(TEX_SLOT_CLUT, 1, &clutTexture);
context_->PSSetSamplers(3, 1, smooth ? stockD3D11.samplerLinear2DClamp.GetAddressOf() : stockD3D11.samplerPoint2DClamp.GetAddressOf());
context_->PSSetSamplers(3, 1, smooth ? samplerLinear2DClamp_.GetAddressOf() : samplerPoint2DClamp_.GetAddressOf());
}
void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
+10 -4
View File
@@ -37,6 +37,9 @@ public:
SamplerCacheD3D11() {}
~SamplerCacheD3D11();
HRESULT GetOrCreateSampler(ID3D11Device *device, const SamplerCacheKey &key, ID3D11SamplerState **);
void Destroy() {
cache_.clear();
}
private:
std::map<SamplerCacheKey, Microsoft::WRL::ComPtr<ID3D11SamplerState>> cache_;
@@ -55,10 +58,11 @@ public:
bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level, bool *isFramebuffer) override;
void DeviceLost() override { draw_ = nullptr; }
void DeviceRestore(Draw::DrawContext *draw) override { draw_ = draw; }
void DeviceLost() override;
void DeviceRestore(Draw::DrawContext *draw) override;
void InitDeviceObjects();
void DestroyDeviceObjects();
protected:
void BindTexture(TexCacheEntry *entry) override;
@@ -74,8 +78,8 @@ private:
void BuildTexture(TexCacheEntry *const entry) override;
Microsoft::WRL::ComPtr<ID3D11Device> device_;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> context_;
ID3D11Device *device_;
ID3D11DeviceContext *context_;
ID3D11Resource *&DxTex(const TexCacheEntry *entry) const {
return (ID3D11Resource *&)entry->texturePtr;
@@ -88,6 +92,8 @@ private:
ID3D11ShaderResourceView *lastBoundTexture_ = D3D11_INVALID_TEX;
Microsoft::WRL::ComPtr<ID3D11Buffer> depalConstants_;
Microsoft::WRL::ComPtr<ID3D11SamplerState> samplerPoint2DClamp_;
Microsoft::WRL::ComPtr<ID3D11SamplerState> samplerLinear2DClamp_;
};
DXGI_FORMAT GetClutDestFormatD3D11(GEPaletteFormat format);
+8
View File
@@ -63,6 +63,14 @@ HRESULT D3D11Context::CreateTheDevice(IDXGIAdapter *adapter) {
// DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it
hr = ptr_D3D11CreateDevice(adapter, driverType, nullptr, createDeviceFlags, (D3D_FEATURE_LEVEL *)&featureLevels[3], numFeatureLevels - 3,
D3D11_SDK_VERSION, &device_, &featureLevel_, &context_);
} else if ((hr == DXGI_ERROR_SDK_COMPONENT_MISSING) && (createDeviceFlags & D3D11_CREATE_DEVICE_DEBUG)) {
// Likely no debug device available.
// This happens in debug builds if you don't install the Graphics Tools optional feature in Windows 10+.
// So, we just retry without the debug flag.
WARN_LOG(Log::G3D, "D3D11CreateDevice failed with DXGI_ERROR_SDK_COMPONENT_MISSING, retrying without debug flag.");
createDeviceFlags &= ~D3D11_CREATE_DEVICE_DEBUG;
hr = ptr_D3D11CreateDevice(adapter, driverType, nullptr, createDeviceFlags, (D3D_FEATURE_LEVEL *)featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &device_, &featureLevel_, &context_);
}
return hr;
}