Check for D3D11 R/W bind conflicts at subresource granularity. Refs #244

This commit is contained in:
baldurk
2016-06-23 19:45:15 +02:00
parent a8457b56f6
commit b59199aa91
3 changed files with 433 additions and 213 deletions
+263 -118
View File
@@ -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);
}
+165 -93
View File
@@ -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);
}
/////////////////////////////////////////////////////////////////////////
+5 -2
View File
@@ -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();
}