From 47bdf9408b8a4ffc94403809112fe4da7b61de31 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 21 Nov 2017 19:50:57 +0100 Subject: [PATCH] [dxvk] Added buffer view class --- src/dxvk/dxvk_buffer.cpp | 26 +++++++++++++ src/dxvk/dxvk_buffer.h | 72 +++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_cmdlist.cpp | 10 +++++ src/dxvk/dxvk_cmdlist.h | 6 +++ src/dxvk/dxvk_context.cpp | 35 ++++++++++++----- src/dxvk/dxvk_context.h | 9 +++-- src/dxvk/dxvk_device.cpp | 7 ++++ src/dxvk/dxvk_device.h | 12 ++++++ src/dxvk/dxvk_framebuffer.cpp | 6 +-- src/dxvk/dxvk_image.h | 8 ++-- src/dxvk/dxvk_recorder.h | 6 +++ 11 files changed, 177 insertions(+), 20 deletions(-) diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index 471b7fca..15a80853 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -39,4 +39,30 @@ namespace dxvk { m_vkd->vkDestroyBuffer(m_vkd->device(), m_buffer, nullptr); } + + DxvkBufferView::DxvkBufferView( + const Rc& vkd, + const Rc& buffer, + const DxvkBufferViewCreateInfo& info) + : m_vkd(vkd), m_buffer(buffer), m_info(info) { + TRACE(this, buffer); + + VkBufferViewCreateInfo viewInfo; + viewInfo.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; + viewInfo.pNext = nullptr; + viewInfo.flags = 0; + viewInfo.buffer = buffer->handle(); + viewInfo.format = info.format; + viewInfo.offset = info.rangeOffset; + viewInfo.range = info.rangeLength; + + if (m_vkd->vkCreateBufferView(m_vkd->device(), &viewInfo, nullptr, &m_view) != VK_SUCCESS) + throw DxvkError("DxvkBufferView::DxvkBufferView: Failed to create buffer view"); + } + + + DxvkBufferView::~DxvkBufferView() { + TRACE(this); + } + } \ No newline at end of file diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index b08ea3d8..8e115af6 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -29,6 +29,25 @@ namespace dxvk { }; + /** + * \brief Buffer view create info + * + * The properties of a buffer view that + * are to \ref DxvkDevice::createBufferView + */ + struct DxvkBufferViewCreateInfo { + + /// Buffer data format, like image data + VkFormat format; + + /// Offset of the buffer region to include in the view + VkDeviceSize rangeOffset; + + /// Size of the buffer region to include in the view + VkDeviceSize rangeLength; + }; + + /** * \brief DXVK buffer * @@ -85,6 +104,59 @@ namespace dxvk { }; + /** + * \brief Buffer view + * + * Allows the application to interpret buffer + * contents like formatted pixel data. These + * buffer views are used as texel buffers. + */ + class DxvkBufferView : public DxvkResource { + + public: + + DxvkBufferView( + const Rc& vkd, + const Rc& buffer, + const DxvkBufferViewCreateInfo& info); + + ~DxvkBufferView(); + + /** + * \brief Buffer view handle + * \returns Buffer view handle + */ + VkBufferView handle() const { + return m_view; + } + + /** + * \brief Buffer view properties + * \returns Buffer view properties + */ + const DxvkBufferViewCreateInfo& info() const { + return m_info; + } + + /** + * \brief Underlying buffer object + * \returns Underlying buffer object + */ + Rc buffer() const { + return m_buffer; + } + + private: + + Rc m_vkd; + Rc m_buffer; + + DxvkBufferViewCreateInfo m_info; + VkBufferView m_view; + + }; + + /** * \brief Buffer binding * diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 4161fb6c..98a79a69 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -136,6 +136,16 @@ namespace dxvk { } + void DxvkCommandList::cmdBindVertexBuffers( + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets) { + m_vkd->vkCmdBindVertexBuffers(m_buffer, + firstBinding, bindingCount, pBuffers, pOffsets); + } + + void DxvkCommandList::cmdClearAttachments( uint32_t attachmentCount, const VkClearAttachment* pAttachments, diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 0de8b0d6..c2f1a86d 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -91,6 +91,12 @@ namespace dxvk { VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) final; + void cmdBindVertexBuffers( + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets) final; + void cmdClearAttachments( uint32_t attachmentCount, const VkClearAttachment* pAttachments, diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index aafbf07f..602c735d 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -172,8 +172,7 @@ namespace dxvk { m_state.vp.scissorRects.at(i) = scissorRects[i]; } - m_cmd->cmdSetViewport(0, viewportCount, viewports); - m_cmd->cmdSetScissor (0, viewportCount, scissorRects); + this->updateViewports(); } @@ -296,16 +295,22 @@ namespace dxvk { } - void DxvkContext::bindDynamicState() { + void DxvkContext::updateDynamicState() { if (m_state.flags.test(DxvkContextFlag::GpDirtyDynamicState)) { m_state.flags.clr(DxvkContextFlag::GpDirtyDynamicState); - // TODO implement + this->updateViewports(); } } - void DxvkContext::bindIndexBuffer() { + void DxvkContext::updateViewports() { + m_cmd->cmdSetViewport(0, m_state.vp.viewportCount, m_state.vp.viewports.data()); + m_cmd->cmdSetScissor (0, m_state.vp.viewportCount, m_state.vp.scissorRects.data()); + } + + + void DxvkContext::updateIndexBufferBinding() { if (m_state.flags.test(DxvkContextFlag::GpDirtyIndexBuffer)) { m_state.flags.clr(DxvkContextFlag::GpDirtyIndexBuffer); @@ -321,11 +326,21 @@ namespace dxvk { } - void DxvkContext::bindVertexBuffers() { + void DxvkContext::updateVertexBufferBindings() { if (m_state.flags.test(DxvkContextFlag::GpDirtyVertexBuffers)) { m_state.flags.clr(DxvkContextFlag::GpDirtyVertexBuffers); - // TODO implement + for (uint32_t i = 0; i < m_state.vi.vertexBuffers.size(); i++) { + const DxvkBufferBinding vbo = m_state.vi.vertexBuffers.at(i); + + VkBuffer handle = vbo.bufferHandle(); + VkDeviceSize offset = vbo.bufferOffset(); + + if (handle != VK_NULL_HANDLE) { + m_cmd->cmdBindVertexBuffers(i, 1, &handle, &offset); + m_cmd->trackResource(vbo.resource()); + } + } } } @@ -333,9 +348,9 @@ namespace dxvk { void DxvkContext::commitGraphicsState() { this->renderPassBegin(); this->bindGraphicsPipeline(); - this->bindDynamicState(); - this->bindIndexBuffer(); - this->bindVertexBuffers(); + this->updateDynamicState(); + this->updateIndexBufferBinding(); + this->updateVertexBufferBindings(); } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 954dd21e..bf42ec94 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -192,9 +192,12 @@ namespace dxvk { void renderPassEnd(); void bindGraphicsPipeline(); - void bindDynamicState(); - void bindIndexBuffer(); - void bindVertexBuffers(); + + void updateDynamicState(); + void updateViewports(); + + void updateIndexBufferBinding(); + void updateVertexBufferBindings(); void commitGraphicsState(); diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index c116fb27..e340d6af 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -60,6 +60,13 @@ namespace dxvk { } + Rc DxvkDevice::createBufferView( + const Rc& buffer, + const DxvkBufferViewCreateInfo& createInfo) { + return new DxvkBufferView(m_vkd, buffer, createInfo); + } + + Rc DxvkDevice::createImage( const DxvkImageCreateInfo& createInfo, VkMemoryPropertyFlags memoryType) { diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 455f907a..6365f3d2 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -3,6 +3,7 @@ #include "dxvk_adapter.h" #include "dxvk_buffer.h" #include "dxvk_compute.h" +#include "dxvk_constant_state.h" #include "dxvk_context.h" #include "dxvk_framebuffer.h" #include "dxvk_memory.h" @@ -97,6 +98,17 @@ namespace dxvk { const DxvkBufferCreateInfo& createInfo, VkMemoryPropertyFlags memoryType); + /** + * \brief Creates a buffer view + * + * \param [in] buffer The buffer to view + * \param [in] createInfo Buffer view properties + * \returns The buffer view object + */ + Rc createBufferView( + const Rc& buffer, + const DxvkBufferViewCreateInfo& createInfo); + /** * \brief Creates an image object * diff --git a/src/dxvk/dxvk_framebuffer.cpp b/src/dxvk/dxvk_framebuffer.cpp index 37ad0a1f..ea754134 100644 --- a/src/dxvk/dxvk_framebuffer.cpp +++ b/src/dxvk/dxvk_framebuffer.cpp @@ -12,13 +12,13 @@ namespace dxvk { for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { if (m_colorTargets.at(i) != nullptr) { result.setColorFormat(i, m_colorTargets.at(i)->info().format); - result.setSampleCount(m_colorTargets.at(i)->imageInfo().sampleCount); + result.setSampleCount(m_colorTargets.at(i)->image()->info().sampleCount); } } if (m_depthTarget != nullptr) { result.setDepthFormat(m_depthTarget->info().format); - result.setSampleCount(m_depthTarget->imageInfo().sampleCount); + result.setSampleCount(m_depthTarget->image()->info().sampleCount); } return result; @@ -55,7 +55,7 @@ namespace dxvk { DxvkFramebufferSize DxvkRenderTargets::renderTargetSize( const Rc& renderTarget) const { - auto extent = renderTarget->imageInfo().extent; + auto extent = renderTarget->image()->info().extent; auto layers = renderTarget->info().numLayers; return DxvkFramebufferSize { extent.width, extent.height, layers }; } diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index 3380f0cd..9ae67550 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -118,11 +118,11 @@ namespace dxvk { } /** - * \brief Image properties - * \returns Image properties + * \brief Image + * \returns Image */ - const DxvkImageCreateInfo& imageInfo() const { - return m_image->info(); + Rc image() const { + return m_image; } private: diff --git a/src/dxvk/dxvk_recorder.h b/src/dxvk/dxvk_recorder.h index 8f37076c..3ef78680 100644 --- a/src/dxvk/dxvk_recorder.h +++ b/src/dxvk/dxvk_recorder.h @@ -48,6 +48,12 @@ namespace dxvk { VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) = 0; + virtual void cmdBindVertexBuffers( + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets) = 0; + virtual void cmdClearAttachments( uint32_t attachmentCount, const VkClearAttachment* pAttachments,