Fixes to D3D viewport management. For some reason, still having strange driver-bug-ish problems in unbuffered...

This commit is contained in:
Henrik Rydgard 2015-11-12 14:47:43 +01:00
parent 5a8e86e8ba
commit 7e3cd987cd
8 changed files with 33 additions and 34 deletions

View File

@ -200,16 +200,17 @@ namespace DX9 {
void FramebufferManagerDX9::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) {
if (useBufferedRendering_ && vfb && vfb->fbo) {
fbo_bind_as_render_target(vfb->fbo);
dxstate.viewport.set(0, 0, vfb->renderWidth, vfb->renderHeight);
DXSetViewport(0, 0, vfb->renderWidth, vfb->renderHeight);
} else {
float x, y, w, h;
CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, ROTATION_LOCKED_HORIZONTAL);
dxstate.viewport.set(x, y, w, h);
DXSetViewport(x, y, w, h);
}
MakePixelTexture(srcPixels, srcPixelFormat, srcStride, width, height);
DisableState();
DrawActiveTexture(drawPixelsTex_, dstX, dstY, width, height, vfb->bufferWidth, vfb->bufferHeight, 0.0f, 0.0f, 1.0f, 1.0f, ROTATION_LOCKED_HORIZONTAL);
textureCache_->ForgetLastTexture();
dxstate.viewport.restore();
}
void FramebufferManagerDX9::DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) {
@ -515,20 +516,14 @@ namespace DX9 {
shaderManager_->DirtyLastShader();
pD3Ddevice->SetTexture(0, nullptr);
D3DVIEWPORT9 vp;
vp.MinZ = 0;
vp.MaxZ = 1;
vp.X = 0;
vp.Y = 0;
vp.Width = vfb->renderWidth;
vp.Height = vfb->renderHeight;
pD3Ddevice->SetViewport(&vp);
DXSetViewport(0, 0, vfb->renderWidth, vfb->renderHeight);
// This should clear stencil and alpha without changing the other colors.
HRESULT hr = pD3Ddevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coord, 5 * sizeof(float));
if (FAILED(hr)) {
ERROR_LOG_REPORT(G3D, "ReformatFramebufferFrom() failed: %08x", hr);
}
dxstate.viewport.restore();
}
RebindFramebuffer();
@ -682,9 +677,10 @@ namespace DX9 {
}
void FramebufferManagerDX9::CopyDisplayToOutput() {
fbo_unbind();
dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
if (useBufferedRendering_) {
DXSetViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
}
currentRenderVfb_ = 0;
u32 offsetX = 0;
@ -794,7 +790,7 @@ namespace DX9 {
HRESULT hr = fbo_blit_color(vfb->fbo, &srcRect, nullptr, &dstRect, g_Config.iBufFilter == SCALE_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT);
if (FAILED(hr)) {
ERROR_LOG_REPORT_ONCE(blit_fail, G3D, "fbo_blit_color failed on display: %08x", hr);
dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
DXSetViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
// These are in the output display coordinates
if (g_Config.iBufFilter == SCALE_LINEAR) {
dxstate.texMagFilter.set(D3DTEXF_LINEAR);
@ -814,7 +810,7 @@ namespace DX9 {
fbo_bind_as_render_target(extraFBOs_[0]);
int fbo_w, fbo_h;
fbo_get_dimensions(extraFBOs_[0], &fbo_w, &fbo_h);
dxstate.viewport.set(0, 0, fbo_w, fbo_h);
DXSetViewport(0, 0, fbo_w, fbo_h);
DrawActiveTexture(colorTexture, 0, 0, fbo_w, fbo_h, fbo_w, fbo_h, true, 1.0f, 1.0f, postShaderProgram_);
fbo_unbind();
@ -826,18 +822,19 @@ namespace DX9 {
return;
}
colorTexture = fbo_get_color_texture(extraFBOs_[0]);
dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
DXSetViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
// These are in the output display coordinates
DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, 480.0f / (float)vfb->width, 272.0f / (float)vfb->height);
} else {
// Use post-shader, but run shader at output resolution.
dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
DXSetViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
// These are in the output display coordinates
DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, 480.0f / (float)vfb->width, 272.0f / (float)vfb->height, postShaderProgram_);
}
*/
pD3Ddevice->SetTexture(0, NULL);
}
dxstate.viewport.restore();
}
void FramebufferManagerDX9::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) {
@ -1107,7 +1104,6 @@ namespace DX9 {
void FramebufferManagerDX9::EndFrame() {
if (resized_) {
DestroyAllFBOs();
dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
// Actually, auto mode should be more granular...
// Round up to a zoom factor for the render size.
int zoom = g_Config.iInternalResolution;

View File

@ -509,7 +509,6 @@ void DIRECTX9_GPU::InitClearInternal() {
dxstate.colorMask.set(true, true, true, true);
pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.f, 0);
}
dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
}
void DIRECTX9_GPU::DumpNextFrame() {
@ -521,7 +520,7 @@ void DIRECTX9_GPU::BeginFrame() {
}
void DIRECTX9_GPU::ReapplyGfxStateInternal() {
DX9::dxstate.Restore();
dxstate.Restore();
GPUCommon::ReapplyGfxStateInternal();
}

View File

@ -221,7 +221,7 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, bool skipZer
if (dstBuffer->fbo) {
fbo_bind_as_render_target(dstBuffer->fbo);
}
dxstate.viewport.set(0, 0, w, h);
DXSetViewport(0, 0, w, h);
MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight);
@ -279,7 +279,7 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, bool skipZer
}
}
dxstate.stencilMask.set(0xFF);
dxstate.viewport.restore();
RebindFramebuffer();
return true;
}

