1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-01 16:24:12 +01:00

[d3d11] Initial support for image updates + mapping

This commit is contained in:
Philip Rebohle 2017-12-25 20:40:48 +01:00
parent a368d04fa0
commit 0d3a1b25a1
5 changed files with 126 additions and 7 deletions

View File

@ -2,6 +2,7 @@
#include "d3d11_context.h"
#include "d3d11_device.h"
#include "d3d11_texture.h"
#include "../dxbc/dxbc_util.h"
@ -228,8 +229,44 @@ namespace dxvk {
pMappedResource->DepthPitch = buffer->info().size;
return S_OK;
} else {
Logger::err("D3D11: Mapping of image resources currently not supported");
return E_NOTIMPL;
D3D11TextureInfo textureInfo;
if (FAILED(GetCommonTextureInfo(pResource, &textureInfo))) {
Logger::err("D3D11DeviceContext: Cannot map a device-local image");
return E_FAIL;
}
if (textureInfo.image->mapPtr(0) == nullptr) {
Logger::err("D3D11DeviceContext: Cannot map a device-local image");
return E_FAIL;
}
if (pMappedResource == nullptr)
return S_OK;
if (textureInfo.image->isInUse()) {
// Don't wait if the application tells us not to
if (MapFlags & D3D11_MAP_FLAG_DO_NOT_WAIT)
return DXGI_ERROR_WAS_STILL_DRAWING;
this->Flush();
this->Synchronize();
}
const DxvkImageCreateInfo imageInfo = textureInfo.image->info();
const VkImageSubresource imageSubresource =
GetSubresourceFromIndex(VK_IMAGE_ASPECT_COLOR_BIT,
imageInfo.mipLevels, Subresource);
const VkSubresourceLayout layout =
textureInfo.image->querySubresourceLayout(imageSubresource);
// TODO handle undefined stuff
pMappedResource->pData = textureInfo.image->mapPtr(layout.offset);
pMappedResource->RowPitch = layout.rowPitch;
pMappedResource->DepthPitch = layout.depthPitch;
return S_OK;
}
}
@ -446,7 +483,7 @@ namespace dxvk {
}
if (offset + size > bufferSlice.length()) {
Logger::err("D3D11: UpdateSubresource: Buffer size out of bounds");
Logger::err("D3D11DeviceContext: Buffer update range out of bounds");
return;
}
@ -457,9 +494,46 @@ namespace dxvk {
size, pSrcData);
}
} else {
Logger::err("D3D11DeviceContext::UpdateSubresource: Images not yet supported");
D3D11TextureInfo textureInfo;
if (FAILED(GetCommonTextureInfo(pDstResource, &textureInfo))) {
Logger::err("D3D11DeviceContext: Failed to retrieve DXVK image");
return;
}
VkOffset3D offset = { 0, 0, 0 };
VkExtent3D extent = textureInfo.image->info().extent;
if (pDstBox != nullptr) {
if (pDstBox->left >= pDstBox->right
|| pDstBox->top >= pDstBox->bottom
|| pDstBox->front >= pDstBox->back)
return; // no-op, but legal
offset.x = pDstBox->left;
offset.y = pDstBox->top;
offset.z = pDstBox->front;
extent.width = pDstBox->right - pDstBox->left;
extent.height = pDstBox->bottom - pDstBox->top;
extent.depth = pDstBox->back - pDstBox->front;
}
const VkImageSubresource imageSubresource =
GetSubresourceFromIndex(VK_IMAGE_ASPECT_COLOR_BIT,
textureInfo.image->info().mipLevels, DstSubresource);
VkImageSubresourceLayers layers;
layers.aspectMask = imageSubresource.aspectMask;
layers.mipLevel = imageSubresource.mipLevel;
layers.baseArrayLayer = imageSubresource.arrayLayer;
layers.layerCount = 1;
m_context->updateImage(
textureInfo.image, layers,
offset, extent, pSrcData,
SrcRowPitch, SrcDepthPitch);
}
}

View File

@ -363,4 +363,16 @@ namespace dxvk {
}
}
VkImageSubresource GetSubresourceFromIndex(
VkImageAspectFlags Aspect,
UINT MipLevels,
UINT Subresource) {
VkImageSubresource result;
result.aspectMask = Aspect;
result.mipLevel = Subresource % MipLevels;
result.arrayLayer = Subresource / MipLevels;
return result;
}
}

View File

@ -173,4 +173,9 @@ namespace dxvk {
ID3D11Resource* pResource,
D3D11TextureInfo* pTextureInfo);
VkImageSubresource GetSubresourceFromIndex(
VkImageAspectFlags Aspect,
UINT MipLevels,
UINT Subresource);
}

View File

@ -48,8 +48,6 @@ namespace dxvk {
/**
* \brief Physical buffer resource
*
*
*/
class DxvkBufferResource : public DxvkResource {

View File

@ -155,6 +155,36 @@ namespace dxvk {
return size;
}
/**
* \brief Queries memory layout of a subresource
*
* Can be used to retrieve the exact pointer to a
* subresource of a mapped image with linear tiling.
* \param [in] subresource The image subresource
* \returns Memory layout of that subresource
*/
VkSubresourceLayout querySubresourceLayout(
const VkImageSubresource& subresource) const {
VkSubresourceLayout result;
m_vkd->vkGetImageSubresourceLayout(
m_vkd->device(), m_image,
&subresource, &result);
return result;
}
/**
* \brief Map pointer
*
* If the image has been created on a host-visible
* memory type, its memory is mapped and can be
* accessed by the host.
* \param [in] offset Byte offset into mapped region
* \returns Pointer to mapped memory region
*/
void* mapPtr(VkDeviceSize offset) const {
return m_memory.mapPtr(offset);
}
private:
Rc<vk::DeviceFn> m_vkd;