Skip to content

Commit

Permalink
Merge pull request #6909 from unknownbrackets/debugger
Browse files Browse the repository at this point in the history
d3d: Use INTZ depth textures where supported
  • Loading branch information
hrydgard committed Sep 14, 2014
2 parents bccb8df + dc1013a commit 1a7d629
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 43 deletions.
26 changes: 22 additions & 4 deletions GPU/Common/GPUDebugInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ enum GPUDebugBufferFormat {
GPU_DBG_FORMAT_FLOAT = 0x10,
GPU_DBG_FORMAT_16BIT = 0x11,
GPU_DBG_FORMAT_8BIT = 0x12,
GPU_DBG_FORMAT_24BIT_8X = 0x13,
GPU_DBG_FORMAT_24X_8BIT = 0x14,
};

inline GPUDebugBufferFormat &operator |=(GPUDebugBufferFormat &lhs, const GPUDebugBufferFormat &rhs) {
Expand Down Expand Up @@ -137,11 +139,23 @@ struct GPUDebugBuffer {
fmt_ = fmt;
flipped_ = flipped;

u32 pixelSize = 2;
if (fmt == GPU_DBG_FORMAT_8888 || fmt == GPU_DBG_FORMAT_8888_BGRA || fmt == GPU_DBG_FORMAT_FLOAT) {
u32 pixelSize;
switch (fmt) {
case GPU_DBG_FORMAT_8888:
case GPU_DBG_FORMAT_8888_BGRA:
case GPU_DBG_FORMAT_FLOAT:
case GPU_DBG_FORMAT_24BIT_8X:
case GPU_DBG_FORMAT_24X_8BIT:
pixelSize = 4;
} else if (fmt == GPU_DBG_FORMAT_8BIT) {
break;

case GPU_DBG_FORMAT_8BIT:
pixelSize = 1;
break;

default:
pixelSize = 2;
break;
}

data_ = new u8[pixelSize * stride * height];
Expand All @@ -154,7 +168,11 @@ struct GPUDebugBuffer {
data_ = NULL;
}

u8 *GetData() const {
u8 *GetData() {
return data_;
}

const u8 *GetData() const {
return data_;
}

Expand Down
141 changes: 135 additions & 6 deletions GPU/Directx9/FramebufferDX9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,7 @@ namespace DX9 {

// Copy depth pixel value from the read framebuffer to the draw framebuffer
if (prevVfb && !g_Config.bDisableSlowFramebufEffects) {
// TODO
//BlitFramebufferDepth(prevVfb, vfb);
BlitFramebufferDepth(prevVfb, vfb);
}
if (vfb->drawnFormat != vfb->format) {
// TODO: Might ultimately combine this with the resize step in DoSetRenderFrameBuffer().
Expand Down Expand Up @@ -541,6 +540,64 @@ namespace DX9 {
}
}

void FramebufferManagerDX9::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) {
if (!src->fbo || !dst->fbo || !useBufferedRendering_) {
return;
}

// If depth wasn't updated, then we're at least "two degrees" away from the data.
// This is an optimization: it probably doesn't need to be copied in this case.
if (!src->depthUpdated) {
return;
}

if (src->z_address == dst->z_address &&
src->z_stride != 0 && dst->z_stride != 0 &&
src->renderWidth == dst->renderWidth &&
src->renderHeight == dst->renderHeight) {

// Let's only do this if not clearing.
if (!gstate.isModeClear() || !gstate.isClearModeDepthMask()) {
// Doesn't work. Use a shader maybe?
/*fbo_unbind();
LPDIRECT3DTEXTURE9 srcTex = fbo_get_depth_texture(src->fbo);
LPDIRECT3DTEXTURE9 dstTex = fbo_get_depth_texture(dst->fbo);
if (srcTex && dstTex) {
D3DSURFACE_DESC srcDesc;
srcTex->GetLevelDesc(0, &srcDesc);
D3DSURFACE_DESC dstDesc;
dstTex->GetLevelDesc(0, &dstDesc);
D3DLOCKED_RECT srcLock;
D3DLOCKED_RECT dstLock;
HRESULT srcLockRes = srcTex->LockRect(0, &srcLock, nullptr, D3DLOCK_READONLY);
HRESULT dstLockRes = dstTex->LockRect(0, &dstLock, nullptr, 0);
if (SUCCEEDED(srcLockRes) && SUCCEEDED(dstLockRes)) {
int pitch = std::min(srcLock.Pitch, dstLock.Pitch);
u32 h = std::min(srcDesc.Height, dstDesc.Height);
const u8 *srcp = (const u8 *)srcLock.pBits;
u8 *dstp = (u8 *)dstLock.pBits;
for (u32 y = 0; y < h; ++y) {
memcpy(dstp, srcp, pitch);
dstp += dstLock.Pitch;
srcp += srcLock.Pitch;
}
}
if (SUCCEEDED(srcLockRes)) {
srcTex->UnlockRect(0);
}
if (SUCCEEDED(dstLockRes)) {
dstTex->UnlockRect(0);
}
}
RebindFramebuffer();*/
}
}
}

FBO *FramebufferManagerDX9::GetTempFBO(u16 w, u16 h, FBOColorDepth depth) {
u64 key = ((u64)depth << 32) | (w << 16) | h;
auto it = tempFBOs_.find(key);
Expand Down Expand Up @@ -1214,13 +1271,85 @@ namespace DX9 {
}

bool FramebufferManagerDX9::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
// TODO: Is this possible?
return false;
u32 fb_address = gstate.getFrameBufRawAddress();
int fb_stride = gstate.FrameBufStride();

u32 z_address = gstate.getDepthBufRawAddress();
int z_stride = gstate.DepthBufStride();

VirtualFramebuffer *vfb = currentRenderVfb_;
if (!vfb) {
vfb = GetVFBAt(fb_address);
}

if (!vfb) {
// If there's no vfb and we're drawing there, must be memory?
buffer = GPUDebugBuffer(Memory::GetPointer(z_address | 0x04000000), z_stride, 512, GPU_DBG_FORMAT_16BIT);
return true;
}

bool success = false;
LPDIRECT3DTEXTURE9 tex = fbo_get_depth_texture(vfb->fbo);
if (tex) {
D3DSURFACE_DESC desc;
D3DLOCKED_RECT locked;
tex->GetLevelDesc(0, &desc);
RECT rect = {0, 0, desc.Width, desc.Height};
HRESULT hr = tex->LockRect(0, &locked, &rect, D3DLOCK_READONLY);

if (SUCCEEDED(hr)) {
GPUDebugBufferFormat fmt = GPU_DBG_FORMAT_24BIT_8X;
int pixelSize = 4;

buffer.Allocate(locked.Pitch / pixelSize, desc.Height, fmt, gstate_c.flipTexture);
memcpy(buffer.GetData(), locked.pBits, locked.Pitch * desc.Height);
success = true;
tex->UnlockRect(0);
}
}

return success;
}

bool FramebufferManagerDX9::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
// TODO: Is this possible?
return false;
u32 fb_address = gstate.getFrameBufRawAddress();
int fb_stride = gstate.FrameBufStride();

u32 z_address = gstate.getDepthBufRawAddress();
int z_stride = gstate.DepthBufStride();

VirtualFramebuffer *vfb = currentRenderVfb_;
if (!vfb) {
vfb = GetVFBAt(fb_address);
}

if (!vfb) {
// If there's no vfb and we're drawing there, must be memory?
buffer = GPUDebugBuffer(Memory::GetPointer(z_address | 0x04000000), z_stride, 512, GPU_DBG_FORMAT_16BIT);
return true;
}

bool success = false;
LPDIRECT3DTEXTURE9 tex = fbo_get_depth_texture(vfb->fbo);
if (tex) {
D3DSURFACE_DESC desc;
D3DLOCKED_RECT locked;
tex->GetLevelDesc(0, &desc);
RECT rect = {0, 0, desc.Width, desc.Height};
HRESULT hr = tex->LockRect(0, &locked, &rect, D3DLOCK_READONLY);

if (SUCCEEDED(hr)) {
GPUDebugBufferFormat fmt = GPU_DBG_FORMAT_24X_8BIT;
int pixelSize = 4;

buffer.Allocate(locked.Pitch / pixelSize, desc.Height, fmt, gstate_c.flipTexture);
memcpy(buffer.GetData(), locked.pBits, locked.Pitch * desc.Height);
success = true;
tex->UnlockRect(0);
}
}

return success;
}

} // namespace DX9
2 changes: 2 additions & 0 deletions GPU/Directx9/FramebufferDX9.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ class FramebufferManagerDX9 : public FramebufferManagerCommon {
void DeviceLost();
void CopyDisplayToOutput();

void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst);

virtual void ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) override;

std::vector<FramebufferInfo> GetFramebufferList();
Expand Down
46 changes: 37 additions & 9 deletions GPU/Directx9/helper/fbo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct FBO {
LPDIRECT3DSURFACE9 surf;
LPDIRECT3DSURFACE9 depthstencil;
LPDIRECT3DTEXTURE9 tex;
LPDIRECT3DTEXTURE9 depthstenciltex;

int width;
int height;
Expand All @@ -21,29 +22,36 @@ namespace DX9 {

static LPDIRECT3DSURFACE9 deviceRTsurf;
static LPDIRECT3DSURFACE9 deviceDSsurf;
static bool supportsINTZ = false;

#define FB_DIV 1
#define FOURCC_INTZ ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z')))

void fbo_init() {
void fbo_init(LPDIRECT3D9 d3d) {
pD3Ddevice->GetRenderTarget(0, &deviceRTsurf);
pD3Ddevice->GetDepthStencilSurface(&deviceDSsurf);

if (d3d) {
D3DDISPLAYMODE displayMode;
d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode);
HRESULT intzFormat = d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, displayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_INTZ);
supportsINTZ = SUCCEEDED(intzFormat);
}
}

void fbo_shutdown() {
deviceRTsurf->Release();
deviceDSsurf->Release();
}

FBO * current_fbo = NULL;


FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, FBOColorDepth colorDepth) {
static uint32_t id = 0;

FBO *fbo = new FBO();
fbo->width = width;
fbo->height = height;
fbo->colorDepth = colorDepth;
fbo->depthstenciltex = nullptr;

HRESULT rtResult = pD3Ddevice->CreateTexture(fbo->width, fbo->height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &fbo->tex, NULL);
if (FAILED(rtResult)) {
Expand All @@ -53,11 +61,22 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F
}
fbo->tex->GetSurfaceLevel(0, &fbo->surf);

HRESULT dsResult = pD3Ddevice->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL);
HRESULT dsResult;
if (supportsINTZ) {
dsResult = pD3Ddevice->CreateTexture(fbo->width, fbo->height, 1, D3DUSAGE_DEPTHSTENCIL, FOURCC_INTZ, D3DPOOL_DEFAULT, &fbo->depthstenciltex, NULL);
if (SUCCEEDED(dsResult)) {
dsResult = fbo->depthstenciltex->GetSurfaceLevel(0, &fbo->depthstencil);
}
} else {
dsResult = pD3Ddevice->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL);
}
if (FAILED(dsResult)) {
ELOG("Failed to create depth buffer");
fbo->surf->Release();
fbo->tex->Release();
if (fbo->depthstenciltex) {
fbo->depthstenciltex->Release();
}
delete fbo;
return NULL;
}
Expand All @@ -70,13 +89,12 @@ void fbo_destroy(FBO *fbo) {
fbo->tex->Release();
fbo->surf->Release();
fbo->depthstencil->Release();
if (fbo->depthstenciltex) {
fbo->depthstenciltex->Release();
}
delete fbo;
}