View File

@ -1042,15 +1042,7 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame
pD3Ddevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
pD3Ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
D3DVIEWPORT9 vp;
vp.MinZ = 0;
vp.MaxZ = 1;
vp.X = 0;
vp.Y = 0;
vp.Width = framebuffer->renderWidth;
vp.Height = framebuffer->renderHeight;
pD3Ddevice->SetViewport(&vp);
DXSetViewport(0, 0, framebuffer->renderWidth, framebuffer->renderHeight);
HRESULT hr = pD3Ddevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, (3 + 2) * sizeof(float));
if (FAILED(hr)) {
ERROR_LOG_REPORT(G3D, "Depal render failed: %08x", hr);

View File

@ -37,8 +37,7 @@ void DirectXState::Restore() {
colorMask.restore(); count++;
// why not?
// viewport.restore(); count++;
viewport.restore(); count++;
alphaTest.restore(); count++;
alphaTestFunc.restore(); count++;

View File

@ -342,6 +342,7 @@ private:
class StateVp {
D3DVIEWPORT9 viewport;
public:
StateVp() { memset(&viewport, 0, sizeof(viewport)); }
inline void set(int x, int y, int w, int h, float n = 0.f, float f = 1.f) {
D3DVIEWPORT9 newviewport;
newviewport.X = x;
@ -350,8 +351,7 @@ private:
newviewport.Height = h;
newviewport.MinZ = n;
newviewport.MaxZ = f;
if (memcmp(&viewport, &newviewport, sizeof(viewport))) {
if (memcmp(&viewport, &newviewport, sizeof(viewport)) != 0) {
viewport = newviewport;
restore();
}

View File

@ -11,6 +11,17 @@ LPDIRECT3DDEVICE9 pD3Ddevice = NULL;
LPDIRECT3DDEVICE9EX pD3DdeviceEx = NULL;
LPDIRECT3D9 pD3D = NULL;
void DXSetViewport(float x, float y, float w, float h, float minZ, float maxZ) {
D3DVIEWPORT9 vp;
vp.X = (DWORD)x;
vp.Y = (DWORD)y;
vp.Width = (DWORD)w;
vp.Height = (DWORD)h;
vp.MinZ = minZ;
vp.MaxZ = maxZ;
pD3Ddevice->SetViewport(&vp);
}
static const char * vscode =
"struct VS_IN {\n"
" float4 ObjPos : POSITION;\n"

View File

@ -31,6 +31,8 @@ bool CompileVertexShader(const char *code, LPDIRECT3DVERTEXSHADER9 *pShader, ID3
void DestroyShaders();
void DirectxInit(HWND window);
void DXSetViewport(float x, float y, float w, float h, float minZ = 0.0f, float maxZ = 1.0f);
#define D3DBLEND_UNK D3DBLEND_FORCE_DWORD
};