D3D11: Use ComPtr smart pointer where possible

This commit is contained in:
Stenzek 2019-03-09 23:31:37 +10:00
parent 3d8014beb5
commit 1151a1238f
16 changed files with 146 additions and 235 deletions

View File

@ -11,13 +11,13 @@
namespace DX11
{
static ID3D11Buffer* s_bbox_buffer;
static ID3D11Buffer* s_bbox_staging_buffer;
static ID3D11UnorderedAccessView* s_bbox_uav;
static ComPtr<ID3D11Buffer> s_bbox_buffer;
static ComPtr<ID3D11Buffer> s_bbox_staging_buffer;
static ComPtr<ID3D11UnorderedAccessView> s_bbox_uav;
ID3D11UnorderedAccessView*& BBox::GetUAV()
ID3D11UnorderedAccessView* BBox::GetUAV()
{
return s_bbox_uav;
return s_bbox_uav.Get();
}
void BBox::Init()
@ -36,7 +36,7 @@ void BBox::Init()
HRESULT hr;
hr = D3D::device->CreateBuffer(&desc, &data, &s_bbox_buffer);
CHECK(SUCCEEDED(hr), "Create BoundingBox Buffer.");
D3DCommon::SetDebugObjectName(s_bbox_buffer, "BoundingBox Buffer");
D3DCommon::SetDebugObjectName(s_bbox_buffer.Get(), "BoundingBox Buffer");
// Second to use as a staging buffer.
desc.Usage = D3D11_USAGE_STAGING;
@ -44,7 +44,7 @@ void BBox::Init()
desc.BindFlags = 0;
hr = D3D::device->CreateBuffer(&desc, nullptr, &s_bbox_staging_buffer);
CHECK(SUCCEEDED(hr), "Create BoundingBox Staging Buffer.");
D3DCommon::SetDebugObjectName(s_bbox_staging_buffer, "BoundingBox Staging Buffer");
D3DCommon::SetDebugObjectName(s_bbox_staging_buffer.Get(), "BoundingBox Staging Buffer");
// UAV is required to allow concurrent access.
D3D11_UNORDERED_ACCESS_VIEW_DESC UAVdesc = {};
@ -53,37 +53,37 @@ void BBox::Init()
UAVdesc.Buffer.FirstElement = 0;
UAVdesc.Buffer.Flags = 0;
UAVdesc.Buffer.NumElements = 4;
hr = D3D::device->CreateUnorderedAccessView(s_bbox_buffer, &UAVdesc, &s_bbox_uav);
hr = D3D::device->CreateUnorderedAccessView(s_bbox_buffer.Get(), &UAVdesc, &s_bbox_uav);
CHECK(SUCCEEDED(hr), "Create BoundingBox UAV.");
D3DCommon::SetDebugObjectName(s_bbox_uav, "BoundingBox UAV");
D3D::stateman->SetOMUAV(s_bbox_uav);
D3DCommon::SetDebugObjectName(s_bbox_uav.Get(), "BoundingBox UAV");
D3D::stateman->SetOMUAV(s_bbox_uav.Get());
}
}
void BBox::Shutdown()
{
SAFE_RELEASE(s_bbox_buffer);
SAFE_RELEASE(s_bbox_staging_buffer);
SAFE_RELEASE(s_bbox_uav);
s_bbox_uav.Reset();
s_bbox_staging_buffer.Reset();
s_bbox_buffer.Reset();
}
void BBox::Set(int index, int value)
{
D3D11_BOX box{index * sizeof(s32), 0, 0, (index + 1) * sizeof(s32), 1, 1};
D3D::context->UpdateSubresource(s_bbox_buffer, 0, &box, &value, 0, 0);
D3D::context->UpdateSubresource(s_bbox_buffer.Get(), 0, &box, &value, 0, 0);
}
int BBox::Get(int index)
{
int data = 0;
D3D::context->CopyResource(s_bbox_staging_buffer, s_bbox_buffer);
D3D::context->CopyResource(s_bbox_staging_buffer.Get(), s_bbox_buffer.Get());
D3D11_MAPPED_SUBRESOURCE map;
HRESULT hr = D3D::context->Map(s_bbox_staging_buffer, 0, D3D11_MAP_READ, 0, &map);
HRESULT hr = D3D::context->Map(s_bbox_staging_buffer.Get(), 0, D3D11_MAP_READ, 0, &map);
if (SUCCEEDED(hr))
{
data = ((s32*)map.pData)[index];
}
D3D::context->Unmap(s_bbox_staging_buffer, 0);
D3D::context->Unmap(s_bbox_staging_buffer.Get(), 0);
return data;
}
}; // namespace DX11

View File

