mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-27 04:54:15 +01:00
[dxvk] Added pipeline manager stub
This commit is contained in:
parent
6e057b2b53
commit
883ae9f39d
@ -3,15 +3,99 @@
|
|||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
DxvkComputePipeline::DxvkComputePipeline(
|
DxvkComputePipeline::DxvkComputePipeline(
|
||||||
const Rc<vk::DeviceFn>& vkd)
|
const Rc<vk::DeviceFn>& vkd,
|
||||||
|
const Rc<DxvkShader>& shader)
|
||||||
: m_vkd(vkd) {
|
: m_vkd(vkd) {
|
||||||
// TODO implement
|
|
||||||
|
std::vector<VkDescriptorSetLayoutBinding> bindings;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < shader->slotCount(); i++)
|
||||||
|
bindings.push_back(shader->slotBinding(0, i));
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutCreateInfo dlayout;
|
||||||
|
dlayout.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||||
|
dlayout.pNext = nullptr;
|
||||||
|
dlayout.flags = 0;
|
||||||
|
dlayout.bindingCount = bindings.size();
|
||||||
|
dlayout.pBindings = bindings.data();
|
||||||
|
|
||||||
|
if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(),
|
||||||
|
&dlayout, nullptr, &m_descriptorSetLayout) != VK_SUCCESS)
|
||||||
|
throw DxvkError("DxvkComputePipeline::DxvkComputePipeline: Failed to create descriptor set layout");
|
||||||
|
|
||||||
|
VkPipelineLayoutCreateInfo playout;
|
||||||
|
playout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
playout.pNext = nullptr;
|
||||||
|
playout.flags = 0;
|
||||||
|
playout.setLayoutCount = 1;
|
||||||
|
playout.pSetLayouts = &m_descriptorSetLayout;
|
||||||
|
playout.pushConstantRangeCount = 0;
|
||||||
|
playout.pPushConstantRanges = nullptr;
|
||||||
|
|
||||||
|
if (m_vkd->vkCreatePipelineLayout(m_vkd->device(),
|
||||||
|
&playout, nullptr, &m_pipelineLayout) != VK_SUCCESS) {
|
||||||
|
this->destroyObjects();
|
||||||
|
throw DxvkError("DxvkComputePipeline::DxvkComputePipeline: Failed to create pipeline layout");
|
||||||
|
}
|
||||||
|
|
||||||
|
DxvkSpirvCodeBuffer code = shader->code(0);
|
||||||
|
|
||||||
|
VkShaderModuleCreateInfo minfo;
|
||||||
|
minfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||||
|
minfo.pNext = nullptr;
|
||||||
|
minfo.flags = 0;
|
||||||
|
minfo.codeSize = code.size();
|
||||||
|
minfo.pCode = code.data();
|
||||||
|
|
||||||
|
if (m_vkd->vkCreateShaderModule(m_vkd->device(),
|
||||||
|
&minfo, nullptr, &m_module) != VK_SUCCESS) {
|
||||||
|
this->destroyObjects();
|
||||||
|
throw DxvkError("DxvkComputePipeline::DxvkComputePipeline: Failed to create shader module");
|
||||||
|
}
|
||||||
|
|
||||||
|
VkPipelineShaderStageCreateInfo sinfo;
|
||||||
|
sinfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||||
|
sinfo.pNext = nullptr;
|
||||||
|
sinfo.flags = 0;
|
||||||
|
sinfo.stage = VK_SHADER_STAGE_COMPUTE_BIT;
|
||||||
|
sinfo.module = m_module;
|
||||||
|
sinfo.pName = "main";
|
||||||
|
sinfo.pSpecializationInfo = nullptr;
|
||||||
|
|
||||||
|
VkComputePipelineCreateInfo info;
|
||||||
|
info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
|
||||||
|
info.pNext = nullptr;
|
||||||
|
info.flags = 0;
|
||||||
|
info.stage = sinfo;
|
||||||
|
info.layout = m_pipelineLayout;
|
||||||
|
info.basePipelineHandle = VK_NULL_HANDLE;
|
||||||
|
info.basePipelineIndex = 0;
|
||||||
|
|
||||||
|
if (m_vkd->vkCreateComputePipelines(m_vkd->device(),
|
||||||
|
VK_NULL_HANDLE, 1, &info, nullptr, &m_pipeline) != VK_SUCCESS) {
|
||||||
|
this->destroyObjects();
|
||||||
|
throw DxvkError("DxvkComputePipeline::DxvkComputePipeline: Failed to compipe pipeline");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkComputePipeline::~DxvkComputePipeline() {
|
DxvkComputePipeline::~DxvkComputePipeline() {
|
||||||
m_vkd->vkDestroyPipeline(
|
this->destroyObjects();
|
||||||
m_vkd->device(), m_pipeline, nullptr);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkComputePipeline::destroyObjects() {
|
||||||
|
if (m_pipeline != VK_NULL_HANDLE)
|
||||||
|
m_vkd->vkDestroyPipeline(m_vkd->device(), m_pipeline, nullptr);
|
||||||
|
|
||||||
|
if (m_module != VK_NULL_HANDLE)
|
||||||
|
m_vkd->vkDestroyShaderModule(m_vkd->device(), m_module, nullptr);
|
||||||
|
|
||||||
|
if (m_pipelineLayout != VK_NULL_HANDLE)
|
||||||
|
m_vkd->vkDestroyPipelineLayout(m_vkd->device(), m_pipelineLayout, nullptr);
|
||||||
|
|
||||||
|
if (m_descriptorSetLayout != VK_NULL_HANDLE)
|
||||||
|
m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), m_descriptorSetLayout, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "dxvk_shader.h"
|
#include "dxvk_shader.h"
|
||||||
|
#include "dxvk_resource.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
@ -12,13 +13,26 @@ namespace dxvk {
|
|||||||
* pipelines do not need to be recompiled against any sort
|
* pipelines do not need to be recompiled against any sort
|
||||||
* of pipeline state.
|
* of pipeline state.
|
||||||
*/
|
*/
|
||||||
class DxvkComputePipeline : public RcObject {
|
class DxvkComputePipeline : public DxvkResource {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DxvkComputePipeline(const Rc<vk::DeviceFn>& vkd);
|
DxvkComputePipeline(
|
||||||
|
const Rc<vk::DeviceFn>& vkd,
|
||||||
|
const Rc<DxvkShader>& shader);
|
||||||
~DxvkComputePipeline();
|
~DxvkComputePipeline();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Descriptor set layout
|
||||||
|
*
|
||||||
|
* The descriptor set layout for this pipeline.
|
||||||
|
* Use this to allocate new descriptor sets.
|
||||||
|
* \returns The descriptor set layout
|
||||||
|
*/
|
||||||
|
VkDescriptorSetLayout descriptorSetLayout() const {
|
||||||
|
return m_descriptorSetLayout;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Pipeline handle
|
* \brief Pipeline handle
|
||||||
* \returns Pipeline handle
|
* \returns Pipeline handle
|
||||||
@ -30,7 +44,12 @@ namespace dxvk {
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
Rc<vk::DeviceFn> m_vkd;
|
||||||
VkPipeline m_pipeline;
|
VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE;
|
||||||
|
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
||||||
|
VkShaderModule m_module = VK_NULL_HANDLE;
|
||||||
|
VkPipeline m_pipeline = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
void destroyObjects();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
|
#include "dxvk_device.h"
|
||||||
#include "dxvk_context.h"
|
#include "dxvk_context.h"
|
||||||
#include "dxvk_main.h"
|
#include "dxvk_main.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
DxvkContext::DxvkContext() {
|
DxvkContext::DxvkContext(const Rc<DxvkDevice>& device)
|
||||||
TRACE(this);
|
: m_device(device) {
|
||||||
|
TRACE(this, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +17,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DxvkContext();
|
DxvkContext(
|
||||||
|
const Rc<DxvkDevice>& device);
|
||||||
~DxvkContext();
|
~DxvkContext();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,6 +126,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
const Rc<DxvkDevice> m_device;
|
||||||
|
|
||||||
Rc<DxvkRecorder> m_cmd;
|
Rc<DxvkRecorder> m_cmd;
|
||||||
DxvkContextState m_state;
|
DxvkContextState m_state;
|
||||||
|
|
||||||
|
@ -8,13 +8,12 @@
|
|||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief DXVK command list
|
* \brief DXVK deferred command list
|
||||||
*
|
*
|
||||||
* Stores a command buffer that a context can use to record Vulkan
|
* Buffers Vulkan commands so that they can be recorded
|
||||||
* commands. The command list shall also reference the resources
|
* into an actual Vulkan command buffer later. This is
|
||||||
* used by the recorded commands for automatic lifetime tracking.
|
* used to implement D3D11 Deferred Contexts, which do
|
||||||
* When the command list has completed execution, resources that
|
* not map particularly well to Vulkan's command buffers.
|
||||||
* are no longer used may get destroyed.
|
|
||||||
*/
|
*/
|
||||||
class DxvkDeferredCommands : public DxvkRecorder {
|
class DxvkDeferredCommands : public DxvkRecorder {
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
Rc<DxvkContext> DxvkDevice::createContext() {
|
Rc<DxvkContext> DxvkDevice::createContext() {
|
||||||
return new DxvkContext();
|
return new DxvkContext(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -66,6 +66,18 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rc<DxvkShader> DxvkDevice::createShader(
|
||||||
|
VkShaderStageFlagBits stage,
|
||||||
|
DxvkSpirvCodeBuffer&& code,
|
||||||
|
uint32_t numResourceSlots,
|
||||||
|
const DxvkResourceSlot* resourceSlots) {
|
||||||
|
return new DxvkShader(stage,
|
||||||
|
std::move(code),
|
||||||
|
numResourceSlots,
|
||||||
|
resourceSlots);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkSwapchain> DxvkDevice::createSwapchain(
|
Rc<DxvkSwapchain> DxvkDevice::createSwapchain(
|
||||||
const Rc<DxvkSurface>& surface,
|
const Rc<DxvkSurface>& surface,
|
||||||
const DxvkSwapchainProperties& properties) {
|
const DxvkSwapchainProperties& properties) {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "dxvk_adapter.h"
|
#include "dxvk_adapter.h"
|
||||||
#include "dxvk_buffer.h"
|
#include "dxvk_buffer.h"
|
||||||
|
#include "dxvk_compute.h"
|
||||||
#include "dxvk_context.h"
|
#include "dxvk_context.h"
|
||||||
#include "dxvk_framebuffer.h"
|
#include "dxvk_framebuffer.h"
|
||||||
#include "dxvk_memory.h"
|
#include "dxvk_memory.h"
|
||||||
@ -115,13 +116,17 @@ namespace dxvk {
|
|||||||
/**
|
/**
|
||||||
* \brief Creates a shader module
|
* \brief Creates a shader module
|
||||||
*
|
*
|
||||||
* \param [in] iface Shader interface
|
* \param [in] stage Shader stage
|
||||||
* \param [in] code SPIR-V code
|
* \param [in] code SPIR-V code
|
||||||
|
* \param [in] numResourceSlots Resource slot count
|
||||||
|
* \param [in] resourceSlots Resource slot array
|
||||||
* \returns Shader module
|
* \returns Shader module
|
||||||
*/
|
*/
|
||||||
Rc<DxvkShader> createShader(
|
Rc<DxvkShader> createShader(
|
||||||
const DxvkShaderInterface& iface,
|
VkShaderStageFlagBits stage,
|
||||||
const SpirvCodeBuffer& code);
|
DxvkSpirvCodeBuffer&& code,
|
||||||
|
uint32_t numResourceSlots,
|
||||||
|
const DxvkResourceSlot* resourceSlots);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Creates a swap chain
|
* \brief Creates a swap chain
|
||||||
|
0
src/dxvk/dxvk_graphics.cpp
Normal file
0
src/dxvk/dxvk_graphics.cpp
Normal file
36
src/dxvk/dxvk_graphics.h
Normal file
36
src/dxvk/dxvk_graphics.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "dxvk_shader.h"
|
||||||
|
#include "dxvk_resource.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Graphics pipeline
|
||||||
|
*
|
||||||
|
* Stores the pipeline layout as well as methods to
|
||||||
|
* recompile the graphics pipeline against a given
|
||||||
|
* pipeline state vector.
|
||||||
|
*/
|
||||||
|
class DxvkGraphicsPipeline : public DxvkResource {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DxvkGraphicsPipeline(
|
||||||
|
const Rc<vk::DeviceFn>& vkd,
|
||||||
|
const Rc<DxvkShader>& vs,
|
||||||
|
const Rc<DxvkShader>& tcs,
|
||||||
|
const Rc<DxvkShader>& tes,
|
||||||
|
const Rc<DxvkShader>& gs,
|
||||||
|
const Rc<DxvkShader>& fs);
|
||||||
|
~DxvkGraphicsPipeline();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::mutex m_mutex;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
26
src/dxvk/dxvk_pipemgr.cpp
Normal file
26
src/dxvk/dxvk_pipemgr.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include "dxvk_pipemgr.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
DxvkPipelineManager:: DxvkPipelineManager() { }
|
||||||
|
DxvkPipelineManager::~DxvkPipelineManager() { }
|
||||||
|
|
||||||
|
|
||||||
|
Rc<DxvkComputePipeline> DxvkPipelineManager::getComputePipeline(
|
||||||
|
const Rc<DxvkShader>& cs) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rc<DxvkGraphicsPipeline> DxvkPipelineManager::getGraphicsPipeline(
|
||||||
|
const Rc<DxvkShader>& vs,
|
||||||
|
const Rc<DxvkShader>& tcs,
|
||||||
|
const Rc<DxvkShader>& tes,
|
||||||
|
const Rc<DxvkShader>& gs,
|
||||||
|
const Rc<DxvkShader>& fs) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
58
src/dxvk/dxvk_pipemgr.h
Normal file
58
src/dxvk/dxvk_pipemgr.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dxvk_compute.h"
|
||||||
|
#include "dxvk_graphics.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Pipeline manager
|
||||||
|
*
|
||||||
|
* Creates and manages pipeline objects
|
||||||
|
* for various combinations of shaders.
|
||||||
|
*/
|
||||||
|
class DxvkPipelineManager : public RcObject {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DxvkPipelineManager();
|
||||||
|
~DxvkPipelineManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves compute pipeline
|
||||||
|
*
|
||||||
|
* Retrieves a compute pipeline object for the given
|
||||||
|
* shader. If no such pipeline object exists, a new
|
||||||
|
* one will be created.
|
||||||
|
* \param [in] cs Compute shader
|
||||||
|
*/
|
||||||
|
Rc<DxvkComputePipeline> getComputePipeline(
|
||||||
|
const Rc<DxvkShader>& cs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves graphics pipeline
|
||||||
|
*
|
||||||
|
* Retrieves a graphics pipeline object for the given
|
||||||
|
* combination of shaders. If no such pipeline object
|
||||||
|
* exists, a new one will be created.
|
||||||
|
* \param [in] vs Vertex shader
|
||||||
|
* \param [in] tcs Tessellation control shader
|
||||||
|
* \param [in] tes Tessellation evaluation shader
|
||||||
|
* \param [in] gs Geometry shader
|
||||||
|
* \param [in] fs Fragment shader
|
||||||
|
* \returns Graphics pipeline
|
||||||
|
*/
|
||||||
|
Rc<DxvkGraphicsPipeline> getGraphicsPipeline(
|
||||||
|
const Rc<DxvkShader>& vs,
|
||||||
|
const Rc<DxvkShader>& tcs,
|
||||||
|
const Rc<DxvkShader>& tes,
|
||||||
|
const Rc<DxvkShader>& gs,
|
||||||
|
const Rc<DxvkShader>& fs);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::mutex m_mutex;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -2,39 +2,56 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
DxvkShaderInterface:: DxvkShaderInterface() { }
|
|
||||||
DxvkShaderInterface::~DxvkShaderInterface() { }
|
|
||||||
|
|
||||||
void DxvkShaderInterface::enableResourceSlot(
|
|
||||||
const DxvkResourceSlot& slot) {
|
|
||||||
m_slots.push_back(slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkShader::DxvkShader(
|
DxvkShader::DxvkShader(
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
VkShaderStageFlagBits stage,
|
||||||
const DxvkShaderInterface& iface,
|
DxvkSpirvCodeBuffer&& code,
|
||||||
const SpirvCodeBuffer& code)
|
uint32_t numResourceSlots,
|
||||||
: m_vkd(vkd), m_iface(iface) {
|
const DxvkResourceSlot* resourceSlots)
|
||||||
TRACE(this);
|
: m_stage (stage),
|
||||||
|
m_code (std::move(code)) {
|
||||||
|
TRACE(this, stage, numResourceSlots);
|
||||||
|
|
||||||
VkShaderModuleCreateInfo info;
|
for (uint32_t i = 0; i < numResourceSlots; i++)
|
||||||
info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
m_slots.push_back(resourceSlots[i]);
|
||||||
info.pNext = nullptr;
|
|
||||||
info.flags = 0;
|
|
||||||
info.codeSize = code.size();
|
|
||||||
info.pCode = code.code();
|
|
||||||
|
|
||||||
if (m_vkd->vkCreateShaderModule(m_vkd->device(),
|
|
||||||
&info, nullptr, &m_shader) != VK_SUCCESS)
|
|
||||||
throw DxvkError("DxvkShader::DxvkShader: Failed to create shader");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkShader::~DxvkShader() {
|
DxvkShader::~DxvkShader() {
|
||||||
TRACE(this);
|
TRACE(this);
|
||||||
m_vkd->vkDestroyShaderModule(
|
}
|
||||||
m_vkd->device(), m_shader, nullptr);
|
|
||||||
|
|
||||||
|
DxvkSpirvCodeBuffer DxvkShader::code(
|
||||||
|
uint32_t bindingOffset) const {
|
||||||
|
// TODO implement properly
|
||||||
|
if (bindingOffset != 0)
|
||||||
|
Logger::warn("DxvkShader::code: bindingOffset != 0 not yet supported");
|
||||||
|
return m_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t DxvkShader::slotCount() const {
|
||||||
|
return m_slots.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkResourceSlot DxvkShader::slot(uint32_t slotId) const {
|
||||||
|
return m_slots.at(slotId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutBinding DxvkShader::slotBinding(
|
||||||
|
uint32_t slotId,
|
||||||
|
uint32_t bindingOffset) const {
|
||||||
|
auto dtype = static_cast<VkDescriptorType>(m_slots.at(slotId).type);
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutBinding info;
|
||||||
|
info.binding = bindingOffset + slotId;
|
||||||
|
info.descriptorType = dtype;
|
||||||
|
info.descriptorCount = 1;
|
||||||
|
info.stageFlags = m_stage;
|
||||||
|
info.pImmutableSamplers = nullptr;
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -15,10 +15,11 @@ namespace dxvk {
|
|||||||
* that can be accessed by shaders.
|
* that can be accessed by shaders.
|
||||||
*/
|
*/
|
||||||
enum class DxvkResourceType : uint32_t {
|
enum class DxvkResourceType : uint32_t {
|
||||||
UniformBuffer = 0x00,
|
UniformBuffer = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||||
ImageSampler = 0x01,
|
ImageSampler = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
SampledImage = 0x02,
|
SampledImage = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
StorageBuffer = 0x03,
|
StorageBuffer = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
StorageImage = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -31,32 +32,6 @@ namespace dxvk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Shader interface
|
|
||||||
*
|
|
||||||
* Stores a list of resource bindings in the
|
|
||||||
* order they are defined in the shader module.
|
|
||||||
*/
|
|
||||||
class DxvkShaderInterface {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DxvkShaderInterface();
|
|
||||||
~DxvkShaderInterface();
|
|
||||||
|
|
||||||
auto size() const { return m_slots.size(); }
|
|
||||||
auto data() const { return m_slots.data(); }
|
|
||||||
|
|
||||||
void enableResourceSlot(
|
|
||||||
const DxvkResourceSlot& slot);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::vector<DxvkResourceSlot> m_slots;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Shader module
|
* \brief Shader module
|
||||||
*
|
*
|
||||||
@ -70,24 +45,63 @@ namespace dxvk {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
DxvkShader(
|
DxvkShader(
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
VkShaderStageFlagBits stage,
|
||||||
const DxvkShaderInterface& iface,
|
DxvkSpirvCodeBuffer&& code,
|
||||||
const SpirvCodeBuffer& code);
|
uint32_t numResourceSlots,
|
||||||
|
const DxvkResourceSlot* resourceSlots);
|
||||||
~DxvkShader();
|
~DxvkShader();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Shader module handle
|
* \brief Retrieves shader code
|
||||||
* \returns Shader module handle
|
*
|
||||||
|
* Since the exact binding IDs are not known by the
|
||||||
|
* time the shader is created, we need to offset them
|
||||||
|
* by the first binding index reserved for the shader
|
||||||
|
* stage that this shader belongs to.
|
||||||
|
* \param [in] bindingOffset First binding ID
|
||||||
|
* \returns Modified code buffer
|
||||||
*/
|
*/
|
||||||
VkShaderModule handle() const {
|
DxvkSpirvCodeBuffer code(
|
||||||
return m_shader;
|
uint32_t bindingOffset) const;
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* \brief Number of resource slots
|
||||||
|
* \returns Number of enabled slots
|
||||||
|
*/
|
||||||
|
uint32_t slotCount() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves resource slot properties
|
||||||
|
*
|
||||||
|
* Resource slots store which resources that are bound
|
||||||
|
* to a DXVK context are used by the shader. The slot
|
||||||
|
* ID corresponds to the binding index relative to the
|
||||||
|
* first binding index within the shader.
|
||||||
|
* \param [in] slotId Slot index
|
||||||
|
* \returns The resource slot
|
||||||
|
*/
|
||||||
|
DxvkResourceSlot slot(
|
||||||
|
uint32_t slotId) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Descriptor set layout binding
|
||||||
|
*
|
||||||
|
* Creates Vulkan-compatible binding information for
|
||||||
|
* a single resource slot. Each resource slot used
|
||||||
|
* by the shader corresponds to one binding in Vulkan.
|
||||||
|
* \param [in] slotId Shader binding slot ID
|
||||||
|
* \param [in] bindingOffset Binding index offset
|
||||||
|
* \returns Binding info
|
||||||
|
*/
|
||||||
|
VkDescriptorSetLayoutBinding slotBinding(
|
||||||
|
uint32_t slotId, uint32_t bindingOffset) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
VkShaderStageFlagBits m_stage;
|
||||||
DxvkShaderInterface m_iface;
|
DxvkSpirvCodeBuffer m_code;
|
||||||
VkShaderModule m_shader;
|
|
||||||
|
std::vector<DxvkResourceSlot> m_slots;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,12 +6,13 @@ dxvk_src = files([
|
|||||||
'dxvk_deferred.cpp',
|
'dxvk_deferred.cpp',
|
||||||
'dxvk_device.cpp',
|
'dxvk_device.cpp',
|
||||||
'dxvk_framebuffer.cpp',
|
'dxvk_framebuffer.cpp',
|
||||||
|
'dxvk_graphics.cpp',
|
||||||
'dxvk_image.cpp',
|
'dxvk_image.cpp',
|
||||||
'dxvk_instance.cpp',
|
'dxvk_instance.cpp',
|
||||||
'dxvk_layout.cpp',
|
|
||||||
'dxvk_lifetime.cpp',
|
'dxvk_lifetime.cpp',
|
||||||
'dxvk_main.cpp',
|
'dxvk_main.cpp',
|
||||||
'dxvk_memory.cpp',
|
'dxvk_memory.cpp',
|
||||||
|
'dxvk_pipemgr.cpp',
|
||||||
'dxvk_recorder.cpp',
|
'dxvk_recorder.cpp',
|
||||||
'dxvk_renderpass.cpp',
|
'dxvk_renderpass.cpp',
|
||||||
'dxvk_resource.cpp',
|
'dxvk_resource.cpp',
|
||||||
|
@ -5,18 +5,18 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
SpirvCodeBuffer:: SpirvCodeBuffer() { }
|
DxvkSpirvCodeBuffer:: DxvkSpirvCodeBuffer() { }
|
||||||
SpirvCodeBuffer::~SpirvCodeBuffer() { }
|
DxvkSpirvCodeBuffer::~DxvkSpirvCodeBuffer() { }
|
||||||
|
|
||||||
|
|
||||||
SpirvCodeBuffer::SpirvCodeBuffer(
|
DxvkSpirvCodeBuffer::DxvkSpirvCodeBuffer(
|
||||||
std::basic_istream<uint32_t>& stream)
|
std::basic_istream<uint32_t>& stream)
|
||||||
: m_code(
|
: m_code(
|
||||||
std::istreambuf_iterator<uint32_t>(stream),
|
std::istreambuf_iterator<uint32_t>(stream),
|
||||||
std::istreambuf_iterator<uint32_t>()) { }
|
std::istreambuf_iterator<uint32_t>()) { }
|
||||||
|
|
||||||
|
|
||||||
void SpirvCodeBuffer::append(const SpirvCodeBuffer& other) {
|
void DxvkSpirvCodeBuffer::append(const DxvkSpirvCodeBuffer& other) {
|
||||||
const size_t size = m_code.size();
|
const size_t size = m_code.size();
|
||||||
m_code.resize(size + other.m_code.size());
|
m_code.resize(size + other.m_code.size());
|
||||||
|
|
||||||
@ -27,30 +27,30 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpirvCodeBuffer::putWord(uint32_t word) {
|
void DxvkSpirvCodeBuffer::putWord(uint32_t word) {
|
||||||
m_code.push_back(word);
|
m_code.push_back(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpirvCodeBuffer::putIns(spv::Op opCode, uint16_t wordCount) {
|
void DxvkSpirvCodeBuffer::putIns(spv::Op opCode, uint16_t wordCount) {
|
||||||
this->putWord(
|
this->putWord(
|
||||||
(static_cast<uint32_t>(opCode) << 0)
|
(static_cast<uint32_t>(opCode) << 0)
|
||||||
| (static_cast<uint32_t>(wordCount) << 16));
|
| (static_cast<uint32_t>(wordCount) << 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpirvCodeBuffer::putInt32(uint32_t word) {
|
void DxvkSpirvCodeBuffer::putInt32(uint32_t word) {
|
||||||
this->putWord(word);
|
this->putWord(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpirvCodeBuffer::putInt64(uint64_t value) {
|
void DxvkSpirvCodeBuffer::putInt64(uint64_t value) {
|
||||||
this->putWord(value >> 0);
|
this->putWord(value >> 0);
|
||||||
this->putWord(value >> 32);
|
this->putWord(value >> 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpirvCodeBuffer::putFloat32(float value) {
|
void DxvkSpirvCodeBuffer::putFloat32(float value) {
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
static_assert(sizeof(tmp) == sizeof(value));
|
static_assert(sizeof(tmp) == sizeof(value));
|
||||||
std::memcpy(&tmp, &value, sizeof(value));
|
std::memcpy(&tmp, &value, sizeof(value));
|
||||||
@ -58,7 +58,7 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpirvCodeBuffer::putFloat64(double value) {
|
void DxvkSpirvCodeBuffer::putFloat64(double value) {
|
||||||
uint64_t tmp;
|
uint64_t tmp;
|
||||||
static_assert(sizeof(tmp) == sizeof(value));
|
static_assert(sizeof(tmp) == sizeof(value));
|
||||||
std::memcpy(&tmp, &value, sizeof(value));
|
std::memcpy(&tmp, &value, sizeof(value));
|
||||||
@ -66,7 +66,7 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpirvCodeBuffer::putStr(const char* str) {
|
void DxvkSpirvCodeBuffer::putStr(const char* str) {
|
||||||
uint32_t word = 0;
|
uint32_t word = 0;
|
||||||
uint32_t nbit = 0;
|
uint32_t nbit = 0;
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpirvCodeBuffer::putHeader(uint32_t boundIds) {
|
void DxvkSpirvCodeBuffer::putHeader(uint32_t boundIds) {
|
||||||
this->putWord(spv::MagicNumber);
|
this->putWord(spv::MagicNumber);
|
||||||
this->putWord(spv::Version);
|
this->putWord(spv::Version);
|
||||||
this->putWord(0); // Generator
|
this->putWord(0); // Generator
|
||||||
@ -94,13 +94,13 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t SpirvCodeBuffer::strLen(const char* str) {
|
uint32_t DxvkSpirvCodeBuffer::strLen(const char* str) {
|
||||||
// Null-termination plus padding
|
// Null-termination plus padding
|
||||||
return (std::strlen(str) + 4) / 4;
|
return (std::strlen(str) + 4) / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpirvCodeBuffer::store(std::basic_ostream<uint32_t>& stream) const {
|
void DxvkSpirvCodeBuffer::store(std::basic_ostream<uint32_t>& stream) const {
|
||||||
stream.write(m_code.data(), m_code.size());
|
stream.write(m_code.data(), m_code.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,20 +16,20 @@ namespace dxvk {
|
|||||||
* Stores arbitrary SPIR-V instructions in a
|
* Stores arbitrary SPIR-V instructions in a
|
||||||
* format that can be read by Vulkan drivers.
|
* format that can be read by Vulkan drivers.
|
||||||
*/
|
*/
|
||||||
class SpirvCodeBuffer {
|
class DxvkSpirvCodeBuffer {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SpirvCodeBuffer();
|
DxvkSpirvCodeBuffer();
|
||||||
SpirvCodeBuffer(
|
DxvkSpirvCodeBuffer(
|
||||||
std::basic_istream<uint32_t>& stream);
|
std::basic_istream<uint32_t>& stream);
|
||||||
~SpirvCodeBuffer();
|
~DxvkSpirvCodeBuffer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Code
|
* \brief Code data
|
||||||
* \returns Code
|
* \returns Code data
|
||||||
*/
|
*/
|
||||||
const uint32_t* code() const {
|
const uint32_t* data() const {
|
||||||
return m_code.data();
|
return m_code.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ namespace dxvk {
|
|||||||
* code when doing so in advance is impossible.
|
* code when doing so in advance is impossible.
|
||||||
* \param [in] other Code buffer to append
|
* \param [in] other Code buffer to append
|
||||||
*/
|
*/
|
||||||
void append(const SpirvCodeBuffer& other);
|
void append(const DxvkSpirvCodeBuffer& other);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Appends an 32-bit word to the buffer
|
* \brief Appends an 32-bit word to the buffer
|
||||||
|
Loading…
x
Reference in New Issue
Block a user