mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 10:24:12 +01:00
[d3d11] Implemented depth-stencil binding and clear methods
This commit is contained in:
parent
a43bb134e0
commit
b3c391d071
@ -276,17 +276,15 @@ namespace dxvk {
|
||||
ID3D11RenderTargetView* pRenderTargetView,
|
||||
const FLOAT ColorRGBA[4]) {
|
||||
auto rtv = static_cast<D3D11RenderTargetView*>(pRenderTargetView);
|
||||
|
||||
const Rc<DxvkImageView> dxvkView = rtv->GetDXVKImageView();
|
||||
const Rc<DxvkImage> dxvkImage = dxvkView->image();
|
||||
const Rc<DxvkImageView> dxvkView = rtv->GetDXVKImageView();
|
||||
|
||||
// Find out whether the given attachment is currently bound
|
||||
// or not, and if it is, which attachment index it has.
|
||||
int32_t attachmentIndex = -1;
|
||||
|
||||
if (m_state.om.framebuffer != nullptr) {
|
||||
attachmentIndex = m_state.om.framebuffer
|
||||
->renderTargets().getAttachmentId(dxvkView);
|
||||
for (uint32_t i = 0; i < m_state.om.renderTargetViews.size(); i++) {
|
||||
if (m_state.om.renderTargetViews.at(i) == rtv)
|
||||
attachmentIndex = i;
|
||||
}
|
||||
|
||||
// Copy the clear color into a clear value structure.
|
||||
@ -309,10 +307,10 @@ namespace dxvk {
|
||||
VkClearRect clearRect;
|
||||
clearRect.rect.offset.x = 0;
|
||||
clearRect.rect.offset.y = 0;
|
||||
clearRect.rect.extent.width = dxvkImage->info().extent.width;
|
||||
clearRect.rect.extent.height = dxvkImage->info().extent.height;
|
||||
clearRect.rect.extent.width = dxvkView->imageInfo().extent.width;
|
||||
clearRect.rect.extent.height = dxvkView->imageInfo().extent.height;
|
||||
clearRect.baseArrayLayer = 0;
|
||||
clearRect.layerCount = dxvkImage->info().numLayers;
|
||||
clearRect.layerCount = dxvkView->imageInfo().numLayers;
|
||||
|
||||
if (m_parent->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0)
|
||||
clearRect.layerCount = 1;
|
||||
@ -321,7 +319,7 @@ namespace dxvk {
|
||||
} else {
|
||||
// Image is not bound to the pipeline. We can still clear
|
||||
// it, but we'll have to use a generic clear function.
|
||||
m_context->clearColorImage(dxvkImage,
|
||||
m_context->clearColorImage(dxvkView->image(),
|
||||
clearValue, dxvkView->subresources());
|
||||
}
|
||||
}
|
||||
@ -346,7 +344,45 @@ namespace dxvk {
|
||||
UINT ClearFlags,
|
||||
FLOAT Depth,
|
||||
UINT8 Stencil) {
|
||||
Logger::err("D3D11DeviceContext::ClearDepthStencilView: Not implemented");
|
||||
auto dsv = static_cast<D3D11DepthStencilView*>(pDepthStencilView);
|
||||
const Rc<DxvkImageView> dxvkView = dsv->GetDXVKImageView();
|
||||
|
||||
VkClearDepthStencilValue clearValue;
|
||||
clearValue.depth = Depth;
|
||||
clearValue.stencil = Stencil;
|
||||
|
||||
if (m_state.om.depthStencilView == dsv) {
|
||||
// Image is bound to the pipeline for rendering. We can
|
||||
// use the clear function that operates on attachments.
|
||||
VkClearAttachment clearInfo;
|
||||
clearInfo.aspectMask = 0;
|
||||
clearInfo.colorAttachment = 0;
|
||||
clearInfo.clearValue.depthStencil = clearValue;
|
||||
|
||||
if (ClearFlags & D3D11_CLEAR_DEPTH)
|
||||
clearInfo.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
|
||||
if (ClearFlags & D3D11_CLEAR_STENCIL)
|
||||
clearInfo.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
|
||||
// Clear the full area
|
||||
VkClearRect clearRect;
|
||||
clearRect.rect.offset.x = 0;
|
||||
clearRect.rect.offset.y = 0;
|
||||
clearRect.rect.extent.width = dxvkView->imageInfo().extent.width;
|
||||
clearRect.rect.extent.height = dxvkView->imageInfo().extent.height;
|
||||
clearRect.baseArrayLayer = 0;
|
||||
clearRect.layerCount = dxvkView->imageInfo().numLayers;
|
||||
|
||||
// FIXME Is this correct? Docs don't say anything
|
||||
if (m_parent->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0)
|
||||
clearRect.layerCount = 1;
|
||||
|
||||
m_context->clearRenderTarget(clearInfo, clearRect);
|
||||
} else {
|
||||
m_context->clearDepthStencilImage(dxvkView->image(),
|
||||
clearValue, dxvkView->subresources());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1109,7 +1145,6 @@ namespace dxvk {
|
||||
UINT NumViews,
|
||||
ID3D11RenderTargetView* const* ppRenderTargetViews,
|
||||
ID3D11DepthStencilView* pDepthStencilView) {
|
||||
// Update state vector for OMGetRenderTargets
|
||||
for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) {
|
||||
D3D11RenderTargetView* view = nullptr;
|
||||
|
||||
@ -1119,6 +1154,9 @@ namespace dxvk {
|
||||
m_state.om.renderTargetViews.at(i) = view;
|
||||
}
|
||||
|
||||
m_state.om.depthStencilView = static_cast<D3D11DepthStencilView*>(pDepthStencilView);
|
||||
|
||||
|
||||
// TODO unbind overlapping shader resource views
|
||||
|
||||
Rc<DxvkFramebuffer> framebuffer = nullptr;
|
||||
@ -1134,15 +1172,13 @@ namespace dxvk {
|
||||
attachments.setColorTarget(i, m_state.om.renderTargetViews.at(i)->GetDXVKImageView());
|
||||
}
|
||||
|
||||
// TODO implement depth-stencil views
|
||||
if (pDepthStencilView != nullptr)
|
||||
Logger::err("D3D11DeviceContext::OMSetRenderTargets: Depth-stencil view not supported");
|
||||
if (m_state.om.depthStencilView != nullptr)
|
||||
attachments.setDepthTarget(m_state.om.depthStencilView->GetDXVKImageView());
|
||||
|
||||
framebuffer = m_device->createFramebuffer(attachments);
|
||||
}
|
||||
|
||||
// Bind the framebuffer object to the context
|
||||
m_state.om.framebuffer = framebuffer;
|
||||
m_context->bindFramebuffer(framebuffer);
|
||||
}
|
||||
|
||||
|
@ -74,8 +74,7 @@ namespace dxvk {
|
||||
|
||||
struct D3D11ContextStateOM {
|
||||
std::array<Com<D3D11RenderTargetView>, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> renderTargetViews;
|
||||
|
||||
Rc<DxvkFramebuffer> framebuffer;
|
||||
Com<D3D11DepthStencilView> depthStencilView;
|
||||
};
|
||||
|
||||
|
||||
|
@ -194,6 +194,18 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkCommandList::cmdClearDepthStencilImage(
|
||||
VkImage image,
|
||||
VkImageLayout imageLayout,
|
||||
const VkClearDepthStencilValue* pDepthStencil,
|
||||
uint32_t rangeCount,
|
||||
const VkImageSubresourceRange* pRanges) {
|
||||
m_vkd->vkCmdClearDepthStencilImage(m_buffer,
|
||||
image, imageLayout, pDepthStencil,
|
||||
rangeCount, pRanges);
|
||||
}
|
||||
|
||||
|
||||
void DxvkCommandList::cmdCopyBuffer(
|
||||
VkBuffer srcBuffer,
|
||||
VkBuffer dstBuffer,
|
||||
|
@ -117,6 +117,13 @@ namespace dxvk {
|
||||
uint32_t rangeCount,
|
||||
const VkImageSubresourceRange* pRanges);
|
||||
|
||||
void cmdClearDepthStencilImage(
|
||||
VkImage image,
|
||||
VkImageLayout imageLayout,
|
||||
const VkClearDepthStencilValue* pDepthStencil,
|
||||
uint32_t rangeCount,
|
||||
const VkImageSubresourceRange* pRanges);
|
||||
|
||||
void cmdCopyBuffer(
|
||||
VkBuffer srcBuffer,
|
||||
VkBuffer dstBuffer,
|
||||
|
@ -229,6 +229,38 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::clearDepthStencilImage(
|
||||
const Rc<DxvkImage>& image,
|
||||
const VkClearDepthStencilValue& value,
|
||||
const VkImageSubresourceRange& subresources) {
|
||||
this->renderPassEnd();
|
||||
|
||||
if (image->info().layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
|
||||
m_barriers.accessImage(image, subresources,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, 0, 0,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
m_barriers.recordCommands(m_cmd);
|
||||
}
|
||||
|
||||
m_cmd->cmdClearDepthStencilImage(image->handle(),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
&value, 1, &subresources);
|
||||
|
||||
m_barriers.accessImage(image, subresources,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
image->info().layout,
|
||||
image->info().stages,
|
||||
image->info().access);
|
||||
m_barriers.recordCommands(m_cmd);
|
||||
|
||||
m_cmd->trackResource(image);
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::clearRenderTarget(
|
||||
const VkClearAttachment& attachment,
|
||||
const VkClearRect& clearArea) {
|
||||
|
@ -155,6 +155,18 @@ namespace dxvk {
|
||||
const VkClearColorValue& value,
|
||||
const VkImageSubresourceRange& subresources);
|
||||
|
||||
/**
|
||||
* \brief Clears subresources of a depth-stencil image
|
||||
*
|
||||
* \param [in] image The image to clear
|
||||
* \param [in] value Clear value
|
||||
* \param [in] subresources Subresources to clear
|
||||
*/
|
||||
void clearDepthStencilImage(
|
||||
const Rc<DxvkImage>& image,
|
||||
const VkClearDepthStencilValue& value,
|
||||
const VkImageSubresourceRange& subresources);
|
||||
|
||||
/**
|
||||
* \brief Clears an active render target
|
||||
*
|
||||
|
@ -53,26 +53,6 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
int32_t DxvkRenderTargets::getAttachmentId(
|
||||
const Rc<DxvkImageView>& view) const {
|
||||
if (view == nullptr)
|
||||
return -1;
|
||||
|
||||
if (m_depthTarget == view)
|
||||
return 0;
|
||||
|
||||
uint32_t colorAttachmentBaseId =
|
||||
m_depthTarget == nullptr ? 0 : 1;
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||
if (m_colorTargets.at(i) == view)
|
||||
return i + colorAttachmentBaseId;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
DxvkFramebufferSize DxvkRenderTargets::renderTargetSize(
|
||||
const Rc<DxvkImageView>& renderTarget) const {
|
||||
auto extent = renderTarget->image()->info().extent;
|
||||
|
@ -94,18 +94,6 @@ namespace dxvk {
|
||||
*/
|
||||
DxvkFramebufferSize getImageSize() const;
|
||||
|
||||
/**
|
||||
* \brief Retrieves the ID of an attachment
|
||||
*
|
||||
* This can be used to locate a color attachment
|
||||
* or the depth-stencil attachment. Returns -1
|
||||
* if the given view is not an attachment.
|
||||
* \param [in] view View to find
|
||||
* \returns Attachment ID, or \c -1
|
||||
*/
|
||||
int32_t getAttachmentId(
|
||||
const Rc<DxvkImageView>& view) const;
|
||||
|
||||
private:
|
||||
|
||||
std::array<Rc<DxvkImageView>, MaxNumRenderTargets> m_colorTargets;
|
||||
|
Loading…
Reference in New Issue
Block a user