@ -10,7 +10,7 @@ namespace DX11
class BBox
{
public:
static ID3D11UnorderedAccessView*& GetUAV();
static ID3D11UnorderedAccessView* GetUAV();
static void Init();
static void Shutdown();

View File

@ -15,22 +15,6 @@
#include "Common/CommonTypes.h"
#include "Common/MsgHandler.h"
#define SAFE_RELEASE(x) \
{ \
if (x) \
(x)->Release(); \
(x) = nullptr; \
}
#define SAFE_DELETE(x) \
{ \
delete (x); \
(x) = nullptr; \
}
#define SAFE_DELETE_ARRAY(x) \
{ \
delete[](x); \
(x) = nullptr; \
}
#define CHECK(cond, Message, ...) \
if (!(cond)) \
{ \

View File

@ -299,27 +299,14 @@ void StateManager::SyncComputeBindings()
}
} // namespace D3D
StateCache::~StateCache()
{
for (auto& it : m_depth)
SAFE_RELEASE(it.second);
for (auto& it : m_raster)
SAFE_RELEASE(it.second);
for (auto& it : m_blend)
SAFE_RELEASE(it.second);
for (auto& it : m_sampler)
SAFE_RELEASE(it.second);
}
StateCache::~StateCache() = default;
ID3D11SamplerState* StateCache::Get(SamplerState state)
{
std::lock_guard<std::mutex> guard(m_lock);
auto it = m_sampler.find(state.hex);
if (it != m_sampler.end())
return it->second;
return it->second.Get();
D3D11_SAMPLER_DESC sampdc = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT());
if (state.mipmap_filter == SamplerState::Filter::Linear)
@ -359,11 +346,11 @@ ID3D11SamplerState* StateCache::Get(SamplerState state)
sampdc.MaxAnisotropy = 1u << g_ActiveConfig.iMaxAnisotropy;
}
ID3D11SamplerState* res = nullptr;
ComPtr<ID3D11SamplerState> res;
HRESULT hr = D3D::device->CreateSamplerState(&sampdc, &res);
CHECK(SUCCEEDED(hr), "Creating D3D sampler state failed");
m_sampler.emplace(state.hex, res);
return res;
return res.Get();
}
ID3D11BlendState* StateCache::Get(BlendingState state)
@ -371,7 +358,7 @@ ID3D11BlendState* StateCache::Get(BlendingState state)
std::lock_guard<std::mutex> guard(m_lock);
auto it = m_blend.find(state.hex);
if (it != m_blend.end())
return it->second;
return it->second.Get();
if (state.logicopenable && D3D::device1)
{
@ -437,12 +424,11 @@ ID3D11BlendState* StateCache::Get(BlendingState state)
tdesc.BlendOp = state.subtract ? D3D11_BLEND_OP_REV_SUBTRACT : D3D11_BLEND_OP_ADD;
tdesc.BlendOpAlpha = state.subtractAlpha ? D3D11_BLEND_OP_REV_SUBTRACT : D3D11_BLEND_OP_ADD;
ID3D11BlendState* res = nullptr;
ComPtr<ID3D11BlendState> res;
HRESULT hr = D3D::device->CreateBlendState(&desc, &res);
CHECK(SUCCEEDED(hr), "Creating D3D blend state failed");
m_blend.emplace(state.hex, res);
return res;
return res.Get();
}
ID3D11RasterizerState* StateCache::Get(RasterizationState state)
@ -450,7 +436,7 @@ ID3D11RasterizerState* StateCache::Get(RasterizationState state)
std::lock_guard<std::mutex> guard(m_lock);
auto it = m_raster.find(state.hex);
if (it != m_raster.end())
return it->second;
return it->second.Get();
static constexpr std::array<D3D11_CULL_MODE, 4> cull_modes = {
{D3D11_CULL_NONE, D3D11_CULL_BACK, D3D11_CULL_FRONT, D3D11_CULL_BACK}};
@ -460,11 +446,11 @@ ID3D11RasterizerState* StateCache::Get(RasterizationState state)
desc.CullMode = cull_modes[state.cullmode];
desc.ScissorEnable = TRUE;
ID3D11RasterizerState* res = nullptr;
ComPtr<ID3D11RasterizerState> res;
HRESULT hr = D3D::device->CreateRasterizerState(&desc, &res);
CHECK(SUCCEEDED(hr), "Creating D3D rasterizer state failed");
m_raster.emplace(state.hex, res);
return res;
return res.Get();
}
ID3D11DepthStencilState* StateCache::Get(DepthState state)
@ -472,7 +458,7 @@ ID3D11DepthStencilState* StateCache::Get(DepthState state)
std::lock_guard<std::mutex> guard(m_lock);
auto it = m_depth.find(state.hex);
if (it != m_depth.end())
return it->second;
return it->second.Get();
D3D11_DEPTH_STENCIL_DESC depthdc = CD3D11_DEPTH_STENCIL_DESC(CD3D11_DEFAULT());
@ -503,12 +489,11 @@ ID3D11DepthStencilState* StateCache::Get(DepthState state)
depthdc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
}
ID3D11DepthStencilState* res = nullptr;
ComPtr<ID3D11DepthStencilState> res;
HRESULT hr = D3D::device->CreateDepthStencilState(&depthdc, &res);
CHECK(SUCCEEDED(hr), "Creating D3D depth stencil state failed");
m_depth.emplace(state.hex, res);
return res;
return res.Get();
}
D3D11_PRIMITIVE_TOPOLOGY StateCache::GetPrimitiveTopology(PrimitiveType primitive)

View File

@ -34,10 +34,10 @@ public:
static D3D11_PRIMITIVE_TOPOLOGY GetPrimitiveTopology(PrimitiveType primitive);
private:
std::unordered_map<u32, ID3D11DepthStencilState*> m_depth;
std::unordered_map<u32, ID3D11RasterizerState*> m_raster;
std::unordered_map<u32, ID3D11BlendState*> m_blend;
std::unordered_map<SamplerState::StorageType, ID3D11SamplerState*> m_sampler;
std::unordered_map<u32, ComPtr<ID3D11DepthStencilState>> m_depth;
std::unordered_map<u32, ComPtr<ID3D11RasterizerState>> m_raster;
std::unordered_map<u32, ComPtr<ID3D11BlendState>> m_blend;
std::unordered_map<SamplerState::StorageType, ComPtr<ID3D11SamplerState>> m_sampler;
std::mutex m_lock;
};

View File

