mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-15 07:29:17 +01:00
[dxvk] Implemented shader resource binding
This commit is contained in:
parent
a6bf7659b0
commit
b5d068366d
@ -33,6 +33,26 @@ namespace dxvk {
|
|||||||
m_acquireSync = m_device->createSemaphore();
|
m_acquireSync = m_device->createSemaphore();
|
||||||
m_presentSync = m_device->createSemaphore();
|
m_presentSync = m_device->createSemaphore();
|
||||||
|
|
||||||
|
// Sampler for presentation
|
||||||
|
DxvkSamplerCreateInfo samplerInfo;
|
||||||
|
samplerInfo.magFilter = VK_FILTER_NEAREST;
|
||||||
|
samplerInfo.minFilter = VK_FILTER_NEAREST;
|
||||||
|
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||||
|
samplerInfo.mipmapLodBias = 0.0f;
|
||||||
|
samplerInfo.mipmapLodMin = 0.0f;
|
||||||
|
samplerInfo.mipmapLodMax = 0.0f;
|
||||||
|
samplerInfo.useAnisotropy = VK_FALSE;
|
||||||
|
samplerInfo.maxAnisotropy = 1.0f;
|
||||||
|
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||||
|
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||||
|
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||||
|
samplerInfo.compareToDepth = VK_FALSE;
|
||||||
|
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||||
|
samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||||
|
samplerInfo.usePixelCoord = VK_FALSE;
|
||||||
|
|
||||||
|
m_sampler = m_device->createSampler(samplerInfo);
|
||||||
|
|
||||||
// Set up context state. The shader bindings and the
|
// Set up context state. The shader bindings and the
|
||||||
// constant state objects will never be modified.
|
// constant state objects will never be modified.
|
||||||
m_context->bindGraphicsPipeline(createPipeline());
|
m_context->bindGraphicsPipeline(createPipeline());
|
||||||
@ -133,9 +153,12 @@ namespace dxvk {
|
|||||||
|
|
||||||
m_context->setViewports(1, &viewport, &scissor);
|
m_context->setViewports(1, &viewport, &scissor);
|
||||||
|
|
||||||
// TODO bind back buffer as a shader resource
|
m_context->bindResourceSampler(
|
||||||
// m_context->bindSampler(0, m_sampler);
|
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
// m_context->bindSampledImage(1, view);
|
BindingIds::Sampler, m_sampler);
|
||||||
|
m_context->bindResourceImage(
|
||||||
|
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
|
BindingIds::Texture, view);
|
||||||
m_context->draw(4, 1, 0, 0);
|
m_context->draw(4, 1, 0, 0);
|
||||||
|
|
||||||
m_device->submitCommandList(
|
m_device->submitCommandList(
|
||||||
@ -279,10 +302,26 @@ namespace dxvk {
|
|||||||
uint32_t typeVec2 = module.defVectorType(typeF32, 2);
|
uint32_t typeVec2 = module.defVectorType(typeF32, 2);
|
||||||
uint32_t typeVec4 = module.defVectorType(typeF32, 4);
|
uint32_t typeVec4 = module.defVectorType(typeF32, 4);
|
||||||
uint32_t typeFn = module.defFunctionType(typeVoid, 0, nullptr);
|
uint32_t typeFn = module.defFunctionType(typeVoid, 0, nullptr);
|
||||||
|
uint32_t typeSampler = module.defSamplerType();
|
||||||
|
uint32_t typeTexture = module.defImageType(
|
||||||
|
typeF32, spv::Dim2D, 0, 0, 0, 1, spv::ImageFormatUnknown);
|
||||||
|
uint32_t typeSampledTex = module.defSampledImageType(typeTexture);
|
||||||
|
|
||||||
// Pointer type definitions
|
// Pointer type definitions
|
||||||
uint32_t ptrInputVec2 = module.defPointerType(typeVec2, spv::StorageClassInput);
|
uint32_t ptrInputVec2 = module.defPointerType(typeVec2, spv::StorageClassInput);
|
||||||
uint32_t ptrOutputVec4 = module.defPointerType(typeVec4, spv::StorageClassOutput);
|
uint32_t ptrOutputVec4 = module.defPointerType(typeVec4, spv::StorageClassOutput);
|
||||||
|
uint32_t ptrSampler = module.defPointerType(typeSampler, spv::StorageClassUniformConstant);
|
||||||
|
uint32_t ptrTexture = module.defPointerType(typeTexture, spv::StorageClassUniformConstant);
|
||||||
|
|
||||||
|
// Sampler
|
||||||
|
uint32_t rcSampler = module.newVar(ptrSampler, spv::StorageClassUniformConstant);
|
||||||
|
module.decorateDescriptorSet(rcSampler, 0);
|
||||||
|
module.decorateBinding(rcSampler, BindingIds::Sampler);
|
||||||
|
|
||||||
|
// Texture
|
||||||
|
uint32_t rcTexture = module.newVar(ptrTexture, spv::StorageClassUniformConstant);
|
||||||
|
module.decorateDescriptorSet(rcTexture, 0);
|
||||||
|
module.decorateBinding(rcTexture, BindingIds::Texture);
|
||||||
|
|
||||||
// Input variable: Texture coordinates
|
// Input variable: Texture coordinates
|
||||||
uint32_t inTexCoord = module.newVar(
|
uint32_t inTexCoord = module.newVar(
|
||||||
@ -299,13 +338,14 @@ namespace dxvk {
|
|||||||
module.opLabel(module.allocateId());
|
module.opLabel(module.allocateId());
|
||||||
|
|
||||||
// Load texture coordinates
|
// Load texture coordinates
|
||||||
uint32_t tmpTexCoord = module.opLoad(typeVec2, inTexCoord);
|
module.opStore(outColor,
|
||||||
|
module.opImageSampleImplicitLod(
|
||||||
// Compute final color
|
typeVec4,
|
||||||
uint32_t swizzleIndices[4] = { 0, 1, 2, 3 };
|
module.opSampledImage(
|
||||||
uint32_t tmpColor = module.opVectorShuffle(
|
typeSampledTex,
|
||||||
typeVec4, tmpTexCoord, tmpTexCoord, 4, swizzleIndices);
|
module.opLoad(typeTexture, rcTexture),
|
||||||
module.opStore(outColor, tmpColor);
|
module.opLoad(typeSampler, rcSampler)),
|
||||||
|
module.opLoad(typeVec2, inTexCoord)));
|
||||||
|
|
||||||
module.opReturn();
|
module.opReturn();
|
||||||
module.functionEnd();
|
module.functionEnd();
|
||||||
@ -325,12 +365,14 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
Rc<DxvkBindingLayout> DxgiPresenter::createBindingLayout() {
|
Rc<DxvkBindingLayout> DxgiPresenter::createBindingLayout() {
|
||||||
std::array<DxvkBindingInfo, 2> bindings;
|
std::array<DxvkDescriptorSlot, 2> bindings;
|
||||||
bindings.at(0).type = VK_DESCRIPTOR_TYPE_SAMPLER;
|
bindings.at(BindingIds::Sampler).slot = BindingIds::Sampler;
|
||||||
bindings.at(0).stages = VK_SHADER_STAGE_FRAGMENT_BIT;
|
bindings.at(BindingIds::Sampler).type = VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||||
|
bindings.at(BindingIds::Sampler).stages = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
|
||||||
bindings.at(1).type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
bindings.at(BindingIds::Texture).slot = BindingIds::Texture;
|
||||||
bindings.at(1).stages = VK_SHADER_STAGE_FRAGMENT_BIT;
|
bindings.at(BindingIds::Texture).type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||||
|
bindings.at(BindingIds::Texture).stages = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
|
||||||
return m_device->createBindingLayout(
|
return m_device->createBindingLayout(
|
||||||
bindings.size(), bindings.data());
|
bindings.size(), bindings.data());
|
||||||
|
@ -43,6 +43,11 @@ namespace dxvk {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
enum BindingIds : uint32_t {
|
||||||
|
Sampler = 0,
|
||||||
|
Texture = 1,
|
||||||
|
};
|
||||||
|
|
||||||
Rc<DxvkDevice> m_device;
|
Rc<DxvkDevice> m_device;
|
||||||
Rc<DxvkContext> m_context;
|
Rc<DxvkContext> m_context;
|
||||||
|
|
||||||
@ -52,6 +57,8 @@ namespace dxvk {
|
|||||||
Rc<DxvkSemaphore> m_acquireSync;
|
Rc<DxvkSemaphore> m_acquireSync;
|
||||||
Rc<DxvkSemaphore> m_presentSync;
|
Rc<DxvkSemaphore> m_presentSync;
|
||||||
|
|
||||||
|
Rc<DxvkSampler> m_sampler;
|
||||||
|
|
||||||
Rc<DxvkShader> createVertexShader();
|
Rc<DxvkShader> createVertexShader();
|
||||||
Rc<DxvkShader> createFragmentShader();
|
Rc<DxvkShader> createFragmentShader();
|
||||||
|
|
||||||
|
@ -45,9 +45,6 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set initial window mode and fullscreen state
|
// Set initial window mode and fullscreen state
|
||||||
if (FAILED(this->ResizeTarget(&pDesc->BufferDesc)))
|
|
||||||
throw DxvkError("DxgiSwapChain::DxgiSwapChain: Failed to set initial display mode");
|
|
||||||
|
|
||||||
if (FAILED(this->SetFullscreenState(!pDesc->Windowed, nullptr)))
|
if (FAILED(this->SetFullscreenState(!pDesc->Windowed, nullptr)))
|
||||||
throw DxvkError("DxgiSwapChain::DxgiSwapChain: Failed to set initial fullscreen state");
|
throw DxvkError("DxgiSwapChain::DxgiSwapChain: Failed to set initial fullscreen state");
|
||||||
|
|
||||||
@ -319,7 +316,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkImageCreateInfo imageInfo;
|
DxvkImageCreateInfo imageInfo;
|
||||||
imageInfo.type = VK_IMAGE_TYPE_2D;
|
imageInfo.type = VK_IMAGE_TYPE_2D;
|
||||||
imageInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
|
imageInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
|
||||||
imageInfo.sampleCount = VK_SAMPLE_COUNT_1_BIT;
|
imageInfo.sampleCount = VK_SAMPLE_COUNT_1_BIT;
|
||||||
imageInfo.extent.width = m_desc.BufferDesc.Width;
|
imageInfo.extent.width = m_desc.BufferDesc.Width;
|
||||||
imageInfo.extent.height = m_desc.BufferDesc.Height;
|
imageInfo.extent.height = m_desc.BufferDesc.Height;
|
||||||
|
61
src/dxvk/dxvk_binding.h
Normal file
61
src/dxvk/dxvk_binding.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dxvk_buffer.h"
|
||||||
|
#include "dxvk_descriptor.h"
|
||||||
|
#include "dxvk_image.h"
|
||||||
|
#include "dxvk_sampler.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Bound shader resource
|
||||||
|
*/
|
||||||
|
struct DxvkShaderResourceSlot {
|
||||||
|
Rc<DxvkSampler> sampler;
|
||||||
|
Rc<DxvkImageView> imageView;
|
||||||
|
Rc<DxvkBufferView> bufferView;
|
||||||
|
DxvkBufferBinding bufferSlice;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Shader resource slots
|
||||||
|
*/
|
||||||
|
class DxvkShaderResourceSlots {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DxvkShaderResourceSlots() { }
|
||||||
|
DxvkShaderResourceSlots(size_t n) {
|
||||||
|
m_resources .resize(n);
|
||||||
|
m_descriptors.resize(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t descriptorCount() const {
|
||||||
|
return m_descriptors.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const DxvkDescriptorInfo* descriptors() const {
|
||||||
|
return m_descriptors.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
const DxvkShaderResourceSlot& getShaderResource(uint32_t slot) const {
|
||||||
|
return m_resources.at(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bindShaderResource(
|
||||||
|
uint32_t slot,
|
||||||
|
const DxvkShaderResourceSlot& resource,
|
||||||
|
const DxvkDescriptorInfo& descriptor) {
|
||||||
|
m_resources .at(slot) = resource;
|
||||||
|
m_descriptors .at(slot) = descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::vector<DxvkShaderResourceSlot> m_resources;
|
||||||
|
std::vector<DxvkDescriptorInfo> m_descriptors;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -60,7 +60,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
DxvkBufferView::~DxvkBufferView() {
|
DxvkBufferView::~DxvkBufferView() {
|
||||||
|
m_vkd->vkDestroyBufferView(
|
||||||
|
m_vkd->device(), m_view, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -12,7 +12,6 @@ namespace dxvk {
|
|||||||
* passed to \ref DxvkDevice::createBuffer
|
* passed to \ref DxvkDevice::createBuffer
|
||||||
*/
|
*/
|
||||||
struct DxvkBufferCreateInfo {
|
struct DxvkBufferCreateInfo {
|
||||||
|
|
||||||
/// Size of the buffer, in bytes
|
/// Size of the buffer, in bytes
|
||||||
VkDeviceSize size;
|
VkDeviceSize size;
|
||||||
|
|
||||||
@ -25,7 +24,6 @@ namespace dxvk {
|
|||||||
|
|
||||||
/// Allowed access patterns
|
/// Allowed access patterns
|
||||||
VkAccessFlags access;
|
VkAccessFlags access;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -36,7 +34,6 @@ namespace dxvk {
|
|||||||
* are to \ref DxvkDevice::createBufferView
|
* are to \ref DxvkDevice::createBufferView
|
||||||
*/
|
*/
|
||||||
struct DxvkBufferViewCreateInfo {
|
struct DxvkBufferViewCreateInfo {
|
||||||
|
|
||||||
/// Buffer data format, like image data
|
/// Buffer data format, like image data
|
||||||
VkFormat format;
|
VkFormat format;
|
||||||
|
|
||||||
|
@ -91,6 +91,51 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkCommandList::bindResourceDescriptors(
|
||||||
|
VkPipelineBindPoint pipeline,
|
||||||
|
VkPipelineLayout pipelineLayout,
|
||||||
|
VkDescriptorSetLayout descriptorLayout,
|
||||||
|
uint32_t descriptorCount,
|
||||||
|
const DxvkDescriptorSlot* descriptorSlots,
|
||||||
|
const DxvkDescriptorInfo* descriptorInfos) {
|
||||||
|
|
||||||
|
// Allocate a new descriptor set
|
||||||
|
VkDescriptorSet dset = m_descAlloc.alloc(descriptorLayout);
|
||||||
|
|
||||||
|
// Write data to the descriptor set
|
||||||
|
// TODO recycle vector as a class member
|
||||||
|
std::vector<VkWriteDescriptorSet> descriptorWrites;
|
||||||
|
descriptorWrites.resize(descriptorCount);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < descriptorCount; i++) {
|
||||||
|
auto& curr = descriptorWrites.at(i);
|
||||||
|
auto& binding = descriptorSlots[i];
|
||||||
|
|
||||||
|
curr.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
curr.pNext = nullptr;
|
||||||
|
curr.dstSet = dset;
|
||||||
|
curr.dstBinding = i;
|
||||||
|
curr.dstArrayElement = 0;
|
||||||
|
curr.descriptorCount = 1;
|
||||||
|
curr.descriptorType = binding.type;
|
||||||
|
curr.pImageInfo = &descriptorInfos[binding.slot].image;
|
||||||
|
curr.pBufferInfo = &descriptorInfos[binding.slot].buffer;
|
||||||
|
curr.pTexelBufferView = &descriptorInfos[binding.slot].texelBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_vkd->vkUpdateDescriptorSets(
|
||||||
|
m_vkd->device(),
|
||||||
|
descriptorWrites.size(),
|
||||||
|
descriptorWrites.data(),
|
||||||
|
0, nullptr);
|
||||||
|
|
||||||
|
// Bind descriptor set to the pipeline
|
||||||
|
m_vkd->vkCmdBindDescriptorSets(m_buffer,
|
||||||
|
pipeline, pipelineLayout, 0, 1,
|
||||||
|
&dset, 0, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkCommandList::cmdBeginRenderPass(
|
void DxvkCommandList::cmdBeginRenderPass(
|
||||||
const VkRenderPassBeginInfo* pRenderPassBegin,
|
const VkRenderPassBeginInfo* pRenderPassBegin,
|
||||||
VkSubpassContents contents) {
|
VkSubpassContents contents) {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "dxvk_descriptor.h"
|
#include "dxvk_descriptor.h"
|
||||||
#include "dxvk_lifetime.h"
|
#include "dxvk_lifetime.h"
|
||||||
|
#include "dxvk_pipeline.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
@ -76,6 +77,14 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
void bindResourceDescriptors(
|
||||||
|
VkPipelineBindPoint pipeline,
|
||||||
|
VkPipelineLayout pipelineLayout,
|
||||||
|
VkDescriptorSetLayout descriptorLayout,
|
||||||
|
uint32_t descriptorCount,
|
||||||
|
const DxvkDescriptorSlot* descriptorSlots,
|
||||||
|
const DxvkDescriptorInfo* descriptorInfos);
|
||||||
|
|
||||||
void cmdBeginRenderPass(
|
void cmdBeginRenderPass(
|
||||||
const VkRenderPassBeginInfo* pRenderPassBegin,
|
const VkRenderPassBeginInfo* pRenderPassBegin,
|
||||||
VkSubpassContents contents);
|
VkSubpassContents contents);
|
||||||
|
@ -14,7 +14,7 @@ namespace dxvk {
|
|||||||
info.pNext = nullptr;
|
info.pNext = nullptr;
|
||||||
info.flags = 0;
|
info.flags = 0;
|
||||||
info.stage = cs->stageInfo();
|
info.stage = cs->stageInfo();
|
||||||
info.layout = this->pipelineLayout();
|
info.layout = m_layout->pipelineLayout();
|
||||||
info.basePipelineHandle = VK_NULL_HANDLE;
|
info.basePipelineHandle = VK_NULL_HANDLE;
|
||||||
info.basePipelineIndex = 0;
|
info.basePipelineIndex = 0;
|
||||||
|
|
||||||
|
@ -25,25 +25,15 @@ namespace dxvk {
|
|||||||
~DxvkComputePipeline();
|
~DxvkComputePipeline();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Descriptor set layout
|
* \brief Pipeline layout
|
||||||
*
|
*
|
||||||
* The descriptor set layout for this pipeline.
|
* Stores the pipeline layout and the descriptor set
|
||||||
* Use this to allocate new descriptor sets.
|
* layout, as well as information on the resource
|
||||||
* \returns The descriptor set layout
|
* slots used by the pipeline.
|
||||||
|
* \returns Pipeline layout
|
||||||
*/
|
*/
|
||||||
VkDescriptorSetLayout descriptorSetLayout() const {
|
Rc<DxvkBindingLayout> layout() const {
|
||||||
return m_layout->descriptorSetLayout();
|
return m_layout;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Pipeline layout layout
|
|
||||||
*
|
|
||||||
* The pipeline layout for this pipeline.
|
|
||||||
* Use this to bind descriptor sets.
|
|
||||||
* \returns The descriptor set layout
|
|
||||||
*/
|
|
||||||
VkPipelineLayout pipelineLayout() const {
|
|
||||||
return m_layout->pipelineLayout();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,6 +53,32 @@ 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(
|
void DxvkContext::bindIndexBuffer(
|
||||||
const DxvkBufferBinding& buffer) {
|
const DxvkBufferBinding& buffer) {
|
||||||
if (m_state.vi.indexBuffer != buffer) {
|
if (m_state.vi.indexBuffer != buffer) {
|
||||||
@ -62,25 +88,93 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::bindComputePipeline(
|
void DxvkContext::bindResourceBuffer(
|
||||||
const Rc<DxvkComputePipeline>& pipeline) {
|
VkPipelineBindPoint pipe,
|
||||||
m_state.cp = pipeline;
|
uint32_t slot,
|
||||||
|
const DxvkBufferBinding& buffer) {
|
||||||
|
auto rc = this->getShaderResourceSlots(pipe);
|
||||||
|
|
||||||
m_flags.set(
|
if (rc->getShaderResource(slot).bufferSlice != buffer) {
|
||||||
DxvkContextFlag::CpDirtyPipeline,
|
m_flags.set(this->getResourceDirtyFlag(pipe));
|
||||||
DxvkContextFlag::CpDirtyResources);
|
|
||||||
|
DxvkShaderResourceSlot resource;
|
||||||
|
resource.bufferSlice = buffer;
|
||||||
|
|
||||||
|
DxvkDescriptorInfo descriptor;
|
||||||
|
|
||||||
|
if (buffer.bufferHandle() != VK_NULL_HANDLE)
|
||||||
|
descriptor.buffer = buffer.descriptorInfo();
|
||||||
|
|
||||||
|
rc->bindShaderResource(slot, resource, descriptor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::bindGraphicsPipeline(
|
void DxvkContext::bindResourceTexelBuffer(
|
||||||
const Rc<DxvkGraphicsPipeline>& pipeline) {
|
VkPipelineBindPoint pipe,
|
||||||
m_state.gp = pipeline;
|
uint32_t slot,
|
||||||
|
const Rc<DxvkBufferView>& bufferView) {
|
||||||
|
auto rc = this->getShaderResourceSlots(pipe);
|
||||||
|
|
||||||
m_flags.set(
|
if (rc->getShaderResource(slot).bufferView != bufferView) {
|
||||||
DxvkContextFlag::GpDirtyPipeline,
|
m_flags.set(this->getResourceDirtyFlag(pipe));
|
||||||
DxvkContextFlag::GpDirtyResources,
|
|
||||||
DxvkContextFlag::GpDirtyVertexBuffers,
|
DxvkShaderResourceSlot resource;
|
||||||
DxvkContextFlag::GpDirtyIndexBuffer);
|
resource.bufferView = bufferView;
|
||||||
|
|
||||||
|
DxvkDescriptorInfo descriptor;
|
||||||
|
|
||||||
|
if (bufferView != nullptr)
|
||||||
|
descriptor.texelBuffer = bufferView->handle();
|
||||||
|
|
||||||
|
rc->bindShaderResource(slot, resource, descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkContext::bindResourceImage(
|
||||||
|
VkPipelineBindPoint pipe,
|
||||||
|
uint32_t slot,
|
||||||
|
const Rc<DxvkImageView>& image) {
|
||||||
|
auto rc = this->getShaderResourceSlots(pipe);
|
||||||
|
|
||||||
|
if (rc->getShaderResource(slot).imageView != image) {
|
||||||
|
m_flags.set(this->getResourceDirtyFlag(pipe));
|
||||||
|
|
||||||
|
DxvkShaderResourceSlot resource;
|
||||||
|
resource.imageView = image;
|
||||||
|
|
||||||
|
DxvkDescriptorInfo descriptor;
|
||||||
|
|
||||||
|
if (image != nullptr) {
|
||||||
|
descriptor.image.imageView = image->handle();
|
||||||
|
descriptor.image.imageLayout = image->imageLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
rc->bindShaderResource(slot, resource, descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkContext::bindResourceSampler(
|
||||||
|
VkPipelineBindPoint pipe,
|
||||||
|
uint32_t slot,
|
||||||
|
const Rc<DxvkSampler>& sampler) {
|
||||||
|
auto rc = this->getShaderResourceSlots(pipe);
|
||||||
|
|
||||||
|
if (rc->getShaderResource(slot).sampler != sampler) {
|
||||||
|
m_flags.set(this->getResourceDirtyFlag(pipe));
|
||||||
|
|
||||||
|
DxvkShaderResourceSlot resource;
|
||||||
|
resource.sampler = sampler;
|
||||||
|
|
||||||
|
DxvkDescriptorInfo descriptor;
|
||||||
|
|
||||||
|
if (sampler != nullptr)
|
||||||
|
descriptor.image.sampler = sampler->handle();
|
||||||
|
|
||||||
|
rc->bindShaderResource(slot, resource, descriptor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -166,6 +260,8 @@ namespace dxvk {
|
|||||||
this->commitComputeState();
|
this->commitComputeState();
|
||||||
|
|
||||||
m_cmd->cmdDispatch(x, y, z);
|
m_cmd->cmdDispatch(x, y, z);
|
||||||
|
|
||||||
|
this->commitComputeBarriers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -335,12 +431,18 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::bindComputePipeline() {
|
void DxvkContext::updateComputePipeline() {
|
||||||
// TODO implement
|
if (m_flags.test(DxvkContextFlag::CpDirtyPipeline)) {
|
||||||
|
m_flags.clr(DxvkContextFlag::CpDirtyPipeline);
|
||||||
|
|
||||||
|
m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||||
|
m_state.cPipe->getPipelineHandle());
|
||||||
|
m_cmd->trackResource(m_state.cPipe);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::bindGraphicsPipeline() {
|
void DxvkContext::updateGraphicsPipeline() {
|
||||||
if (m_flags.test(DxvkContextFlag::GpDirtyPipeline)) {
|
if (m_flags.test(DxvkContextFlag::GpDirtyPipeline)) {
|
||||||
m_flags.clr(DxvkContextFlag::GpDirtyPipeline);
|
m_flags.clr(DxvkContextFlag::GpDirtyPipeline);
|
||||||
|
|
||||||
@ -355,8 +457,42 @@ namespace dxvk {
|
|||||||
gpState.viewportCount = m_state.vp.viewportCount;
|
gpState.viewportCount = m_state.vp.viewportCount;
|
||||||
|
|
||||||
m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,
|
m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
m_state.gp->getPipelineHandle(gpState));
|
m_state.gPipe->getPipelineHandle(gpState));
|
||||||
m_cmd->trackResource(m_state.gp);
|
m_cmd->trackResource(m_state.gPipe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkContext::updateComputeShaderResources() {
|
||||||
|
if (m_flags.test(DxvkContextFlag::CpDirtyResources)) {
|
||||||
|
m_flags.clr(DxvkContextFlag::CpDirtyResources);
|
||||||
|
|
||||||
|
auto layout = m_state.cPipe->layout();
|
||||||
|
|
||||||
|
m_cmd->bindResourceDescriptors(
|
||||||
|
VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||||
|
layout->pipelineLayout(),
|
||||||
|
layout->descriptorSetLayout(),
|
||||||
|
layout->bindingCount(),
|
||||||
|
layout->bindings(),
|
||||||
|
m_cResources.descriptors());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkContext::updateGraphicsShaderResources() {
|
||||||
|
if (m_flags.test(DxvkContextFlag::GpDirtyResources)) {
|
||||||
|
m_flags.clr(DxvkContextFlag::GpDirtyResources);
|
||||||
|
|
||||||
|
auto layout = m_state.gPipe->layout();
|
||||||
|
|
||||||
|
m_cmd->bindResourceDescriptors(
|
||||||
|
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
|
layout->pipelineLayout(),
|
||||||
|
layout->descriptorSetLayout(),
|
||||||
|
layout->bindingCount(),
|
||||||
|
layout->bindings(),
|
||||||
|
m_gResources.descriptors());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,16 +549,41 @@ namespace dxvk {
|
|||||||
|
|
||||||
void DxvkContext::commitComputeState() {
|
void DxvkContext::commitComputeState() {
|
||||||
this->renderPassEnd();
|
this->renderPassEnd();
|
||||||
this->bindComputePipeline();
|
this->updateComputePipeline();
|
||||||
|
this->updateComputeShaderResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::commitGraphicsState() {
|
void DxvkContext::commitGraphicsState() {
|
||||||
this->renderPassBegin();
|
this->renderPassBegin();
|
||||||
this->bindGraphicsPipeline();
|
this->updateGraphicsPipeline();
|
||||||
this->updateDynamicState();
|
this->updateDynamicState();
|
||||||
this->updateIndexBufferBinding();
|
this->updateIndexBufferBinding();
|
||||||
this->updateVertexBufferBindings();
|
this->updateVertexBufferBindings();
|
||||||
|
this->updateGraphicsShaderResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkContext::commitComputeBarriers() {
|
||||||
|
// TODO implement
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkShaderResourceSlots* DxvkContext::getShaderResourceSlots(VkPipelineBindPoint pipe) {
|
||||||
|
switch (pipe) {
|
||||||
|
case VK_PIPELINE_BIND_POINT_GRAPHICS: return &m_gResources;
|
||||||
|
case VK_PIPELINE_BIND_POINT_COMPUTE : return &m_cResources;
|
||||||
|
default: return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkContextFlag DxvkContext::getResourceDirtyFlag(VkPipelineBindPoint pipe) const {
|
||||||
|
switch (pipe) {
|
||||||
|
default:
|
||||||
|
case VK_PIPELINE_BIND_POINT_GRAPHICS: return DxvkContextFlag::GpDirtyResources;
|
||||||
|
case VK_PIPELINE_BIND_POINT_COMPUTE : return DxvkContextFlag::CpDirtyResources;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "dxvk_barrier.h"
|
#include "dxvk_barrier.h"
|
||||||
|
#include "dxvk_binding.h"
|
||||||
#include "dxvk_cmdlist.h"
|
#include "dxvk_cmdlist.h"
|
||||||
#include "dxvk_context_state.h"
|
#include "dxvk_context_state.h"
|
||||||
#include "dxvk_data.h"
|
#include "dxvk_data.h"
|
||||||
@ -53,19 +54,8 @@ namespace dxvk {
|
|||||||
void bindFramebuffer(
|
void bindFramebuffer(
|
||||||
const Rc<DxvkFramebuffer>& fb);
|
const Rc<DxvkFramebuffer>& fb);
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Binds index buffer
|
|
||||||
* \param [in] buffer New index buffer
|
|
||||||
*/
|
|
||||||
void bindIndexBuffer(
|
|
||||||
const DxvkBufferBinding& buffer);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Binds compute pipeline
|
* \brief Binds compute pipeline
|
||||||
*
|
|
||||||
* Note that binding a new pipeline implicitly
|
|
||||||
* invalidates all resource bindings that are
|
|
||||||
* used by the pipeline.
|
|
||||||
* \param [in] pipeline The pipeline to bind
|
* \param [in] pipeline The pipeline to bind
|
||||||
*/
|
*/
|
||||||
void bindComputePipeline(
|
void bindComputePipeline(
|
||||||
@ -73,15 +63,76 @@ namespace dxvk {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Binds graphics pipeline
|
* \brief Binds graphics pipeline
|
||||||
*
|
|
||||||
* Note that binding a new pipeline implicitly
|
|
||||||
* invalidates all bindings that are used by
|
|
||||||
* the pipeline.
|
|
||||||
* \param [in] pipeline The pipeline to bind
|
* \param [in] pipeline The pipeline to bind
|
||||||
*/
|
*/
|
||||||
void bindGraphicsPipeline(
|
void bindGraphicsPipeline(
|
||||||
const Rc<DxvkGraphicsPipeline>& pipeline);
|
const Rc<DxvkGraphicsPipeline>& pipeline);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Binds index buffer
|
||||||
|
*
|
||||||
|
* The index buffer will be used when
|
||||||
|
* issuing \c drawIndexed commands.
|
||||||
|
* \param [in] buffer New index buffer
|
||||||
|
*/
|
||||||
|
void bindIndexBuffer(
|
||||||
|
const DxvkBufferBinding& buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Binds buffer as a shader resource
|
||||||
|
*
|
||||||
|
* Can be used for uniform and storage buffers.
|
||||||
|
* \param [in] pipe Target pipeline
|
||||||
|
* \param [in] slot Resource binding slot
|
||||||
|
* \param [in] buffer Buffer to bind
|
||||||
|
*/
|
||||||
|
void bindResourceBuffer(
|
||||||
|
VkPipelineBindPoint pipe,
|
||||||
|
uint32_t slot,
|
||||||
|
const DxvkBufferBinding& buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Binds texel buffer view
|
||||||
|
*
|
||||||
|
* Can be used for both uniform texel
|
||||||
|
* buffers and storage texel buffers.
|
||||||
|
* \param [in] pipe Target pipeline
|
||||||
|
* \param [in] slot Resource binding slot
|
||||||
|
* \param [in] bufferView Buffer view to bind
|
||||||
|
*/
|
||||||
|
void bindResourceTexelBuffer(
|
||||||
|
VkPipelineBindPoint pipe,
|
||||||
|
uint32_t slot,
|
||||||
|
const Rc<DxvkBufferView>& bufferView);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Binds image view
|
||||||
|
*
|
||||||
|
* Can be used for sampled images with a
|
||||||
|
* dedicated sampler and storage images.
|
||||||
|
* \param [in] pipe Target pipeline
|
||||||
|
* \param [in] slot Resource binding slot
|
||||||
|
* \param [in] imageView Image view to bind
|
||||||
|
*/
|
||||||
|
void bindResourceImage(
|
||||||
|
VkPipelineBindPoint pipe,
|
||||||
|
uint32_t slot,
|
||||||
|
const Rc<DxvkImageView>& image);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Binds image sampler
|
||||||
|
*
|
||||||
|
* Binds a sampler that can be used together with
|
||||||
|
* an image in order to read from a texture.
|
||||||
|
* \param [in] pipe Target pipeline
|
||||||
|
* \param [in] slot Resource binding slot
|
||||||
|
* \param [in] sampler Sampler view to bind
|
||||||
|
*/
|
||||||
|
void bindResourceSampler(
|
||||||
|
VkPipelineBindPoint pipe,
|
||||||
|
uint32_t slot,
|
||||||
|
const Rc<DxvkSampler>& sampler);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Binds vertex buffer
|
* \brief Binds vertex buffer
|
||||||
*
|
*
|
||||||
@ -262,13 +313,17 @@ namespace dxvk {
|
|||||||
DxvkContextState m_state;
|
DxvkContextState m_state;
|
||||||
DxvkBarrierSet m_barriers;
|
DxvkBarrierSet m_barriers;
|
||||||
|
|
||||||
std::vector<VkWriteDescriptorSet> m_descriptorSetWrites;
|
DxvkShaderResourceSlots m_cResources = { 1024 };
|
||||||
|
DxvkShaderResourceSlots m_gResources = { 4096 };
|
||||||
|
|
||||||
void renderPassBegin();
|
void renderPassBegin();
|
||||||
void renderPassEnd();
|
void renderPassEnd();
|
||||||
|
|
||||||
void bindComputePipeline();
|
void updateComputePipeline();
|
||||||
void bindGraphicsPipeline();
|
void updateGraphicsPipeline();
|
||||||
|
|
||||||
|
void updateComputeShaderResources();
|
||||||
|
void updateGraphicsShaderResources();
|
||||||
|
|
||||||
void updateDynamicState();
|
void updateDynamicState();
|
||||||
void updateViewports();
|
void updateViewports();
|
||||||
@ -278,6 +333,15 @@ namespace dxvk {
|
|||||||
|
|
||||||
void commitComputeState();
|
void commitComputeState();
|
||||||
void commitGraphicsState();
|
void commitGraphicsState();
|
||||||
|
|
||||||
|
void commitComputeBarriers();
|
||||||
|
|
||||||
|
DxvkShaderResourceSlots* getShaderResourceSlots(
|
||||||
|
VkPipelineBindPoint pipe);
|
||||||
|
|
||||||
|
DxvkContextFlag getResourceDirtyFlag(
|
||||||
|
VkPipelineBindPoint pipe) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -7,6 +7,8 @@
|
|||||||
#include "dxvk_graphics.h"
|
#include "dxvk_graphics.h"
|
||||||
#include "dxvk_image.h"
|
#include "dxvk_image.h"
|
||||||
#include "dxvk_limits.h"
|
#include "dxvk_limits.h"
|
||||||
|
#include "dxvk_pipeline.h"
|
||||||
|
#include "dxvk_sampler.h"
|
||||||
#include "dxvk_shader.h"
|
#include "dxvk_shader.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
@ -64,8 +66,8 @@ namespace dxvk {
|
|||||||
DxvkOutputMergerState om;
|
DxvkOutputMergerState om;
|
||||||
DxvkConstantStateObjects co;
|
DxvkConstantStateObjects co;
|
||||||
|
|
||||||
Rc<DxvkGraphicsPipeline> gp;
|
Rc<DxvkGraphicsPipeline> gPipe;
|
||||||
Rc<DxvkComputePipeline> cp;
|
Rc<DxvkComputePipeline> cPipe;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -4,6 +4,19 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Descriptor info
|
||||||
|
*
|
||||||
|
* Stores information that is required to
|
||||||
|
* update a single resource descriptor.
|
||||||
|
*/
|
||||||
|
struct DxvkDescriptorInfo {
|
||||||
|
VkDescriptorImageInfo image = { VK_NULL_HANDLE, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_UNDEFINED };
|
||||||
|
VkDescriptorBufferInfo buffer = { VK_NULL_HANDLE, 0, 0 };
|
||||||
|
VkBufferView texelBuffer = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Descriptor set allocator
|
* \brief Descriptor set allocator
|
||||||
*
|
*
|
||||||
|
@ -79,6 +79,12 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rc<DxvkSampler> DxvkDevice::createSampler(
|
||||||
|
const DxvkSamplerCreateInfo& createInfo) {
|
||||||
|
return new DxvkSampler(m_vkd, createInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkSemaphore> DxvkDevice::createSemaphore() {
|
Rc<DxvkSemaphore> DxvkDevice::createSemaphore() {
|
||||||
return new DxvkSemaphore(m_vkd);
|
return new DxvkSemaphore(m_vkd);
|
||||||
}
|
}
|
||||||
@ -93,7 +99,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
Rc<DxvkBindingLayout> DxvkDevice::createBindingLayout(
|
Rc<DxvkBindingLayout> DxvkDevice::createBindingLayout(
|
||||||
uint32_t bindingCount,
|
uint32_t bindingCount,
|
||||||
const DxvkBindingInfo* bindingInfos) {
|
const DxvkDescriptorSlot* bindingInfos) {
|
||||||
return new DxvkBindingLayout(m_vkd, bindingCount, bindingInfos);
|
return new DxvkBindingLayout(m_vkd, bindingCount, bindingInfos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "dxvk_image.h"
|
#include "dxvk_image.h"
|
||||||
#include "dxvk_memory.h"
|
#include "dxvk_memory.h"
|
||||||
#include "dxvk_renderpass.h"
|
#include "dxvk_renderpass.h"
|
||||||
|
#include "dxvk_sampler.h"
|
||||||
#include "dxvk_shader.h"
|
#include "dxvk_shader.h"
|
||||||
#include "dxvk_swapchain.h"
|
#include "dxvk_swapchain.h"
|
||||||
#include "dxvk_sync.h"
|
#include "dxvk_sync.h"
|
||||||
@ -141,6 +142,15 @@ namespace dxvk {
|
|||||||
const Rc<DxvkImage>& image,
|
const Rc<DxvkImage>& image,
|
||||||
const DxvkImageViewCreateInfo& createInfo);
|
const DxvkImageViewCreateInfo& createInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Creates a sampler object
|
||||||
|
*
|
||||||
|
* \param [in] createInfo Sampler parameters
|
||||||
|
* \returns Newly created sampler object
|
||||||
|
*/
|
||||||
|
Rc<DxvkSampler> createSampler(
|
||||||
|
const DxvkSamplerCreateInfo& createInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Creates a semaphore object
|
* \brief Creates a semaphore object
|
||||||
* \returns Newly created semaphore
|
* \returns Newly created semaphore
|
||||||
@ -167,7 +177,7 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
Rc<DxvkBindingLayout> createBindingLayout(
|
Rc<DxvkBindingLayout> createBindingLayout(
|
||||||
uint32_t bindingCount,
|
uint32_t bindingCount,
|
||||||
const DxvkBindingInfo* bindingInfos);
|
const DxvkDescriptorSlot* bindingInfos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Creates a compute pipeline
|
* \brief Creates a compute pipeline
|
||||||
|
@ -119,7 +119,7 @@ namespace dxvk {
|
|||||||
info.pDepthStencilState = &state.depthStencilState->info();
|
info.pDepthStencilState = &state.depthStencilState->info();
|
||||||
info.pColorBlendState = &state.blendState->info();
|
info.pColorBlendState = &state.blendState->info();
|
||||||
info.pDynamicState = &dsInfo;
|
info.pDynamicState = &dsInfo;
|
||||||
info.layout = this->pipelineLayout();
|
info.layout = m_layout->pipelineLayout();
|
||||||
info.renderPass = state.renderPass;
|
info.renderPass = state.renderPass;
|
||||||
info.subpass = 0;
|
info.subpass = 0;
|
||||||
info.basePipelineHandle = VK_NULL_HANDLE;
|
info.basePipelineHandle = VK_NULL_HANDLE;
|
||||||
|
@ -58,26 +58,16 @@ namespace dxvk {
|
|||||||
const Rc<DxvkShader>& fs);
|
const Rc<DxvkShader>& fs);
|
||||||
~DxvkGraphicsPipeline();
|
~DxvkGraphicsPipeline();
|
||||||
|
|
||||||
/**
|
|
||||||
* \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_layout->descriptorSetLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Pipeline layout
|
* \brief Pipeline layout
|
||||||
*
|
*
|
||||||
* The pipeline layout for this pipeline.
|
* Stores the pipeline layout and the descriptor set
|
||||||
* Use this to bind descriptor sets.
|
* layout, as well as information on the resource
|
||||||
* \returns The descriptor set layout
|
* slots used by the pipeline.
|
||||||
|
* \returns Pipeline layout
|
||||||
*/
|
*/
|
||||||
VkPipelineLayout pipelineLayout() const {
|
Rc<DxvkBindingLayout> layout() const {
|
||||||
return m_layout->pipelineLayout();
|
return m_layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -178,6 +178,14 @@ namespace dxvk {
|
|||||||
return m_image;
|
return m_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Image layout
|
||||||
|
* \returns Image layout
|
||||||
|
*/
|
||||||
|
VkImageLayout imageLayout() const {
|
||||||
|
return m_image->info().layout;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Subresource range
|
* \brief Subresource range
|
||||||
* \returns Subresource range
|
* \returns Subresource range
|
||||||
|
@ -10,6 +10,7 @@ namespace dxvk {
|
|||||||
MaxNumVertexBindings = 32,
|
MaxNumVertexBindings = 32,
|
||||||
MaxNumOutputStreams = 4,
|
MaxNumOutputStreams = 4,
|
||||||
MaxNumViewports = 16,
|
MaxNumViewports = 16,
|
||||||
|
MaxNumResourceSlots = 4096,
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "dxvk_pipeline.h"
|
#include "dxvk_pipeline.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
@ -5,25 +7,31 @@ namespace dxvk {
|
|||||||
DxvkBindingLayout::DxvkBindingLayout(
|
DxvkBindingLayout::DxvkBindingLayout(
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
const Rc<vk::DeviceFn>& vkd,
|
||||||
uint32_t bindingCount,
|
uint32_t bindingCount,
|
||||||
const DxvkBindingInfo* bindingInfos)
|
const DxvkDescriptorSlot* bindingInfos)
|
||||||
: m_vkd(vkd) {
|
: m_vkd(vkd) {
|
||||||
|
|
||||||
|
m_bindingSlots.resize(bindingCount);
|
||||||
|
std::memcpy(m_bindingSlots.data(), bindingInfos,
|
||||||
|
bindingCount * sizeof(DxvkDescriptorSlot));
|
||||||
|
|
||||||
|
std::vector<VkDescriptorSetLayoutBinding> bindings;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < bindingCount; i++) {
|
for (uint32_t i = 0; i < bindingCount; i++) {
|
||||||
VkDescriptorSetLayoutBinding binding;
|
VkDescriptorSetLayoutBinding binding;
|
||||||
binding.binding = i;
|
binding.binding = i;
|
||||||
binding.descriptorType = bindingInfos[i].type;
|
binding.descriptorType = bindingInfos[i].type;
|
||||||
binding.descriptorCount = bindingInfos[i].stages == 0 ? 0 : 1;
|
binding.descriptorCount = 1;
|
||||||
binding.stageFlags = bindingInfos[i].stages;
|
binding.stageFlags = bindingInfos[i].stages;
|
||||||
binding.pImmutableSamplers = nullptr;
|
binding.pImmutableSamplers = nullptr;
|
||||||
m_bindings.push_back(binding);
|
bindings.push_back(binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorSetLayoutCreateInfo dsetInfo;
|
VkDescriptorSetLayoutCreateInfo dsetInfo;
|
||||||
dsetInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
dsetInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||||
dsetInfo.pNext = nullptr;
|
dsetInfo.pNext = nullptr;
|
||||||
dsetInfo.flags = 0;
|
dsetInfo.flags = 0;
|
||||||
dsetInfo.bindingCount = m_bindings.size();
|
dsetInfo.bindingCount = bindings.size();
|
||||||
dsetInfo.pBindings = m_bindings.data();
|
dsetInfo.pBindings = bindings.data();
|
||||||
|
|
||||||
if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(),
|
if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(),
|
||||||
&dsetInfo, nullptr, &m_descriptorSetLayout) != VK_SUCCESS)
|
&dsetInfo, nullptr, &m_descriptorSetLayout) != VK_SUCCESS)
|
||||||
@ -59,14 +67,4 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkBindingInfo DxvkBindingLayout::binding(uint32_t id) const {
|
|
||||||
const VkDescriptorSetLayoutBinding& bindingInfo = m_bindings.at(id);
|
|
||||||
|
|
||||||
DxvkBindingInfo result;
|
|
||||||
result.type = bindingInfo.descriptorType;
|
|
||||||
result.stages = bindingInfo.stageFlags;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -11,9 +11,10 @@ namespace dxvk {
|
|||||||
* Vulkan. DXVK does not use descriptor arrays.
|
* Vulkan. DXVK does not use descriptor arrays.
|
||||||
* Instead, each binding stores one descriptor.
|
* Instead, each binding stores one descriptor.
|
||||||
*/
|
*/
|
||||||
struct DxvkBindingInfo {
|
struct DxvkDescriptorSlot {
|
||||||
VkDescriptorType type;
|
uint32_t slot; ///< Resource slot index for the context
|
||||||
VkShaderStageFlags stages;
|
VkDescriptorType type; ///< Descriptor type (aka resource type)
|
||||||
|
VkShaderStageFlags stages; ///< Stages that can use the resource
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ namespace dxvk {
|
|||||||
DxvkBindingLayout(
|
DxvkBindingLayout(
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
const Rc<vk::DeviceFn>& vkd,
|
||||||
uint32_t bindingCount,
|
uint32_t bindingCount,
|
||||||
const DxvkBindingInfo* bindingInfos);
|
const DxvkDescriptorSlot* bindingInfos);
|
||||||
|
|
||||||
~DxvkBindingLayout();
|
~DxvkBindingLayout();
|
||||||
|
|
||||||
@ -38,17 +39,17 @@ namespace dxvk {
|
|||||||
* \brief Number of resource bindings
|
* \brief Number of resource bindings
|
||||||
* \returns Resource binding count
|
* \returns Resource binding count
|
||||||
*/
|
*/
|
||||||
uint32_t numBindings() const {
|
uint32_t bindingCount() const {
|
||||||
return m_bindings.size();
|
return m_bindingSlots.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retrieves binding info
|
* \brief Resource binding info
|
||||||
*
|
* \returns Resource binding info
|
||||||
* \param [in] binding ID
|
|
||||||
* \returns Binding info
|
|
||||||
*/
|
*/
|
||||||
DxvkBindingInfo binding(uint32_t id) const;
|
const DxvkDescriptorSlot* bindings() const {
|
||||||
|
return m_bindingSlots.data();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Descriptor set layout handle
|
* \brief Descriptor set layout handle
|
||||||
@ -73,7 +74,7 @@ namespace dxvk {
|
|||||||
VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE;
|
VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE;
|
||||||
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
||||||
|
|
||||||
std::vector<VkDescriptorSetLayoutBinding> m_bindings;
|
std::vector<DxvkDescriptorSlot> m_bindingSlots;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
#include "dxvk_sampler.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
DxvkSampler::DxvkSampler(
|
||||||
|
const Rc<vk::DeviceFn>& vkd,
|
||||||
|
const DxvkSamplerCreateInfo& info)
|
||||||
|
: m_vkd(vkd), m_info(info) {
|
||||||
|
VkSamplerCreateInfo samplerInfo;
|
||||||
|
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||||
|
samplerInfo.pNext = nullptr;
|
||||||
|
samplerInfo.flags = 0;
|
||||||
|
samplerInfo.magFilter = info.magFilter;
|
||||||
|
samplerInfo.minFilter = info.minFilter;
|
||||||
|
samplerInfo.mipmapMode = info.mipmapMode;
|
||||||
|
samplerInfo.addressModeU = info.addressModeU;
|
||||||
|
samplerInfo.addressModeV = info.addressModeV;
|
||||||
|
samplerInfo.addressModeW = info.addressModeW;
|
||||||
|
samplerInfo.mipLodBias = info.mipmapLodBias;
|
||||||
|
samplerInfo.anisotropyEnable = info.useAnisotropy;
|
||||||
|
samplerInfo.maxAnisotropy = info.maxAnisotropy;
|
||||||
|
samplerInfo.compareEnable = info.compareToDepth;
|
||||||
|
samplerInfo.compareOp = info.compareOp;
|
||||||
|
samplerInfo.minLod = info.mipmapLodMin;
|
||||||
|
samplerInfo.maxLod = info.mipmapLodMax;
|
||||||
|
samplerInfo.borderColor = info.borderColor;
|
||||||
|
samplerInfo.unnormalizedCoordinates = info.usePixelCoord;
|
||||||
|
|
||||||
|
if (m_vkd->vkCreateSampler(m_vkd->device(),
|
||||||
|
&samplerInfo, nullptr, &m_sampler) != VK_SUCCESS)
|
||||||
|
throw DxvkError("DxvkSampler::DxvkSampler: Failed to create sampler");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkSampler::~DxvkSampler() {
|
||||||
|
m_vkd->vkDestroySampler(
|
||||||
|
m_vkd->device(), m_sampler, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dxvk_resource.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sampler properties
|
||||||
|
*/
|
||||||
|
struct DxvkSamplerCreateInfo {
|
||||||
|
/// Texture filter propertoes
|
||||||
|
VkFilter magFilter;
|
||||||
|
VkFilter minFilter;
|
||||||
|
|
||||||
|
/// Mipmapping properties
|
||||||
|
VkSamplerMipmapMode mipmapMode;
|
||||||
|
float mipmapLodBias;
|
||||||
|
float mipmapLodMin;
|
||||||
|
float mipmapLodMax;
|
||||||
|
|
||||||
|
/// Anisotropic filtering
|
||||||
|
VkBool32 useAnisotropy;
|
||||||
|
float maxAnisotropy;
|
||||||
|
|
||||||
|
/// Address modes
|
||||||
|
VkSamplerAddressMode addressModeU;
|
||||||
|
VkSamplerAddressMode addressModeV;
|
||||||
|
VkSamplerAddressMode addressModeW;
|
||||||
|
|
||||||
|
/// Compare op for shadow textures
|
||||||
|
VkBool32 compareToDepth;
|
||||||
|
VkCompareOp compareOp;
|
||||||
|
|
||||||
|
/// Texture border color
|
||||||
|
VkBorderColor borderColor;
|
||||||
|
|
||||||
|
/// Enables unnormalized coordinates
|
||||||
|
VkBool32 usePixelCoord;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sampler
|
||||||
|
*
|
||||||
|
* Manages a sampler object that can be bound to
|
||||||
|
* a pipeline. Sampler objects provide parameters
|
||||||
|
* for texture lookups within a shader.
|
||||||
|
*/
|
||||||
|
class DxvkSampler : public DxvkResource {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DxvkSampler(
|
||||||
|
const Rc<vk::DeviceFn>& vkd,
|
||||||
|
const DxvkSamplerCreateInfo& info);
|
||||||
|
~DxvkSampler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sampler handle
|
||||||
|
* \returns Sampler handle
|
||||||
|
*/
|
||||||
|
VkSampler handle() const {
|
||||||
|
return m_sampler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sampler parameters
|
||||||
|
* \returns Sampler parameters
|
||||||
|
*/
|
||||||
|
const DxvkSamplerCreateInfo& info() const {
|
||||||
|
return m_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Rc<vk::DeviceFn> m_vkd;
|
||||||
|
DxvkSamplerCreateInfo m_info;
|
||||||
|
VkSampler m_sampler = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -19,6 +19,7 @@ dxvk_src = files([
|
|||||||
'dxvk_pipeline.cpp',
|
'dxvk_pipeline.cpp',
|
||||||
'dxvk_renderpass.cpp',
|
'dxvk_renderpass.cpp',
|
||||||
'dxvk_resource.cpp',
|
'dxvk_resource.cpp',
|
||||||
|
'dxvk_sampler.cpp',
|
||||||
'dxvk_shader.cpp',
|
'dxvk_shader.cpp',
|
||||||
'dxvk_surface.cpp',
|
'dxvk_surface.cpp',
|
||||||
'dxvk_swapchain.cpp',
|
'dxvk_swapchain.cpp',
|
||||||
|
@ -221,6 +221,16 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SpirvModule::decorateBinding(
|
||||||
|
uint32_t object,
|
||||||
|
uint32_t binding) {
|
||||||
|
m_annotations.putIns (spv::OpDecorate, 4);
|
||||||
|
m_annotations.putWord (object);
|
||||||
|
m_annotations.putWord (spv::DecorationBinding);
|
||||||
|
m_annotations.putInt32(binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpirvModule::decorateBlock(uint32_t object) {
|
void SpirvModule::decorateBlock(uint32_t object) {
|
||||||
m_annotations.putIns (spv::OpDecorate, 3);
|
m_annotations.putIns (spv::OpDecorate, 3);
|
||||||
m_annotations.putWord (object);
|
m_annotations.putWord (object);
|
||||||
@ -248,6 +258,16 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SpirvModule::decorateDescriptorSet(
|
||||||
|
uint32_t object,
|
||||||
|
uint32_t set) {
|
||||||
|
m_annotations.putIns (spv::OpDecorate, 4);
|
||||||
|
m_annotations.putWord (object);
|
||||||
|
m_annotations.putWord (spv::DecorationDescriptorSet);
|
||||||
|
m_annotations.putInt32(set);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpirvModule::decorateLocation(
|
void SpirvModule::decorateLocation(
|
||||||
uint32_t object,
|
uint32_t object,
|
||||||
uint32_t location) {
|
uint32_t location) {
|
||||||
@ -378,6 +398,36 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t SpirvModule::defSamplerType() {
|
||||||
|
return this->defType(spv::OpTypeSampler, 0, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t SpirvModule::defImageType(
|
||||||
|
uint32_t sampledType,
|
||||||
|
spv::Dim dimensionality,
|
||||||
|
uint32_t depth,
|
||||||
|
uint32_t arrayed,
|
||||||
|
uint32_t multisample,
|
||||||
|
uint32_t sampled,
|
||||||
|
spv::ImageFormat format) {
|
||||||
|
std::array<uint32_t, 7> args = {
|
||||||
|
sampledType, dimensionality,
|
||||||
|
depth, arrayed, multisample,
|
||||||
|
sampled, format
|
||||||
|
};
|
||||||
|
|
||||||
|
return this->defType(spv::OpTypeImage,
|
||||||
|
args.size(), args.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t SpirvModule::defSampledImageType(
|
||||||
|
uint32_t imageType) {
|
||||||
|
return this->defType(spv::OpTypeSampledImage, 1, &imageType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t SpirvModule::newVar(
|
uint32_t SpirvModule::newVar(
|
||||||
uint32_t pointerType,
|
uint32_t pointerType,
|
||||||
spv::StorageClass storageClass) {
|
spv::StorageClass storageClass) {
|
||||||
@ -675,6 +725,36 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t SpirvModule::opSampledImage(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t image,
|
||||||
|
uint32_t sampler) {
|
||||||
|
uint32_t resultId = this->allocateId();
|
||||||
|
|
||||||
|
m_code.putIns (spv::OpSampledImage, 5);
|
||||||
|
m_code.putWord(resultType);
|
||||||
|
m_code.putWord(resultId);
|
||||||
|
m_code.putWord(image);
|
||||||
|
m_code.putWord(sampler);
|
||||||
|
return resultId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t SpirvModule::opImageSampleImplicitLod(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t sampledImage,
|
||||||
|
uint32_t coordinates) {
|
||||||
|
uint32_t resultId = this->allocateId();
|
||||||
|
|
||||||
|
m_code.putIns (spv::OpImageSampleImplicitLod, 5);
|
||||||
|
m_code.putWord(resultType);
|
||||||
|
m_code.putWord(resultId);
|
||||||
|
m_code.putWord(sampledImage);
|
||||||
|
m_code.putWord(coordinates);
|
||||||
|
return resultId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpirvModule::opReturn() {
|
void SpirvModule::opReturn() {
|
||||||
m_code.putIns (spv::OpReturn, 1);
|
m_code.putIns (spv::OpReturn, 1);
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,10 @@ namespace dxvk {
|
|||||||
uint32_t constCount,
|
uint32_t constCount,
|
||||||
const uint32_t* constIds);
|
const uint32_t* constIds);
|
||||||
|
|
||||||
|
void decorateBinding(
|
||||||
|
uint32_t object,
|
||||||
|
uint32_t binding);
|
||||||
|
|
||||||
void decorateBlock(
|
void decorateBlock(
|
||||||
uint32_t object);
|
uint32_t object);
|
||||||
|
|
||||||
@ -92,6 +96,10 @@ namespace dxvk {
|
|||||||
uint32_t object,
|
uint32_t object,
|
||||||
uint32_t location);
|
uint32_t location);
|
||||||
|
|
||||||
|
void decorateDescriptorSet(
|
||||||
|
uint32_t object,
|
||||||
|
uint32_t set);
|
||||||
|
|
||||||
void decorateLocation(
|
void decorateLocation(
|
||||||
uint32_t object,
|
uint32_t object,
|
||||||
uint32_t location);
|
uint32_t location);
|
||||||
@ -140,6 +148,20 @@ namespace dxvk {
|
|||||||
uint32_t variableType,
|
uint32_t variableType,
|
||||||
spv::StorageClass storageClass);
|
spv::StorageClass storageClass);
|
||||||
|
|
||||||
|
uint32_t defSamplerType();
|
||||||
|
|
||||||
|
uint32_t defImageType(
|
||||||
|
uint32_t sampledType,
|
||||||
|
spv::Dim dimensionality,
|
||||||
|
uint32_t depth,
|
||||||
|
uint32_t arrayed,
|
||||||
|
uint32_t multisample,
|
||||||
|
uint32_t sampled,
|
||||||
|
spv::ImageFormat format);
|
||||||
|
|
||||||
|
uint32_t defSampledImageType(
|
||||||
|
uint32_t imageType);
|
||||||
|
|
||||||
uint32_t newVar(
|
uint32_t newVar(
|
||||||
uint32_t pointerType,
|
uint32_t pointerType,
|
||||||
spv::StorageClass storageClass);
|
spv::StorageClass storageClass);
|
||||||
@ -239,6 +261,16 @@ namespace dxvk {
|
|||||||
uint32_t pointerId,
|
uint32_t pointerId,
|
||||||
uint32_t valueId);
|
uint32_t valueId);
|
||||||
|
|
||||||
|
uint32_t opSampledImage(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t image,
|
||||||
|
uint32_t sampler);
|
||||||
|
|
||||||
|
uint32_t opImageSampleImplicitLod(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t sampledImage,
|
||||||
|
uint32_t coordinates);
|
||||||
|
|
||||||
void opReturn();
|
void opReturn();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -63,7 +63,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
void run() {
|
void run() {
|
||||||
FLOAT color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
FLOAT color[4] = { 0.8f, 0.2f, 0.2f, 1.0f };
|
||||||
|
|
||||||
m_context->OMSetRenderTargets(1, &m_bufferView, nullptr);
|
m_context->OMSetRenderTargets(1, &m_bufferView, nullptr);
|
||||||
m_context->ClearRenderTargetView(m_bufferView.ptr(), color);
|
m_context->ClearRenderTargetView(m_bufferView.ptr(), color);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user