void * fbo_get_rtt(FBO *fbo) {
return fbo->tex;
}

void fbo_unbind() {
pD3Ddevice->SetRenderTarget(0, deviceRTsurf);
pD3Ddevice->SetDepthStencilSurface(deviceDSsurf);
Expand All @@ -97,6 +115,10 @@ LPDIRECT3DTEXTURE9 fbo_get_color_texture(FBO *fbo) {
return fbo->tex;
}

LPDIRECT3DTEXTURE9 fbo_get_depth_texture(FBO *fbo) {
return fbo->depthstenciltex;
}

LPDIRECT3DSURFACE9 fbo_get_color_for_read(FBO *fbo) {
return fbo->surf;
}
Expand All @@ -109,6 +131,12 @@ void fbo_bind_color_as_texture(FBO *fbo, int color) {
pD3Ddevice->SetTexture(0, fbo->tex);
}

void fbo_bind_depth_as_texture(FBO *fbo) {
if (fbo->depthstenciltex) {
pD3Ddevice->SetTexture(0, fbo->depthstenciltex);
}
}

void fbo_get_dimensions(FBO *fbo, int *w, int *h) {
*w = fbo->width;
*h = fbo->height;
Expand Down
6 changes: 3 additions & 3 deletions GPU/Directx9/helper/fbo.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F
void fbo_bind_as_render_target(FBO *fbo);
// color must be 0, for now.
void fbo_bind_color_as_texture(FBO *fbo, int color);
void fbo_bind_depth_as_texture(FBO *fbo);
LPDIRECT3DSURFACE9 fbo_get_color_for_read(FBO *fbo);
LPDIRECT3DSURFACE9 fbo_get_color_for_write(FBO *fbo);
void fbo_unbind();
Expand All @@ -37,11 +38,10 @@ void fbo_resolve(FBO *fbo);
HRESULT fbo_blit_color(FBO *src, const RECT *srcRect, FBO *dst, const RECT *dstRect, D3DTEXTUREFILTERTYPE filter);

LPDIRECT3DTEXTURE9 fbo_get_color_texture(FBO *fbo);

void * fbo_get_rtt(FBO *fbo);
LPDIRECT3DTEXTURE9 fbo_get_depth_texture(FBO *fbo);

// To get default depth and rt surface
void fbo_init();
void fbo_init(LPDIRECT3D9 d3d);
void fbo_shutdown();

};
2 changes: 1 addition & 1 deletion GPU/Directx9/helper/global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ void DirectxInit(HWND window) {

CompileShaders();

fbo_init();
fbo_init(pD3D);
}

};
Loading

0 comments on commit 1a7d629

Please sign in to comment.