@ -28,39 +28,9 @@ DXPipeline::DXPipeline(ID3D11InputLayout* input_layout, ID3D11VertexShader* vert
m_rasterizer_state(rasterizer_state), m_depth_state(depth_state), m_blend_state(blend_state),
m_primitive_topology(primitive_topology), m_use_logic_op(use_logic_op)
{
if (m_input_layout)
m_input_layout->AddRef();
if (m_vertex_shader)
m_vertex_shader->AddRef();
if (m_geometry_shader)
m_geometry_shader->AddRef();
if (m_pixel_shader)
m_pixel_shader->AddRef();
if (m_rasterizer_state)
m_rasterizer_state->AddRef();
if (m_depth_state)
m_depth_state->AddRef();
if (m_blend_state)
m_blend_state->AddRef();
}
DXPipeline::~DXPipeline()
{
if (m_input_layout)
m_input_layout->Release();
if (m_vertex_shader)
m_vertex_shader->Release();
if (m_geometry_shader)
m_geometry_shader->Release();
if (m_pixel_shader)
m_pixel_shader->Release();
if (m_rasterizer_state)
m_rasterizer_state->Release();
if (m_depth_state)
m_depth_state->Release();
if (m_blend_state)
m_blend_state->Release();
}
DXPipeline::~DXPipeline() = default;
std::unique_ptr<DXPipeline> DXPipeline::Create(const AbstractPipelineConfig& config)
{
@ -71,12 +41,7 @@ std::unique_ptr<DXPipeline> DXPipeline::Create(const AbstractPipelineConfig& con
D3D11_PRIMITIVE_TOPOLOGY primitive_topology =
StateCache::GetPrimitiveTopology(config.rasterization_state.primitive);
if (!rasterizer_state || !depth_state || !blend_state)
{
SAFE_RELEASE(rasterizer_state);
SAFE_RELEASE(depth_state);
SAFE_RELEASE(blend_state);
return nullptr;
}
const DXShader* vertex_shader = static_cast<const DXShader*>(config.vertex_shader);
const DXShader* geometry_shader = static_cast<const DXShader*>(config.geometry_shader);

View File

@ -20,13 +20,13 @@ public:
bool use_logic_op);
~DXPipeline() override;
ID3D11InputLayout* GetInputLayout() const { return m_input_layout; }
ID3D11VertexShader* GetVertexShader() const { return m_vertex_shader; }
ID3D11GeometryShader* GetGeometryShader() const { return m_geometry_shader; }
ID3D11PixelShader* GetPixelShader() const { return m_pixel_shader; }
ID3D11RasterizerState* GetRasterizerState() const { return m_rasterizer_state; }
ID3D11DepthStencilState* GetDepthState() const { return m_depth_state; }
ID3D11BlendState* GetBlendState() const { return m_blend_state; }
ID3D11InputLayout* GetInputLayout() const { return m_input_layout.Get(); }
ID3D11VertexShader* GetVertexShader() const { return m_vertex_shader.Get(); }
ID3D11GeometryShader* GetGeometryShader() const { return m_geometry_shader.Get(); }
ID3D11PixelShader* GetPixelShader() const { return m_pixel_shader.Get(); }
ID3D11RasterizerState* GetRasterizerState() const { return m_rasterizer_state.Get(); }
ID3D11DepthStencilState* GetDepthState() const { return m_depth_state.Get(); }
ID3D11BlendState* GetBlendState() const { return m_blend_state.Get(); }
D3D11_PRIMITIVE_TOPOLOGY GetPrimitiveTopology() const { return m_primitive_topology; }
bool HasGeometryShader() const { return m_geometry_shader != nullptr; }
bool UseLogicOp() const { return m_use_logic_op; }
@ -34,13 +34,13 @@ public:
static std::unique_ptr<DXPipeline> Create(const AbstractPipelineConfig& config);
private:
ID3D11InputLayout* m_input_layout;
ID3D11VertexShader* m_vertex_shader;
ID3D11GeometryShader* m_geometry_shader;
ID3D11PixelShader* m_pixel_shader;
ID3D11RasterizerState* m_rasterizer_state;
ID3D11DepthStencilState* m_depth_state;
ID3D11BlendState* m_blend_state;
ComPtr<ID3D11InputLayout> m_input_layout;
ComPtr<ID3D11VertexShader> m_vertex_shader;
ComPtr<ID3D11GeometryShader> m_geometry_shader;
ComPtr<ID3D11PixelShader> m_pixel_shader;
ComPtr<ID3D11RasterizerState> m_rasterizer_state;
ComPtr<ID3D11DepthStencilState> m_depth_state;
ComPtr<ID3D11BlendState> m_blend_state;
D3D11_PRIMITIVE_TOPOLOGY m_primitive_topology;
bool m_use_logic_op;
};

View File

@ -13,33 +13,30 @@ DXShader::DXShader(ShaderStage stage, BinaryData bytecode, ID3D11DeviceChild* sh
{
}
DXShader::~DXShader()
{
m_shader->Release();
}
DXShader::~DXShader() = default;
ID3D11VertexShader* DXShader::GetD3DVertexShader() const
{
DEBUG_ASSERT(m_stage == ShaderStage::Vertex);
return static_cast<ID3D11VertexShader*>(m_shader);
return static_cast<ID3D11VertexShader*>(m_shader.Get());
}
ID3D11GeometryShader* DXShader::GetD3DGeometryShader() const
{
DEBUG_ASSERT(m_stage == ShaderStage::Geometry);
return static_cast<ID3D11GeometryShader*>(m_shader);
return static_cast<ID3D11GeometryShader*>(m_shader.Get());
}
ID3D11PixelShader* DXShader::GetD3DPixelShader() const
{
DEBUG_ASSERT(m_stage == ShaderStage::Pixel);
return static_cast<ID3D11PixelShader*>(m_shader);
return static_cast<ID3D11PixelShader*>(m_shader.Get());
}
ID3D11ComputeShader* DXShader::GetD3DComputeShader() const
{
DEBUG_ASSERT(m_stage == ShaderStage::Compute);
return static_cast<ID3D11ComputeShader*>(m_shader);
return static_cast<ID3D11ComputeShader*>(m_shader.Get());
}
std::unique_ptr<DXShader> DXShader::CreateFromBytecode(ShaderStage stage, BinaryData bytecode)
@ -48,48 +45,48 @@ std::unique_ptr<DXShader> DXShader::CreateFromBytecode(ShaderStage stage, Binary
{
case ShaderStage::Vertex:
{
ID3D11VertexShader* vs;
ComPtr<ID3D11VertexShader> vs;
HRESULT hr = D3D::device->CreateVertexShader(bytecode.data(), bytecode.size(), nullptr, &vs);
CHECK(SUCCEEDED(hr), "Create vertex shader");
if (FAILED(hr))
return nullptr;
return std::make_unique<DXShader>(ShaderStage::Vertex, std::move(bytecode), vs);
return std::make_unique<DXShader>(ShaderStage::Vertex, std::move(bytecode), vs.Get());
}
case ShaderStage::Geometry:
{
ID3D11GeometryShader* gs;
ComPtr<ID3D11GeometryShader> gs;
HRESULT hr = D3D::device->CreateGeometryShader(bytecode.data(), bytecode.size(), nullptr, &gs);
CHECK(SUCCEEDED(hr), "Create geometry shader");
if (FAILED(hr))
return nullptr;
return std::make_unique<DXShader>(ShaderStage::Geometry, std::move(bytecode), gs);
return std::make_unique<DXShader>(ShaderStage::Geometry, std::move(bytecode), gs.Get());
}
break;
case ShaderStage::Pixel:
{
ID3D11PixelShader* ps;
ComPtr<ID3D11PixelShader> ps;
HRESULT hr = D3D::device->CreatePixelShader(bytecode.data(), bytecode.size(), nullptr, &ps);
CHECK(SUCCEEDED(hr), "Create pixel shader");
if (FAILED(hr))
return nullptr;
return std::make_unique<DXShader>(ShaderStage::Pixel, std::move(bytecode), ps);
return std::make_unique<DXShader>(ShaderStage::Pixel, std::move(bytecode), ps.Get());
}
break;
case ShaderStage::Compute:
{
ID3D11ComputeShader* cs;
ComPtr<ID3D11ComputeShader> cs;
HRESULT hr = D3D::device->CreateComputeShader(bytecode.data(), bytecode.size(), nullptr, &cs);
CHECK(SUCCEEDED(hr), "Create compute shader");
if (FAILED(hr))
return nullptr;
return std::make_unique<DXShader>(ShaderStage::Compute, std::move(bytecode), cs);
return std::make_unique<DXShader>(ShaderStage::Compute, std::move(bytecode), cs.Get());
}
break;

View File

@ -3,9 +3,9 @@
// Refer to the license.txt file included.
#pragma once
#include <d3d11.h>
#include <memory>
#include "VideoBackends/D3D/D3DBase.h"
#include "VideoBackends/D3DCommon/Shader.h"
namespace DX11
@ -26,7 +26,7 @@ public:
static std::unique_ptr<DXShader> CreateFromBytecode(ShaderStage stage, BinaryData bytecode);
private:
ID3D11DeviceChild* m_shader;
ComPtr<ID3D11DeviceChild> m_shader;
};
} // namespace DX11

View File

@ -170,7 +170,6 @@ DXStagingTexture::~DXStagingTexture()
{
if (IsMapped())
DXStagingTexture::Unmap();
SAFE_RELEASE(m_tex);
}
std::unique_ptr<DXStagingTexture> DXStagingTexture::Create(StagingTextureType type,
@ -197,13 +196,13 @@ std::unique_ptr<DXStagingTexture> DXStagingTexture::Create(StagingTextureType ty
CD3D11_TEXTURE2D_DESC desc(D3DCommon::GetDXGIFormatForAbstractFormat(config.format, false),
config.width, config.height, 1, 1, 0, usage, cpu_flags);
ID3D11Texture2D* texture;
ComPtr<ID3D11Texture2D> texture;
HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, &texture);
CHECK(SUCCEEDED(hr), "Create staging texture");
if (FAILED(hr))
return nullptr;
return std::unique_ptr<DXStagingTexture>(new DXStagingTexture(type, config, texture));
return std::unique_ptr<DXStagingTexture>(new DXStagingTexture(type, config, texture.Get()));
}
void DXStagingTexture::CopyFromTexture(const AbstractTexture* src,
@ -226,14 +225,14 @@ void DXStagingTexture::CopyFromTexture(const AbstractTexture* src,
{
// Copy whole resource, needed for depth textures.
D3D::context->CopySubresourceRegion(
m_tex, 0, 0, 0, 0, static_cast<const DXTexture*>(src)->GetD3DTexture(),
m_tex.Get(), 0, 0, 0, 0, static_cast<const DXTexture*>(src)->GetD3DTexture(),
D3D11CalcSubresource(src_level, src_layer, src->GetLevels()), nullptr);
}
else
{
CD3D11_BOX src_box(src_rect.left, src_rect.top, 0, src_rect.right, src_rect.bottom, 1);
D3D::context->CopySubresourceRegion(
m_tex, 0, static_cast<u32>(dst_rect.left), static_cast<u32>(dst_rect.top), 0,
m_tex.Get(), 0, static_cast<u32>(dst_rect.left), static_cast<u32>(dst_rect.top), 0,
static_cast<const DXTexture*>(src)->GetD3DTexture(),
D3D11CalcSubresource(src_level, src_layer, src->GetLevels()), &src_box);
}
@ -261,7 +260,8 @@ void DXStagingTexture::CopyToTexture(const MathUtil::Rectangle<int>& src_rect, A
{
D3D::context->CopySubresourceRegion(
static_cast<const DXTexture*>(dst)->GetD3DTexture(),
D3D11CalcSubresource(dst_level, dst_layer, dst->GetLevels()), 0, 0, 0, m_tex, 0, nullptr);
D3D11CalcSubresource(dst_level, dst_layer, dst->GetLevels()), 0, 0, 0, m_tex.Get(), 0,
nullptr);
}
else
{
@ -269,7 +269,8 @@ void DXStagingTexture::CopyToTexture(const MathUtil::Rectangle<int>& src_rect, A
D3D::context->CopySubresourceRegion(
static_cast<const DXTexture*>(dst)->GetD3DTexture(),
D3D11CalcSubresource(dst_level, dst_layer, dst->GetLevels()),
static_cast<u32>(dst_rect.left), static_cast<u32>(dst_rect.top), 0, m_tex, 0, &src_box);
static_cast<u32>(dst_rect.left), static_cast<u32>(dst_rect.top), 0, m_tex.Get(), 0,
&src_box);
}
}
@ -287,7 +288,7 @@ bool DXStagingTexture::Map()
map_type = D3D11_MAP_READ_WRITE;
D3D11_MAPPED_SUBRESOURCE sr;
HRESULT hr = D3D::context->Map(m_tex, 0, map_type, 0, &sr);
HRESULT hr = D3D::context->Map(m_tex.Get(), 0, map_type, 0, &sr);
CHECK(SUCCEEDED(hr), "Map readback texture");
if (FAILED(hr))
return false;
@ -302,7 +303,7 @@ void DXStagingTexture::Unmap()
if (!m_map_pointer)
return;
D3D::context->Unmap(m_tex, 0);
D3D::context->Unmap(m_tex.Get(), 0);
m_map_pointer = nullptr;
}
@ -323,15 +324,7 @@ DXFramebuffer::DXFramebuffer(AbstractTexture* color_attachment, AbstractTexture*
{
}
DXFramebuffer::~DXFramebuffer()
{
if (m_rtv)
m_rtv->Release();
if (m_integer_rtv)
m_integer_rtv->Release();
if (m_dsv)
m_dsv->Release();
}
DXFramebuffer::~DXFramebuffer() = default;
std::unique_ptr<DXFramebuffer> DXFramebuffer::Create(DXTexture* color_attachment,
DXTexture* depth_attachment)
@ -349,8 +342,8 @@ std::unique_ptr<DXFramebuffer> DXFramebuffer::Create(DXTexture* color_attachment
const u32 layers = either_attachment->GetLayers();
const u32 samples = either_attachment->GetSamples();
ID3D11RenderTargetView* rtv = nullptr;
ID3D11RenderTargetView* integer_rtv = nullptr;
ComPtr<ID3D11RenderTargetView> rtv;
ComPtr<ID3D11RenderTargetView> integer_rtv;
if (color_attachment)
{
CD3D11_RENDER_TARGET_VIEW_DESC desc(
@ -361,6 +354,8 @@ std::unique_ptr<DXFramebuffer> DXFramebuffer::Create(DXTexture* color_attachment
HRESULT hr =
D3D::device->CreateRenderTargetView(color_attachment->GetD3DTexture(), &desc, &rtv);
CHECK(SUCCEEDED(hr), "Create render target view for framebuffer");
if (FAILED(hr))
return nullptr;
// Only create the integer RTV on Win8+.
DXGI_FORMAT integer_format =
@ -374,7 +369,7 @@ std::unique_ptr<DXFramebuffer> DXFramebuffer::Create(DXTexture* color_attachment
}
}
ID3D11DepthStencilView* dsv = nullptr;
ComPtr<ID3D11DepthStencilView> dsv;
if (depth_attachment)
{
const CD3D11_DEPTH_STENCIL_VIEW_DESC desc(
@ -385,11 +380,13 @@ std::unique_ptr<DXFramebuffer> DXFramebuffer::Create(DXTexture* color_attachment
HRESULT hr =
D3D::device->CreateDepthStencilView(depth_attachment->GetD3DTexture(), &desc, &dsv);
CHECK(SUCCEEDED(hr), "Create depth stencil view for framebuffer");
if (FAILED(hr))
return nullptr;
}
return std::make_unique<DXFramebuffer>(color_attachment, depth_attachment, color_format,
depth_format, width, height, layers, samples, rtv,
integer_rtv, dsv);
depth_format, width, height, layers, samples, rtv.Get(),
integer_rtv.Get(), dsv.Get());
}
} // namespace DX11

View File

@ -69,7 +69,7 @@ public:
private:
DXStagingTexture(StagingTextureType type, const TextureConfig& config, ID3D11Texture2D* tex);
ID3D11Texture2D* m_tex = nullptr;
ComPtr<ID3D11Texture2D> m_tex = nullptr;
};
class DXFramebuffer final : public AbstractFramebuffer
@ -81,17 +81,17 @@ public:
ID3D11RenderTargetView* integer_rtv, ID3D11DepthStencilView* dsv);
~DXFramebuffer() override;
ID3D11RenderTargetView* const* GetRTVArray() const { return &m_rtv; }
ID3D11RenderTargetView* const* GetIntegerRTVArray() const { return &m_integer_rtv; }
ID3D11RenderTargetView* const* GetRTVArray() const { return m_rtv.GetAddressOf(); }
ID3D11RenderTargetView* const* GetIntegerRTVArray() const { return m_integer_rtv.GetAddressOf(); }
UINT GetNumRTVs() const { return m_rtv ? 1 : 0; }
ID3D11DepthStencilView* GetDSV() const { return m_dsv; }
ID3D11DepthStencilView* GetDSV() const { return m_dsv.Get(); }
static std::unique_ptr<DXFramebuffer> Create(DXTexture* color_attachment,
DXTexture* depth_attachment);
protected:
ID3D11RenderTargetView* m_rtv;
ID3D11RenderTargetView* m_integer_rtv;
ID3D11DepthStencilView* m_dsv;
ComPtr<ID3D11RenderTargetView> m_rtv;
ComPtr<ID3D11RenderTargetView> m_integer_rtv;
ComPtr<ID3D11DepthStencilView> m_dsv;
};
} // namespace DX11

View File

@ -147,7 +147,8 @@ D3DVertexFormat::D3DVertexFormat(const PortableVertexDeclaration& vtx_decl)
D3DVertexFormat::~D3DVertexFormat()
{
ID3D11InputLayout* layout = m_layout.load();
SAFE_RELEASE(layout);
if (layout)
layout->Release();
}
ID3D11InputLayout* D3DVertexFormat::GetInputLayout(const void* vs_bytecode, size_t vs_bytecode_size)
@ -167,7 +168,9 @@ ID3D11InputLayout* D3DVertexFormat::GetInputLayout(const void* vs_bytecode, size
ID3D11InputLayout* expected = nullptr;
if (!m_layout.compare_exchange_strong(expected, layout))
{
SAFE_RELEASE(layout);
if (layout)
layout->Release();
layout = expected;
}

View File

@ -22,14 +22,7 @@ PerfQuery::PerfQuery() : m_query_read_pos()
ResetQuery();
}
PerfQuery::~PerfQuery()
{
for (ActiveQuery& entry : m_query_buffer)
{
// TODO: EndQuery?
entry.query->Release();
}
}
PerfQuery::~PerfQuery() = default;
void PerfQuery::EnableQuery(PerfQueryGroup type)
{
@ -49,7 +42,7 @@ void PerfQuery::EnableQuery(PerfQueryGroup type)
{
auto& entry = m_query_buffer[(m_query_read_pos + m_query_count) % m_query_buffer.size()];
D3D::context->Begin(entry.query);
D3D::context->Begin(entry.query.Get());
entry.query_type = type;
++m_query_count;
@ -63,7 +56,7 @@ void PerfQuery::DisableQuery(PerfQueryGroup type)
{
auto& entry = m_query_buffer[(m_query_read_pos + m_query_count + m_query_buffer.size() - 1) %
m_query_buffer.size()];
D3D::context->End(entry.query);
D3D::context->End(entry.query.Get());
}
}
@ -98,7 +91,7 @@ void PerfQuery::FlushOne()
while (hr != S_OK)
{
// TODO: Might cause us to be stuck in an infinite loop!
hr = D3D::context->GetData(entry.query, &result, sizeof(result), 0);
hr = D3D::context->GetData(entry.query.Get(), &result, sizeof(result), 0);
}
// NOTE: Reported pixel metrics should be referenced to native resolution
@ -125,8 +118,8 @@ void PerfQuery::WeakFlush()
auto& entry = m_query_buffer[m_query_read_pos];
UINT64 result = 0;
HRESULT hr =
D3D::context->GetData(entry.query, &result, sizeof(result), D3D11_ASYNC_GETDATA_DONOTFLUSH);
HRESULT hr = D3D::context->GetData(entry.query.Get(), &result, sizeof(result),
D3D11_ASYNC_GETDATA_DONOTFLUSH);
if (hr == S_OK)
{
@ -149,4 +142,4 @@ bool PerfQuery::IsFlushed() const
return 0 == m_query_count;
}
} // namespace
} // namespace DX11

