mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-14 22:29:15 +01:00
[d3d11] Refactor resource initialization
In addition to moving the code to a separate class, this also improves flushing behaviour by limiting the amount of memory being initialized rather than the number of commands executed.
This commit is contained in:
parent
1d3a121e89
commit
662b6429a8
@ -102,18 +102,16 @@ namespace dxvk {
|
|||||||
reinterpret_cast<void**>(&m_dxgiAdapter))))
|
reinterpret_cast<void**>(&m_dxgiAdapter))))
|
||||||
throw DxvkError("D3D11Device: Failed to query adapter");
|
throw DxvkError("D3D11Device: Failed to query adapter");
|
||||||
|
|
||||||
|
m_initializer = new D3D11Initializer(m_dxvkDevice);
|
||||||
m_context = new D3D11ImmediateContext(this, m_dxvkDevice);
|
m_context = new D3D11ImmediateContext(this, m_dxvkDevice);
|
||||||
|
|
||||||
m_resourceInitContext = m_dxvkDevice->createContext();
|
|
||||||
m_resourceInitContext->beginRecording(
|
|
||||||
m_dxvkDevice->createCommandList());
|
|
||||||
|
|
||||||
CreateCounterBuffer();
|
CreateCounterBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
D3D11Device::~D3D11Device() {
|
D3D11Device::~D3D11Device() {
|
||||||
delete m_context;
|
delete m_context;
|
||||||
|
delete m_initializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -145,7 +143,7 @@ namespace dxvk {
|
|||||||
const Com<D3D11Buffer> buffer
|
const Com<D3D11Buffer> buffer
|
||||||
= new D3D11Buffer(this, pDesc);
|
= new D3D11Buffer(this, pDesc);
|
||||||
|
|
||||||
this->InitBuffer(buffer.ptr(), pInitialData);
|
m_initializer->InitBuffer(buffer.ptr(), pInitialData);
|
||||||
*ppBuffer = buffer.ref();
|
*ppBuffer = buffer.ref();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
} catch (const DxvkError& e) {
|
} catch (const DxvkError& e) {
|
||||||
@ -182,7 +180,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const Com<D3D11Texture1D> texture = new D3D11Texture1D(this, &desc);
|
const Com<D3D11Texture1D> texture = new D3D11Texture1D(this, &desc);
|
||||||
this->InitTexture(texture->GetCommonTexture(), pInitialData);
|
m_initializer->InitTexture(texture->GetCommonTexture(), pInitialData);
|
||||||
*ppTexture1D = texture.ref();
|
*ppTexture1D = texture.ref();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
} catch (const DxvkError& e) {
|
} catch (const DxvkError& e) {
|
||||||
@ -219,7 +217,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const Com<D3D11Texture2D> texture = new D3D11Texture2D(this, &desc);
|
const Com<D3D11Texture2D> texture = new D3D11Texture2D(this, &desc);
|
||||||
this->InitTexture(texture->GetCommonTexture(), pInitialData);
|
m_initializer->InitTexture(texture->GetCommonTexture(), pInitialData);
|
||||||
*ppTexture2D = texture.ref();
|
*ppTexture2D = texture.ref();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
} catch (const DxvkError& e) {
|
} catch (const DxvkError& e) {
|
||||||
@ -256,7 +254,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const Com<D3D11Texture3D> texture = new D3D11Texture3D(this, &desc);
|
const Com<D3D11Texture3D> texture = new D3D11Texture3D(this, &desc);
|
||||||
this->InitTexture(texture->GetCommonTexture(), pInitialData);
|
m_initializer->InitTexture(texture->GetCommonTexture(), pInitialData);
|
||||||
*ppTexture3D = texture.ref();
|
*ppTexture3D = texture.ref();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
} catch (const DxvkError& e) {
|
} catch (const DxvkError& e) {
|
||||||
@ -1752,10 +1750,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void D3D11Device::FlushInitContext() {
|
void D3D11Device::FlushInitContext() {
|
||||||
LockResourceInitContext();
|
m_initializer->Flush();
|
||||||
if (m_resourceInitCommands != 0)
|
|
||||||
SubmitResourceInitCommands();
|
|
||||||
UnlockResourceInitContext(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1877,113 +1872,6 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D11Device::InitBuffer(
|
|
||||||
D3D11Buffer* pBuffer,
|
|
||||||
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
|
||||||
const DxvkBufferSlice bufferSlice = pBuffer->GetBufferSlice();
|
|
||||||
|
|
||||||
D3D11_BUFFER_DESC desc;
|
|
||||||
pBuffer->GetDesc(&desc);
|
|
||||||
|
|
||||||
if (pInitialData != nullptr && pInitialData->pSysMem != nullptr) {
|
|
||||||
LockResourceInitContext();
|
|
||||||
|
|
||||||
m_resourceInitContext->updateBuffer(
|
|
||||||
bufferSlice.buffer(),
|
|
||||||
bufferSlice.offset(),
|
|
||||||
bufferSlice.length(),
|
|
||||||
pInitialData->pSysMem);
|
|
||||||
|
|
||||||
UnlockResourceInitContext(1);
|
|
||||||
} else if (desc.Usage == D3D11_USAGE_DEFAULT) {
|
|
||||||
LockResourceInitContext();
|
|
||||||
|
|
||||||
m_resourceInitContext->clearBuffer(
|
|
||||||
bufferSlice.buffer(),
|
|
||||||
bufferSlice.offset(),
|
|
||||||
bufferSlice.length(),
|
|
||||||
0u);
|
|
||||||
|
|
||||||
UnlockResourceInitContext(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void D3D11Device::InitTexture(
|
|
||||||
D3D11CommonTexture* pTexture,
|
|
||||||
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
|
||||||
const Rc<DxvkImage> image = pTexture->GetImage();
|
|
||||||
const DxvkFormatInfo* formatInfo = imageFormatInfo(image->info().format);
|
|
||||||
|
|
||||||
if (pInitialData != nullptr && pInitialData->pSysMem != nullptr) {
|
|
||||||
LockResourceInitContext();
|
|
||||||
|
|
||||||
// pInitialData is an array that stores an entry for
|
|
||||||
// every single subresource. Since we will define all
|
|
||||||
// subresources, this counts as initialization.
|
|
||||||
VkImageSubresourceLayers subresourceLayers;
|
|
||||||
subresourceLayers.aspectMask = formatInfo->aspectMask;
|
|
||||||
subresourceLayers.mipLevel = 0;
|
|
||||||
subresourceLayers.baseArrayLayer = 0;
|
|
||||||
subresourceLayers.layerCount = 1;
|
|
||||||
|
|
||||||
for (uint32_t layer = 0; layer < image->info().numLayers; layer++) {
|
|
||||||
for (uint32_t level = 0; level < image->info().mipLevels; level++) {
|
|
||||||
subresourceLayers.baseArrayLayer = layer;
|
|
||||||
subresourceLayers.mipLevel = level;
|
|
||||||
|
|
||||||
const uint32_t id = D3D11CalcSubresource(
|
|
||||||
level, layer, image->info().mipLevels);
|
|
||||||
|
|
||||||
m_resourceInitContext->updateImage(
|
|
||||||
image, subresourceLayers,
|
|
||||||
VkOffset3D { 0, 0, 0 },
|
|
||||||
image->mipLevelExtent(level),
|
|
||||||
pInitialData[id].pSysMem,
|
|
||||||
pInitialData[id].SysMemPitch,
|
|
||||||
pInitialData[id].SysMemSlicePitch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint32_t subresourceCount =
|
|
||||||
image->info().numLayers * image->info().mipLevels;
|
|
||||||
UnlockResourceInitContext(subresourceCount);
|
|
||||||
} else {
|
|
||||||
LockResourceInitContext();
|
|
||||||
|
|
||||||
// While the Microsoft docs state that resource contents are
|
|
||||||
// undefined if no initial data is provided, some applications
|
|
||||||
// expect a resource to be pre-cleared. We can only do that
|
|
||||||
// for non-compressed images, but that should be fine.
|
|
||||||
VkImageSubresourceRange subresources;
|
|
||||||
subresources.aspectMask = formatInfo->aspectMask;
|
|
||||||
subresources.baseMipLevel = 0;
|
|
||||||
subresources.levelCount = image->info().mipLevels;
|
|
||||||
subresources.baseArrayLayer = 0;
|
|
||||||
subresources.layerCount = image->info().numLayers;
|
|
||||||
|
|
||||||
if (formatInfo->flags.test(DxvkFormatFlag::BlockCompressed)) {
|
|
||||||
m_resourceInitContext->initImage(
|
|
||||||
image, subresources);
|
|
||||||
} else {
|
|
||||||
if (subresources.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
|
|
||||||
m_resourceInitContext->clearColorImage(
|
|
||||||
image, VkClearColorValue(), subresources);
|
|
||||||
} else {
|
|
||||||
VkClearDepthStencilValue value;
|
|
||||||
value.depth = 1.0f;
|
|
||||||
value.stencil = 0;
|
|
||||||
|
|
||||||
m_resourceInitContext->clearDepthStencilImage(
|
|
||||||
image, value, subresources);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UnlockResourceInitContext(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT D3D11Device::GetFormatSupportFlags(DXGI_FORMAT Format, UINT* pFlags1, UINT* pFlags2) const {
|
HRESULT D3D11Device::GetFormatSupportFlags(DXGI_FORMAT Format, UINT* pFlags1, UINT* pFlags2) const {
|
||||||
// Query some general information from DXGI, DXVK and Vulkan about the format
|
// Query some general information from DXGI, DXVK and Vulkan about the format
|
||||||
const DXGI_VK_FORMAT_INFO fmtMapping = m_dxgiAdapter->LookupFormat(Format, DXGI_VK_FORMAT_MODE_ANY);
|
const DXGI_VK_FORMAT_INFO fmtMapping = m_dxgiAdapter->LookupFormat(Format, DXGI_VK_FORMAT_MODE_ANY);
|
||||||
@ -2158,33 +2046,6 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D11Device::LockResourceInitContext() {
|
|
||||||
m_resourceInitMutex.lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void D3D11Device::UnlockResourceInitContext(uint64_t CommandCount) {
|
|
||||||
m_resourceInitCommands += CommandCount;
|
|
||||||
|
|
||||||
if (m_resourceInitCommands >= InitCommandThreshold)
|
|
||||||
SubmitResourceInitCommands();
|
|
||||||
|
|
||||||
m_resourceInitMutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void D3D11Device::SubmitResourceInitCommands() {
|
|
||||||
m_dxvkDevice->submitCommandList(
|
|
||||||
m_resourceInitContext->endRecording(),
|
|
||||||
nullptr, nullptr);
|
|
||||||
|
|
||||||
m_resourceInitContext->beginRecording(
|
|
||||||
m_dxvkDevice->createCommandList());
|
|
||||||
|
|
||||||
m_resourceInitCommands = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
D3D_FEATURE_LEVEL D3D11Device::GetMaxFeatureLevel() {
|
D3D_FEATURE_LEVEL D3D11Device::GetMaxFeatureLevel() {
|
||||||
static const std::array<std::pair<std::string, D3D_FEATURE_LEVEL>, 7> s_featureLevels = {{
|
static const std::array<std::pair<std::string, D3D_FEATURE_LEVEL>, 7> s_featureLevels = {{
|
||||||
{ "11_1", D3D_FEATURE_LEVEL_11_1 },
|
{ "11_1", D3D_FEATURE_LEVEL_11_1 },
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "../util/com/com_private_data.h"
|
#include "../util/com/com_private_data.h"
|
||||||
|
|
||||||
|
#include "d3d11_initializer.h"
|
||||||
#include "d3d11_interfaces.h"
|
#include "d3d11_interfaces.h"
|
||||||
#include "d3d11_options.h"
|
#include "d3d11_options.h"
|
||||||
#include "d3d11_shader.h"
|
#include "d3d11_shader.h"
|
||||||
@ -357,16 +358,13 @@ namespace dxvk {
|
|||||||
const D3D11OptionSet m_d3d11Options;
|
const D3D11OptionSet m_d3d11Options;
|
||||||
const DxbcOptions m_dxbcOptions;
|
const DxbcOptions m_dxbcOptions;
|
||||||
|
|
||||||
D3D11ImmediateContext* m_context = nullptr;
|
D3D11Initializer* m_initializer = nullptr;
|
||||||
|
D3D11ImmediateContext* m_context = nullptr;
|
||||||
|
|
||||||
std::mutex m_counterMutex;
|
std::mutex m_counterMutex;
|
||||||
std::vector<uint32_t> m_counterSlices;
|
std::vector<uint32_t> m_counterSlices;
|
||||||
Rc<DxvkBuffer> m_counterBuffer;
|
Rc<DxvkBuffer> m_counterBuffer;
|
||||||
|
|
||||||
std::mutex m_resourceInitMutex;
|
|
||||||
Rc<DxvkContext> m_resourceInitContext;
|
|
||||||
uint64_t m_resourceInitCommands = 0;
|
|
||||||
|
|
||||||
D3D11StateObjectSet<D3D11BlendState> m_bsStateObjects;
|
D3D11StateObjectSet<D3D11BlendState> m_bsStateObjects;
|
||||||
D3D11StateObjectSet<D3D11DepthStencilState> m_dsStateObjects;
|
D3D11StateObjectSet<D3D11DepthStencilState> m_dsStateObjects;
|
||||||
D3D11StateObjectSet<D3D11RasterizerState> m_rsStateObjects;
|
D3D11StateObjectSet<D3D11RasterizerState> m_rsStateObjects;
|
||||||
@ -381,14 +379,6 @@ namespace dxvk {
|
|||||||
const DxbcModuleInfo* pModuleInfo,
|
const DxbcModuleInfo* pModuleInfo,
|
||||||
DxbcProgramType ProgramType);
|
DxbcProgramType ProgramType);
|
||||||
|
|
||||||
void InitBuffer(
|
|
||||||
D3D11Buffer* pBuffer,
|
|
||||||
const D3D11_SUBRESOURCE_DATA* pInitialData);
|
|
||||||
|
|
||||||
void InitTexture(
|
|
||||||
D3D11CommonTexture* pTexture,
|
|
||||||
const D3D11_SUBRESOURCE_DATA* pInitialData);
|
|
||||||
|
|
||||||
HRESULT GetFormatSupportFlags(
|
HRESULT GetFormatSupportFlags(
|
||||||
DXGI_FORMAT Format,
|
DXGI_FORMAT Format,
|
||||||
UINT* pFlags1,
|
UINT* pFlags1,
|
||||||
@ -400,10 +390,6 @@ namespace dxvk {
|
|||||||
|
|
||||||
void CreateCounterBuffer();
|
void CreateCounterBuffer();
|
||||||
|
|
||||||
void LockResourceInitContext();
|
|
||||||
void UnlockResourceInitContext(uint64_t CommandCount);
|
|
||||||
void SubmitResourceInitCommands();
|
|
||||||
|
|
||||||
static D3D_FEATURE_LEVEL GetMaxFeatureLevel();
|
static D3D_FEATURE_LEVEL GetMaxFeatureLevel();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
207
src/d3d11/d3d11_initializer.cpp
Normal file
207
src/d3d11/d3d11_initializer.cpp
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "d3d11_initializer.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
D3D11Initializer::D3D11Initializer(
|
||||||
|
const Rc<DxvkDevice>& Device)
|
||||||
|
: m_device(Device), m_context(m_device->createContext()) {
|
||||||
|
m_context->beginRecording(
|
||||||
|
m_device->createCommandList());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
D3D11Initializer::~D3D11Initializer() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11Initializer::Flush() {
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
|
if (m_transferCommands != 0)
|
||||||
|
FlushInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D11Initializer::InitBuffer(
|
||||||
|
D3D11Buffer* pBuffer,
|
||||||
|
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
||||||
|
VkMemoryPropertyFlags memFlags = pBuffer->GetBuffer()->memFlags();
|
||||||
|
|
||||||
|
(memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
|
||||||
|
? InitHostVisibleBuffer(pBuffer, pInitialData)
|
||||||
|
: InitDeviceLocalBuffer(pBuffer, pInitialData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11Initializer::InitTexture(
|
||||||
|
D3D11CommonTexture* pTexture,
|
||||||
|
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
||||||
|
VkMemoryPropertyFlags memFlags = pTexture->GetImage()->memFlags();
|
||||||
|
|
||||||
|
(memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
|
||||||
|
? InitHostVisibleTexture(pTexture, pInitialData)
|
||||||
|
: InitDeviceLocalTexture(pTexture, pInitialData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11Initializer::InitDeviceLocalBuffer(
|
||||||
|
D3D11Buffer* pBuffer,
|
||||||
|
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
|
DxvkBufferSlice bufferSlice = pBuffer->GetBufferSlice();
|
||||||
|
|
||||||
|
if (pInitialData != nullptr && pInitialData->pSysMem != nullptr) {
|
||||||
|
m_transferMemory += bufferSlice.length();
|
||||||
|
m_transferCommands += 1;
|
||||||
|
|
||||||
|
m_context->updateBuffer(
|
||||||
|
bufferSlice.buffer(),
|
||||||
|
bufferSlice.offset(),
|
||||||
|
bufferSlice.length(),
|
||||||
|
pInitialData->pSysMem);
|
||||||
|
} else {
|
||||||
|
m_transferCommands += 1;
|
||||||
|
|
||||||
|
m_context->clearBuffer(
|
||||||
|
bufferSlice.buffer(),
|
||||||
|
bufferSlice.offset(),
|
||||||
|
bufferSlice.length(),
|
||||||
|
0u);
|
||||||
|
}
|
||||||
|
|
||||||
|
FlushImplicit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11Initializer::InitHostVisibleBuffer(
|
||||||
|
D3D11Buffer* pBuffer,
|
||||||
|
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
||||||
|
// If the buffer is mapped, we can write data directly
|
||||||
|
// to the mapped memory region instead of doing it on
|
||||||
|
// the GPU. Same goes for zero-initialization.
|
||||||
|
DxvkBufferSlice bufferSlice = pBuffer->GetBufferSlice();
|
||||||
|
|
||||||
|
if (pInitialData != nullptr && pInitialData->pSysMem != nullptr) {
|
||||||
|
std::memcpy(
|
||||||
|
bufferSlice.mapPtr(0),
|
||||||
|
pInitialData->pSysMem,
|
||||||
|
bufferSlice.length());
|
||||||
|
} else {
|
||||||
|
std::memset(
|
||||||
|
bufferSlice.mapPtr(0), 0,
|
||||||
|
bufferSlice.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11Initializer::InitDeviceLocalTexture(
|
||||||
|
D3D11CommonTexture* pTexture,
|
||||||
|
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
|
Rc<DxvkImage> image = pTexture->GetImage();
|
||||||
|
|
||||||
|
auto formatInfo = imageFormatInfo(image->info().format);
|
||||||
|
|
||||||
|
if (pInitialData != nullptr && pInitialData->pSysMem != nullptr) {
|
||||||
|
// pInitialData is an array that stores an entry for
|
||||||
|
// every single subresource. Since we will define all
|
||||||
|
// subresources, this counts as initialization.
|
||||||
|
VkImageSubresourceLayers subresourceLayers;
|
||||||
|
subresourceLayers.aspectMask = formatInfo->aspectMask;
|
||||||
|
subresourceLayers.mipLevel = 0;
|
||||||
|
subresourceLayers.baseArrayLayer = 0;
|
||||||
|
subresourceLayers.layerCount = 1;
|
||||||
|
|
||||||
|
for (uint32_t layer = 0; layer < image->info().numLayers; layer++) {
|
||||||
|
for (uint32_t level = 0; level < image->info().mipLevels; level++) {
|
||||||
|
subresourceLayers.baseArrayLayer = layer;
|
||||||
|
subresourceLayers.mipLevel = level;
|
||||||
|
|
||||||
|
const uint32_t id = D3D11CalcSubresource(
|
||||||
|
level, layer, image->info().mipLevels);
|
||||||
|
|
||||||
|
VkOffset3D mipLevelOffset = { 0, 0, 0 };
|
||||||
|
VkExtent3D mipLevelExtent = image->mipLevelExtent(level);
|
||||||
|
|
||||||
|
m_transferCommands += 1;
|
||||||
|
m_transferMemory += util::computeImageDataSize(
|
||||||
|
image->info().format, mipLevelExtent);
|
||||||
|
|
||||||
|
m_context->updateImage(
|
||||||
|
image, subresourceLayers,
|
||||||
|
mipLevelOffset,
|
||||||
|
mipLevelExtent,
|
||||||
|
pInitialData[id].pSysMem,
|
||||||
|
pInitialData[id].SysMemPitch,
|
||||||
|
pInitialData[id].SysMemSlicePitch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_transferCommands += 1;
|
||||||
|
|
||||||
|
// While the Microsoft docs state that resource contents are
|
||||||
|
// undefined if no initial data is provided, some applications
|
||||||
|
// expect a resource to be pre-cleared. We can only do that
|
||||||
|
// for non-compressed images, but that should be fine.
|
||||||
|
VkImageSubresourceRange subresources;
|
||||||
|
subresources.aspectMask = formatInfo->aspectMask;
|
||||||
|
subresources.baseMipLevel = 0;
|
||||||
|
subresources.levelCount = image->info().mipLevels;
|
||||||
|
subresources.baseArrayLayer = 0;
|
||||||
|
subresources.layerCount = image->info().numLayers;
|
||||||
|
|
||||||
|
if (formatInfo->flags.test(DxvkFormatFlag::BlockCompressed)) {
|
||||||
|
m_context->initImage(image, subresources);
|
||||||
|
} else {
|
||||||
|
if (subresources.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
|
||||||
|
VkClearColorValue value = { };
|
||||||
|
|
||||||
|
m_context->clearColorImage(
|
||||||
|
image, value, subresources);
|
||||||
|
} else {
|
||||||
|
VkClearDepthStencilValue value;
|
||||||
|
value.depth = 1.0f;
|
||||||
|
value.stencil = 0;
|
||||||
|
|
||||||
|
m_context->clearDepthStencilImage(
|
||||||
|
image, value, subresources);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FlushImplicit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11Initializer::InitHostVisibleTexture(
|
||||||
|
D3D11CommonTexture* pTexture,
|
||||||
|
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
||||||
|
// TODO implement properly with memset/memcpy
|
||||||
|
InitDeviceLocalTexture(pTexture, pInitialData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11Initializer::FlushImplicit() {
|
||||||
|
if (m_transferCommands > MaxTransferCommands
|
||||||
|
|| m_transferMemory > MaxTransferMemory)
|
||||||
|
FlushInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11Initializer::FlushInternal() {
|
||||||
|
m_device->submitCommandList(
|
||||||
|
m_context->endRecording(),
|
||||||
|
nullptr, nullptr);
|
||||||
|
|
||||||
|
m_context->beginRecording(
|
||||||
|
m_device->createCommandList());
|
||||||
|
|
||||||
|
m_transferCommands = 0;
|
||||||
|
m_transferMemory = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
67
src/d3d11/d3d11_initializer.h
Normal file
67
src/d3d11/d3d11_initializer.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "d3d11_buffer.h"
|
||||||
|
#include "d3d11_texture.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Resource initialization context
|
||||||
|
*
|
||||||
|
* Manages a context which is used for resource
|
||||||
|
* initialization. This includes initialization
|
||||||
|
* with application-defined data, as well as
|
||||||
|
* zero-initialization for buffers and images.
|
||||||
|
*/
|
||||||
|
class D3D11Initializer {
|
||||||
|
constexpr static size_t MaxTransferMemory = 32 * 1024 * 1024;
|
||||||
|
constexpr static size_t MaxTransferCommands = 512;
|
||||||
|
public:
|
||||||
|
|
||||||
|
D3D11Initializer(
|
||||||
|
const Rc<DxvkDevice>& Device);
|
||||||
|
|
||||||
|
~D3D11Initializer();
|
||||||
|
|
||||||
|
void Flush();
|
||||||
|
|
||||||
|
void InitBuffer(
|
||||||
|
D3D11Buffer* pBuffer,
|
||||||
|
const D3D11_SUBRESOURCE_DATA* pInitialData);
|
||||||
|
|
||||||
|
void InitTexture(
|
||||||
|
D3D11CommonTexture* pTexture,
|
||||||
|
const D3D11_SUBRESOURCE_DATA* pInitialData);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::mutex m_mutex;
|
||||||
|
|
||||||
|
Rc<DxvkDevice> m_device;
|
||||||
|
Rc<DxvkContext> m_context;
|
||||||
|
|
||||||
|
size_t m_transferCommands = 0;
|
||||||
|
size_t m_transferMemory = 0;
|
||||||
|
|
||||||
|
void InitDeviceLocalBuffer(
|
||||||
|
D3D11Buffer* pBuffer,
|
||||||
|
const D3D11_SUBRESOURCE_DATA* pInitialData);
|
||||||
|
|
||||||
|
void InitHostVisibleBuffer(
|
||||||
|
D3D11Buffer* pBuffer,
|
||||||
|
const D3D11_SUBRESOURCE_DATA* pInitialData);
|
||||||
|
|
||||||
|
void InitDeviceLocalTexture(
|
||||||
|
D3D11CommonTexture* pTexture,
|
||||||
|
const D3D11_SUBRESOURCE_DATA* pInitialData);
|
||||||
|
|
||||||
|
void InitHostVisibleTexture(
|
||||||
|
D3D11CommonTexture* pTexture,
|
||||||
|
const D3D11_SUBRESOURCE_DATA* pInitialData);
|
||||||
|
|
||||||
|
void FlushImplicit();
|
||||||
|
void FlushInternal();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -10,6 +10,7 @@ d3d11_src = [
|
|||||||
'd3d11_depth_stencil.cpp',
|
'd3d11_depth_stencil.cpp',
|
||||||
'd3d11_device.cpp',
|
'd3d11_device.cpp',
|
||||||
'd3d11_enums.cpp',
|
'd3d11_enums.cpp',
|
||||||
|
'd3d11_initializer.cpp',
|
||||||
'd3d11_input_layout.cpp',
|
'd3d11_input_layout.cpp',
|
||||||
'd3d11_interop.cpp',
|
'd3d11_interop.cpp',
|
||||||
'd3d11_main.cpp',
|
'd3d11_main.cpp',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user