mirror of https://github.com/bkaradzic/bgfx
D3D11: Fixed compute image mip selection.
This commit is contained in:
parent
0670b98700
commit
63e10f3357
|
@ -131,7 +131,11 @@ bgfx::ShaderHandle loadShader(const char* _name)
|
|||
bgfx::ProgramHandle loadProgram(bx::FileReaderI* _reader, const char* _vsName, const char* _fsName)
|
||||
{
|
||||
bgfx::ShaderHandle vsh = loadShader(_reader, _vsName);
|
||||
bgfx::ShaderHandle fsh = loadShader(_reader, _fsName);
|
||||
bgfx::ShaderHandle fsh = BGFX_INVALID_HANDLE;
|
||||
if (NULL != _fsName)
|
||||
{
|
||||
fsh = loadShader(_reader, _fsName);
|
||||
}
|
||||
|
||||
return bgfx::createProgram(vsh, fsh, true /* destroy shaders when program is destroyed */);
|
||||
}
|
||||
|
|
18
src/bgfx.cpp
18
src/bgfx.cpp
|
@ -2507,28 +2507,18 @@ again:
|
|||
ProgramHandle createProgram(ShaderHandle _vsh, ShaderHandle _fsh, bool _destroyShaders)
|
||||
{
|
||||
BGFX_CHECK_MAIN_THREAD();
|
||||
ProgramHandle handle = s_ctx->createProgram(_vsh, _fsh);
|
||||
|
||||
if (_destroyShaders)
|
||||
if (!isValid(_fsh) )
|
||||
{
|
||||
destroyShader(_vsh);
|
||||
destroyShader(_fsh);
|
||||
return createProgram(_vsh, _destroyShaders);
|
||||
}
|
||||
|
||||
return handle;
|
||||
return s_ctx->createProgram(_vsh, _fsh, _destroyShaders);
|
||||
}
|
||||
|
||||
ProgramHandle createProgram(ShaderHandle _csh, bool _destroyShader)
|
||||
{
|
||||
BGFX_CHECK_MAIN_THREAD();
|
||||
ProgramHandle handle = s_ctx->createProgram(_csh);
|
||||
|
||||
if (_destroyShader)
|
||||
{
|
||||
destroyShader(_csh);
|
||||
}
|
||||
|
||||
return handle;
|
||||
return s_ctx->createProgram(_csh, _destroyShader);
|
||||
}
|
||||
|
||||
void destroyProgram(ProgramHandle _handle)
|
||||
|
|
27
src/bgfx_p.h
27
src/bgfx_p.h
|
@ -2603,6 +2603,7 @@ namespace bgfx
|
|||
sr.m_refCount = 1;
|
||||
sr.m_hash = iohash;
|
||||
sr.m_num = 0;
|
||||
sr.m_owned = false;
|
||||
sr.m_uniforms = NULL;
|
||||
|
||||
UniformHandle* uniforms = (UniformHandle*)alloca(count*sizeof(UniformHandle) );
|
||||
|
@ -2682,6 +2683,16 @@ namespace bgfx
|
|||
shaderDecRef(_handle);
|
||||
}
|
||||
|
||||
void shaderTakeOwnership(ShaderHandle _handle)
|
||||
{
|
||||
ShaderRef& sr = m_shaderRef[_handle.idx];
|
||||
if (!sr.m_owned)
|
||||
{
|
||||
sr.m_owned = true;
|
||||
shaderDecRef(_handle);
|
||||
}
|
||||
}
|
||||
|
||||
void shaderIncRef(ShaderHandle _handle)
|
||||
{
|
||||
ShaderRef& sr = m_shaderRef[_handle.idx];
|
||||
|
@ -2712,7 +2723,7 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
|
||||
BGFX_API_FUNC(ProgramHandle createProgram(ShaderHandle _vsh, ShaderHandle _fsh) )
|
||||
BGFX_API_FUNC(ProgramHandle createProgram(ShaderHandle _vsh, ShaderHandle _fsh, bool _destroyShaders) )
|
||||
{
|
||||
if (!isValid(_vsh)
|
||||
|| !isValid(_fsh) )
|
||||
|
@ -2749,10 +2760,16 @@ namespace bgfx
|
|||
cmdbuf.write(_fsh);
|
||||
}
|
||||
|
||||
if (_destroyShaders)
|
||||
{
|
||||
shaderTakeOwnership(_vsh);
|
||||
shaderTakeOwnership(_fsh);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
BGFX_API_FUNC(ProgramHandle createProgram(ShaderHandle _vsh) )
|
||||
BGFX_API_FUNC(ProgramHandle createProgram(ShaderHandle _vsh, bool _destroyShader) )
|
||||
{
|
||||
if (!isValid(_vsh) )
|
||||
{
|
||||
|
@ -2779,6 +2796,11 @@ namespace bgfx
|
|||
cmdbuf.write(fsh);
|
||||
}
|
||||
|
||||
if (_destroyShader)
|
||||
{
|
||||
shaderTakeOwnership(_vsh);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -3564,6 +3586,7 @@ namespace bgfx
|
|||
uint32_t m_hash;
|
||||
int16_t m_refCount;
|
||||
uint16_t m_num;
|
||||
bool m_owned;
|
||||
};
|
||||
|
||||
struct ProgramRef
|
||||
|
|
|
@ -100,15 +100,15 @@ namespace bgfx
|
|||
class StateCacheT
|
||||
{
|
||||
public:
|
||||
void add(uint64_t _id, Ty* _item)
|
||||
void add(uint64_t _key, Ty* _value)
|
||||
{
|
||||
invalidate(_id);
|
||||
m_hashMap.insert(stl::make_pair(_id, _item) );
|
||||
invalidate(_key);
|
||||
m_hashMap.insert(stl::make_pair(_key, _value) );
|
||||
}
|
||||
|
||||
Ty* find(uint64_t _id)
|
||||
Ty* find(uint64_t _key)
|
||||
{
|
||||
typename HashMap::iterator it = m_hashMap.find(_id);
|
||||
typename HashMap::iterator it = m_hashMap.find(_key);
|
||||
if (it != m_hashMap.end() )
|
||||
{
|
||||
return it->second;
|
||||
|
@ -117,9 +117,9 @@ namespace bgfx
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void invalidate(uint64_t _id)
|
||||
void invalidate(uint64_t _key)
|
||||
{
|
||||
typename HashMap::iterator it = m_hashMap.find(_id);
|
||||
typename HashMap::iterator it = m_hashMap.find(_key);
|
||||
if (it != m_hashMap.end() )
|
||||
{
|
||||
DX_RELEASE_WARNONLY(it->second, 0);
|
||||
|
@ -151,15 +151,15 @@ namespace bgfx
|
|||
class StateCache
|
||||
{
|
||||
public:
|
||||
void add(uint64_t _id, uint16_t _item)
|
||||
void add(uint64_t _key, uint16_t _value)
|
||||
{
|
||||
invalidate(_id);
|
||||
m_hashMap.insert(stl::make_pair(_id, _item) );
|
||||
invalidate(_key);
|
||||
m_hashMap.insert(stl::make_pair(_key, _value) );
|
||||
}
|
||||
|
||||
uint16_t find(uint64_t _id)
|
||||
uint16_t find(uint64_t _key)
|
||||
{
|
||||
HashMap::iterator it = m_hashMap.find(_id);
|
||||
HashMap::iterator it = m_hashMap.find(_key);
|
||||
if (it != m_hashMap.end() )
|
||||
{
|
||||
return it->second;
|
||||
|
@ -168,9 +168,9 @@ namespace bgfx
|
|||
return UINT16_MAX;
|
||||
}
|
||||
|
||||
void invalidate(uint64_t _id)
|
||||
void invalidate(uint64_t _key)
|
||||
{
|
||||
HashMap::iterator it = m_hashMap.find(_id);
|
||||
HashMap::iterator it = m_hashMap.find(_key);
|
||||
if (it != m_hashMap.end() )
|
||||
{
|
||||
m_hashMap.erase(it);
|
||||
|
@ -196,33 +196,28 @@ namespace bgfx
|
|||
class StateCacheLru
|
||||
{
|
||||
public:
|
||||
void add(uint64_t _hash, Ty _value)
|
||||
void add(uint64_t _key, Ty _value, uint16_t _parent)
|
||||
{
|
||||
uint16_t handle = m_alloc.alloc();
|
||||
if (UINT16_MAX == handle)
|
||||
{
|
||||
uint16_t back = m_alloc.getBack();
|
||||
m_alloc.free(back);
|
||||
HashMap::iterator it = m_hashMap.find(m_data[back].m_hash);
|
||||
if (it != m_hashMap.end() )
|
||||
{
|
||||
m_hashMap.erase(it);
|
||||
}
|
||||
|
||||
invalidate(back);
|
||||
handle = m_alloc.alloc();
|
||||
}
|
||||
|
||||
BX_CHECK(UINT16_MAX != handle, "Failed to find handle.");
|
||||
|
||||
Data& data = m_data[handle];
|
||||
data.m_hash = _hash;
|
||||
data.m_value = _value;
|
||||
m_hashMap.insert(stl::make_pair(_hash, handle) );
|
||||
data.m_hash = _key;
|
||||
data.m_value = _value;
|
||||
data.m_parent = _parent;
|
||||
m_hashMap.insert(stl::make_pair(_key, handle) );
|
||||
}
|
||||
|
||||
Ty* find(uint64_t _hash)
|
||||
Ty* find(uint64_t _key)
|
||||
{
|
||||
HashMap::iterator it = m_hashMap.find(_hash);
|
||||
HashMap::iterator it = m_hashMap.find(_key);
|
||||
if (it != m_hashMap.end() )
|
||||
{
|
||||
uint16_t handle = it->second;
|
||||
|
@ -233,8 +228,59 @@ namespace bgfx
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void invalidate(uint64_t _key)
|
||||
{
|
||||
HashMap::iterator it = m_hashMap.find(_key);
|
||||
if (it != m_hashMap.end() )
|
||||
{
|
||||
uint16_t handle = it->second;
|
||||
m_alloc.free(_handle);
|
||||
m_hashMap.erase(it);
|
||||
release(m_data[handle].m_value);
|
||||
}
|
||||
}
|
||||
|
||||
void invalidate(uint16_t _handle)
|
||||
{
|
||||
if (m_alloc.isValid(_handle) )
|
||||
{
|
||||
m_alloc.free(_handle);
|
||||
Data& data = m_data[_handle];
|
||||
m_hashMap.erase(m_hashMap.find(data.m_hash) );
|
||||
release(data.m_value);
|
||||
}
|
||||
}
|
||||
|
||||
void invalidateWithParent(uint16_t _parent)
|
||||
{
|
||||
for (uint32_t ii = 0; ii < m_alloc.getNumHandles();)
|
||||
{
|
||||
uint16_t handle = m_alloc.getHandleAt(ii);
|
||||
Data& data = m_data[handle];
|
||||
|
||||
if (data.m_parent == _parent)
|
||||
{
|
||||
m_alloc.free(handle);
|
||||
Data& data = m_data[handle];
|
||||
m_hashMap.erase(m_hashMap.find(data.m_hash) );
|
||||
release(data.m_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
++ii;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
for (uint32_t ii = 0, num = m_alloc.getNumHandles(); ii < num; ++ii)
|
||||
{
|
||||
uint16_t handle = m_alloc.getHandleAt(ii);
|
||||
Data& data = m_data[handle];
|
||||
release(data.m_value);
|
||||
}
|
||||
|
||||
m_hashMap.clear();
|
||||
m_alloc.reset();
|
||||
}
|
||||
|
@ -244,6 +290,17 @@ namespace bgfx
|
|||
return uint32_t(m_hashMap.size() );
|
||||
}
|
||||
|
||||
template<typename Ty>
|
||||
void release(Ty)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
void release<IUnknown*>(IUnknown* _ptr)
|
||||
{
|
||||
DX_RELEASE(_ptr, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef stl::unordered_map<uint64_t, uint16_t> HashMap;
|
||||
HashMap m_hashMap;
|
||||
|
@ -252,6 +309,7 @@ namespace bgfx
|
|||
{
|
||||
uint64_t m_hash;
|
||||
Ty m_value;
|
||||
uint16_t m_parent;
|
||||
};
|
||||
|
||||
Data m_data[MaxHandleT];
|
||||
|
|
|
@ -680,7 +680,7 @@ namespace bgfx { namespace d3d11
|
|||
uint32_t flags = 0
|
||||
| D3D11_CREATE_DEVICE_SINGLETHREADED
|
||||
| D3D11_CREATE_DEVICE_BGRA_SUPPORT
|
||||
// | D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
|
||||
| D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
|
||||
| (BX_ENABLED(BGFX_CONFIG_DEBUG) ? D3D11_CREATE_DEVICE_DEBUG : 0)
|
||||
;
|
||||
|
||||
|
@ -1777,6 +1777,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
m_depthStencilStateCache.invalidate();
|
||||
m_rasterizerStateCache.invalidate();
|
||||
m_samplerStateCache.invalidate();
|
||||
m_srvUavLru.invalidate();
|
||||
}
|
||||
|
||||
void invalidateCompute()
|
||||
|
@ -2394,6 +2395,101 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
commitTextureStage();
|
||||
}
|
||||
|
||||
ID3D11UnorderedAccessView* getCachedUav(TextureHandle _handle, uint8_t _mip)
|
||||
{
|
||||
bx::HashMurmur2A murmur;
|
||||
murmur.begin();
|
||||
murmur.add(_handle);
|
||||
murmur.add(_mip);
|
||||
murmur.add(0);
|
||||
uint32_t hash = murmur.end();
|
||||
|
||||
IUnknown** ptr = m_srvUavLru.find(hash);
|
||||
ID3D11UnorderedAccessView* uav;
|
||||
if (NULL == ptr)
|
||||
{
|
||||
TextureD3D11& texture = m_textures[_handle.idx];
|
||||
|
||||
D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
|
||||
desc.Format = s_textureFormat[texture.m_textureFormat].m_fmtSrv;
|
||||
switch (texture.m_type)
|
||||
{
|
||||
case TextureD3D11::Texture2D:
|
||||
case TextureD3D11::TextureCube:
|
||||
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
|
||||
desc.Texture2D.MipSlice = _mip;
|
||||
break;
|
||||
|
||||
case TextureD3D11::Texture3D:
|
||||
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
|
||||
desc.Texture3D.MipSlice = _mip;
|
||||
desc.Texture3D.FirstWSlice = 0;
|
||||
desc.Texture3D.WSize = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
DX_CHECK(m_device->CreateUnorderedAccessView(texture.m_ptr, &desc, &uav) );
|
||||
|
||||
m_srvUavLru.add(hash, uav, _handle.idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
uav = static_cast<ID3D11UnorderedAccessView*>(*ptr);
|
||||
}
|
||||
|
||||
return uav;
|
||||
}
|
||||
|
||||
ID3D11ShaderResourceView* getCachedSrv(TextureHandle _handle, uint8_t _mip)
|
||||
{
|
||||
bx::HashMurmur2A murmur;
|
||||
murmur.begin();
|
||||
murmur.add(_handle);
|
||||
murmur.add(_mip);
|
||||
murmur.add(0);
|
||||
uint32_t hash = murmur.end();
|
||||
|
||||
IUnknown** ptr = m_srvUavLru.find(hash);
|
||||
ID3D11ShaderResourceView* srv;
|
||||
if (NULL == ptr)
|
||||
{
|
||||
TextureD3D11& texture = m_textures[_handle.idx];
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
|
||||
desc.Format = s_textureFormat[texture.m_textureFormat].m_fmtSrv;
|
||||
switch (texture.m_type)
|
||||
{
|
||||
case TextureD3D11::Texture2D:
|
||||
desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
desc.Texture2D.MostDetailedMip = _mip;
|
||||
desc.Texture2D.MipLevels = 1;
|
||||
break;
|
||||
|
||||
case TextureD3D11::TextureCube:
|
||||
desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
|
||||
desc.TextureCube.MostDetailedMip = _mip;
|
||||
desc.TextureCube.MipLevels = 1;
|
||||
break;
|
||||
|
||||
case TextureD3D11::Texture3D:
|
||||
desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
|
||||
desc.Texture3D.MostDetailedMip = _mip;
|
||||
desc.Texture3D.MipLevels = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
DX_CHECK(m_device->CreateShaderResourceView(texture.m_ptr, &desc, &srv) );
|
||||
|
||||
m_srvUavLru.add(hash, srv, _handle.idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
srv = static_cast<ID3D11ShaderResourceView*>(*ptr);
|
||||
}
|
||||
|
||||
return srv;
|
||||
}
|
||||
|
||||
void ovrPostReset()
|
||||
{
|
||||
#if BGFX_CONFIG_USE_OVR
|
||||
|
@ -2838,6 +2934,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
StateCacheT<ID3D11InputLayout> m_inputLayoutCache;
|
||||
StateCacheT<ID3D11RasterizerState> m_rasterizerStateCache;
|
||||
StateCacheT<ID3D11SamplerState> m_samplerStateCache;
|
||||
StateCacheLru<IUnknown*, 1024> m_srvUavLru;
|
||||
|
||||
TextVideoMem m_textVideoMem;
|
||||
|
||||
|
@ -3307,7 +3404,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
const bool swizzle = TextureFormat::BGRA8 == m_textureFormat && 0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE);
|
||||
|
||||
BX_TRACE("Texture %3d: %s (requested: %s), %dx%d%s%s%s."
|
||||
, this - s_renderD3D11->m_textures
|
||||
, getHandle()
|
||||
, getName( (TextureFormat::Enum)m_textureFormat)
|
||||
, getName( (TextureFormat::Enum)m_requestedFormat)
|
||||
, textureWidth
|
||||
|
@ -3504,6 +3601,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
|
||||
void TextureD3D11::destroy()
|
||||
{
|
||||
s_renderD3D11->m_srvUavLru.invalidateWithParent(getHandle().idx);
|
||||
DX_RELEASE(m_srv, 0);
|
||||
DX_RELEASE(m_uav, 0);
|
||||
DX_RELEASE(m_ptr, 0);
|
||||
|
@ -3560,6 +3658,12 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
{
|
||||
}
|
||||
|
||||
TextureHandle TextureD3D11::getHandle() const
|
||||
{
|
||||
TextureHandle handle = { (uint16_t)(this - s_renderD3D11->m_textures) };
|
||||
return handle;
|
||||
}
|
||||
|
||||
void FrameBufferD3D11::create(uint8_t _num, const TextureHandle* _handles)
|
||||
{
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_rtv); ++ii)
|
||||
|
@ -4074,14 +4178,20 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
{
|
||||
case Binding::Image:
|
||||
{
|
||||
const TextureD3D11& texture = m_textures[bind.m_idx];
|
||||
TextureD3D11& texture = m_textures[bind.m_idx];
|
||||
if (Access::Read != bind.m_un.m_compute.m_access)
|
||||
{
|
||||
uav[ii] = texture.m_uav;
|
||||
uav[ii] = 0 == bind.m_un.m_compute.m_mip
|
||||
? texture.m_uav
|
||||
: s_renderD3D11->getCachedUav(texture.getHandle(), bind.m_un.m_compute.m_mip)
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
srv[ii] = texture.m_srv;
|
||||
srv[ii] = 0 == bind.m_un.m_compute.m_mip
|
||||
? texture.m_srv
|
||||
: s_renderD3D11->getCachedSrv(texture.getHandle(), bind.m_un.m_compute.m_mip)
|
||||
;
|
||||
sampler[ii] = texture.m_sampler;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -284,6 +284,7 @@ namespace bgfx { namespace d3d11
|
|||
void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
|
||||
void commit(uint8_t _stage, uint32_t _flags = BGFX_SAMPLER_DEFAULT_FLAGS);
|
||||
void resolve();
|
||||
TextureHandle getHandle() const;
|
||||
|
||||
union
|
||||
{
|
||||
|
|
|
@ -2589,7 +2589,8 @@ data.NumQualityLevels = 0;
|
|||
{
|
||||
default:
|
||||
case D3D12_UAV_DIMENSION_TEXTURE2D:
|
||||
uavd->Texture2D.MipSlice = _mip;
|
||||
uavd->Texture2D.MipSlice = _mip;
|
||||
uavd->Texture2D.PlaneSlice = 0;
|
||||
break;
|
||||
|
||||
case D3D12_UAV_DIMENSION_TEXTURE3D:
|
||||
|
@ -4111,7 +4112,7 @@ data.NumQualityLevels = 0;
|
|||
|
||||
m_commandList->SetGraphicsRootDescriptorTable(Rdt::SRV, srvHandle[0]);
|
||||
|
||||
bindLru.add(bindHash, srvHandle[0]);
|
||||
bindLru.add(bindHash, srvHandle[0], 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue