mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Check for D3D11 R/W bind conflicts at subresource granularity. Refs #244
This commit is contained in:
@@ -966,23 +966,12 @@ void D3D11RenderState::ReleaseRef(ID3D11DeviceChild *p)
|
||||
}
|
||||
}
|
||||
|
||||
bool D3D11RenderState::IsBoundIUnknownForWrite(IUnknown *resource, bool readDepthOnly,
|
||||
bool D3D11RenderState::IsBoundIUnknownForWrite(const ResourceRange &range, bool readDepthOnly,
|
||||
bool readStencilOnly)
|
||||
{
|
||||
for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
if(CSUAVs[i])
|
||||
{
|
||||
CSUAVs[i]->GetResource(&res);
|
||||
if(resource == (IUnknown *)res)
|
||||
found = true;
|
||||
SAFE_RELEASE(res);
|
||||
}
|
||||
|
||||
if(found || resource == (IUnknown *)CSUAVs[i])
|
||||
if(range.Intersects(ResourceRange(CSUAVs[i])))
|
||||
{
|
||||
// RDCDEBUG("Resource was bound on CS UAV %u", i);
|
||||
return true;
|
||||
@@ -991,7 +980,7 @@ bool D3D11RenderState::IsBoundIUnknownForWrite(IUnknown *resource, bool readDept
|
||||
|
||||
for(UINT i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++)
|
||||
{
|
||||
if(resource == (IUnknown *)SO.Buffers[i])
|
||||
if(range.Intersects(ResourceRange(SO.Buffers[i])))
|
||||
{
|
||||
// RDCDEBUG("Resource was bound on SO buffer %u", i);
|
||||
return true;
|
||||
@@ -1000,18 +989,7 @@ bool D3D11RenderState::IsBoundIUnknownForWrite(IUnknown *resource, bool readDept
|
||||
|
||||
for(UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
if(OM.RenderTargets[i])
|
||||
{
|
||||
OM.RenderTargets[i]->GetResource(&res);
|
||||
if(resource == (IUnknown *)res)
|
||||
found = true;
|
||||
SAFE_RELEASE(res);
|
||||
}
|
||||
|
||||
if(found || resource == (IUnknown *)OM.RenderTargets[i])
|
||||
if(range.Intersects(ResourceRange(OM.RenderTargets[i])))
|
||||
{
|
||||
// RDCDEBUG("Resource was bound on RTV %u", i);
|
||||
return true;
|
||||
@@ -1020,18 +998,7 @@ bool D3D11RenderState::IsBoundIUnknownForWrite(IUnknown *resource, bool readDept
|
||||
|
||||
for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
if(OM.UAVs[i])
|
||||
{
|
||||
OM.UAVs[i]->GetResource(&res);
|
||||
if(resource == (IUnknown *)res)
|
||||
found = true;
|
||||
SAFE_RELEASE(res);
|
||||
}
|
||||
|
||||
if(found || resource == (IUnknown *)OM.UAVs[i])
|
||||
if(range.Intersects(ResourceRange(OM.UAVs[i])))
|
||||
{
|
||||
// RDCDEBUG("Resource was bound on OM UAV %d", i);
|
||||
return true;
|
||||
@@ -1039,25 +1006,17 @@ bool D3D11RenderState::IsBoundIUnknownForWrite(IUnknown *resource, bool readDept
|
||||
}
|
||||
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
UINT depthFlags = 0;
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
if(OM.DepthView)
|
||||
{
|
||||
OM.DepthView->GetResource(&res);
|
||||
if(resource == (IUnknown *)res)
|
||||
found = true;
|
||||
SAFE_RELEASE(res);
|
||||
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC d;
|
||||
OM.DepthView->GetDesc(&d);
|
||||
|
||||
depthFlags = d.Flags;
|
||||
}
|
||||
|
||||
if(found || resource == (IUnknown *)OM.DepthView)
|
||||
if(range.Intersects(ResourceRange(OM.DepthView)))
|
||||
{
|
||||
// RDCDEBUG("Resource was bound on OM DSV");
|
||||
|
||||
@@ -1083,22 +1042,11 @@ bool D3D11RenderState::IsBoundIUnknownForWrite(IUnknown *resource, bool readDept
|
||||
return false;
|
||||
}
|
||||
|
||||
void D3D11RenderState::UnbindIUnknownForWrite(IUnknown *resource)
|
||||
void D3D11RenderState::UnbindIUnknownForWrite(const ResourceRange &range)
|
||||
{
|
||||
for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
if(CSUAVs[i])
|
||||
{
|
||||
CSUAVs[i]->GetResource(&res);
|
||||
if(resource == (IUnknown *)res)
|
||||
found = true;
|
||||
SAFE_RELEASE(res);
|
||||
}
|
||||
|
||||
if(found || resource == (IUnknown *)CSUAVs[i])
|
||||
if(range.Intersects(ResourceRange(CSUAVs[i])))
|
||||
{
|
||||
ReleaseRef(CSUAVs[i]);
|
||||
CSUAVs[i] = NULL;
|
||||
@@ -1107,7 +1055,7 @@ void D3D11RenderState::UnbindIUnknownForWrite(IUnknown *resource)
|
||||
|
||||
for(UINT i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++)
|
||||
{
|
||||
if(resource == (IUnknown *)SO.Buffers[i])
|
||||
if(range.Intersects(ResourceRange(SO.Buffers[i])))
|
||||
{
|
||||
ReleaseRef(SO.Buffers[i]);
|
||||
SO.Buffers[i] = NULL;
|
||||
@@ -1116,18 +1064,7 @@ void D3D11RenderState::UnbindIUnknownForWrite(IUnknown *resource)
|
||||
|
||||
for(UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
if(OM.RenderTargets[i])
|
||||
{
|
||||
OM.RenderTargets[i]->GetResource(&res);
|
||||
if(resource == (IUnknown *)res)
|
||||
found = true;
|
||||
SAFE_RELEASE(res);
|
||||
}
|
||||
|
||||
if(found || resource == (IUnknown *)OM.RenderTargets[i])
|
||||
if(range.Intersects(ResourceRange(OM.RenderTargets[i])))
|
||||
{
|
||||
ReleaseRef(OM.RenderTargets[i]);
|
||||
OM.RenderTargets[i] = NULL;
|
||||
@@ -1136,57 +1073,26 @@ void D3D11RenderState::UnbindIUnknownForWrite(IUnknown *resource)
|
||||
|
||||
for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
if(OM.UAVs[i])
|
||||
{
|
||||
OM.UAVs[i]->GetResource(&res);
|
||||
if(resource == (IUnknown *)res)
|
||||
found = true;
|
||||
SAFE_RELEASE(res);
|
||||
}
|
||||
|
||||
if(found || resource == (IUnknown *)OM.UAVs[i])
|
||||
if(range.Intersects(ResourceRange(OM.UAVs[i])))
|
||||
{
|
||||
ReleaseRef(OM.UAVs[i]);
|
||||
OM.UAVs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(range.Intersects(ResourceRange(OM.DepthView)))
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
UINT depthFlags = 0;
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
if(OM.DepthView)
|
||||
{
|
||||
OM.DepthView->GetResource(&res);
|
||||
if(resource == (IUnknown *)res)
|
||||
found = true;
|
||||
SAFE_RELEASE(res);
|
||||
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC d;
|
||||
OM.DepthView->GetDesc(&d);
|
||||
|
||||
depthFlags = d.Flags;
|
||||
}
|
||||
|
||||
if(found || resource == (IUnknown *)OM.DepthView)
|
||||
{
|
||||
ReleaseRef(OM.DepthView);
|
||||
OM.DepthView = NULL;
|
||||
}
|
||||
ReleaseRef(OM.DepthView);
|
||||
OM.DepthView = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void D3D11RenderState::UnbindIUnknownForRead(IUnknown *resource, bool allowDepthOnly,
|
||||
void D3D11RenderState::UnbindIUnknownForRead(const ResourceRange &range, bool allowDepthOnly,
|
||||
bool allowStencilOnly)
|
||||
{
|
||||
for(int i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++)
|
||||
{
|
||||
if(resource == (IUnknown *)IA.VBs[i])
|
||||
if(range.Intersects(ResourceRange(IA.VBs[i])))
|
||||
{
|
||||
// RDCDEBUG("Resource was bound on IA VB %u", i);
|
||||
ReleaseRef(IA.VBs[i]);
|
||||
@@ -1194,7 +1100,7 @@ void D3D11RenderState::UnbindIUnknownForRead(IUnknown *resource, bool allowDepth
|
||||
}
|
||||
}
|
||||
|
||||
if(resource == (IUnknown *)IA.IndexBuffer)
|
||||
if(range.Intersects(ResourceRange(IA.IndexBuffer)))
|
||||
{
|
||||
// RDCDEBUG("Resource was bound on IA IB");
|
||||
ReleaseRef(IA.IndexBuffer);
|
||||
@@ -1207,7 +1113,7 @@ void D3D11RenderState::UnbindIUnknownForRead(IUnknown *resource, bool allowDepth
|
||||
{
|
||||
for(UINT i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++)
|
||||
{
|
||||
if(resource == (IUnknown *)sh->ConstantBuffers[i])
|
||||
if(range.Intersects(ResourceRange(sh->ConstantBuffers[i])))
|
||||
{
|
||||
// RDCDEBUG("Resource was bound on %s CB %u", names[s], i);
|
||||
ReleaseRef(sh->ConstantBuffers[i]);
|
||||
@@ -1217,8 +1123,6 @@ void D3D11RenderState::UnbindIUnknownForRead(IUnknown *resource, bool allowDepth
|
||||
|
||||
for(UINT i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
bool readDepthOnly = false;
|
||||
bool readStencilOnly = false;
|
||||
|
||||
@@ -1226,11 +1130,11 @@ void D3D11RenderState::UnbindIUnknownForRead(IUnknown *resource, bool allowDepth
|
||||
DXGI_FORMAT fmt = DXGI_FORMAT_UNKNOWN;
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
if(sh->SRVs[i])
|
||||
// we only need to fetch the information about depth/stencil
|
||||
// read-only status if we're actually going to care about it.
|
||||
if(sh->SRVs[i] && (allowDepthOnly || allowStencilOnly))
|
||||
{
|
||||
sh->SRVs[i]->GetResource(&res);
|
||||
if(resource == (IUnknown *)res)
|
||||
found = true;
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
sh->SRVs[i]->GetDesc(&srvDesc);
|
||||
@@ -1269,7 +1173,7 @@ void D3D11RenderState::UnbindIUnknownForRead(IUnknown *resource, bool allowDepth
|
||||
SAFE_RELEASE(res);
|
||||
}
|
||||
|
||||
if(found || resource == (IUnknown *)sh->SRVs[i])
|
||||
if(range.Intersects(ResourceRange(sh->SRVs[i])))
|
||||
{
|
||||
// RDCDEBUG("Resource was bound on %s SRV %u", names[s], i);
|
||||
|
||||
@@ -1653,3 +1557,244 @@ D3D11RenderStateTracker::~D3D11RenderStateTracker()
|
||||
{
|
||||
m_RS.ApplyState(m_pContext);
|
||||
}
|
||||
|
||||
D3D11RenderState::ResourceRange::ResourceRange(ID3D11ShaderResourceView *srv)
|
||||
{
|
||||
minMip = minSlice = 0;
|
||||
|
||||
if(srv == NULL)
|
||||
{
|
||||
resource = NULL;
|
||||
maxMip = maxSlice = ~0U;
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
srv->GetResource(&res);
|
||||
res->Release();
|
||||
resource = (IUnknown *)res;
|
||||
|
||||
UINT numMips = ~0U, numSlices = ~0U;
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
|
||||
srv->GetDesc(&srvd);
|
||||
|
||||
switch(srvd.ViewDimension)
|
||||
{
|
||||
case D3D11_SRV_DIMENSION_TEXTURE1D:
|
||||
minMip = srvd.Texture1D.MostDetailedMip;
|
||||
numMips = srvd.Texture1D.MipLevels;
|
||||
break;
|
||||
case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
|
||||
minMip = srvd.Texture1DArray.MostDetailedMip;
|
||||
numMips = srvd.Texture1DArray.MipLevels;
|
||||
minSlice = srvd.Texture1DArray.FirstArraySlice;
|
||||
numSlices = srvd.Texture1DArray.ArraySize;
|
||||
break;
|
||||
case D3D11_SRV_DIMENSION_TEXTURE2D:
|
||||
minMip = srvd.Texture2D.MostDetailedMip;
|
||||
numMips = srvd.Texture2D.MipLevels;
|
||||
break;
|
||||
case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
|
||||
minMip = srvd.Texture2DArray.MostDetailedMip;
|
||||
numMips = srvd.Texture2DArray.MipLevels;
|
||||
minSlice = srvd.Texture2DArray.FirstArraySlice;
|
||||
numSlices = srvd.Texture2DArray.ArraySize;
|
||||
break;
|
||||
case D3D11_SRV_DIMENSION_TEXTURE2DMS: break;
|
||||
case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
|
||||
minSlice = srvd.Texture2DMSArray.FirstArraySlice;
|
||||
numSlices = srvd.Texture2DMSArray.ArraySize;
|
||||
break;
|
||||
case D3D11_SRV_DIMENSION_TEXTURE3D:
|
||||
minMip = srvd.Texture3D.MostDetailedMip;
|
||||
numMips = srvd.Texture3D.MipLevels;
|
||||
break;
|
||||
case D3D11_SRV_DIMENSION_TEXTURECUBE:
|
||||
minMip = srvd.TextureCube.MostDetailedMip;
|
||||
numMips = srvd.TextureCube.MipLevels;
|
||||
break;
|
||||
case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY:
|
||||
minMip = srvd.TextureCubeArray.MostDetailedMip;
|
||||
numMips = srvd.TextureCubeArray.MipLevels;
|
||||
minSlice = srvd.TextureCubeArray.First2DArrayFace;
|
||||
numSlices = srvd.TextureCubeArray.NumCubes * 6;
|
||||
break;
|
||||
case D3D11_SRV_DIMENSION_UNKNOWN:
|
||||
case D3D11_SRV_DIMENSION_BUFFER:
|
||||
case D3D11_SRV_DIMENSION_BUFFEREX: break;
|
||||
}
|
||||
|
||||
SetMaxes(numMips, numSlices);
|
||||
}
|
||||
|
||||
D3D11RenderState::ResourceRange::ResourceRange(ID3D11UnorderedAccessView *uav)
|
||||
{
|
||||
minMip = minSlice = 0;
|
||||
|
||||
if(uav == NULL)
|
||||
{
|
||||
resource = NULL;
|
||||
maxMip = maxSlice = ~0U;
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
uav->GetResource(&res);
|
||||
res->Release();
|
||||
resource = (IUnknown *)res;
|
||||
|
||||
UINT numMips = ~0U, numSlices = ~0U;
|
||||
|
||||
D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
|
||||
uav->GetDesc(&desc);
|
||||
|
||||
switch(desc.ViewDimension)
|
||||
{
|
||||
case D3D11_UAV_DIMENSION_TEXTURE1D:
|
||||
minMip = desc.Texture1D.MipSlice;
|
||||
numMips = 1;
|
||||
break;
|
||||
case D3D11_UAV_DIMENSION_TEXTURE1DARRAY:
|
||||
minMip = desc.Texture1DArray.MipSlice;
|
||||
numMips = 1;
|
||||
minSlice = desc.Texture1DArray.FirstArraySlice;
|
||||
numSlices = desc.Texture1DArray.ArraySize;
|
||||
break;
|
||||
case D3D11_UAV_DIMENSION_TEXTURE2D:
|
||||
minMip = desc.Texture2D.MipSlice;
|
||||
numMips = 1;
|
||||
break;
|
||||
case D3D11_UAV_DIMENSION_TEXTURE2DARRAY:
|
||||
minMip = desc.Texture2DArray.MipSlice;
|
||||
numMips = 1;
|
||||
minSlice = desc.Texture2DArray.FirstArraySlice;
|
||||
numSlices = desc.Texture2DArray.ArraySize;
|
||||
break;
|
||||
case D3D11_UAV_DIMENSION_TEXTURE3D:
|
||||
minMip = desc.Texture3D.MipSlice;
|
||||
numMips = 1;
|
||||
minSlice = desc.Texture3D.FirstWSlice;
|
||||
numSlices = desc.Texture3D.WSize;
|
||||
break;
|
||||
case D3D11_UAV_DIMENSION_UNKNOWN:
|
||||
case D3D11_UAV_DIMENSION_BUFFER: break;
|
||||
}
|
||||
|
||||
SetMaxes(numMips, numSlices);
|
||||
}
|
||||
|
||||
D3D11RenderState::ResourceRange::ResourceRange(ID3D11RenderTargetView *rtv)
|
||||
{
|
||||
minMip = minSlice = 0;
|
||||
|
||||
if(rtv == NULL)
|
||||
{
|
||||
resource = NULL;
|
||||
maxMip = maxSlice = ~0U;
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
rtv->GetResource(&res);
|
||||
res->Release();
|
||||
resource = (IUnknown *)res;
|
||||
|
||||
UINT numMips = ~0U, numSlices = ~0U;
|
||||
|
||||
D3D11_RENDER_TARGET_VIEW_DESC desc;
|
||||
rtv->GetDesc(&desc);
|
||||
|
||||
switch(desc.ViewDimension)
|
||||
{
|
||||
case D3D11_RTV_DIMENSION_TEXTURE1D:
|
||||
minMip = desc.Texture1D.MipSlice;
|
||||
numMips = 1;
|
||||
break;
|
||||
case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
|
||||
minMip = desc.Texture1DArray.MipSlice;
|
||||
numMips = 1;
|
||||
minSlice = desc.Texture1DArray.FirstArraySlice;
|
||||
numSlices = desc.Texture1DArray.ArraySize;
|
||||
break;
|
||||
case D3D11_RTV_DIMENSION_TEXTURE2D:
|
||||
minMip = desc.Texture2D.MipSlice;
|
||||
numMips = 1;
|
||||
break;
|
||||
case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
|
||||
minMip = desc.Texture2DArray.MipSlice;
|
||||
numMips = 1;
|
||||
minSlice = desc.Texture2DArray.FirstArraySlice;
|
||||
numSlices = desc.Texture2DArray.ArraySize;
|
||||
break;
|
||||
case D3D11_RTV_DIMENSION_TEXTURE2DMS: break;
|
||||
case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
|
||||
minSlice = desc.Texture2DMSArray.FirstArraySlice;
|
||||
numSlices = desc.Texture2DMSArray.ArraySize;
|
||||
break;
|
||||
case D3D11_RTV_DIMENSION_TEXTURE3D:
|
||||
minMip = desc.Texture3D.MipSlice;
|
||||
numMips = 1;
|
||||
minSlice = desc.Texture3D.FirstWSlice;
|
||||
numSlices = desc.Texture3D.WSize;
|
||||
break;
|
||||
case D3D11_RTV_DIMENSION_UNKNOWN:
|
||||
case D3D11_RTV_DIMENSION_BUFFER: break;
|
||||
}
|
||||
|
||||
SetMaxes(numMips, numSlices);
|
||||
}
|
||||
|
||||
D3D11RenderState::ResourceRange::ResourceRange(ID3D11DepthStencilView *dsv)
|
||||
{
|
||||
minMip = minSlice = 0;
|
||||
|
||||
if(dsv == NULL)
|
||||
{
|
||||
resource = NULL;
|
||||
maxMip = maxSlice = ~0U;
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
dsv->GetResource(&res);
|
||||
res->Release();
|
||||
resource = (IUnknown *)res;
|
||||
|
||||
UINT numMips = ~0U, numSlices = ~0U;
|
||||
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC desc;
|
||||
dsv->GetDesc(&desc);
|
||||
|
||||
switch(desc.ViewDimension)
|
||||
{
|
||||
case D3D11_DSV_DIMENSION_TEXTURE1D:
|
||||
minMip = desc.Texture1D.MipSlice;
|
||||
numMips = 1;
|
||||
break;
|
||||
case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
|
||||
minMip = desc.Texture1DArray.MipSlice;
|
||||
numMips = 1;
|
||||
minSlice = desc.Texture1DArray.FirstArraySlice;
|
||||
numSlices = desc.Texture1DArray.ArraySize;
|
||||
break;
|
||||
case D3D11_DSV_DIMENSION_TEXTURE2D:
|
||||
minMip = desc.Texture2D.MipSlice;
|
||||
numMips = 1;
|
||||
break;
|
||||
case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
|
||||
minMip = desc.Texture2DArray.MipSlice;
|
||||
numMips = 1;
|
||||
minSlice = desc.Texture2DArray.FirstArraySlice;
|
||||
numSlices = desc.Texture2DArray.ArraySize;
|
||||
break;
|
||||
case D3D11_DSV_DIMENSION_TEXTURE2DMS: break;
|
||||
case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
|
||||
minSlice = desc.Texture2DMSArray.FirstArraySlice;
|
||||
numSlices = desc.Texture2DMSArray.ArraySize;
|
||||
break;
|
||||
case D3D11_DSV_DIMENSION_UNKNOWN: break;
|
||||
}
|
||||
|
||||
SetMaxes(numMips, numSlices);
|
||||
}
|
||||
|
||||
@@ -56,80 +56,165 @@ struct D3D11RenderState
|
||||
// need to be aware of depth-stencil as a special case, DSV can be flagged read-only
|
||||
// of depth, stencil or both to allow read binds of that component at the same time.
|
||||
|
||||
bool IsBoundIUnknownForWrite(IUnknown *resource, bool readDepthOnly, bool readStencilOnly);
|
||||
void UnbindIUnknownForRead(IUnknown *resource, bool allowDepthOnly, bool allowStencilOnly);
|
||||
struct ResourceRange
|
||||
{
|
||||
ResourceRange(ID3D11Buffer *res)
|
||||
{
|
||||
resource = res;
|
||||
minMip = minSlice = 0;
|
||||
maxMip = maxSlice = ~0U;
|
||||
fullRange = true;
|
||||
}
|
||||
|
||||
ResourceRange(ID3D11Texture2D *res)
|
||||
{
|
||||
resource = res;
|
||||
minMip = minSlice = 0;
|
||||
maxMip = maxSlice = ~0U;
|
||||
fullRange = true;
|
||||
}
|
||||
|
||||
// initialises the range with the contents of the view
|
||||
ResourceRange(ID3D11ShaderResourceView *srv);
|
||||
ResourceRange(ID3D11UnorderedAccessView *uav);
|
||||
ResourceRange(ID3D11RenderTargetView *rtv);
|
||||
ResourceRange(ID3D11DepthStencilView *dsv);
|
||||
|
||||
void SetMaxes(UINT numMips, UINT numSlices)
|
||||
{
|
||||
if(numMips == ~0U)
|
||||
maxMip = ~0U;
|
||||
else
|
||||
maxMip = minMip + numMips - 1;
|
||||
|
||||
if(numSlices == ~0U)
|
||||
maxSlice = ~0U;
|
||||
else
|
||||
maxSlice = minSlice + numSlices - 1;
|
||||
|
||||
// save this bool for faster intersection tests. Note that full range could also
|
||||
// be true if maxMip == 12 or something, but since this is just a conservative
|
||||
// early out we are only concerned with a common case.
|
||||
fullRange = (minMip == 0 && minSlice == 0 && maxMip == ~0U && maxSlice == ~0U);
|
||||
}
|
||||
|
||||
bool Intersects(const ResourceRange &range) const
|
||||
{
|
||||
if(resource != range.resource)
|
||||
return false;
|
||||
|
||||
// we are the same resource, but maybe we refer to disjoint
|
||||
// ranges of the subresources. Do an early-out check though
|
||||
// if either of the ranges refers to the whole resource
|
||||
if(fullRange || range.fullRange)
|
||||
return true;
|
||||
|
||||
// do we refer to the same mip anywhere
|
||||
if(minMip <= range.maxMip && range.minMip <= maxMip)
|
||||
{
|
||||
// and the same slice? (for resources without slices, this will just be
|
||||
// 0 - ~0U so definitely true
|
||||
if(minSlice <= range.maxSlice && range.minSlice <= maxSlice)
|
||||
return true;
|
||||
}
|
||||
|
||||
// if not, then we don't intersect
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
ResourceRange();
|
||||
|
||||
IUnknown *resource;
|
||||
UINT minMip;
|
||||
UINT minSlice;
|
||||
UINT maxMip;
|
||||
UINT maxSlice;
|
||||
bool fullRange;
|
||||
};
|
||||
|
||||
// the below functions are only called with ResourceRange, which is only constructable for
|
||||
// views (where it takes the resource and visible subresources from the view parameters)
|
||||
// or directly for a resource. Thus, they are never called with a view directly, or any other
|
||||
// type.
|
||||
|
||||
// is any part of this range bound for a writing part of the pipeline? if so, read binds will bind
|
||||
// NULL
|
||||
bool IsBoundIUnknownForWrite(const ResourceRange &range, bool readDepthOnly, bool readStencilOnly);
|
||||
|
||||
// this range was bound for writing - find any overlapping read binds and set them to NULL
|
||||
void UnbindIUnknownForRead(const ResourceRange &range, bool allowDepthOnly, bool allowStencilOnly);
|
||||
|
||||
// just for utility, not used below
|
||||
void UnbindIUnknownForWrite(IUnknown *resource);
|
||||
void UnbindIUnknownForWrite(const ResourceRange &range);
|
||||
|
||||
// define template but only implement for specific types, so we can more easily reason
|
||||
// about what types are passing through these functions
|
||||
template <typename T>
|
||||
bool IsBoundForWrite(T *resource)
|
||||
{
|
||||
if(resource == NULL)
|
||||
return false;
|
||||
bool IsBoundForWrite(T *resource);
|
||||
|
||||
return IsBoundIUnknownForWrite((IUnknown *)resource, false, false);
|
||||
template <>
|
||||
bool IsBoundForWrite(ID3D11InputLayout *resource)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool IsBoundForWrite(ID3D11Resource *resource)
|
||||
bool IsBoundForWrite(ID3D11ClassInstance *resource)
|
||||
{
|
||||
if(resource == NULL)
|
||||
return false;
|
||||
|
||||
bool readDepthOnly = false;
|
||||
bool readStencilOnly = false;
|
||||
|
||||
D3D11_RESOURCE_DIMENSION dim;
|
||||
resource->GetType(&dim);
|
||||
|
||||
if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D)
|
||||
{
|
||||
D3D11_TEXTURE1D_DESC d;
|
||||
((ID3D11Texture1D *)resource)->GetDesc(&d);
|
||||
|
||||
if(d.Format == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT ||
|
||||
d.Format == DXGI_FORMAT_X24_TYPELESS_G8_UINT)
|
||||
{
|
||||
readStencilOnly = true;
|
||||
}
|
||||
if(d.Format == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS ||
|
||||
d.Format == DXGI_FORMAT_R24_UNORM_X8_TYPELESS)
|
||||
{
|
||||
readDepthOnly = true;
|
||||
}
|
||||
}
|
||||
else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC d;
|
||||
((ID3D11Texture2D *)resource)->GetDesc(&d);
|
||||
|
||||
if(d.Format == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT ||
|
||||
d.Format == DXGI_FORMAT_X24_TYPELESS_G8_UINT)
|
||||
{
|
||||
readStencilOnly = true;
|
||||
}
|
||||
if(d.Format == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS ||
|
||||
d.Format == DXGI_FORMAT_R24_UNORM_X8_TYPELESS)
|
||||
{
|
||||
readDepthOnly = true;
|
||||
}
|
||||
}
|
||||
|
||||
return IsBoundIUnknownForWrite((IUnknown *)resource, readDepthOnly, readStencilOnly);
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool IsBoundForWrite(ID3D11ShaderResourceView *resource)
|
||||
bool IsBoundForWrite(ID3D11DeviceChild *shader)
|
||||
{
|
||||
if(resource == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool IsBoundForWrite(ID3D11SamplerState *resource)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool IsBoundForWrite(ID3D11BlendState *state)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool IsBoundForWrite(ID3D11RasterizerState *state)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool IsBoundForWrite(ID3D11DepthStencilState *state)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool IsBoundForWrite(ID3D11Buffer *buffer)
|
||||
{
|
||||
if(buffer == NULL)
|
||||
return false;
|
||||
|
||||
return IsBoundIUnknownForWrite(ResourceRange(buffer), false, false);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool IsBoundForWrite(ID3D11ShaderResourceView *srv)
|
||||
{
|
||||
if(srv == NULL)
|
||||
return false;
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
resource->GetResource(&res);
|
||||
srv->GetResource(&res);
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
|
||||
resource->GetDesc(&srvd);
|
||||
srv->GetDesc(&srvd);
|
||||
|
||||
bool readDepthOnly = false;
|
||||
bool readStencilOnly = false;
|
||||
@@ -180,79 +265,66 @@ struct D3D11RenderState
|
||||
}
|
||||
}
|
||||
|
||||
bool ret = IsBoundIUnknownForWrite((IUnknown *)res, readDepthOnly, readStencilOnly);
|
||||
|
||||
SAFE_RELEASE(res);
|
||||
|
||||
return ret;
|
||||
return IsBoundIUnknownForWrite(ResourceRange(srv), readDepthOnly, readStencilOnly);
|
||||
}
|
||||
|
||||
// same as IsBoundForWrite above
|
||||
template <typename T>
|
||||
void UnbindForRead(T *resource)
|
||||
void UnbindForRead(T *resource);
|
||||
|
||||
template <>
|
||||
void UnbindForRead(ID3D11Buffer *buffer)
|
||||
{
|
||||
if(resource == NULL)
|
||||
if(buffer == NULL)
|
||||
return;
|
||||
UnbindIUnknownForRead((IUnknown *)resource, false, false);
|
||||
UnbindIUnknownForRead(ResourceRange(buffer), false, false);
|
||||
}
|
||||
|
||||
template <>
|
||||
void UnbindForRead(ID3D11RenderTargetView *resource)
|
||||
void UnbindForRead(ID3D11RenderTargetView *rtv)
|
||||
{
|
||||
if(resource == NULL)
|
||||
if(rtv == NULL)
|
||||
return;
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
resource->GetResource(&res);
|
||||
|
||||
UnbindIUnknownForRead((IUnknown *)res, false, false);
|
||||
|
||||
SAFE_RELEASE(res);
|
||||
UnbindIUnknownForRead(ResourceRange(rtv), false, false);
|
||||
}
|
||||
|
||||
template <>
|
||||
void UnbindForRead(ID3D11DepthStencilView *resource)
|
||||
void UnbindForRead(ID3D11DepthStencilView *dsv)
|
||||
{
|
||||
if(resource == NULL)
|
||||
if(dsv == NULL)
|
||||
return;
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
resource->GetResource(&res);
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC desc;
|
||||
dsv->GetDesc(&desc);
|
||||
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC d;
|
||||
resource->GetDesc(&d);
|
||||
|
||||
if(d.Flags == (D3D11_DSV_READ_ONLY_DEPTH | D3D11_DSV_READ_ONLY_STENCIL))
|
||||
if(desc.Flags == (D3D11_DSV_READ_ONLY_DEPTH | D3D11_DSV_READ_ONLY_STENCIL))
|
||||
{
|
||||
// don't need to.
|
||||
}
|
||||
else if(d.Flags == D3D11_DSV_READ_ONLY_DEPTH)
|
||||
else if(desc.Flags == D3D11_DSV_READ_ONLY_DEPTH)
|
||||
{
|
||||
UnbindIUnknownForRead((IUnknown *)res, true, false);
|
||||
UnbindIUnknownForRead(ResourceRange(dsv), true, false);
|
||||
}
|
||||
else if(d.Flags == D3D11_DSV_READ_ONLY_STENCIL)
|
||||
else if(desc.Flags == D3D11_DSV_READ_ONLY_STENCIL)
|
||||
{
|
||||
UnbindIUnknownForRead((IUnknown *)res, false, true);
|
||||
UnbindIUnknownForRead(ResourceRange(dsv), false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnbindIUnknownForRead((IUnknown *)res, false, false);
|
||||
UnbindIUnknownForRead(ResourceRange(dsv), false, false);
|
||||
}
|
||||
|
||||
SAFE_RELEASE(res);
|
||||
}
|
||||
|
||||
template <>
|
||||
void UnbindForRead(ID3D11UnorderedAccessView *resource)
|
||||
void UnbindForRead(ID3D11UnorderedAccessView *uav)
|
||||
{
|
||||
if(resource == NULL)
|
||||
if(uav == NULL)
|
||||
return;
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
resource->GetResource(&res);
|
||||
|
||||
UnbindIUnknownForRead((IUnknown *)res, false, false);
|
||||
|
||||
SAFE_RELEASE(res);
|
||||
UnbindIUnknownForRead(ResourceRange(uav), false, false);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -299,8 +299,11 @@ void WrappedIDXGISwapChain3::ReleaseBuffersForResize()
|
||||
WrappedID3D11Texture2D1 *wrapped = (WrappedID3D11Texture2D1 *)m_pBackBuffers[i];
|
||||
if(wrapped)
|
||||
{
|
||||
m_pDevice->GetImmediateContext()->GetCurrentPipelineState()->UnbindIUnknownForWrite(wrapped);
|
||||
m_pDevice->GetImmediateContext()->GetCurrentPipelineState()->UnbindForRead(wrapped);
|
||||
D3D11RenderState::ResourceRange range(wrapped);
|
||||
|
||||
m_pDevice->GetImmediateContext()->GetCurrentPipelineState()->UnbindIUnknownForWrite(range);
|
||||
m_pDevice->GetImmediateContext()->GetCurrentPipelineState()->UnbindIUnknownForRead(
|
||||
range, false, false);
|
||||
|
||||
wrapped->ViewRelease();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user