mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 10:54:16 +01:00
[dxvk] Re-implemented pipeline creation within the backend
This commit is contained in:
parent
e95dc64c77
commit
19851c8432
@ -9,7 +9,7 @@ exe_wrapper = 'wine'
|
||||
c_args = ['-Og', '-ggdb']
|
||||
c_link_args = ['-static', '-static-libgcc']
|
||||
|
||||
cpp_args = ['-std=c++17', '-Og', '-ggdb']
|
||||
cpp_args = ['-std=c++17', '-Og', '-gstabs']
|
||||
cpp_link_args = ['-static', '-static-libgcc', '-static-libstdc++']
|
||||
|
||||
[host_machine]
|
||||
|
@ -55,8 +55,6 @@ namespace dxvk {
|
||||
|
||||
// Set up context state. The shader bindings and the
|
||||
// constant state objects will never be modified.
|
||||
m_context->bindGraphicsPipeline(createPipeline());
|
||||
|
||||
m_context->setInputAssemblyState(
|
||||
new DxvkInputAssemblyState(
|
||||
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
|
||||
@ -111,6 +109,14 @@ namespace dxvk {
|
||||
new DxvkBlendState(
|
||||
VK_FALSE, VK_LOGIC_OP_NO_OP,
|
||||
1, &blendAttachment));
|
||||
|
||||
m_context->bindShader(
|
||||
VK_SHADER_STAGE_VERTEX_BIT,
|
||||
this->createVertexShader());
|
||||
|
||||
m_context->bindShader(
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
this->createFragmentShader());
|
||||
}
|
||||
|
||||
|
||||
@ -329,7 +335,8 @@ namespace dxvk {
|
||||
|
||||
// Create the actual shader module
|
||||
return m_device->createShader(
|
||||
VK_SHADER_STAGE_VERTEX_BIT, module.compile());
|
||||
VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0, nullptr, module.compile());
|
||||
}
|
||||
|
||||
|
||||
@ -397,42 +404,24 @@ namespace dxvk {
|
||||
module.opReturn();
|
||||
module.functionEnd();
|
||||
|
||||
|
||||
// Register function entry point
|
||||
std::array<uint32_t, 2> interfaces = { inTexCoord, outColor };
|
||||
|
||||
module.addEntryPoint(entryPointId, spv::ExecutionModelFragment,
|
||||
"main", interfaces.size(), interfaces.data());
|
||||
|
||||
// Shader resource slots
|
||||
std::array<DxvkResourceSlot, 2> resourceSlots = {{
|
||||
{ BindingIds::Sampler, VK_DESCRIPTOR_TYPE_SAMPLER },
|
||||
{ BindingIds::Texture, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE },
|
||||
}};
|
||||
|
||||
// Create the actual shader module
|
||||
return m_device->createShader(
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT, module.compile());
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkBindingLayout> DxgiPresenter::createBindingLayout() {
|
||||
std::array<DxvkDescriptorSlot, 2> bindings;
|
||||
bindings.at(BindingIds::Sampler).slot = BindingIds::Sampler;
|
||||
bindings.at(BindingIds::Sampler).type = VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||
bindings.at(BindingIds::Sampler).stages = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
|
||||
bindings.at(BindingIds::Texture).slot = BindingIds::Texture;
|
||||
bindings.at(BindingIds::Texture).type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||
bindings.at(BindingIds::Texture).stages = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
|
||||
return m_device->createBindingLayout(
|
||||
bindings.size(), bindings.data());
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkGraphicsPipeline> DxgiPresenter::createPipeline() {
|
||||
const Rc<DxvkShader> vs = this->createVertexShader();
|
||||
const Rc<DxvkShader> fs = this->createFragmentShader();
|
||||
|
||||
return m_device->createGraphicsPipeline(
|
||||
this->createBindingLayout(),
|
||||
vs, nullptr, nullptr, nullptr, fs);
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
resourceSlots.size(),
|
||||
resourceSlots.data(),
|
||||
module.compile());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -76,10 +76,6 @@ namespace dxvk {
|
||||
Rc<DxvkShader> createVertexShader();
|
||||
Rc<DxvkShader> createFragmentShader();
|
||||
|
||||
Rc<DxvkBindingLayout> createBindingLayout();
|
||||
|
||||
Rc<DxvkGraphicsPipeline> createPipeline();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -336,6 +336,7 @@ namespace dxvk {
|
||||
DxvkImageCreateInfo imageInfo;
|
||||
imageInfo.type = VK_IMAGE_TYPE_2D;
|
||||
imageInfo.format = bufferFormat.actual;
|
||||
imageInfo.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
||||
imageInfo.sampleCount = VK_SAMPLE_COUNT_1_BIT;
|
||||
imageInfo.extent.width = m_desc.BufferDesc.Width;
|
||||
imageInfo.extent.height = m_desc.BufferDesc.Height;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "dxvk_descriptor.h"
|
||||
#include "dxvk_lifetime.h"
|
||||
#include "dxvk_pipeline.h"
|
||||
#include "dxvk_pipelayout.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
|
@ -3,17 +3,36 @@
|
||||
namespace dxvk {
|
||||
|
||||
DxvkComputePipeline::DxvkComputePipeline(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
const Rc<DxvkBindingLayout>& layout,
|
||||
const Rc<DxvkShader>& cs)
|
||||
: m_vkd(vkd), m_layout(layout), m_cs(cs) {
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
const Rc<DxvkShader>& cs)
|
||||
: m_vkd(vkd) {
|
||||
DxvkDescriptorSlotMapping slotMapping;
|
||||
cs->defineResourceSlots(slotMapping);
|
||||
|
||||
m_layout = new DxvkBindingLayout(vkd,
|
||||
slotMapping.bindingCount(),
|
||||
slotMapping.bindingInfos());
|
||||
|
||||
m_cs = cs->createShaderModule(slotMapping);
|
||||
|
||||
this->compilePipeline();
|
||||
}
|
||||
|
||||
|
||||
DxvkComputePipeline::~DxvkComputePipeline() {
|
||||
if (m_pipeline != VK_NULL_HANDLE)
|
||||
m_vkd->vkDestroyPipeline(m_vkd->device(), m_pipeline, nullptr);
|
||||
}
|
||||
|
||||
|
||||
void DxvkComputePipeline::compilePipeline() {
|
||||
std::vector<VkDescriptorSetLayoutBinding> bindings;
|
||||
|
||||
VkComputePipelineCreateInfo info;
|
||||
info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
|
||||
info.pNext = nullptr;
|
||||
info.flags = 0;
|
||||
info.stage = cs->stageInfo();
|
||||
info.stage = m_cs->stageInfo();
|
||||
info.layout = m_layout->pipelineLayout();
|
||||
info.basePipelineHandle = VK_NULL_HANDLE;
|
||||
info.basePipelineIndex = 0;
|
||||
@ -23,10 +42,4 @@ namespace dxvk {
|
||||
throw DxvkError("DxvkComputePipeline::DxvkComputePipeline: Failed to compile pipeline");
|
||||
}
|
||||
|
||||
|
||||
DxvkComputePipeline::~DxvkComputePipeline() {
|
||||
if (m_pipeline != VK_NULL_HANDLE)
|
||||
m_vkd->vkDestroyPipeline(m_vkd->device(), m_pipeline, nullptr);
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "dxvk_pipeline.h"
|
||||
#include "dxvk_pipelayout.h"
|
||||
#include "dxvk_resource.h"
|
||||
#include "dxvk_shader.h"
|
||||
|
||||
@ -19,9 +19,8 @@ namespace dxvk {
|
||||
public:
|
||||
|
||||
DxvkComputePipeline(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
const Rc<DxvkBindingLayout>& layout,
|
||||
const Rc<DxvkShader>& cs);
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
const Rc<DxvkShader>& cs);
|
||||
~DxvkComputePipeline();
|
||||
|
||||
/**
|
||||
@ -48,10 +47,12 @@ namespace dxvk {
|
||||
|
||||
Rc<vk::DeviceFn> m_vkd;
|
||||
Rc<DxvkBindingLayout> m_layout;
|
||||
Rc<DxvkShader> m_cs;
|
||||
Rc<DxvkShaderModule> m_cs;
|
||||
|
||||
VkPipeline m_pipeline = VK_NULL_HANDLE;
|
||||
|
||||
void compilePipeline();
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -53,32 +53,6 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::bindComputePipeline(
|
||||
const Rc<DxvkComputePipeline>& pipeline) {
|
||||
if (m_state.cPipe != pipeline) {
|
||||
m_state.cPipe = pipeline;
|
||||
|
||||
m_flags.set(
|
||||
DxvkContextFlag::CpDirtyPipeline,
|
||||
DxvkContextFlag::CpDirtyResources);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::bindGraphicsPipeline(
|
||||
const Rc<DxvkGraphicsPipeline>& pipeline) {
|
||||
if (m_state.gPipe != pipeline) {
|
||||
m_state.gPipe = pipeline;
|
||||
|
||||
m_flags.set(
|
||||
DxvkContextFlag::GpDirtyPipeline,
|
||||
DxvkContextFlag::GpDirtyResources,
|
||||
DxvkContextFlag::GpDirtyVertexBuffers,
|
||||
DxvkContextFlag::GpDirtyIndexBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::bindIndexBuffer(
|
||||
const DxvkBufferBinding& buffer) {
|
||||
if (m_state.vi.indexBuffer != buffer) {
|
||||
@ -178,6 +152,31 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::bindShader(
|
||||
VkShaderStageFlagBits stage,
|
||||
const Rc<DxvkShader>& shader) {
|
||||
DxvkShaderStage* shaderStage = nullptr;
|
||||
|
||||
switch (stage) {
|
||||
case VK_SHADER_STAGE_VERTEX_BIT: shaderStage = &m_state.gp.vs; break;
|
||||
case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: shaderStage = &m_state.gp.tcs; break;
|
||||
case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: shaderStage = &m_state.gp.tes; break;
|
||||
case VK_SHADER_STAGE_GEOMETRY_BIT: shaderStage = &m_state.gp.gs; break;
|
||||
case VK_SHADER_STAGE_FRAGMENT_BIT: shaderStage = &m_state.gp.fs; break;
|
||||
case VK_SHADER_STAGE_COMPUTE_BIT: shaderStage = &m_state.cp.cs; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
if (shaderStage->shader != shader) {
|
||||
shaderStage->shader = shader;
|
||||
|
||||
m_flags.set(stage == VK_SHADER_STAGE_COMPUTE_BIT
|
||||
? DxvkContextFlag::CpDirtyPipeline
|
||||
: DxvkContextFlag::GpDirtyPipeline);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::bindVertexBuffer(
|
||||
uint32_t binding,
|
||||
const DxvkBufferBinding& buffer) {
|
||||
@ -445,9 +444,12 @@ namespace dxvk {
|
||||
if (m_flags.test(DxvkContextFlag::CpDirtyPipeline)) {
|
||||
m_flags.clr(DxvkContextFlag::CpDirtyPipeline);
|
||||
|
||||
m_state.cp.pipeline = m_device->createComputePipeline(
|
||||
m_state.cp.cs.shader);
|
||||
|
||||
m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||
m_state.cPipe->getPipelineHandle());
|
||||
m_cmd->trackResource(m_state.cPipe);
|
||||
m_state.cp.pipeline->getPipelineHandle());
|
||||
m_cmd->trackResource(m_state.cp.pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
@ -456,6 +458,10 @@ namespace dxvk {
|
||||
if (m_flags.test(DxvkContextFlag::GpDirtyPipeline)) {
|
||||
m_flags.clr(DxvkContextFlag::GpDirtyPipeline);
|
||||
|
||||
m_state.gp.pipeline = m_device->createGraphicsPipeline(
|
||||
m_state.gp.vs.shader, m_state.gp.tcs.shader, m_state.gp.tes.shader,
|
||||
m_state.gp.gs.shader, m_state.gp.fs.shader);
|
||||
|
||||
DxvkGraphicsPipelineStateInfo gpState;
|
||||
gpState.inputAssemblyState = m_state.co.inputAssemblyState;
|
||||
gpState.inputLayout = m_state.co.inputLayout;
|
||||
@ -467,8 +473,8 @@ namespace dxvk {
|
||||
gpState.viewportCount = m_state.vp.viewportCount;
|
||||
|
||||
m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
m_state.gPipe->getPipelineHandle(gpState));
|
||||
m_cmd->trackResource(m_state.gPipe);
|
||||
m_state.gp.pipeline->getPipelineHandle(gpState));
|
||||
m_cmd->trackResource(m_state.gp.pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,7 +483,7 @@ namespace dxvk {
|
||||
if (m_flags.test(DxvkContextFlag::CpDirtyResources)) {
|
||||
m_flags.clr(DxvkContextFlag::CpDirtyResources);
|
||||
|
||||
auto layout = m_state.cPipe->layout();
|
||||
auto layout = m_state.cp.pipeline->layout();
|
||||
|
||||
m_cmd->bindResourceDescriptors(
|
||||
VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||
@ -494,7 +500,7 @@ namespace dxvk {
|
||||
if (m_flags.test(DxvkContextFlag::GpDirtyResources)) {
|
||||
m_flags.clr(DxvkContextFlag::GpDirtyResources);
|
||||
|
||||
auto layout = m_state.gPipe->layout();
|
||||
auto layout = m_state.gp.pipeline->layout();
|
||||
|
||||
m_cmd->bindResourceDescriptors(
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
|
@ -54,20 +54,6 @@ namespace dxvk {
|
||||
void bindFramebuffer(
|
||||
const Rc<DxvkFramebuffer>& fb);
|
||||
|
||||
/**
|
||||
* \brief Binds compute pipeline
|
||||
* \param [in] pipeline The pipeline to bind
|
||||
*/
|
||||
void bindComputePipeline(
|
||||
const Rc<DxvkComputePipeline>& pipeline);
|
||||
|
||||
/**
|
||||
* \brief Binds graphics pipeline
|
||||
* \param [in] pipeline The pipeline to bind
|
||||
*/
|
||||
void bindGraphicsPipeline(
|
||||
const Rc<DxvkGraphicsPipeline>& pipeline);
|
||||
|
||||
/**
|
||||
* \brief Binds index buffer
|
||||
*
|
||||
@ -133,6 +119,16 @@ namespace dxvk {
|
||||
uint32_t slot,
|
||||
const Rc<DxvkSampler>& sampler);
|
||||
|
||||
/**
|
||||
* \brief Binds a shader to a given state
|
||||
*
|
||||
* \param [in] stage Target shader stage
|
||||
* \param [in] shader The shader to bind
|
||||
*/
|
||||
void bindShader(
|
||||
VkShaderStageFlagBits stage,
|
||||
const Rc<DxvkShader>& shader);
|
||||
|
||||
/**
|
||||
* \brief Binds vertex buffer
|
||||
*
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "dxvk_graphics.h"
|
||||
#include "dxvk_image.h"
|
||||
#include "dxvk_limits.h"
|
||||
#include "dxvk_pipeline.h"
|
||||
#include "dxvk_pipelayout.h"
|
||||
#include "dxvk_sampler.h"
|
||||
#include "dxvk_shader.h"
|
||||
|
||||
@ -54,6 +54,28 @@ namespace dxvk {
|
||||
};
|
||||
|
||||
|
||||
struct DxvkShaderStage {
|
||||
Rc<DxvkShader> shader;
|
||||
};
|
||||
|
||||
|
||||
struct DxvkGraphicsPipelineState {
|
||||
DxvkShaderStage vs;
|
||||
DxvkShaderStage tcs;
|
||||
DxvkShaderStage tes;
|
||||
DxvkShaderStage gs;
|
||||
DxvkShaderStage fs;
|
||||
|
||||
Rc<DxvkGraphicsPipeline> pipeline;
|
||||
};
|
||||
|
||||
|
||||
struct DxvkComputePipelineState {
|
||||
DxvkShaderStage cs;
|
||||
Rc<DxvkComputePipeline> pipeline;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Pipeline state
|
||||
*
|
||||
@ -66,8 +88,8 @@ namespace dxvk {
|
||||
DxvkOutputMergerState om;
|
||||
DxvkConstantStateObjects co;
|
||||
|
||||
Rc<DxvkGraphicsPipeline> gPipe;
|
||||
Rc<DxvkComputePipeline> cPipe;
|
||||
DxvkGraphicsPipelineState gp;
|
||||
DxvkComputePipelineState cp;
|
||||
};
|
||||
|
||||
}
|
@ -11,7 +11,8 @@ namespace dxvk {
|
||||
m_vkd (vkd),
|
||||
m_features (features),
|
||||
m_memory (new DxvkMemoryAllocator(adapter, vkd)),
|
||||
m_renderPassPool (new DxvkRenderPassPool (vkd)) {
|
||||
m_renderPassPool (new DxvkRenderPassPool (vkd)),
|
||||
m_pipelineManager (new DxvkPipelineManager(vkd)) {
|
||||
m_vkd->vkGetDeviceQueue(m_vkd->device(),
|
||||
m_adapter->graphicsQueueFamily(), 0,
|
||||
&m_graphicsQueue);
|
||||
@ -23,6 +24,7 @@ namespace dxvk {
|
||||
|
||||
DxvkDevice::~DxvkDevice() {
|
||||
m_renderPassPool = nullptr;
|
||||
m_pipelineManager = nullptr;
|
||||
m_memory = nullptr;
|
||||
|
||||
m_vkd->vkDeviceWaitIdle(m_vkd->device());
|
||||
@ -92,34 +94,27 @@ namespace dxvk {
|
||||
|
||||
Rc<DxvkShader> DxvkDevice::createShader(
|
||||
VkShaderStageFlagBits stage,
|
||||
uint32_t slotCount,
|
||||
const DxvkResourceSlot* slotInfos,
|
||||
const SpirvCodeBuffer& code) {
|
||||
return new DxvkShader(m_vkd, stage, code);
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkBindingLayout> DxvkDevice::createBindingLayout(
|
||||
uint32_t bindingCount,
|
||||
const DxvkDescriptorSlot* bindingInfos) {
|
||||
return new DxvkBindingLayout(m_vkd, bindingCount, bindingInfos);
|
||||
return new DxvkShader(m_vkd, stage,
|
||||
slotCount, slotInfos, code);
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkComputePipeline> DxvkDevice::createComputePipeline(
|
||||
const Rc<DxvkBindingLayout>& layout,
|
||||
const Rc<DxvkShader>& cs) {
|
||||
return new DxvkComputePipeline(m_vkd, layout, cs);
|
||||
const Rc<DxvkShader>& cs) {
|
||||
return m_pipelineManager->createComputePipeline(cs);
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkGraphicsPipeline> DxvkDevice::createGraphicsPipeline(
|
||||
const Rc<DxvkBindingLayout>& layout,
|
||||
const Rc<DxvkShader>& vs,
|
||||
const Rc<DxvkShader>& tcs,
|
||||
const Rc<DxvkShader>& tes,
|
||||
const Rc<DxvkShader>& gs,
|
||||
const Rc<DxvkShader>& fs) {
|
||||
return new DxvkGraphicsPipeline(m_vkd,
|
||||
layout, vs, tcs, tes, gs, fs);
|
||||
const Rc<DxvkShader>& vs,
|
||||
const Rc<DxvkShader>& tcs,
|
||||
const Rc<DxvkShader>& tes,
|
||||
const Rc<DxvkShader>& gs,
|
||||
const Rc<DxvkShader>& fs) {
|
||||
return m_pipelineManager->createGraphicsPipeline(vs, tcs, tes, gs, fs);
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "dxvk_framebuffer.h"
|
||||
#include "dxvk_image.h"
|
||||
#include "dxvk_memory.h"
|
||||
#include "dxvk_pipemanager.h"
|
||||
#include "dxvk_renderpass.h"
|
||||
#include "dxvk_sampler.h"
|
||||
#include "dxvk_shader.h"
|
||||
@ -166,48 +167,36 @@ namespace dxvk {
|
||||
*/
|
||||
Rc<DxvkShader> createShader(
|
||||
VkShaderStageFlagBits stage,
|
||||
uint32_t slotCount,
|
||||
const DxvkResourceSlot* slotInfos,
|
||||
const SpirvCodeBuffer& code);
|
||||
|
||||
/**
|
||||
* \brief Creates binding layout
|
||||
*
|
||||
* \param [in] bindingCount Number of bindings
|
||||
* \param [in] bindingInfos Binding descriptions
|
||||
* \returns New binding layout
|
||||
*/
|
||||
Rc<DxvkBindingLayout> createBindingLayout(
|
||||
uint32_t bindingCount,
|
||||
const DxvkDescriptorSlot* bindingInfos);
|
||||
|
||||
/**
|
||||
* \brief Creates a compute pipeline
|
||||
* \brief Retrieves a compute pipeline
|
||||
*
|
||||
* \param [in] layout Pipeline binding layout
|
||||
* \param [in] cs Compute shader
|
||||
* \returns New compute pipeline
|
||||
* \returns The compute pipeline
|
||||
*/
|
||||
Rc<DxvkComputePipeline> createComputePipeline(
|
||||
const Rc<DxvkBindingLayout>& layout,
|
||||
const Rc<DxvkShader>& cs);
|
||||
const Rc<DxvkShader>& cs);
|
||||
|
||||
/**
|
||||
* \brief Creates a graphics pipeline
|
||||
* \brief Retrieves a graphics pipeline object
|
||||
*
|
||||
* \param [in] layout Pipeline binding layout
|
||||
* \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 New graphics pipeline
|
||||
* \returns The graphics pipeline
|
||||
*/
|
||||
Rc<DxvkGraphicsPipeline> createGraphicsPipeline(
|
||||
const Rc<DxvkBindingLayout>& layout,
|
||||
const Rc<DxvkShader>& vs,
|
||||
const Rc<DxvkShader>& tcs,
|
||||
const Rc<DxvkShader>& tes,
|
||||
const Rc<DxvkShader>& gs,
|
||||
const Rc<DxvkShader>& fs);
|
||||
const Rc<DxvkShader>& vs,
|
||||
const Rc<DxvkShader>& tcs,
|
||||
const Rc<DxvkShader>& tes,
|
||||
const Rc<DxvkShader>& gs,
|
||||
const Rc<DxvkShader>& fs);
|
||||
|
||||
/**
|
||||
* \brief Creates a swap chain
|
||||
@ -252,6 +241,7 @@ namespace dxvk {
|
||||
|
||||
Rc<DxvkMemoryAllocator> m_memory;
|
||||
Rc<DxvkRenderPassPool> m_renderPassPool;
|
||||
Rc<DxvkPipelineManager> m_pipelineManager;
|
||||
|
||||
VkQueue m_graphicsQueue;
|
||||
VkQueue m_presentQueue;
|
||||
|
@ -39,16 +39,29 @@ namespace dxvk {
|
||||
|
||||
|
||||
DxvkGraphicsPipeline::DxvkGraphicsPipeline(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
const Rc<DxvkBindingLayout>& layout,
|
||||
const Rc<DxvkShader>& vs,
|
||||
const Rc<DxvkShader>& tcs,
|
||||
const Rc<DxvkShader>& tes,
|
||||
const Rc<DxvkShader>& gs,
|
||||
const Rc<DxvkShader>& fs)
|
||||
: m_vkd(vkd), m_layout(layout),
|
||||
m_vs(vs), m_tcs(tcs), m_tes(tes), m_gs(gs), m_fs(fs) {
|
||||
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)
|
||||
: m_vkd(vkd) {
|
||||
DxvkDescriptorSlotMapping slotMapping;
|
||||
if (vs != nullptr) vs ->defineResourceSlots(slotMapping);
|
||||
if (tcs != nullptr) tcs->defineResourceSlots(slotMapping);
|
||||
if (tes != nullptr) tes->defineResourceSlots(slotMapping);
|
||||
if (gs != nullptr) gs ->defineResourceSlots(slotMapping);
|
||||
if (fs != nullptr) fs ->defineResourceSlots(slotMapping);
|
||||
|
||||
m_layout = new DxvkBindingLayout(vkd,
|
||||
slotMapping.bindingCount(),
|
||||
slotMapping.bindingInfos());
|
||||
|
||||
if (vs != nullptr) m_vs = vs ->createShaderModule(slotMapping);
|
||||
if (tcs != nullptr) m_tcs = tcs->createShaderModule(slotMapping);
|
||||
if (tes != nullptr) m_tes = tes->createShaderModule(slotMapping);
|
||||
if (gs != nullptr) m_gs = gs ->createShaderModule(slotMapping);
|
||||
if (fs != nullptr) m_fs = fs ->createShaderModule(slotMapping);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "dxvk_constant_state.h"
|
||||
#include "dxvk_hash.h"
|
||||
#include "dxvk_pipeline.h"
|
||||
#include "dxvk_pipelayout.h"
|
||||
#include "dxvk_resource.h"
|
||||
#include "dxvk_shader.h"
|
||||
|
||||
@ -49,13 +49,12 @@ namespace dxvk {
|
||||
public:
|
||||
|
||||
DxvkGraphicsPipeline(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
const Rc<DxvkBindingLayout>& layout,
|
||||
const Rc<DxvkShader>& vs,
|
||||
const Rc<DxvkShader>& tcs,
|
||||
const Rc<DxvkShader>& tes,
|
||||
const Rc<DxvkShader>& gs,
|
||||
const Rc<DxvkShader>& fs);
|
||||
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();
|
||||
|
||||
/**
|
||||
@ -82,11 +81,11 @@ namespace dxvk {
|
||||
Rc<vk::DeviceFn> m_vkd;
|
||||
Rc<DxvkBindingLayout> m_layout;
|
||||
|
||||
Rc<DxvkShader> m_vs;
|
||||
Rc<DxvkShader> m_tcs;
|
||||
Rc<DxvkShader> m_tes;
|
||||
Rc<DxvkShader> m_gs;
|
||||
Rc<DxvkShader> m_fs;
|
||||
Rc<DxvkShaderModule> m_vs;
|
||||
Rc<DxvkShaderModule> m_tcs;
|
||||
Rc<DxvkShaderModule> m_tes;
|
||||
Rc<DxvkShaderModule> m_gs;
|
||||
Rc<DxvkShaderModule> m_fs;
|
||||
|
||||
std::mutex m_mutex;
|
||||
|
||||
|
@ -1,9 +1,44 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "dxvk_pipeline.h"
|
||||
#include "dxvk_pipelayout.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
DxvkDescriptorSlotMapping:: DxvkDescriptorSlotMapping() { }
|
||||
DxvkDescriptorSlotMapping::~DxvkDescriptorSlotMapping() { }
|
||||
|
||||
|
||||
void DxvkDescriptorSlotMapping::defineSlot(
|
||||
uint32_t slot,
|
||||
VkDescriptorType type,
|
||||
VkShaderStageFlagBits stage) {
|
||||
uint32_t bindingId = this->getBindingId(slot);
|
||||
|
||||
if (bindingId != InvalidBinding) {
|
||||
m_descriptorSlots.at(bindingId).stages |= stage;
|
||||
} else {
|
||||
DxvkDescriptorSlot slotInfo;
|
||||
slotInfo.slot = slot;
|
||||
slotInfo.type = type;
|
||||
slotInfo.stages = stage;
|
||||
m_descriptorSlots.push_back(slotInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t DxvkDescriptorSlotMapping::getBindingId(uint32_t slot) {
|
||||
// This won't win a performance competition, but the number
|
||||
// of bindings used by a shader is usually much smaller than
|
||||
// the number of resource slots available to the system.
|
||||
for (uint32_t i = 0; i < m_descriptorSlots.size(); i++) {
|
||||
if (m_descriptorSlots.at(i).slot == slot)
|
||||
return i;
|
||||
}
|
||||
|
||||
return InvalidBinding;
|
||||
}
|
||||
|
||||
|
||||
DxvkBindingLayout::DxvkBindingLayout(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
uint32_t bindingCount,
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "dxvk_include.h"
|
||||
|
||||
namespace dxvk {
|
||||
@ -18,6 +20,69 @@ namespace dxvk {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Descriptor slot mapping
|
||||
*
|
||||
* Convenience class that generates descriptor slot
|
||||
* index to binding index mappings. This is required
|
||||
* when generating Vulkan pipeline and descriptor set
|
||||
* layouts.
|
||||
*/
|
||||
class DxvkDescriptorSlotMapping {
|
||||
constexpr static uint32_t InvalidBinding = 0xFFFFFFFFu;
|
||||
public:
|
||||
|
||||
DxvkDescriptorSlotMapping();
|
||||
~DxvkDescriptorSlotMapping();
|
||||
|
||||
/**
|
||||
* \brief Number of descriptor bindings
|
||||
* \returns Descriptor binding count
|
||||
*/
|
||||
uint32_t bindingCount() const {
|
||||
return m_descriptorSlots.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Descriptor binding infos
|
||||
* \returns Descriptor binding infos
|
||||
*/
|
||||
const DxvkDescriptorSlot* bindingInfos() const {
|
||||
return m_descriptorSlots.data();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Defines a new slot
|
||||
*
|
||||
* Adds a slot to the mapping. If the slot is already
|
||||
* defined by another shader stage, this will extend
|
||||
* the stage mask by the given stage. Otherwise, an
|
||||
* entirely new binding is added.
|
||||
* \param [in] slot Resource slot
|
||||
* \param [in] type Resource type
|
||||
* \param [in] stage Shader stage
|
||||
*/
|
||||
void defineSlot(
|
||||
uint32_t slot,
|
||||
VkDescriptorType type,
|
||||
VkShaderStageFlagBits stage);
|
||||
|
||||
/**
|
||||
* \brief Gets binding ID for a slot
|
||||
*
|
||||
* \param [in] slot Resource slot
|
||||
* \returns Binding index, or \c InvalidBinding
|
||||
*/
|
||||
uint32_t getBindingId(
|
||||
uint32_t slot);
|
||||
|
||||
private:
|
||||
|
||||
std::vector<DxvkDescriptorSlot> m_descriptorSlots;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Shader interface
|
||||
*
|
96
src/dxvk/dxvk_pipemanager.cpp
Normal file
96
src/dxvk/dxvk_pipemanager.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
#include "dxvk_pipemanager.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
size_t DxvkPipelineKeyHash::operator () (const DxvkComputePipelineKey& key) const {
|
||||
std::hash<DxvkShader*> hash;
|
||||
return hash(key.cs.ptr());
|
||||
}
|
||||
|
||||
|
||||
size_t DxvkPipelineKeyHash::operator () (const DxvkGraphicsPipelineKey& key) const {
|
||||
DxvkHashState state;
|
||||
|
||||
std::hash<DxvkShader*> hash;
|
||||
state.add(hash(key.vs.ptr()));
|
||||
state.add(hash(key.tcs.ptr()));
|
||||
state.add(hash(key.tes.ptr()));
|
||||
state.add(hash(key.gs.ptr()));
|
||||
state.add(hash(key.fs.ptr()));
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
bool DxvkPipelineKeyEq::operator () (const DxvkComputePipelineKey& a, const DxvkComputePipelineKey& b) const {
|
||||
return a.cs == b.cs;
|
||||
}
|
||||
|
||||
|
||||
bool DxvkPipelineKeyEq::operator () (const DxvkGraphicsPipelineKey& a, const DxvkGraphicsPipelineKey& b) const {
|
||||
return a.vs == b.vs
|
||||
&& a.tcs == b.tcs
|
||||
&& a.tes == b.tes
|
||||
&& a.gs == b.gs
|
||||
&& a.fs == b.fs;
|
||||
}
|
||||
|
||||
|
||||
DxvkPipelineManager::DxvkPipelineManager(const Rc<vk::DeviceFn>& vkd)
|
||||
: m_vkd(vkd) { }
|
||||
|
||||
|
||||
DxvkPipelineManager::~DxvkPipelineManager() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkComputePipeline> DxvkPipelineManager::createComputePipeline(
|
||||
const Rc<DxvkShader>& cs) {
|
||||
if (cs == nullptr)
|
||||
return nullptr;
|
||||
|
||||
DxvkComputePipelineKey key;
|
||||
key.cs = cs;
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
auto pair = m_computePipelines.find(key);
|
||||
|
||||
if (pair != m_computePipelines.end())
|
||||
return pair->second;
|
||||
|
||||
const Rc<DxvkComputePipeline> pipeline
|
||||
= new DxvkComputePipeline(m_vkd, cs);
|
||||
m_computePipelines.insert(std::make_pair(key, pipeline));
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkGraphicsPipeline> DxvkPipelineManager::createGraphicsPipeline(
|
||||
const Rc<DxvkShader>& vs,
|
||||
const Rc<DxvkShader>& tcs,
|
||||
const Rc<DxvkShader>& tes,
|
||||
const Rc<DxvkShader>& gs,
|
||||
const Rc<DxvkShader>& fs) {
|
||||
if (vs == nullptr)
|
||||
return nullptr;
|
||||
|
||||
DxvkGraphicsPipelineKey key;
|
||||
key.vs = vs;
|
||||
key.tcs = tcs;
|
||||
key.tes = tes;
|
||||
key.gs = gs;
|
||||
key.fs = fs;
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
auto pair = m_graphicsPipelines.find(key);
|
||||
|
||||
if (pair != m_graphicsPipelines.end())
|
||||
return pair->second;
|
||||
|
||||
const Rc<DxvkGraphicsPipeline> pipeline
|
||||
= new DxvkGraphicsPipeline(m_vkd, vs, tcs, tes, gs, fs);
|
||||
m_graphicsPipelines.insert(std::make_pair(key, pipeline));
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
}
|
118
src/dxvk/dxvk_pipemanager.h
Normal file
118
src/dxvk/dxvk_pipemanager.h
Normal file
@ -0,0 +1,118 @@
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "dxvk_compute.h"
|
||||
#include "dxvk_graphics.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief Compute pipeline key
|
||||
*
|
||||
* Identifier for a compute pipeline object.
|
||||
* Consists of the compute shader itself.
|
||||
*/
|
||||
struct DxvkComputePipelineKey {
|
||||
Rc<DxvkShader> cs;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Graphics pipeline key
|
||||
*
|
||||
* Identifier for a graphics pipeline object.
|
||||
* Consists of all graphics pipeline shaders.
|
||||
*/
|
||||
struct DxvkGraphicsPipelineKey {
|
||||
Rc<DxvkShader> vs;
|
||||
Rc<DxvkShader> tcs;
|
||||
Rc<DxvkShader> tes;
|
||||
Rc<DxvkShader> gs;
|
||||
Rc<DxvkShader> fs;
|
||||
};
|
||||
|
||||
|
||||
struct DxvkPipelineKeyHash {
|
||||
size_t operator () (const DxvkComputePipelineKey& key) const;
|
||||
size_t operator () (const DxvkGraphicsPipelineKey& key) const;
|
||||
};
|
||||
|
||||
|
||||
struct DxvkPipelineKeyEq {
|
||||
bool operator () (const DxvkComputePipelineKey& a, const DxvkComputePipelineKey& b) const;
|
||||
bool operator () (const DxvkGraphicsPipelineKey& a, const DxvkGraphicsPipelineKey& b) const;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Pipeline manager
|
||||
*
|
||||
* Creates and stores graphics pipelines and compute
|
||||
* pipelines for each combination of shaders that is
|
||||
* used within the application. This is necessary
|
||||
* because DXVK does not expose the concept of shader
|
||||
* pipeline objects to the client API.
|
||||
*/
|
||||
class DxvkPipelineManager : public RcObject {
|
||||
|
||||
public:
|
||||
|
||||
DxvkPipelineManager(
|
||||
const Rc<vk::DeviceFn>& vkd);
|
||||
~DxvkPipelineManager();
|
||||
|
||||
/**
|
||||
* \brief Retrieves a compute pipeline object
|
||||
*
|
||||
* If a pipeline for the given shader stage object
|
||||
* already exists, it will be returned. Otherwise,
|
||||
* a new pipeline will be created.
|
||||
* \param [in] cs Compute shader
|
||||
* \returns Compute pipeline object
|
||||
*/
|
||||
Rc<DxvkComputePipeline> createComputePipeline(
|
||||
const Rc<DxvkShader>& cs);
|
||||
|
||||
/**
|
||||
* \brief Retrieves a graphics pipeline object
|
||||
*
|
||||
* If a pipeline for the given shader stage objects
|
||||
* already exists, it will be returned. Otherwise,
|
||||
* a new pipeline 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 object
|
||||
*/
|
||||
Rc<DxvkGraphicsPipeline> createGraphicsPipeline(
|
||||
const Rc<DxvkShader>& vs,
|
||||
const Rc<DxvkShader>& tcs,
|
||||
const Rc<DxvkShader>& tes,
|
||||
const Rc<DxvkShader>& gs,
|
||||
const Rc<DxvkShader>& fs);
|
||||
|
||||
private:
|
||||
|
||||
const Rc<vk::DeviceFn> m_vkd;
|
||||
|
||||
std::mutex m_mutex;
|
||||
|
||||
std::unordered_map<
|
||||
DxvkComputePipelineKey,
|
||||
Rc<DxvkComputePipeline>,
|
||||
DxvkPipelineKeyHash,
|
||||
DxvkPipelineKeyEq> m_computePipelines;
|
||||
|
||||
std::unordered_map<
|
||||
DxvkGraphicsPipelineKey,
|
||||
Rc<DxvkGraphicsPipeline>,
|
||||
DxvkPipelineKeyHash,
|
||||
DxvkPipelineKeyEq> m_graphicsPipelines;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
DxvkShader::DxvkShader(
|
||||
DxvkShaderModule::DxvkShaderModule(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
VkShaderStageFlagBits stage,
|
||||
const SpirvCodeBuffer& code)
|
||||
@ -20,13 +20,13 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
DxvkShader::~DxvkShader() {
|
||||
DxvkShaderModule::~DxvkShaderModule() {
|
||||
m_vkd->vkDestroyShaderModule(
|
||||
m_vkd->device(), m_module, nullptr);
|
||||
}
|
||||
|
||||
|
||||
VkPipelineShaderStageCreateInfo DxvkShader::stageInfo() const {
|
||||
VkPipelineShaderStageCreateInfo DxvkShaderModule::stageInfo() const {
|
||||
VkPipelineShaderStageCreateInfo info;
|
||||
|
||||
info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
@ -39,4 +39,35 @@ namespace dxvk {
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
DxvkShader::DxvkShader(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
VkShaderStageFlagBits stage,
|
||||
uint32_t slotCount,
|
||||
const DxvkResourceSlot* slotInfos,
|
||||
const SpirvCodeBuffer& code)
|
||||
: m_vkd(vkd), m_stage(stage), m_code(code) {
|
||||
for (uint32_t i = 0; i < slotCount; i++)
|
||||
m_slots.push_back(slotInfos[i]);
|
||||
}
|
||||
|
||||
|
||||
DxvkShader::~DxvkShader() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DxvkShader::defineResourceSlots(
|
||||
DxvkDescriptorSlotMapping& mapping) const {
|
||||
for (const auto& slot : m_slots)
|
||||
mapping.defineSlot(slot.slot, slot.type, m_stage);
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkShaderModule> DxvkShader::createShaderModule(
|
||||
const DxvkDescriptorSlotMapping& mapping) const {
|
||||
// TODO apply mapping
|
||||
return new DxvkShaderModule(m_vkd, m_stage, m_code);
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "dxvk_include.h"
|
||||
#include "dxvk_pipelayout.h"
|
||||
|
||||
#include "../spirv/spirv_code_buffer.h"
|
||||
|
||||
@ -15,30 +16,31 @@ namespace dxvk {
|
||||
* binding that a shader can access.
|
||||
*/
|
||||
struct DxvkResourceSlot {
|
||||
uint32_t binding;
|
||||
uint32_t slot;
|
||||
VkDescriptorType type;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Shader module
|
||||
* \brief Shader module object
|
||||
*
|
||||
* Manages a Vulkan shader module. This will not
|
||||
* perform any sort of shader compilation. Instead,
|
||||
* the context will create pipeline objects on the
|
||||
* perform any shader compilation. Instead, the
|
||||
* context will create pipeline objects on the
|
||||
* fly when executing draw calls.
|
||||
*/
|
||||
class DxvkShader : public RcObject {
|
||||
class DxvkShaderModule : public RcObject {
|
||||
|
||||
public:
|
||||
|
||||
DxvkShader(
|
||||
DxvkShaderModule(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
VkShaderStageFlagBits stage,
|
||||
const SpirvCodeBuffer& code);
|
||||
~DxvkShader();
|
||||
|
||||
VkShaderModule module() const {
|
||||
~DxvkShaderModule();
|
||||
|
||||
VkShaderModule handle() const {
|
||||
return m_module;
|
||||
}
|
||||
|
||||
@ -52,4 +54,51 @@ namespace dxvk {
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Shader object
|
||||
*
|
||||
* Stores a SPIR-V shader and information on the
|
||||
* bindings that the shader uses. In order to use
|
||||
* the shader with a pipeline, a shader module
|
||||
* needs to be created from he shader object.
|
||||
*/
|
||||
class DxvkShader : public RcObject {
|
||||
|
||||
public:
|
||||
|
||||
DxvkShader(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
VkShaderStageFlagBits stage,
|
||||
uint32_t slotCount,
|
||||
const DxvkResourceSlot* slotInfos,
|
||||
const SpirvCodeBuffer& code);
|
||||
~DxvkShader();
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
void defineResourceSlots(
|
||||
DxvkDescriptorSlotMapping& mapping) const;
|
||||
|
||||
/**
|
||||
* \brief Creates a shader module
|
||||
*
|
||||
* Maps the binding slot numbers
|
||||
* \param [in] mapping Resource slot mapping
|
||||
* \returns The shader module
|
||||
*/
|
||||
Rc<DxvkShaderModule> createShaderModule(
|
||||
const DxvkDescriptorSlotMapping& mapping) const;
|
||||
|
||||
private:
|
||||
|
||||
Rc<vk::DeviceFn> m_vkd;
|
||||
VkShaderStageFlagBits m_stage;
|
||||
SpirvCodeBuffer m_code;
|
||||
|
||||
std::vector<DxvkResourceSlot> m_slots;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -16,7 +16,8 @@ dxvk_src = files([
|
||||
'dxvk_lifetime.cpp',
|
||||
'dxvk_main.cpp',
|
||||
'dxvk_memory.cpp',
|
||||
'dxvk_pipeline.cpp',
|
||||
'dxvk_pipelayout.cpp',
|
||||
'dxvk_pipemanager.cpp',
|
||||
'dxvk_renderpass.cpp',
|
||||
'dxvk_resource.cpp',
|
||||
'dxvk_sampler.cpp',
|
||||
|
@ -29,7 +29,7 @@ namespace dxvk {
|
||||
*/
|
||||
spv::Op opCode() const {
|
||||
return static_cast<spv::Op>(
|
||||
m_code[0] & spv::OpCodeMask);
|
||||
this->arg(0) & spv::OpCodeMask);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -37,7 +37,7 @@ namespace dxvk {
|
||||
* \returns Number of DWORDs
|
||||
*/
|
||||
uint32_t length() const {
|
||||
return m_code[0] >> spv::WordCountShift;
|
||||
return this->arg(0) >> spv::WordCountShift;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -113,18 +113,12 @@ public:
|
||||
0, nullptr));
|
||||
|
||||
m_dxvkVertexShader = m_dxvkDevice->createShader(
|
||||
VK_SHADER_STAGE_VERTEX_BIT,
|
||||
VK_SHADER_STAGE_VERTEX_BIT, 0, nullptr,
|
||||
SpirvCodeBuffer(_countof(vsCode), vsCode));
|
||||
|
||||
m_dxvkFragmentShader = m_dxvkDevice->createShader(
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT, 0, nullptr,
|
||||
SpirvCodeBuffer(_countof(fsCode), fsCode));
|
||||
|
||||
m_dxvkBindingLayout = m_dxvkDevice->createBindingLayout(0, nullptr);
|
||||
|
||||
m_dxvkPipeline = m_dxvkDevice->createGraphicsPipeline(m_dxvkBindingLayout,
|
||||
m_dxvkVertexShader, nullptr, nullptr, nullptr, m_dxvkFragmentShader);
|
||||
|
||||
m_dxvkContext->bindGraphicsPipeline(m_dxvkPipeline);
|
||||
}
|
||||
|
||||
~TriangleApp() {
|
||||
@ -158,6 +152,14 @@ public:
|
||||
|
||||
m_dxvkContext->setViewports(1, &viewport, &scissor);
|
||||
|
||||
m_dxvkContext->bindShader(
|
||||
VK_SHADER_STAGE_VERTEX_BIT,
|
||||
m_dxvkVertexShader);
|
||||
|
||||
m_dxvkContext->bindShader(
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
m_dxvkFragmentShader);
|
||||
|
||||
VkClearAttachment clearAttachment;
|
||||
clearAttachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
clearAttachment.colorAttachment = 0;
|
||||
@ -198,10 +200,8 @@ private:
|
||||
Rc<DxvkSwapchain> m_dxvkSwapchain;
|
||||
Rc<DxvkContext> m_dxvkContext;
|
||||
|
||||
Rc<DxvkShader> m_dxvkVertexShader;
|
||||
Rc<DxvkShader> m_dxvkFragmentShader;
|
||||
Rc<DxvkBindingLayout> m_dxvkBindingLayout;
|
||||
Rc<DxvkGraphicsPipeline> m_dxvkPipeline;
|
||||
Rc<DxvkShader> m_dxvkVertexShader;
|
||||
Rc<DxvkShader> m_dxvkFragmentShader;
|
||||
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
lib_d3d11 = dxvk_compiler.find_library('d3d11')
|
||||
lib_dxgi = dxvk_compiler.find_library('dxgi')
|
||||
lib_d3dcompiler_47 = dxvk_compiler.find_library('d3dcompiler_47')
|
||||
lib_d3dcompiler_47 = dxvk_compiler.find_library('d3dcompiler')
|
||||
|
||||
subdir('d3d11')
|
||||
subdir('dxbc')
|
||||
|
Loading…
x
Reference in New Issue
Block a user