View File

@ -5,8 +5,7 @@
#pragma once
#include <array>
#include <d3d11.h>
#include "VideoBackends/D3D/D3DBase.h"
#include "VideoCommon/PerfQueryBase.h"
namespace DX11
@ -27,7 +26,7 @@ public:
private:
struct ActiveQuery
{
ID3D11Query* query;
ComPtr<ID3D11Query> query;
PerfQueryGroup query_type;
};
@ -43,4 +42,4 @@ private:
int m_query_read_pos;
};
} // namespace
} // namespace DX11

View File

@ -28,18 +28,18 @@
namespace DX11
{
static ID3D11Buffer* AllocateConstantBuffer(u32 size)
static ComPtr<ID3D11Buffer> AllocateConstantBuffer(u32 size)
{
const u32 cbsize = Common::AlignUp(size, 16u); // must be a multiple of 16
const CD3D11_BUFFER_DESC cbdesc(cbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC,
D3D11_CPU_ACCESS_WRITE);
ID3D11Buffer* cbuf;
ComPtr<ID3D11Buffer> cbuf;
const HRESULT hr = D3D::device->CreateBuffer(&cbdesc, nullptr, &cbuf);
CHECK(SUCCEEDED(hr), "shader constant buffer (size=%u)", cbsize);
if (FAILED(hr))
return nullptr;
D3DCommon::SetDebugObjectName(cbuf, "constant buffer");
D3DCommon::SetDebugObjectName(cbuf.Get(), "constant buffer");
return cbuf;
}
@ -53,10 +53,10 @@ static void UpdateConstantBuffer(ID3D11Buffer* const buffer, const void* data, u
ADDSTAT(stats.thisFrame.bytesUniformStreamed, data_size);
}
static ID3D11ShaderResourceView*
static ComPtr<ID3D11ShaderResourceView>
CreateTexelBufferView(ID3D11Buffer* buffer, TexelBufferFormat format, DXGI_FORMAT srv_format)
{
ID3D11ShaderResourceView* srv;
ComPtr<ID3D11ShaderResourceView> srv;
CD3D11_SHADER_RESOURCE_VIEW_DESC srv_desc(buffer, srv_format, 0,
VertexManager::TEXEL_STREAM_BUFFER_SIZE /
VertexManager::GetTexelBufferElementSize(format));
@ -67,17 +67,7 @@ CreateTexelBufferView(ID3D11Buffer* buffer, TexelBufferFormat format, DXGI_FORMA
VertexManager::VertexManager() = default;
VertexManager::~VertexManager()
{
for (auto& srv_ptr : m_texel_buffer_views)
SAFE_RELEASE(srv_ptr);
SAFE_RELEASE(m_texel_buffer);
SAFE_RELEASE(m_pixel_constant_buffer);
SAFE_RELEASE(m_geometry_constant_buffer);
SAFE_RELEASE(m_vertex_constant_buffer);
for (auto& buffer : m_buffers)
SAFE_RELEASE(buffer);
}
VertexManager::~VertexManager() = default;
bool VertexManager::Initialize()
{
@ -93,7 +83,7 @@ bool VertexManager::Initialize()
CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, nullptr, &m_buffers[i])),
"Failed to create buffer.");
if (m_buffers[i])
D3DCommon::SetDebugObjectName(m_buffers[i], "Buffer of VertexManager");
D3DCommon::SetDebugObjectName(m_buffers[i].Get(), "Buffer of VertexManager");
}
m_vertex_constant_buffer = AllocateConstantBuffer(sizeof(VertexShaderConstants));
@ -118,7 +108,8 @@ bool VertexManager::Initialize()
}};
for (const auto& it : format_mapping)
{
m_texel_buffer_views[it.first] = CreateTexelBufferView(m_texel_buffer, it.first, it.second);
m_texel_buffer_views[it.first] =
CreateTexelBufferView(m_texel_buffer.Get(), it.first, it.second);
if (!m_texel_buffer_views[it.first])
return false;
}
@ -130,10 +121,10 @@ void VertexManager::UploadUtilityUniforms(const void* uniforms, u32 uniforms_siz
{
// Just use the one buffer for all three.
InvalidateConstants();
UpdateConstantBuffer(m_vertex_constant_buffer, uniforms, uniforms_size);
D3D::stateman->SetVertexConstants(m_vertex_constant_buffer);
D3D::stateman->SetGeometryConstants(m_vertex_constant_buffer);
D3D::stateman->SetPixelConstants(m_vertex_constant_buffer);
UpdateConstantBuffer(m_vertex_constant_buffer.Get(), uniforms, uniforms_size);
D3D::stateman->SetVertexConstants(m_vertex_constant_buffer.Get());
D3D::stateman->SetGeometryConstants(m_vertex_constant_buffer.Get());
D3D::stateman->SetPixelConstants(m_vertex_constant_buffer.Get());
}
bool VertexManager::MapTexelBuffer(u32 required_size, D3D11_MAPPED_SUBRESOURCE& sr)
@ -141,7 +132,7 @@ bool VertexManager::MapTexelBuffer(u32 required_size, D3D11_MAPPED_SUBRESOURCE&
if ((m_texel_buffer_offset + required_size) > TEXEL_STREAM_BUFFER_SIZE)
{
// Restart buffer.
HRESULT hr = D3D::context->Map(m_texel_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &sr);
HRESULT hr = D3D::context->Map(m_texel_buffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &sr);
CHECK(SUCCEEDED(hr), "Map texel buffer");
if (FAILED(hr))
return false;
@ -151,7 +142,7 @@ bool VertexManager::MapTexelBuffer(u32 required_size, D3D11_MAPPED_SUBRESOURCE&
else
{
// Don't overwrite the earlier-used space.
HRESULT hr = D3D::context->Map(m_texel_buffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &sr);
HRESULT hr = D3D::context->Map(m_texel_buffer.Get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &sr);
CHECK(SUCCEEDED(hr), "Map texel buffer");
if (FAILED(hr))
return false;
@ -178,8 +169,8 @@ bool VertexManager::UploadTexelBuffer(const void* data, u32 data_size, TexelBuff
ADDSTAT(stats.thisFrame.bytesUniformStreamed, data_size);
m_texel_buffer_offset += data_size;
D3D::context->Unmap(m_texel_buffer, 0);
D3D::stateman->SetTexture(0, m_texel_buffer_views[static_cast<size_t>(format)]);
D3D::context->Unmap(m_texel_buffer.Get(), 0);
D3D::stateman->SetTexture(0, m_texel_buffer_views[static_cast<size_t>(format)].Get());
return true;
}
@ -208,9 +199,9 @@ bool VertexManager::UploadTexelBuffer(const void* data, u32 data_size, TexelBuff
*out_palette_offset = (m_texel_buffer_offset + palette_byte_offset) / palette_elem_size;
m_texel_buffer_offset += palette_byte_offset + palette_size;
D3D::context->Unmap(m_texel_buffer, 0);
D3D::stateman->SetTexture(0, m_texel_buffer_views[static_cast<size_t>(format)]);
D3D::stateman->SetTexture(1, m_texel_buffer_views[static_cast<size_t>(palette_format)]);
D3D::context->Unmap(m_texel_buffer.Get(), 0);
D3D::stateman->SetTexture(0, m_texel_buffer_views[static_cast<size_t>(format)].Get());
D3D::stateman->SetTexture(1, m_texel_buffer_views[static_cast<size_t>(palette_format)].Get());
return true;
}
@ -250,48 +241,48 @@ void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_in
*out_base_vertex = vertex_stride > 0 ? (cursor / vertex_stride) : 0;
*out_base_index = (cursor + vertexBufferSize) / sizeof(u16);
D3D::context->Map(m_buffers[m_current_buffer], 0, MapType, 0, &map);
D3D::context->Map(m_buffers[m_current_buffer].Get(), 0, MapType, 0, &map);
u8* mappedData = reinterpret_cast<u8*>(map.pData);
if (vertexBufferSize > 0)
std::memcpy(mappedData + cursor, m_base_buffer_pointer, vertexBufferSize);
if (indexBufferSize > 0)
std::memcpy(mappedData + cursor + vertexBufferSize, m_cpu_index_buffer.data(), indexBufferSize);
D3D::context->Unmap(m_buffers[m_current_buffer], 0);
D3D::context->Unmap(m_buffers[m_current_buffer].Get(), 0);
m_buffer_cursor = cursor + totalBufferSize;
ADDSTAT(stats.thisFrame.bytesVertexStreamed, vertexBufferSize);
ADDSTAT(stats.thisFrame.bytesIndexStreamed, indexBufferSize);
D3D::stateman->SetVertexBuffer(m_buffers[m_current_buffer], vertex_stride, 0);
D3D::stateman->SetIndexBuffer(m_buffers[m_current_buffer]);
D3D::stateman->SetVertexBuffer(m_buffers[m_current_buffer].Get(), vertex_stride, 0);
D3D::stateman->SetIndexBuffer(m_buffers[m_current_buffer].Get());
}
void VertexManager::UploadUniforms()
{
if (VertexShaderManager::dirty)
{
UpdateConstantBuffer(m_vertex_constant_buffer, &VertexShaderManager::constants,
UpdateConstantBuffer(m_vertex_constant_buffer.Get(), &VertexShaderManager::constants,
sizeof(VertexShaderConstants));
VertexShaderManager::dirty = false;
}
if (GeometryShaderManager::dirty)
{
UpdateConstantBuffer(m_geometry_constant_buffer, &GeometryShaderManager::constants,
UpdateConstantBuffer(m_geometry_constant_buffer.Get(), &GeometryShaderManager::constants,
sizeof(GeometryShaderConstants));
GeometryShaderManager::dirty = false;
}
if (PixelShaderManager::dirty)
{
UpdateConstantBuffer(m_pixel_constant_buffer, &PixelShaderManager::constants,
UpdateConstantBuffer(m_pixel_constant_buffer.Get(), &PixelShaderManager::constants,
sizeof(PixelShaderConstants));
PixelShaderManager::dirty = false;
}
D3D::stateman->SetPixelConstants(m_pixel_constant_buffer, g_ActiveConfig.bEnablePixelLighting ?
m_vertex_constant_buffer :
nullptr);
D3D::stateman->SetVertexConstants(m_vertex_constant_buffer);
D3D::stateman->SetGeometryConstants(m_geometry_constant_buffer);
D3D::stateman->SetPixelConstants(
m_pixel_constant_buffer.Get(),
g_ActiveConfig.bEnablePixelLighting ? m_vertex_constant_buffer.Get() : nullptr);
D3D::stateman->SetVertexConstants(m_vertex_constant_buffer.Get());
D3D::stateman->SetGeometryConstants(m_geometry_constant_buffer.Get());
}
} // namespace DX11

View File

@ -4,18 +4,15 @@
#pragma once
#include <d3d11.h>
#include <array>
#include <atomic>
#include <memory>
#include <vector>
#include "VideoBackends/D3D/D3DBase.h"
#include "VideoCommon/NativeVertexFormat.h"
#include "VideoCommon/VertexManagerBase.h"
struct ID3D11Buffer;
namespace DX11
{
class D3DVertexFormat : public NativeVertexFormat
@ -60,16 +57,16 @@ private:
bool MapTexelBuffer(u32 required_size, D3D11_MAPPED_SUBRESOURCE& sr);
ID3D11Buffer* m_buffers[BUFFER_COUNT] = {};
ComPtr<ID3D11Buffer> m_buffers[BUFFER_COUNT] = {};
u32 m_current_buffer = 0;
u32 m_buffer_cursor = 0;
ID3D11Buffer* m_vertex_constant_buffer = nullptr;
ID3D11Buffer* m_geometry_constant_buffer = nullptr;
ID3D11Buffer* m_pixel_constant_buffer = nullptr;
ComPtr<ID3D11Buffer> m_vertex_constant_buffer = nullptr;
ComPtr<ID3D11Buffer> m_geometry_constant_buffer = nullptr;
ComPtr<ID3D11Buffer> m_pixel_constant_buffer = nullptr;
ID3D11Buffer* m_texel_buffer = nullptr;
std::array<ID3D11ShaderResourceView*, NUM_TEXEL_BUFFER_FORMATS> m_texel_buffer_views;
ComPtr<ID3D11Buffer> m_texel_buffer = nullptr;
std::array<ComPtr<ID3D11ShaderResourceView>, NUM_TEXEL_BUFFER_FORMATS> m_texel_buffer_views;
u32 m_texel_buffer_offset = 0;
};