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:
parent
18450f4643
commit
7c53a997ef
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -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();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user