1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-20 19:54:19 +01:00

[d3d9] Keep subresource views in subresources, defer creation until needed

Avoid creating a bunch of views that we probably don't need whenever a texture is created
This commit is contained in:
Joshua Ashton 2020-01-16 02:42:02 +00:00
parent 18450f4643
commit 7c53a997ef
5 changed files with 79 additions and 95 deletions

View File

@ -38,7 +38,7 @@ namespace dxvk {
throw e;
}
CreateInitialViews();
CreateSampleView(0);
if (!IsManaged()) {
m_size = m_image->memSize();
@ -292,18 +292,6 @@ namespace dxvk {
}
void D3D9CommonTexture::RecreateSampledView(UINT Lod) {
// This will be a no-op for SYSTEMMEM types given we
// don't expose the cap to allow texturing with them.
if (unlikely(m_mapMode == D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM))
return;
const D3D9_VK_FORMAT_MAPPING formatInfo = m_device->LookupFormat(m_desc.Format);
m_views.Sample = CreateColorViewPair(formatInfo, AllLayers, VK_IMAGE_USAGE_SAMPLED_BIT, Lod);
}
BOOL D3D9CommonTexture::DetermineShadowState() const {
static std::array<D3D9Format, 3> blacklist = {
D3D9Format::INTZ, D3D9Format::DF16, D3D9Format::DF24
@ -427,15 +415,14 @@ namespace dxvk {
Rc<DxvkImageView> D3D9CommonTexture::CreateView(
D3D9_VK_FORMAT_MAPPING FormatInfo,
UINT Layer,
VkImageUsageFlags UsageFlags,
UINT Lod,
BOOL Srgb) {
VkImageUsageFlags UsageFlags,
bool Srgb) {
DxvkImageViewCreateInfo viewInfo;
viewInfo.format = PickSRGB(FormatInfo.FormatColor, FormatInfo.FormatSrgb, Srgb);
viewInfo.format = PickSRGB(m_mapping.FormatColor, m_mapping.FormatSrgb, Srgb);
viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask;
viewInfo.swizzle = FormatInfo.Swizzle;
viewInfo.swizzle = m_mapping.Swizzle;
viewInfo.usage = UsageFlags;
viewInfo.type = GetImageViewTypeFromResourceType(m_type, Layer);
viewInfo.minLevel = Lod;
@ -462,46 +449,14 @@ namespace dxvk {
}
D3D9ColorView D3D9CommonTexture::CreateColorViewPair(
D3D9_VK_FORMAT_MAPPING FormatInfo,
UINT Layer,
VkImageUsageFlags UsageFlags,
UINT Lod) {
D3D9ColorView pair;
pair.Color = CreateView(FormatInfo, Layer, UsageFlags, Lod, FALSE);
void D3D9CommonTexture::CreateSampleView(UINT Lod) {
// This will be a no-op for SYSTEMMEM types given we
// don't expose the cap to allow texturing with them.
if (unlikely(m_mapMode == D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM))
return;
if (FormatInfo.FormatSrgb != VK_FORMAT_UNDEFINED)
pair.Srgb = CreateView(FormatInfo, Layer, UsageFlags, Lod, TRUE);
else
pair.Srgb = pair.Color;
return pair;
}
void D3D9CommonTexture::CreateInitialViews() {
const D3D9_VK_FORMAT_MAPPING formatInfo = m_device->LookupFormat(m_desc.Format);
m_views.Sample = CreateColorViewPair(formatInfo, AllLayers, VK_IMAGE_USAGE_SAMPLED_BIT, 0);
for (uint32_t i = 0; i < m_desc.ArraySize; i++) {
for (uint32_t j = 0; j < m_desc.MipLevels; j++)
m_views.SubresourceSample[i][j] = CreateColorViewPair(formatInfo, i, VK_IMAGE_USAGE_SAMPLED_BIT, j);
}
if (m_desc.Usage & D3DUSAGE_RENDERTARGET) {
for (uint32_t i = 0; i < m_desc.ArraySize; i++) {
for (uint32_t j = 0; j < m_desc.MipLevels; j++)
m_views.SubresourceRenderTarget[i][j] = CreateColorViewPair(formatInfo, i, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, j);
}
}
if (m_desc.Usage & D3DUSAGE_DEPTHSTENCIL) {
for (uint32_t i = 0; i < m_desc.ArraySize; i++) {
for (uint32_t j = 0; j < m_desc.MipLevels; j++)
m_views.SubresourceDepth[i][j] = CreateView(formatInfo, i, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, j, FALSE);
}
}
m_sampleView.Color = CreateView(AllLayers, Lod, VK_IMAGE_USAGE_SAMPLED_BIT, false);
m_sampleView.Srgb = CreateView(AllLayers, Lod, VK_IMAGE_USAGE_SAMPLED_BIT, true);
}

View File

@ -43,7 +43,11 @@ namespace dxvk {
};
struct D3D9ColorView {
inline Rc<DxvkImageView> Pick(bool Srgb) const {
inline Rc<DxvkImageView>& Pick(bool Srgb) {
return Srgb ? this->Srgb : this->Color;
}
inline const Rc<DxvkImageView>& Pick(bool Srgb) const {
return Srgb ? this->Srgb : this->Color;
}
@ -290,20 +294,12 @@ namespace dxvk {
return m_desc.Usage & D3DUSAGE_AUTOGENMIPMAP;
}
/**
* \brief Autogen Mipmap
* \returns Whether the texture is to have automatic mip generation
*/
const D3D9ViewSet& GetViews() const {
return m_views;
}
/**
* \brief Recreate main image view
* Recreates the main view of the sampler w/ a specific LOD.
* SetLOD only works on MANAGED textures so this is A-okay.
*/
void RecreateSampledView(UINT Lod);
void CreateSampleView(UINT Lod);
/**
* \brief Extent
@ -323,7 +319,7 @@ namespace dxvk {
}
bool MarkHazardous() {
return std::exchange(m_views.Hazardous, true);
return std::exchange(m_hazardous, true);
}
D3DRESOURCETYPE GetType() {
@ -337,6 +333,32 @@ namespace dxvk {
bool SetDirty(UINT Subresource, bool value) { return std::exchange(m_dirty[Subresource], value); }
void MarkAllDirty() { for (uint32_t i = 0; i < m_dirty.size(); i++) m_dirty[i] = true; }
const D3D9ColorView& GetSampleView() const {
return m_sampleView;
}
VkImageLayout DetermineRenderTargetLayout() const {
return m_image != nullptr &&
m_image->info().tiling == VK_IMAGE_TILING_OPTIMAL &&
!m_hazardous
? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
: VK_IMAGE_LAYOUT_GENERAL;
}
VkImageLayout DetermineDepthStencilLayout() const {
return m_image != nullptr &&
m_image->info().tiling == VK_IMAGE_TILING_OPTIMAL &&
!m_hazardous
? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
: VK_IMAGE_LAYOUT_GENERAL;
}
Rc<DxvkImageView> CreateView(
UINT Layer,
UINT Lod,
VkImageUsageFlags UsageFlags,
bool Srgb);
private:
D3D9DeviceEx* m_device;
@ -352,8 +374,6 @@ namespace dxvk {
DxvkBufferSliceHandle> m_mappedSlices;
D3D9SubresourceArray<DWORD> m_lockFlags;
D3D9ViewSet m_views;
D3D9_VK_FORMAT_MAPPING m_mapping;
VkExtent3D m_adjustedExtent;
@ -364,6 +384,10 @@ namespace dxvk {
bool m_systemmemModified = false;
bool m_hazardous = false;
D3D9ColorView m_sampleView;
D3D9SubresourceArray<
bool> m_locked = { };
@ -412,20 +436,6 @@ namespace dxvk {
static constexpr UINT AllLayers = UINT32_MAX;
Rc<DxvkImageView> CreateView(
D3D9_VK_FORMAT_MAPPING FormatInfo,
UINT Layer,
VkImageUsageFlags UsageFlags,
UINT Lod,
BOOL Srgb);
D3D9ColorView CreateColorViewPair(
D3D9_VK_FORMAT_MAPPING FormatInfo,
UINT Layer,
VkImageUsageFlags UsageFlags,
UINT Lod);
void CreateInitialViews();
};
}

View File

@ -4068,7 +4068,7 @@ namespace dxvk {
void D3D9DeviceEx::GenerateMips(
D3D9CommonTexture* pResource) {
EmitCs([
cImageView = pResource->GetViews().Sample.Color
cImageView = pResource->GetSampleView().Color
] (DxvkContext* ctx) {
ctx->generateMipmaps(cImageView);
});
@ -4844,7 +4844,7 @@ namespace dxvk {
if (likely(sampleCount == VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM || sampleCount == dsImageInfo.sampleCount)) {
attachments.depth = {
m_state.depthStencil->GetDepthStencilView(),
m_state.depthStencil->GetDepthLayout() };
m_state.depthStencil->GetDepthStencilLayout() };
}
}
@ -5292,7 +5292,7 @@ namespace dxvk {
cColorSlot = colorSlot,
cDepthSlot = depthSlot,
cDepth = commonTex->IsShadow(),
cImageView = commonTex->GetViews().Sample.Pick(srgb)
cImageView = commonTex->GetSampleView().Pick(srgb)
](DxvkContext* ctx) {
ctx->bindResourceView(cColorSlot, !cDepth ? cImageView : nullptr, nullptr);
ctx->bindResourceView(cDepthSlot, cDepth ? cImageView : nullptr, nullptr);

View File

@ -66,23 +66,38 @@ namespace dxvk {
}
Rc<DxvkImageView> GetImageView(bool Srgb) {
return m_texture->GetViews().SubresourceSample[m_face][m_mipLevel].Pick(Srgb);
Rc<DxvkImageView>& view = m_sampleView.Pick(Srgb);
if (unlikely(view == nullptr))
view = m_texture->CreateView(m_face, m_mipLevel, VK_IMAGE_USAGE_SAMPLED_BIT, Srgb);
return view;
}
Rc<DxvkImageView> GetRenderTargetView(bool Srgb) {
return m_texture->GetViews().SubresourceRenderTarget[m_face][m_mipLevel].Pick(Srgb);
Rc<DxvkImageView>& view = m_renderTargetView.Pick(Srgb);
if (unlikely(view == nullptr))
view = m_texture->CreateView(m_face, m_mipLevel, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, Srgb);
return view;
}
VkImageLayout GetRenderTargetLayout() {
return m_texture->GetViews().GetRTLayout();
VkImageLayout GetRenderTargetLayout() const {
return m_texture->DetermineRenderTargetLayout();
}
Rc<DxvkImageView> GetDepthStencilView() {
return m_texture->GetViews().SubresourceDepth[m_face][m_mipLevel];
Rc<DxvkImageView>& view = m_depthStencilView;
if (unlikely(view == nullptr))
view = m_texture->CreateView(m_face, m_mipLevel, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, false);
return view;
}
VkImageLayout GetDepthLayout() {
return m_texture->GetViews().GetDepthLayout();
VkImageLayout GetDepthStencilLayout() const {
return m_texture->DetermineDepthStencilLayout();
}
bool IsNull() {
@ -101,6 +116,10 @@ namespace dxvk {
UINT m_face;
UINT m_mipLevel;
D3D9ColorView m_sampleView;
D3D9ColorView m_renderTargetView;
Rc<DxvkImageView> m_depthStencilView;
};
}

View File

@ -59,7 +59,7 @@ namespace dxvk {
DWORD oldLod = m_lod;
m_lod = LODNew;
m_texture.RecreateSampledView(LODNew);
m_texture.CreateSampleView(LODNew);
if (this->GetPrivateRefCount() > 0)
this->m_parent->MarkSamplersDirty();