mirror of https://github.com/PCSX2/pcsx2.git
GSdx-d3d: Port mipmap max_layer calculation from opengl to direct3d.
Fixes texture corruption on direct3d when full mipmapping was used.
This commit is contained in:
parent
a275cf8e57
commit
e063be3043
|
@ -39,6 +39,8 @@ GSDevice11::GSDevice11()
|
||||||
m_state.topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
m_state.topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||||
m_state.bf = -1;
|
m_state.bf = -1;
|
||||||
|
|
||||||
|
m_mipmap = theApp.GetConfigI("mipmap");
|
||||||
|
|
||||||
if (theApp.GetConfigB("UserHacks")) {
|
if (theApp.GetConfigB("UserHacks")) {
|
||||||
UserHacks_unscale_pt_ln = theApp.GetConfigB("UserHacks_unscale_point_line");
|
UserHacks_unscale_pt_ln = theApp.GetConfigB("UserHacks_unscale_point_line");
|
||||||
UserHacks_disable_NV_hack = theApp.GetConfigB("UserHacks_DisableNVhack");
|
UserHacks_disable_NV_hack = theApp.GetConfigB("UserHacks_DisableNVhack");
|
||||||
|
@ -514,6 +516,10 @@ GSTexture* GSDevice11::CreateSurface(int type, int w, int h, bool msaa, int form
|
||||||
desc.SampleDesc = m_msaa_desc;
|
desc.SampleDesc = m_msaa_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mipmap = m_mipmap > 1 || m_filter != TriFiltering::None;
|
||||||
|
bool mipmap = m_mipmap > 1;
|
||||||
|
int layers = mipmap && format == DXGI_FORMAT_R8G8B8A8_UNORM ? (int)log2(std::max(w,h)) : 1;
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case GSTexture::RenderTarget:
|
case GSTexture::RenderTarget:
|
||||||
|
@ -524,6 +530,7 @@ GSTexture* GSDevice11::CreateSurface(int type, int w, int h, bool msaa, int form
|
||||||
break;
|
break;
|
||||||
case GSTexture::Texture:
|
case GSTexture::Texture:
|
||||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
desc.MipLevels = layers;
|
||||||
break;
|
break;
|
||||||
case GSTexture::Offscreen:
|
case GSTexture::Offscreen:
|
||||||
desc.Usage = D3D11_USAGE_STAGING;
|
desc.Usage = D3D11_USAGE_STAGING;
|
||||||
|
@ -709,14 +716,14 @@ void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
||||||
GSSelector sel;
|
GSSelector sel;
|
||||||
//Don't use shading for stretching, we're just passing through - Note: With Win10 it seems to cause other bugs when shading is off if any of the coords is greater than 0
|
//Don't use shading for stretching, we're just passing through - Note: With Win10 it seems to cause other bugs when shading is off if any of the coords is greater than 0
|
||||||
//I really don't know whats going on there, but this seems to resolve it mostly (if not all, not tester a lot of games, only BIOS, FFXII and VP2)
|
//I really don't know whats going on there, but this seems to resolve it mostly (if not all, not tester a lot of games, only BIOS, FFXII and VP2)
|
||||||
//sel.iip = (sRect.y > 0.0f || sRect.w > 0.0f) ? 1 : 0;
|
//sel.iip = (sRect.y > 0.0f || sRect.w > 0.0f) ? 1 : 0;
|
||||||
//sel.prim = 2; //Triangle Strip
|
//sel.prim = 2; //Triangle Strip
|
||||||
//SetupGS(sel);
|
//SetupGS(sel);
|
||||||
|
|
||||||
GSSetShader(NULL, NULL);
|
GSSetShader(NULL, NULL);
|
||||||
|
|
||||||
/*END OF HACK*/
|
/*END OF HACK*/
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
// ps
|
// ps
|
||||||
|
|
|
@ -60,6 +60,8 @@ class GSDevice11 : public GSDeviceDX
|
||||||
bool UserHacks_unscale_pt_ln;
|
bool UserHacks_unscale_pt_ln;
|
||||||
bool UserHacks_disable_NV_hack;
|
bool UserHacks_disable_NV_hack;
|
||||||
|
|
||||||
|
int m_mipmap;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
ID3D11Buffer* vb;
|
ID3D11Buffer* vb;
|
||||||
|
|
|
@ -32,6 +32,7 @@ GSDevice9::GSDevice9()
|
||||||
FXAA_Compiled = false;
|
FXAA_Compiled = false;
|
||||||
ExShader_Compiled = false;
|
ExShader_Compiled = false;
|
||||||
|
|
||||||
|
m_mipmap = theApp.GetConfigI("mipmap");
|
||||||
|
|
||||||
memset(&m_pp, 0, sizeof(m_pp));
|
memset(&m_pp, 0, sizeof(m_pp));
|
||||||
memset(&m_d3dcaps, 0, sizeof(m_d3dcaps));
|
memset(&m_d3dcaps, 0, sizeof(m_d3dcaps));
|
||||||
|
@ -695,6 +696,10 @@ GSTexture* GSDevice9::CreateSurface(int type, int w, int h, bool msaa, int forma
|
||||||
CComPtr<IDirect3DTexture9> texture;
|
CComPtr<IDirect3DTexture9> texture;
|
||||||
CComPtr<IDirect3DSurface9> surface;
|
CComPtr<IDirect3DSurface9> surface;
|
||||||
|
|
||||||
|
// mipmap = m_mipmap > 1 || m_filter != TriFiltering::None;
|
||||||
|
bool mipmap = m_mipmap > 1;
|
||||||
|
int layers = mipmap && format == D3DFMT_A8R8G8B8 ? (int)log2(std::max(w,h)) : 1;
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case GSTexture::RenderTarget:
|
case GSTexture::RenderTarget:
|
||||||
|
@ -706,7 +711,7 @@ GSTexture* GSDevice9::CreateSurface(int type, int w, int h, bool msaa, int forma
|
||||||
else hr = m_dev->CreateDepthStencilSurface(w, h, (D3DFORMAT)format, D3DMULTISAMPLE_NONE, 0, FALSE, &surface, NULL);
|
else hr = m_dev->CreateDepthStencilSurface(w, h, (D3DFORMAT)format, D3DMULTISAMPLE_NONE, 0, FALSE, &surface, NULL);
|
||||||
break;
|
break;
|
||||||
case GSTexture::Texture:
|
case GSTexture::Texture:
|
||||||
hr = m_dev->CreateTexture(w, h, 1, 0, (D3DFORMAT)format, D3DPOOL_MANAGED, &texture, NULL);
|
hr = m_dev->CreateTexture(w, h, layers, 0, (D3DFORMAT)format, D3DPOOL_MANAGED, &texture, NULL);
|
||||||
break;
|
break;
|
||||||
case GSTexture::Offscreen:
|
case GSTexture::Offscreen:
|
||||||
hr = m_dev->CreateOffscreenPlainSurface(w, h, (D3DFORMAT)format, D3DPOOL_SYSTEMMEM, &surface, NULL);
|
hr = m_dev->CreateOffscreenPlainSurface(w, h, (D3DFORMAT)format, D3DPOOL_SYSTEMMEM, &surface, NULL);
|
||||||
|
@ -981,7 +986,7 @@ void GSDevice9::DoExternalFX(GSTexture* sTex, GSTexture* dTex)
|
||||||
GSVector4 dRect(0, 0, s.x, s.y);
|
GSVector4 dRect(0, 0, s.x, s.y);
|
||||||
|
|
||||||
ExternalFXConstantBuffer cb;
|
ExternalFXConstantBuffer cb;
|
||||||
|
|
||||||
InitExternalFX();
|
InitExternalFX();
|
||||||
|
|
||||||
cb.xyFrame = GSVector2((float)s.x, (float)s.y);
|
cb.xyFrame = GSVector2((float)s.x, (float)s.y);
|
||||||
|
|
|
@ -97,6 +97,8 @@ class GSDevice9 : public GSDeviceDX
|
||||||
bool m_lost;
|
bool m_lost;
|
||||||
D3DFORMAT m_depth_format;
|
D3DFORMAT m_depth_format;
|
||||||
|
|
||||||
|
int m_mipmap;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
IDirect3DVertexBuffer9* vb;
|
IDirect3DVertexBuffer9* vb;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "GSPng.h"
|
#include "GSPng.h"
|
||||||
|
|
||||||
GSTexture11::GSTexture11(ID3D11Texture2D* texture)
|
GSTexture11::GSTexture11(ID3D11Texture2D* texture)
|
||||||
: m_texture(texture)
|
: m_texture(texture), m_layer(0)
|
||||||
{
|
{
|
||||||
ASSERT(m_texture);
|
ASSERT(m_texture);
|
||||||
|
|
||||||
|
@ -44,15 +44,21 @@ GSTexture11::GSTexture11(ID3D11Texture2D* texture)
|
||||||
m_format = (int)m_desc.Format;
|
m_format = (int)m_desc.Format;
|
||||||
|
|
||||||
m_msaa = m_desc.SampleDesc.Count > 1;
|
m_msaa = m_desc.SampleDesc.Count > 1;
|
||||||
|
|
||||||
|
m_max_layer = m_desc.MipLevels;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GSTexture11::Update(const GSVector4i& r, const void* data, int pitch, int layer)
|
bool GSTexture11::Update(const GSVector4i& r, const void* data, int pitch, int layer)
|
||||||
{
|
{
|
||||||
|
if(layer >= m_max_layer)
|
||||||
|
return true;
|
||||||
|
|
||||||
if(m_dev && m_texture)
|
if(m_dev && m_texture)
|
||||||
{
|
{
|
||||||
D3D11_BOX box = { (UINT)r.left, (UINT)r.top, 0U, (UINT)r.right, (UINT)r.bottom, 1U };
|
D3D11_BOX box = { (UINT)r.left, (UINT)r.top, 0U, (UINT)r.right, (UINT)r.bottom, 1U };
|
||||||
|
UINT subresource = layer; // MipSlice + (ArraySlice * MipLevels).
|
||||||
|
|
||||||
m_ctx->UpdateSubresource(m_texture, 0, &box, data, pitch, 0);
|
m_ctx->UpdateSubresource(m_texture, subresource, &box, data, pitch, 0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -65,19 +71,24 @@ bool GSTexture11::Map(GSMap& m, const GSVector4i* r, int layer)
|
||||||
if(r != NULL)
|
if(r != NULL)
|
||||||
{
|
{
|
||||||
// ASSERT(0); // not implemented
|
// ASSERT(0); // not implemented
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(layer >= m_max_layer)
|
||||||
|
return false;
|
||||||
|
|
||||||
if(m_texture && m_desc.Usage == D3D11_USAGE_STAGING)
|
if(m_texture && m_desc.Usage == D3D11_USAGE_STAGING)
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
|
UINT subresource = layer;
|
||||||
|
|
||||||
if(SUCCEEDED(m_ctx->Map(m_texture, 0, D3D11_MAP_READ_WRITE, 0, &map)))
|
if(SUCCEEDED(m_ctx->Map(m_texture, subresource, D3D11_MAP_READ_WRITE, 0, &map)))
|
||||||
{
|
{
|
||||||
m.bits = (uint8*)map.pData;
|
m.bits = (uint8*)map.pData;
|
||||||
m.pitch = (int)map.RowPitch;
|
m.pitch = (int)map.RowPitch;
|
||||||
|
|
||||||
|
m_layer = layer;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +100,8 @@ void GSTexture11::Unmap()
|
||||||
{
|
{
|
||||||
if(m_texture)
|
if(m_texture)
|
||||||
{
|
{
|
||||||
m_ctx->Unmap(m_texture, 0);
|
UINT subresource = m_layer;
|
||||||
|
m_ctx->Unmap(m_texture, subresource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,9 @@ class GSTexture11 : public GSTexture
|
||||||
CComPtr<ID3D11RenderTargetView> m_rtv;
|
CComPtr<ID3D11RenderTargetView> m_rtv;
|
||||||
CComPtr<ID3D11DepthStencilView> m_dsv;
|
CComPtr<ID3D11DepthStencilView> m_dsv;
|
||||||
|
|
||||||
|
int m_layer;
|
||||||
|
int m_max_layer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GSTexture11(ID3D11Texture2D* texture);
|
explicit GSTexture11(ID3D11Texture2D* texture);
|
||||||
|
|
||||||
|
|
|
@ -24,17 +24,20 @@
|
||||||
#include "GSPng.h"
|
#include "GSPng.h"
|
||||||
|
|
||||||
GSTexture9::GSTexture9(IDirect3DSurface9* surface)
|
GSTexture9::GSTexture9(IDirect3DSurface9* surface)
|
||||||
|
: m_surface(surface), m_layer(0), m_generate_mipmap(true)
|
||||||
{
|
{
|
||||||
m_surface = surface;
|
|
||||||
|
|
||||||
surface->GetDevice(&m_dev);
|
surface->GetDevice(&m_dev);
|
||||||
surface->GetDesc(&m_desc);
|
surface->GetDesc(&m_desc);
|
||||||
|
|
||||||
|
m_max_layer = 1;
|
||||||
|
|
||||||
if(m_desc.Type != D3DRTYPE_SURFACE)
|
if(m_desc.Type != D3DRTYPE_SURFACE)
|
||||||
{
|
{
|
||||||
surface->GetContainer(__uuidof(IDirect3DTexture9), (void**)&m_texture);
|
surface->GetContainer(__uuidof(IDirect3DTexture9), (void**)&m_texture);
|
||||||
|
|
||||||
ASSERT(m_texture != NULL);
|
ASSERT(m_texture != NULL);
|
||||||
|
|
||||||
|
m_max_layer = m_texture->GetLevelCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_size.x = (int)m_desc.Width;
|
m_size.x = (int)m_desc.Width;
|
||||||
|
@ -51,9 +54,8 @@ GSTexture9::GSTexture9(IDirect3DSurface9* surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
GSTexture9::GSTexture9(IDirect3DTexture9* texture)
|
GSTexture9::GSTexture9(IDirect3DTexture9* texture)
|
||||||
|
: m_texture(texture), m_layer(0), m_generate_mipmap(true)
|
||||||
{
|
{
|
||||||
m_texture = texture;
|
|
||||||
|
|
||||||
texture->GetDevice(&m_dev);
|
texture->GetDevice(&m_dev);
|
||||||
texture->GetLevelDesc(0, &m_desc);
|
texture->GetLevelDesc(0, &m_desc);
|
||||||
texture->GetSurfaceLevel(0, &m_surface);
|
texture->GetSurfaceLevel(0, &m_surface);
|
||||||
|
@ -71,6 +73,8 @@ GSTexture9::GSTexture9(IDirect3DTexture9* texture)
|
||||||
m_format = (int)m_desc.Format;
|
m_format = (int)m_desc.Format;
|
||||||
|
|
||||||
m_msaa = m_desc.MultiSampleType > 1;
|
m_msaa = m_desc.MultiSampleType > 1;
|
||||||
|
|
||||||
|
m_max_layer = m_texture->GetLevelCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
GSTexture9::~GSTexture9()
|
GSTexture9::~GSTexture9()
|
||||||
|
@ -79,6 +83,16 @@ GSTexture9::~GSTexture9()
|
||||||
|
|
||||||
bool GSTexture9::Update(const GSVector4i& r, const void* data, int pitch, int layer)
|
bool GSTexture9::Update(const GSVector4i& r, const void* data, int pitch, int layer)
|
||||||
{
|
{
|
||||||
|
if(layer >= m_max_layer)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(m_texture)
|
||||||
|
{
|
||||||
|
m_surface = nullptr;
|
||||||
|
|
||||||
|
m_texture->GetSurfaceLevel(layer, &m_surface);
|
||||||
|
}
|
||||||
|
|
||||||
if(m_surface)
|
if(m_surface)
|
||||||
{
|
{
|
||||||
D3DLOCKED_RECT lr;
|
D3DLOCKED_RECT lr;
|
||||||
|
@ -107,6 +121,8 @@ bool GSTexture9::Update(const GSVector4i& r, const void* data, int pitch, int la
|
||||||
|
|
||||||
m_surface->UnlockRect();
|
m_surface->UnlockRect();
|
||||||
|
|
||||||
|
m_generate_mipmap = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,6 +134,16 @@ bool GSTexture9::Map(GSMap& m, const GSVector4i* r, int layer)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
if(layer >= m_max_layer)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(m_texture)
|
||||||
|
{
|
||||||
|
m_surface = nullptr;
|
||||||
|
|
||||||
|
m_texture->GetSurfaceLevel(layer, &m_surface);
|
||||||
|
}
|
||||||
|
|
||||||
if(m_surface)
|
if(m_surface)
|
||||||
{
|
{
|
||||||
D3DLOCKED_RECT lr;
|
D3DLOCKED_RECT lr;
|
||||||
|
@ -127,6 +153,8 @@ bool GSTexture9::Map(GSMap& m, const GSVector4i* r, int layer)
|
||||||
m.bits = (uint8*)lr.pBits;
|
m.bits = (uint8*)lr.pBits;
|
||||||
m.pitch = (int)lr.Pitch;
|
m.pitch = (int)lr.Pitch;
|
||||||
|
|
||||||
|
m_layer = layer;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,6 +167,8 @@ void GSTexture9::Unmap()
|
||||||
if(m_surface)
|
if(m_surface)
|
||||||
{
|
{
|
||||||
m_surface->UnlockRect();
|
m_surface->UnlockRect();
|
||||||
|
|
||||||
|
m_generate_mipmap = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,11 @@ class GSTexture9 : public GSTexture
|
||||||
CComPtr<IDirect3DTexture9> m_texture;
|
CComPtr<IDirect3DTexture9> m_texture;
|
||||||
D3DSURFACE_DESC m_desc;
|
D3DSURFACE_DESC m_desc;
|
||||||
|
|
||||||
|
bool m_generate_mipmap;
|
||||||
|
|
||||||
|
int m_layer;
|
||||||
|
int m_max_layer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GSTexture9(IDirect3DSurface9* surface);
|
explicit GSTexture9(IDirect3DSurface9* surface);
|
||||||
explicit GSTexture9(IDirect3DTexture9* texture);
|
explicit GSTexture9(IDirect3DTexture9* texture);
|
||||||
|
|
Loading…
Reference in New Issue