use ComPtr for D3D9

This commit is contained in:
oltolm 2024-03-24 18:40:25 +01:00
parent 6f5374b8aa
commit 87db979ed7
12 changed files with 124 additions and 194 deletions

View File

@ -9,12 +9,15 @@
#include "Common/SysError.h"
#include "Common/Log.h"
#include "Common/StringUtils.h"
#include <wrl/client.h>
using namespace Microsoft::WRL;
struct ID3DXConstantTable;
LPD3DBLOB CompileShaderToByteCodeD3D9(const char *code, const char *target, std::string *errorMessage) {
LPD3DBLOB pShaderCode = nullptr;
LPD3DBLOB pErrorMsg = nullptr;
ComPtr<ID3DBlob> pShaderCode;
ComPtr<ID3DBlob> pErrorMsg;
// Compile pixel shader.
HRESULT hr = dyn_D3DCompile(code,
@ -34,31 +37,20 @@ LPD3DBLOB CompileShaderToByteCodeD3D9(const char *code, const char *target, std:
OutputDebugStringUTF8(LineNumberString(std::string(code)).c_str());
OutputDebugStringUTF8(errorMessage->c_str());
pErrorMsg->Release();
if (pShaderCode) {
pShaderCode->Release();
pShaderCode = nullptr;
}
} else if (FAILED(hr)) {
*errorMessage = GetStringErrorMsg(hr);
if (pShaderCode) {
pShaderCode->Release();
pShaderCode = nullptr;
}
} else {
errorMessage->clear();
}
return pShaderCode;
return pShaderCode.Detach();
}
bool CompilePixelShaderD3D9(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPIXELSHADER9 *pShader, std::string *errorMessage) {
LPD3DBLOB pShaderCode = CompileShaderToByteCodeD3D9(code, "ps_3_0", errorMessage);
ComPtr<ID3DBlob> pShaderCode = CompileShaderToByteCodeD3D9(code, "ps_3_0", errorMessage);
if (pShaderCode) {
// Create pixel shader.
device->CreatePixelShader((DWORD*)pShaderCode->GetBufferPointer(), pShader);
pShaderCode->Release();
return true;
} else {
return false;
@ -66,11 +58,10 @@ bool CompilePixelShaderD3D9(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT
}
bool CompileVertexShaderD3D9(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DVERTEXSHADER9 *pShader, std::string *errorMessage) {
LPD3DBLOB pShaderCode = CompileShaderToByteCodeD3D9(code, "vs_3_0", errorMessage);
ComPtr<ID3DBlob> pShaderCode = CompileShaderToByteCodeD3D9(code, "vs_3_0", errorMessage);
if (pShaderCode) {
// Create vertex shader.
device->CreateVertexShader((DWORD*)pShaderCode->GetBufferPointer(), pShader);
pShaderCode->Release();
return true;
} else {
return false;

View File

@ -1,11 +1,12 @@
#ifdef _WIN32
#include "Common/GPU/D3D9/D3D9StateCache.h"
#include <wrl/client.h>
DirectXState dxstate;
LPDIRECT3DDEVICE9 pD3Ddevice9 = nullptr;
LPDIRECT3DDEVICE9EX pD3DdeviceEx9 = nullptr;
Microsoft::WRL::ComPtr<IDirect3DDevice9> pD3Ddevice9;
Microsoft::WRL::ComPtr<IDirect3DDevice9Ex> pD3DdeviceEx9;
int DirectXState::state_count = 0;

View File

@ -1,12 +1,13 @@
#pragma once
#include <cstring>
#include <wrl/client.h>
#include "Common/GPU/D3D9/D3D9ShaderCompiler.h"
// TODO: Get rid of these somehow.
extern LPDIRECT3DDEVICE9 pD3Ddevice9;
extern LPDIRECT3DDEVICE9EX pD3DdeviceEx9;
extern Microsoft::WRL::ComPtr<IDirect3DDevice9> pD3Ddevice9;
extern Microsoft::WRL::ComPtr<IDirect3DDevice9Ex> pD3DdeviceEx9;
class DirectXState {
private:

View File

@ -28,6 +28,9 @@
#include "Common/TimeUtil.h"
#include "Common/Log.h"
#include <wrl/client.h>
using namespace Microsoft::WRL;
namespace Draw {
@ -227,17 +230,14 @@ class D3D9InputLayout : public InputLayout {
public:
D3D9InputLayout(LPDIRECT3DDEVICE9 device, const InputLayoutDesc &desc);
~D3D9InputLayout() {
if (decl_) {
decl_->Release();
}
}
int GetStride() const { return stride_; }
void Apply(LPDIRECT3DDEVICE9 device) {
device->SetVertexDeclaration(decl_);
device->SetVertexDeclaration(decl_.Get());
}
private:
LPDIRECT3DVERTEXDECLARATION9 decl_;
ComPtr<IDirect3DVertexDeclaration9> decl_;
int stride_;
};
@ -245,25 +245,21 @@ class D3D9ShaderModule : public ShaderModule {
public:
D3D9ShaderModule(ShaderStage stage, const std::string &tag) : stage_(stage), tag_(tag) {}
~D3D9ShaderModule() {
if (vshader_)
vshader_->Release();
if (pshader_)
pshader_->Release();
}
bool Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, size_t size);
void Apply(LPDIRECT3DDEVICE9 device) {
if (stage_ == ShaderStage::Fragment) {
device->SetPixelShader(pshader_);
device->SetPixelShader(pshader_.Get());
} else {
device->SetVertexShader(vshader_);
device->SetVertexShader(vshader_.Get());
}
}
ShaderStage GetStage() const override { return stage_; }
private:
ShaderStage stage_;
LPDIRECT3DVERTEXSHADER9 vshader_ = nullptr;
LPDIRECT3DPIXELSHADER9 pshader_ = nullptr;
ComPtr<IDirect3DVertexShader9> vshader_;
ComPtr<IDirect3DPixelShader9> pshader_;
std::string tag_;
};
@ -271,12 +267,6 @@ class D3D9Pipeline : public Pipeline {
public:
D3D9Pipeline() {}
~D3D9Pipeline() {
if (vshader) {
vshader->Release();
}
if (pshader) {
pshader->Release();
}
}
D3D9ShaderModule *vshader = nullptr;
@ -300,11 +290,11 @@ public:
LPDIRECT3DBASETEXTURE9 TexturePtr() const {
// TODO: Cleanup
if (tex_) {
return tex_;
return tex_.Get();
} else if (volTex_) {
return volTex_;
return volTex_.Get();
} else if (cubeTex_) {
return cubeTex_;
return cubeTex_.Get();
} else {
return nullptr;
}
@ -314,13 +304,13 @@ public:
private:
void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data, TextureCallback initDataCallback);
bool Create(const TextureDesc &desc);
LPDIRECT3DDEVICE9 device_;
LPDIRECT3DDEVICE9EX deviceEx_;
ComPtr<IDirect3DDevice9> device_;
ComPtr<IDirect3DDevice9Ex> deviceEx_;
TextureType type_;
D3DFORMAT d3dfmt_;
LPDIRECT3DTEXTURE9 tex_ = nullptr;
LPDIRECT3DVOLUMETEXTURE9 volTex_ = nullptr;
LPDIRECT3DCUBETEXTURE9 cubeTex_ = nullptr;
ComPtr<IDirect3DTexture9> tex_;
ComPtr<IDirect3DVolumeTexture9> volTex_;
ComPtr<IDirect3DCubeTexture9> cubeTex_;
};
D3D9Texture::D3D9Texture(LPDIRECT3DDEVICE9 device, LPDIRECT3DDEVICE9EX deviceEx, const TextureDesc &desc)
@ -329,15 +319,6 @@ D3D9Texture::D3D9Texture(LPDIRECT3DDEVICE9 device, LPDIRECT3DDEVICE9EX deviceEx,
}
D3D9Texture::~D3D9Texture() {
if (tex_) {
tex_->Release();
}
if (volTex_) {
volTex_->Release();
}
if (cubeTex_) {
cubeTex_->Release();
}
}
bool D3D9Texture::Create(const TextureDesc &desc) {
@ -346,7 +327,7 @@ bool D3D9Texture::Create(const TextureDesc &desc) {
depth_ = desc.depth;
type_ = desc.type;
format_ = desc.format;
tex_ = NULL;
tex_ = nullptr;
d3dfmt_ = FormatToD3DFMT(desc.format);
if (d3dfmt_ == D3DFMT_UNKNOWN) {
@ -495,15 +476,15 @@ void D3D9Texture::SetToSampler(LPDIRECT3DDEVICE9 device, int sampler) {
switch (type_) {
case TextureType::LINEAR1D:
case TextureType::LINEAR2D:
device->SetTexture(sampler, tex_);
device->SetTexture(sampler, tex_.Get());
break;
case TextureType::LINEAR3D:
device->SetTexture(sampler, volTex_);
device->SetTexture(sampler, volTex_.Get());
break;
case TextureType::CUBE:
device->SetTexture(sampler, cubeTex_);
device->SetTexture(sampler, cubeTex_.Get());
break;
}
}
@ -654,8 +635,8 @@ private:
u8 stencilWriteMask_ = 0xFF;
// Framebuffer state
LPDIRECT3DSURFACE9 deviceRTsurf = 0;
LPDIRECT3DSURFACE9 deviceDSsurf = 0;
ComPtr<IDirect3DSurface9> deviceRTsurf;
ComPtr<IDirect3DSurface9> deviceDSsurf;
bool supportsINTZ = false;
// Dynamic state
@ -1061,16 +1042,10 @@ public:
}
}
~D3D9Buffer() {
if (ibuffer_) {
ibuffer_->Release();
}
if (vbuffer_) {
vbuffer_->Release();
}
}
LPDIRECT3DVERTEXBUFFER9 vbuffer_;
LPDIRECT3DINDEXBUFFER9 ibuffer_;
ComPtr<IDirect3DVertexBuffer9> vbuffer_;
ComPtr<IDirect3DIndexBuffer9> ibuffer_;
size_t maxSize_;
};
@ -1173,7 +1148,7 @@ inline int D3DPrimCount(D3DPRIMITIVETYPE prim, int size) {
}
void D3D9Context::Draw(int vertexCount, int offset) {
device_->SetStreamSource(0, curVBuffer_->vbuffer_, curVBufferOffset_, curPipeline_->inputLayout->GetStride());
device_->SetStreamSource(0, curVBuffer_->vbuffer_.Get(), curVBufferOffset_, curPipeline_->inputLayout->GetStride());
curPipeline_->inputLayout->Apply(device_);
curPipeline_->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_);
ApplyDynamicState();
@ -1184,8 +1159,8 @@ void D3D9Context::DrawIndexed(int vertexCount, int offset) {
curPipeline_->inputLayout->Apply(device_);
curPipeline_->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_);
ApplyDynamicState();
device_->SetStreamSource(0, curVBuffer_->vbuffer_, curVBufferOffset_, curPipeline_->inputLayout->GetStride());
device_->SetIndices(curIBuffer_->ibuffer_);
device_->SetStreamSource(0, curVBuffer_->vbuffer_.Get(), curVBufferOffset_, curPipeline_->inputLayout->GetStride());
device_->SetIndices(curIBuffer_->ibuffer_.Get());
device_->DrawIndexedPrimitive(curPipeline_->prim, 0, 0, vertexCount, offset, D3DPrimCount(curPipeline_->prim, vertexCount));
}
@ -1241,8 +1216,8 @@ void D3D9Context::SetStencilParams(uint8_t refValue, uint8_t writeMask, uint8_t
bool D3D9ShaderModule::Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, size_t size) {
LPD3D_SHADER_MACRO defines = nullptr;
LPD3DINCLUDE includes = nullptr;
LPD3DBLOB codeBuffer = nullptr;
LPD3DBLOB errorBuffer = nullptr;
ComPtr<ID3DBlob> codeBuffer;
ComPtr<ID3DBlob> errorBuffer;
const char *source = (const char *)data;
auto compile = [&](const char *profile) -> HRESULT {
return dyn_D3DCompile(source, (UINT)strlen(source), nullptr, defines, includes, "main", profile, 0, 0, &codeBuffer, &errorBuffer);
@ -1260,10 +1235,6 @@ bool D3D9ShaderModule::Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, si
OutputDebugStringA(source);
OutputDebugStringA(error);
if (errorBuffer)
errorBuffer->Release();
if (codeBuffer)
codeBuffer->Release();
return false;
}
@ -1276,10 +1247,6 @@ bool D3D9ShaderModule::Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, si
success = SUCCEEDED(result);
}
// There could have been warnings.
if (errorBuffer)
errorBuffer->Release();
codeBuffer->Release();
return true;
}
@ -1292,10 +1259,10 @@ public:
~D3D9Framebuffer();
uint32_t id = 0;
LPDIRECT3DSURFACE9 surf = nullptr;
LPDIRECT3DSURFACE9 depthstencil = nullptr;
LPDIRECT3DTEXTURE9 tex = nullptr;
LPDIRECT3DTEXTURE9 depthstenciltex = nullptr;
ComPtr<IDirect3DSurface9> surf;
ComPtr<IDirect3DSurface9> depthstencil;
ComPtr<IDirect3DTexture9> tex;
ComPtr<IDirect3DTexture9> depthstenciltex;
};
Framebuffer *D3D9Context::CreateFramebuffer(const FramebufferDesc &desc) {
@ -1326,11 +1293,9 @@ Framebuffer *D3D9Context::CreateFramebuffer(const FramebufferDesc &desc) {
}
if (FAILED(dsResult)) {
ERROR_LOG(Log::G3D, "Failed to create depth buffer");
fbo->surf->Release();
fbo->tex->Release();
if (fbo->depthstenciltex) {
fbo->depthstenciltex->Release();
}
fbo->surf = nullptr;
fbo->tex = nullptr;
fbo->depthstenciltex = nullptr;
delete fbo;
return NULL;
}
@ -1339,29 +1304,17 @@ Framebuffer *D3D9Context::CreateFramebuffer(const FramebufferDesc &desc) {
}
D3D9Framebuffer::~D3D9Framebuffer() {
if (tex) {
tex->Release();
}
if (surf) {
surf->Release();
}
if (depthstencil) {
depthstencil->Release();
}
if (depthstenciltex) {
depthstenciltex->Release();
}
}
void D3D9Context::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) {
if (fbo) {
D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo;
device_->SetRenderTarget(0, fb->surf);
device_->SetDepthStencilSurface(fb->depthstencil);
device_->SetRenderTarget(0, fb->surf.Get());
device_->SetDepthStencilSurface(fb->depthstencil.Get());
curRenderTarget_ = fb;
} else {
device_->SetRenderTarget(0, deviceRTsurf);
device_->SetDepthStencilSurface(deviceDSsurf);
device_->SetRenderTarget(0, deviceRTsurf.Get());
device_->SetDepthStencilSurface(deviceDSsurf.Get());
curRenderTarget_ = nullptr;
}
@ -1395,22 +1348,22 @@ uintptr_t D3D9Context::GetFramebufferAPITexture(Framebuffer *fbo, int channelBit
if (channelBits & FB_SURFACE_BIT) {
switch (channelBits & 7) {
case FB_DEPTH_BIT:
return (uintptr_t)fb->depthstencil;
return (uintptr_t)fb->depthstencil.Get();
case FB_STENCIL_BIT:
return (uintptr_t)fb->depthstencil;
return (uintptr_t)fb->depthstencil.Get();
case FB_COLOR_BIT:
default:
return (uintptr_t)fb->surf;
return (uintptr_t)fb->surf.Get();
}
} else {
switch (channelBits & 7) {
case FB_DEPTH_BIT:
return (uintptr_t)fb->depthstenciltex;
return (uintptr_t)fb->depthstenciltex.Get();
case FB_STENCIL_BIT:
return 0; // Can't texture from stencil
case FB_COLOR_BIT:
default:
return (uintptr_t)fb->tex;
return (uintptr_t)fb->tex.Get();
}
}
}
@ -1422,13 +1375,13 @@ void D3D9Context::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChan
switch (channelBit) {
case FB_DEPTH_BIT:
if (fb->depthstenciltex) {
device_->SetTexture(binding, fb->depthstenciltex);
device_->SetTexture(binding, fb->depthstenciltex.Get());
}
break;
case FB_COLOR_BIT:
default:
if (fb->tex) {
device_->SetTexture(binding, fb->tex);
device_->SetTexture(binding, fb->tex.Get());
}
break;
}
@ -1449,8 +1402,8 @@ bool D3D9Context::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int
D3D9Framebuffer *src = (D3D9Framebuffer *)srcfb;
D3D9Framebuffer *dst = (D3D9Framebuffer *)dstfb;
LPDIRECT3DSURFACE9 srcSurf;
LPDIRECT3DSURFACE9 dstSurf;
ComPtr<IDirect3DSurface9> srcSurf;
ComPtr<IDirect3DSurface9> dstSurf;
RECT srcRect{ (LONG)srcX1, (LONG)srcY1, (LONG)srcX2, (LONG)srcY2 };
RECT dstRect{ (LONG)dstX1, (LONG)dstY1, (LONG)dstX2, (LONG)dstY2 };
if (channelBits == FB_COLOR_BIT) {
@ -1466,7 +1419,7 @@ bool D3D9Context::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int
} else {
return false;
}
return SUCCEEDED(device_->StretchRect(srcSurf, &srcRect, dstSurf, &dstRect, (filter == FB_BLIT_LINEAR && channelBits == FB_COLOR_BIT) ? D3DTEXF_LINEAR : D3DTEXF_POINT));
return SUCCEEDED(device_->StretchRect(srcSurf.Get(), &srcRect, dstSurf.Get(), &dstRect, (filter == FB_BLIT_LINEAR && channelBits == FB_COLOR_BIT) ? D3DTEXF_LINEAR : D3DTEXF_POINT));
}
bool D3D9Context::CopyFramebufferToMemory(Framebuffer *src, int channelBits, int bx, int by, int bw, int bh, Draw::DataFormat destFormat, void *pixels, int pixelStride, ReadbackMode mode, const char *tag) {
@ -1495,7 +1448,7 @@ bool D3D9Context::CopyFramebufferToMemory(Framebuffer *src, int channelBits, int
D3DLOCKED_RECT locked;
RECT rect = { (LONG)bx, (LONG)by, (LONG)bw, (LONG)bh };
LPDIRECT3DSURFACE9 offscreen = nullptr;
ComPtr<IDirect3DSurface9> offscreen;
HRESULT hr = E_UNEXPECTED;
if (channelBits == FB_COLOR_BIT) {
if (fb)
@ -1505,7 +1458,7 @@ bool D3D9Context::CopyFramebufferToMemory(Framebuffer *src, int channelBits, int
hr = device_->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &offscreen, nullptr);
if (SUCCEEDED(hr)) {
hr = device_->GetRenderTargetData(fb ? fb->surf : deviceRTsurf, offscreen);
hr = device_->GetRenderTargetData(fb ? fb->surf.Get() : deviceRTsurf.Get(), offscreen.Get());
if (SUCCEEDED(hr)) {
hr = offscreen->LockRect(&locked, &rect, D3DLOCK_READONLY);
}
@ -1567,10 +1520,6 @@ bool D3D9Context::CopyFramebufferToMemory(Framebuffer *src, int channelBits, int
if (channelBits != FB_COLOR_BIT) {
fb->depthstenciltex->UnlockRect(0);
}
if (offscreen) {
offscreen->UnlockRect();
offscreen->Release();
}
return SUCCEEDED(hr);
}
@ -1578,10 +1527,6 @@ bool D3D9Context::CopyFramebufferToMemory(Framebuffer *src, int channelBits, int
void D3D9Context::HandleEvent(Event ev, int width, int height, void *param1, void *param2) {
switch (ev) {
case Event::LOST_BACKBUFFER:
if (deviceRTsurf)
deviceRTsurf->Release();
if (deviceDSsurf)
deviceDSsurf->Release();
deviceRTsurf = nullptr;
deviceDSsurf = nullptr;
break;

View File

@ -16,6 +16,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <algorithm>
#include <wrl/client.h>
#include "Common/Log.h"
#include "Common/MemoryUtil.h"
@ -41,6 +42,8 @@
#include "GPU/Directx9/ShaderManagerDX9.h"
#include "GPU/Directx9/GPU_DX9.h"
using Microsoft::WRL::ComPtr;
static const D3DPRIMITIVETYPE d3d_prim[8] = {
// Points, which are expanded to triangles.
D3DPT_TRIANGLELIST,
@ -97,16 +100,7 @@ DrawEngineDX9::DrawEngineDX9(Draw::DrawContext *draw) : draw_(draw), vertexDeclM
}
DrawEngineDX9::~DrawEngineDX9() {
if (transformedVertexDecl_) {
transformedVertexDecl_->Release();
}
DestroyDeviceObjects();
vertexDeclMap_.Iterate([&](const uint32_t &key, IDirect3DVertexDeclaration9 *decl) {
if (decl) {
decl->Release();
}
});
vertexDeclMap_.Clear();
delete tessDataTransferDX9;
}
@ -155,10 +149,11 @@ static void VertexAttribSetup(D3DVERTEXELEMENT9 * VertexElement, u8 fmt, u8 offs
VertexElement->UsageIndex = usage_index;
}
IDirect3DVertexDeclaration9 *DrawEngineDX9::SetupDecFmtForDraw(const DecVtxFormat &decFmt, u32 pspFmt) {
IDirect3DVertexDeclaration9 *vertexDeclCached;
HRESULT DrawEngineDX9::SetupDecFmtForDraw(const DecVtxFormat &decFmt, u32 pspFmt, IDirect3DVertexDeclaration9 **ppVertextDeclaration) {
ComPtr<IDirect3DVertexDeclaration9> vertexDeclCached;
if (vertexDeclMap_.Get(pspFmt, &vertexDeclCached)) {
return vertexDeclCached;
*ppVertextDeclaration = vertexDeclCached.Detach();
return S_OK;
} else {
D3DVERTEXELEMENT9 VertexElements[8];
D3DVERTEXELEMENT9 *VertexElement = &VertexElements[0];
@ -208,16 +203,16 @@ IDirect3DVertexDeclaration9 *DrawEngineDX9::SetupDecFmtForDraw(const DecVtxForma
memcpy(VertexElement, &end, sizeof(D3DVERTEXELEMENT9));
// Create declaration
IDirect3DVertexDeclaration9 *pHardwareVertexDecl = nullptr;
ComPtr<IDirect3DVertexDeclaration9> pHardwareVertexDecl;
HRESULT hr = device_->CreateVertexDeclaration( VertexElements, &pHardwareVertexDecl );
if (FAILED(hr)) {
ERROR_LOG(Log::G3D, "Failed to create vertex declaration!");
pHardwareVertexDecl = nullptr;
}
// Add it to map
vertexDeclMap_.Insert(pspFmt, pHardwareVertexDecl);
return pHardwareVertexDecl;
*ppVertextDeclaration = pHardwareVertexDecl.Detach();
return hr;
}
}
@ -282,10 +277,11 @@ void DrawEngineDX9::DoFlush() {
ApplyDrawStateLate();
VSShader *vshader = shaderManager_->ApplyShader(true, useHWTessellation_, dec_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode, pipelineState_);
IDirect3DVertexDeclaration9 *pHardwareVertexDecl = SetupDecFmtForDraw(dec_->GetDecVtxFmt(), dec_->VertexType());
ComPtr<IDirect3DVertexDeclaration9> pHardwareVertexDecl;
SetupDecFmtForDraw(dec_->GetDecVtxFmt(), dec_->VertexType(), &pHardwareVertexDecl);
if (pHardwareVertexDecl) {
device_->SetVertexDeclaration(pHardwareVertexDecl);
device_->SetVertexDeclaration(pHardwareVertexDecl.Get());
if (vb_ == NULL) {
if (useElements) {
device_->DrawIndexedPrimitiveUP(d3d_prim[prim], 0, numDecodedVerts_, D3DPrimCount(d3d_prim[prim], vertexCount), decIndex_, D3DFMT_INDEX16, decoded_, dec_->GetDecVtxFmt().stride);
@ -398,7 +394,7 @@ void DrawEngineDX9::DoFlush() {
// TODO: Add a post-transform cache here for multi-RECTANGLES only.
// Might help for text drawing.
device_->SetVertexDeclaration(transformedVertexDecl_);
device_->SetVertexDeclaration(transformedVertexDecl_.Get());
device_->DrawIndexedPrimitiveUP(d3d_prim[prim], 0, numDecodedVerts_, D3DPrimCount(d3d_prim[prim], result.drawNumTrans), inds, D3DFMT_INDEX16, result.drawBuffer, sizeof(TransformedVertex));
} else if (result.action == SW_CLEAR) {
u32 clearColor = result.color;

View File

@ -18,6 +18,7 @@
#pragma once
#include <d3d9.h>
#include <wrl/client.h>
#include "Common/Data/Collections/Hashmaps.h"
#include "GPU/GPUState.h"
@ -26,6 +27,7 @@
#include "GPU/Common/VertexDecoderCommon.h"
#include "GPU/Common/DrawEngineCommon.h"
#include "GPU/Common/GPUStateUtils.h"
#include "GPU/MiscTypes.h"
struct DecVtxFormat;
struct UVScale;
@ -95,15 +97,15 @@ private:
void ApplyDrawState(int prim);
void ApplyDrawStateLate();
IDirect3DVertexDeclaration9 *SetupDecFmtForDraw(const DecVtxFormat &decFmt, u32 pspFmt);
HRESULT SetupDecFmtForDraw(const DecVtxFormat &decFmt, u32 pspFmt, IDirect3DVertexDeclaration9 **ppVertexDeclaration);
LPDIRECT3DDEVICE9 device_ = nullptr;
Draw::DrawContext *draw_;
DenseHashMap<u32, IDirect3DVertexDeclaration9 *> vertexDeclMap_;
DenseHashMap<u32, Microsoft::WRL::ComPtr<IDirect3DVertexDeclaration9>> vertexDeclMap_;
// SimpleVertex
IDirect3DVertexDeclaration9* transformedVertexDecl_ = nullptr;
Microsoft::WRL::ComPtr<IDirect3DVertexDeclaration9> transformedVertexDecl_;
// Other
ShaderManagerDX9 *shaderManager_ = nullptr;

View File

@ -74,9 +74,7 @@ PSShader::PSShader(LPDIRECT3DDEVICE9 device, FShaderID id, const char *code) : i
if (!success) {
failed_ = true;
if (shader)
shader->Release();
shader = NULL;
shader = nullptr;
return;
} else {
VERBOSE_LOG(Log::G3D, "Compiled pixel shader:\n%s\n", (const char *)code);
@ -84,8 +82,6 @@ PSShader::PSShader(LPDIRECT3DDEVICE9 device, FShaderID id, const char *code) : i
}
PSShader::~PSShader() {
if (shader)
shader->Release();
}
std::string PSShader::GetShaderString(DebugShaderStringType type) const {
@ -123,9 +119,7 @@ VSShader::VSShader(LPDIRECT3DDEVICE9 device, VShaderID id, const char *code, boo
if (!success) {
failed_ = true;
if (shader)
shader->Release();
shader = NULL;
shader = nullptr;
return;
} else {
VERBOSE_LOG(Log::G3D, "Compiled vertex shader:\n%s\n", (const char *)code);
@ -133,8 +127,6 @@ VSShader::VSShader(LPDIRECT3DDEVICE9 device, VShaderID id, const char *code, boo
}
VSShader::~VSShader() {
if (shader)
shader->Release();
}
std::string VSShader::GetShaderString(DebugShaderStringType type) const {
@ -653,8 +645,8 @@ VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellat
gstate_c.CleanUniforms();
}
device_->SetPixelShader(fs->shader);
device_->SetVertexShader(vs->shader);
device_->SetPixelShader(fs->shader.Get());
device_->SetVertexShader(vs->shader.Get());
lastPShader_ = fs;
lastVShader_ = vs;

View File

@ -19,6 +19,8 @@
#include <map>
#include <cstdint>
#include <d3d9.h>
#include <wrl/client.h>
#include "Common/CommonTypes.h"
#include "GPU/Common/VertexShaderGenerator.h"
@ -43,7 +45,7 @@ public:
std::string GetShaderString(DebugShaderStringType type) const;
LPDIRECT3DPIXELSHADER9 shader = nullptr;
Microsoft::WRL::ComPtr<IDirect3DPixelShader9> shader;
protected:
std::string source_;
@ -63,7 +65,7 @@ public:
std::string GetShaderString(DebugShaderStringType type) const;
LPDIRECT3DVERTEXSHADER9 shader = nullptr;
Microsoft::WRL::ComPtr<IDirect3DVertexShader9> shader;
protected:
std::string source_;

View File

@ -17,6 +17,7 @@
#include <algorithm>
#include <cstring>
#include <wrl/client.h>
#include "Common/TimeUtil.h"
#include "Core/MemMap.h"
@ -37,6 +38,8 @@
// NOTE: In the D3D backends, we flip R and B in the shaders, so while these look wrong, they're OK.
using Microsoft::WRL::ComPtr;
Draw::DataFormat FromD3D9Format(u32 fmt) {
switch (fmt) {
case D3DFMT_A4R4G4B4: return Draw::DataFormat::B4G4R4A4_UNORM_PACK16;
@ -90,7 +93,6 @@ TextureCacheDX9::TextureCacheDX9(Draw::DrawContext *draw, Draw2D *draw2D)
}
TextureCacheDX9::~TextureCacheDX9() {
pFramebufferVertexDecl->Release();
Clear(true);
}
@ -198,7 +200,7 @@ void TextureCacheDX9::BindTexture(TexCacheEntry *entry) {
device_->SetTexture(0, nullptr);
return;
}
LPDIRECT3DBASETEXTURE9 texture = DxTex(entry);
IDirect3DBaseTexture9 *texture = DxTex(entry);
if (texture != lastBoundTexture) {
device_->SetTexture(0, texture);
lastBoundTexture = texture;
@ -356,15 +358,15 @@ bool TextureCacheDX9::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level,
ApplyTexture();
LPDIRECT3DBASETEXTURE9 baseTex;
LPDIRECT3DTEXTURE9 tex;
LPDIRECT3DSURFACE9 offscreen = nullptr;
ComPtr<IDirect3DBaseTexture9> baseTex;
ComPtr<IDirect3DTexture9> tex;
ComPtr<IDirect3DSurface9> offscreen;
HRESULT hr;
bool success = false;
hr = device_->GetTexture(0, &baseTex);
if (SUCCEEDED(hr) && baseTex != NULL) {
hr = baseTex->QueryInterface(IID_IDirect3DTexture9, (void **)&tex);
hr = baseTex.As(&tex);
if (SUCCEEDED(hr)) {
D3DSURFACE_DESC desc;
D3DLOCKED_RECT locked;
@ -374,17 +376,16 @@ bool TextureCacheDX9::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level,
// If it fails, this means it's a render-to-texture, so we have to get creative.
if (FAILED(hr)) {
LPDIRECT3DSURFACE9 renderTarget = nullptr;
ComPtr<IDirect3DSurface9> renderTarget;
hr = tex->GetSurfaceLevel(level, &renderTarget);
if (renderTarget && SUCCEEDED(hr)) {
hr = device_->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &offscreen, NULL);
if (SUCCEEDED(hr)) {
hr = device_->GetRenderTargetData(renderTarget, offscreen);
hr = device_->GetRenderTargetData(renderTarget.Get(), offscreen.Get());
if (SUCCEEDED(hr)) {
hr = offscreen->LockRect(&locked, &rect, D3DLOCK_READONLY);
}
}
renderTarget->Release();
}
*isFramebuffer = true;
} else {
@ -425,14 +426,11 @@ bool TextureCacheDX9::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level,
}
if (offscreen) {
offscreen->UnlockRect();
offscreen->Release();
} else {
tex->UnlockRect(level);
}
}
tex->Release();
}
baseTex->Release();
}
return success;

View File

@ -18,6 +18,7 @@
#pragma once
#include <d3d9.h>
#include <wrl/client.h>
#include "GPU/GPU.h"
#include "GPU/GPUInterface.h"
@ -60,16 +61,16 @@ private:
void BuildTexture(TexCacheEntry *const entry) override;
LPDIRECT3DBASETEXTURE9 &DxTex(const TexCacheEntry *entry) const {
static LPDIRECT3DBASETEXTURE9 &DxTex(const TexCacheEntry *entry) {
return *(LPDIRECT3DBASETEXTURE9 *)&entry->texturePtr;
}
LPDIRECT3DDEVICE9 device_;
LPDIRECT3DDEVICE9EX deviceEx_;
Microsoft::WRL::ComPtr<IDirect3DDevice9> device_;
Microsoft::WRL::ComPtr<IDirect3DDevice9Ex> deviceEx_;
LPDIRECT3DVERTEXDECLARATION9 pFramebufferVertexDecl;
Microsoft::WRL::ComPtr<IDirect3DVertexDeclaration9> pFramebufferVertexDecl;
LPDIRECT3DBASETEXTURE9 lastBoundTexture;
IDirect3DBaseTexture9 *lastBoundTexture = nullptr;
float maxAnisotropyLevel;
FramebufferManagerDX9 *framebufferManagerDX9_;

View File

@ -72,13 +72,13 @@ bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
D3DDISPLAYMODE d3ddm;
if (FAILED(d3d_->GetAdapterDisplayMode(adapterId_, &d3ddm))) {
*error_message = "GetAdapterDisplayMode failed";
d3d_->Release();
d3d_ = nullptr;
return false;
}
if (FAILED(d3d_->GetDeviceCaps(adapterId_, D3DDEVTYPE_HAL, &d3dCaps))) {
*error_message = "GetDeviceCaps failed (?)";
d3d_->Release();
d3d_ = nullptr;
return false;
}
@ -91,7 +91,7 @@ bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
D3DFMT_D24S8))) {
if (hr == D3DERR_NOTAVAILABLE) {
*error_message = "D24S8 depth/stencil not available";
d3d_->Release();
d3d_ = nullptr;
return false;
}
}
@ -131,7 +131,7 @@ bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
if (FAILED(hr)) {
*error_message = "Failed to create D3D device";
d3d_->Release();
d3d_ = nullptr;
return false;
}
@ -143,12 +143,12 @@ bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
// TODO: This makes it slower?
//deviceEx->SetMaximumFrameLatency(1);
}
draw_ = Draw::T3DCreateDX9Context(d3d_, d3dEx_, adapterId_, device_, deviceEx_);
draw_ = Draw::T3DCreateDX9Context(d3d_.Get(), d3dEx_.Get(), adapterId_, device_.Get(), deviceEx_.Get());
SetGPUBackend(GPUBackend::DIRECT3D9);
if (!draw_->CreatePresets()) {
// Shader compiler not installed? Return an error so we can fall back to GL.
device_->Release();
d3d_->Release();
device_ = nullptr;
d3d_ = nullptr;
*error_message = "DirectX9 runtime not correctly installed. Please install.";
return false;
}
@ -185,8 +185,8 @@ void D3D9Context::Shutdown() {
delete draw_;
draw_ = nullptr;
device_->EndScene();
device_->Release();
d3d_->Release();
device_ = nullptr;
d3d_ = nullptr;
UnloadD3DCompiler();
pD3Ddevice9 = nullptr;
pD3DdeviceEx9 = nullptr;

View File

@ -22,6 +22,7 @@
#include "Common/CommonWindows.h"
#include "Windows/GPU/WindowsGraphicsContext.h"
#include <d3d9.h>
#include <wrl/client.h>
namespace Draw {
class DrawContext;
@ -42,11 +43,11 @@ public:
private:
Draw::DrawContext *draw_;
bool has9Ex_;
LPDIRECT3D9 d3d_;
LPDIRECT3D9EX d3dEx_;
Microsoft::WRL::ComPtr<IDirect3D9> d3d_;
Microsoft::WRL::ComPtr<IDirect3D9Ex> d3dEx_;
int adapterId_;
LPDIRECT3DDEVICE9 device_;
LPDIRECT3DDEVICE9EX deviceEx_;
Microsoft::WRL::ComPtr<IDirect3DDevice9> device_;
Microsoft::WRL::ComPtr<IDirect3DDevice9Ex> deviceEx_;
HDC hDC_; // Private GDI Device Context
HWND hWnd_; // Holds Our Window Handle
HMODULE hD3D9_;