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:
parent
a368d04fa0
commit
0d3a1b25a1
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -173,4 +173,9 @@ namespace dxvk {
|
||||
ID3D11Resource* pResource,
|
||||
D3D11TextureInfo* pTextureInfo);
|
||||
|
||||
VkImageSubresource GetSubresourceFromIndex(
|
||||
VkImageAspectFlags Aspect,
|
||||
UINT MipLevels,
|
||||
UINT Subresource);
|
||||
|
||||
}
|
||||
|
@ -48,8 +48,6 @@ namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief Physical buffer resource
|
||||
*
|
||||
*
|
||||
*/
|
||||
class DxvkBufferResource : public DxvkResource {
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user