diff --git a/src/dxvk/dxvk_barrier.cpp b/src/dxvk/dxvk_barrier.cpp index 29f19f2c5..ce1cf033f 100644 --- a/src/dxvk/dxvk_barrier.cpp +++ b/src/dxvk/dxvk_barrier.cpp @@ -33,6 +33,29 @@ namespace dxvk { } + void DxvkBarrierSet::initImage( + const Rc& image, + const VkImageSubresourceRange& subresources, + VkImageLayout dstLayout, + VkPipelineStageFlags dstStages, + VkAccessFlags dstAccess) { + m_dstStages |= dstStages; + + VkImageMemoryBarrier barrier; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.pNext = nullptr; + barrier.srcAccessMask = 0; + barrier.dstAccessMask = dstAccess; + barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + barrier.newLayout = dstLayout; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = image->handle(); + barrier.subresourceRange = subresources; + m_imgBarriers.push_back(barrier); + } + + void DxvkBarrierSet::recordCommands(const Rc& commandList) { if ((m_srcStages | m_dstStages) != 0) { VkPipelineStageFlags srcFlags = m_srcStages; diff --git a/src/dxvk/dxvk_barrier.h b/src/dxvk/dxvk_barrier.h index 0423c89fd..ac08a6a25 100644 --- a/src/dxvk/dxvk_barrier.h +++ b/src/dxvk/dxvk_barrier.h @@ -27,6 +27,13 @@ namespace dxvk { VkPipelineStageFlags stages, VkAccessFlags access); + void initImage( + const Rc& image, + const VkImageSubresourceRange& subresources, + VkImageLayout dstLayout, + VkPipelineStageFlags dstStages, + VkAccessFlags dstAccess); + void recordCommands( const Rc& commandList); diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index e652981a4..f7c7316f0 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -203,6 +203,35 @@ namespace dxvk { } + void DxvkContext::initBuffer( + const Rc& buffer, + const Rc& data) { + // TODO implement + } + + + void DxvkContext::initImage( + const Rc& image, + const Rc& data) { + const DxvkImageCreateInfo& info = image->info(); + + VkImageSubresourceRange sr; + sr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + sr.baseMipLevel = 0; + sr.levelCount = info.mipLevels; + sr.baseArrayLayer = 0; + sr.levelCount = info.numLayers; + + m_barriers.initImage(image, sr, + VK_IMAGE_LAYOUT_GENERAL, + info.stages, + info.access); + m_barriers.recordCommands(m_cmd); + + // TODO implement data upload + } + + void DxvkContext::setViewports( uint32_t viewportCount, const VkViewport* viewports, diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index c8f0f2c90..c5a2c1425 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -3,6 +3,7 @@ #include "dxvk_barrier.h" #include "dxvk_cmdlist.h" #include "dxvk_context_state.h" +#include "dxvk_data.h" #include "dxvk_pipemgr.h" #include "dxvk_util.h" @@ -166,6 +167,33 @@ namespace dxvk { uint32_t vertexOffset, uint32_t firstInstance); + /** + * \brief Initializes a buffer + * + * Uploads initial data to the buffer so that it + * can be used for read-only operations. Unlike + * \ref initImage, calling this is optional. + * \param [in] buffer The buffer to initialize + * \param [in] data Initial data buffer + */ + void initBuffer( + const Rc& buffer, + const Rc& data); + + /** + * \brief Initializes an image + * + * Sets up the image layout for future operations + * and uploads data to the image. Note that this + * method \e must be executed on the GPU before + * the image can be used for any other operations. + * \param [in] image The image to initialize + * \param [in] data Initial data. Can be omitted. + */ + void initImage( + const Rc& image, + const Rc& data); + /** * \brief Sets viewports * diff --git a/src/dxvk/dxvk_data.cpp b/src/dxvk/dxvk_data.cpp new file mode 100644 index 000000000..1b5af8896 --- /dev/null +++ b/src/dxvk/dxvk_data.cpp @@ -0,0 +1,17 @@ +#include + +#include "dxvk_data.h" + +namespace dxvk { + + DxvkDataBuffer:: DxvkDataBuffer() { } + DxvkDataBuffer::~DxvkDataBuffer() { } + + DxvkDataBuffer::DxvkDataBuffer( + const void* data, + size_t size) { + m_data.resize(size); + std::memcpy(m_data.data(), data, size); + } + +} \ No newline at end of file diff --git a/src/dxvk/dxvk_data.h b/src/dxvk/dxvk_data.h new file mode 100644 index 000000000..faa26b8a3 --- /dev/null +++ b/src/dxvk/dxvk_data.h @@ -0,0 +1,42 @@ +#pragma once + +#include "dxvk_include.h" + +namespace dxvk { + + /** + * \brief Data buffer + * + * Stores immutable data. Used for temporary + * copies of data that can be transferred to + * or from DXVK resources. + */ + class DxvkDataBuffer : public RcObject { + + public: + + DxvkDataBuffer(); + DxvkDataBuffer( + const void* data, + size_t size); + ~DxvkDataBuffer(); + + size_t size() const { + return m_data.size(); + } + + void* data() { + return m_data.data(); + } + + const void* data() const { + return m_data.data(); + } + + private: + + std::vector m_data; + + }; + +} \ No newline at end of file diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 2bfe63828..a06fbf479 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -6,6 +6,7 @@ dxvk_src = files([ 'dxvk_compute.cpp', 'dxvk_constant_state.cpp', 'dxvk_context.cpp', + 'dxvk_data.cpp', 'dxvk_descriptor.cpp', 'dxvk_device.cpp', 'dxvk_framebuffer.cpp',