mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
use ComPtr for D3D9
This commit is contained in:
parent
6f5374b8aa
commit
87db979ed7
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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_;
|
||||
|
@ -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;
|
||||
|
@ -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_;
|
||||
|
@ -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;
|
||||
|
@ -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_;
|
||||
|
Loading…
Reference in New Issue
Block a user