diff --git a/renderdoc/driver/d3d11/d3d11_renderstate.cpp b/renderdoc/driver/d3d11/d3d11_renderstate.cpp index 5fb431088..00c359d24 100644 --- a/renderdoc/driver/d3d11/d3d11_renderstate.cpp +++ b/renderdoc/driver/d3d11/d3d11_renderstate.cpp @@ -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); +} diff --git a/renderdoc/driver/d3d11/d3d11_renderstate.h b/renderdoc/driver/d3d11/d3d11_renderstate.h index 435148706..d6ae8377b 100644 --- a/renderdoc/driver/d3d11/d3d11_renderstate.h +++ b/renderdoc/driver/d3d11/d3d11_renderstate.h @@ -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 - 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 - 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); } ///////////////////////////////////////////////////////////////////////// diff --git a/renderdoc/driver/dxgi/dxgi_wrapped.cpp b/renderdoc/driver/dxgi/dxgi_wrapped.cpp index 7a5f0b266..d31089692 100644 --- a/renderdoc/driver/dxgi/dxgi_wrapped.cpp +++ b/renderdoc/driver/dxgi/dxgi_wrapped.cpp @@ -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(); }