Context refactor: from OpenGL-like state to Vulkan-like state

Overview of the changes: The Context class has been split into more Vulkan related functional elements: - The IndexBuffer class, which contains the index buffer information and has been extended to also the functionality to support primitive restart. Should we need primitive restart related caching in the future, this would be the place to do it. - The Attachments class, which contains information about render targets and depth and stencil buffers - The Inputs class, which contains information about descriptor sets and input streams. - The GraphicsState is a completely constant class which can only be modified in the constructor, which represents the state of a graphics pipeline, which never changes past construction. The GraphicsState can be combined with a DynamicState structure in order to create a complete state used by rendering. Also to note: - The DynamicState class in now in Context.hpp, in order for the GraphicsState to have functionality related to it. - PushConstantStorage was moved to vk::Pipeline, as it is used by both the Graphics Pipeline and the Compute Pipeline. - Viewport/scissor functionality is contained in the GraphicsState and was removed from the Renderer. - All *Processor::update() functions now receive only the information that they require, rather that having access to the entire context. Bug: b/132280877 Change-Id: I74f2582d34e45aa1e7b192dbd2b9b770e7af118d Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/48830Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Commit-Queue: Alexis Hétu <sugoi@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com>
parent d94a77b3
// Copyright 2016 The SwiftShader Authors. All Rights Reserved. // Copyright 2020 The SwiftShader Authors. All Rights Reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
...@@ -12,33 +12,78 @@ ...@@ -12,33 +12,78 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef sw_Context_hpp #ifndef vk_Context_hpp
#define sw_Context_hpp #define vk_Context_hpp
#include "Config.hpp" #include "Config.hpp"
#include "Memset.hpp" #include "Memset.hpp"
#include "Stream.hpp" #include "Stream.hpp"
#include "System/Types.hpp" #include "System/Types.hpp"
#include "Vulkan/VkConfig.hpp"
#include "Vulkan/VkDescriptorSet.hpp" #include "Vulkan/VkDescriptorSet.hpp"
#include <vector>
namespace vk { namespace vk {
class Buffer;
class Device;
class ImageView; class ImageView;
class PipelineLayout; class PipelineLayout;
} // namespace vk struct VertexInputBinding
{
Buffer *buffer;
VkDeviceSize offset;
};
namespace sw { struct IndexBuffer
{
inline VkIndexType getIndexType() const { return indexType; }
void setIndexBufferBinding(const VertexInputBinding &indexBufferBinding, VkIndexType type);
void getIndexBuffers(VkPrimitiveTopology topology, uint32_t count, uint32_t first, bool indexed, bool hasPrimitiveRestartEnable, std::vector<std::pair<uint32_t, void *>> *indexBuffers) const;
private:
int bytesPerIndex() const;
class SpirvShader; VertexInputBinding binding;
VkIndexType indexType;
};
struct PushConstantStorage struct Attachments
{ {
unsigned char data[vk::MAX_PUSH_CONSTANT_SIZE]; ImageView *renderTarget[sw::RENDERTARGETS] = {};
ImageView *depthBuffer = nullptr;
ImageView *stencilBuffer = nullptr;
bool isColorClamped(int index) const;
VkFormat renderTargetInternalFormat(int index) const;
};
struct Inputs
{
Inputs(const VkPipelineVertexInputStateCreateInfo *vertexInputState);
void updateDescriptorSets(const DescriptorSet::Array &dso,
const DescriptorSet::Bindings &ds,
const DescriptorSet::DynamicOffsets &ddo);
inline const DescriptorSet::Array &getDescriptorSetObjects() const { return descriptorSetObjects; }
inline const DescriptorSet::Bindings &getDescriptorSets() const { return descriptorSets; }
inline const DescriptorSet::DynamicOffsets &getDescriptorDynamicOffsets() const { return descriptorDynamicOffsets; }
inline const sw::Stream &getStream(uint32_t i) const { return stream[i]; }
void bindVertexInputs(int firstInstance);
void setVertexInputBinding(const VertexInputBinding vertexInputBindings[]);
void advanceInstanceAttributes();
private:
VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {};
DescriptorSet::Array descriptorSetObjects = {};
DescriptorSet::Bindings descriptorSets = {};
DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};
sw::Stream stream[sw::MAX_INTERFACE_COMPONENTS / 4];
}; };
struct BlendState : Memset<BlendState> struct BlendState : sw::Memset<BlendState>
{ {
BlendState() BlendState()
: Memset(this, 0) : Memset(this, 0)
...@@ -70,24 +115,93 @@ struct BlendState : Memset<BlendState> ...@@ -70,24 +115,93 @@ struct BlendState : Memset<BlendState>
VkBlendOp blendOperationAlpha; VkBlendOp blendOperationAlpha;
}; };
class Context struct DynamicState
{
VkViewport viewport;
VkRect2D scissor;
sw::float4 blendConstants;
float depthBiasConstantFactor = 0.0f;
float depthBiasClamp = 0.0f;
float depthBiasSlopeFactor = 0.0f;
float minDepthBounds = 0.0f;
float maxDepthBounds = 0.0f;
uint32_t compareMask[2] = { 0 };
uint32_t writeMask[2] = { 0 };
uint32_t reference[2] = { 0 };
};
struct GraphicsState
{ {
public: GraphicsState(const Device *device, const VkGraphicsPipelineCreateInfo *pCreateInfo, const PipelineLayout *layout, bool robustBufferAccess);
Context() = default;
const GraphicsState combineStates(const DynamicState &dynamicState) const;
inline const PipelineLayout *getPipelineLayout() const { return pipelineLayout; }
inline bool getRobustBufferAccess() const { return robustBufferAccess; }
inline VkPrimitiveTopology getTopology() const { return topology; }
inline VkProvokingVertexModeEXT getProvokingVertexMode() const { return provokingVertexMode; }
inline VkStencilOpState getFrontStencil() const { return frontStencil; }
inline VkStencilOpState getBackStencil() const { return backStencil; }
// Pixel processor states
inline VkCullModeFlags getCullMode() const { return cullMode; }
inline VkFrontFace getFrontFace() const { return frontFace; }
inline VkPolygonMode getPolygonMode() const { return polygonMode; }
inline VkLineRasterizationModeEXT getLineRasterizationMode() const { return lineRasterizationMode; }
inline float getConstantDepthBias() const { return constantDepthBias; }
inline float getSlopeDepthBias() const { return slopeDepthBias; }
inline float getDepthBiasClamp() const { return depthBiasClamp; }
inline bool hasDepthRangeUnrestricted() const { return depthRangeUnrestricted; }
// Pixel processor states
inline bool hasRasterizerDiscard() const { return rasterizerDiscard; }
inline VkCompareOp getDepthCompareMode() const { return depthCompareMode; }
inline float getLineWidth() const { return lineWidth; }
inline unsigned int getMultiSampleMask() const { return multiSampleMask; }
inline int getSampleCount() const { return sampleCount; }
inline bool hasAlphaToCoverage() const { return alphaToCoverage; }
inline bool hasPrimitiveRestartEnable() const { return primitiveRestartEnable; }
inline const VkRect2D &getScissor() const { return scissor; }
inline const VkViewport &getViewport() const { return viewport; }
inline const sw::float4 &getBlendConstants() const { return blendConstants; }
bool isDrawPoint(bool polygonModeAware) const; bool isDrawPoint(bool polygonModeAware) const;
bool isDrawLine(bool polygonModeAware) const; bool isDrawLine(bool polygonModeAware) const;
bool isDrawTriangle(bool polygonModeAware) const; bool isDrawTriangle(bool polygonModeAware) const;
bool depthWriteActive() const; BlendState getBlendState(int index, const Attachments &attachments, bool fragmentContainsKill) const;
bool depthBufferActive() const;
bool stencilActive() const;
void setBlendState(int index, BlendState state); int colorWriteActive(int index, const Attachments &attachments) const;
BlendState getBlendState(int index) const; bool depthWriteActive(const Attachments &attachments) const;
bool isColorClamped(int index) const; bool depthBufferActive(const Attachments &attachments) const;
bool stencilActive(const Attachments &attachments) const;
private:
inline bool hasDynamicState(VkDynamicState dynamicState) const { return (dynamicStateFlags & (1 << dynamicState)) != 0; }
VkBlendFactor sourceBlendFactor(int index) const;
VkBlendFactor destBlendFactor(int index) const;
VkBlendOp blendOperation(int index, const Attachments &attachments) const;
VkBlendFactor sourceBlendFactorAlpha(int index) const;
VkBlendFactor destBlendFactorAlpha(int index) const;
VkBlendOp blendOperationAlpha(int index, const Attachments &attachments) const;
bool alphaBlendActive(int index, const Attachments &attachments, bool fragmentContainsKill) const;
bool colorWriteActive(const Attachments &attachments) const;
const PipelineLayout *pipelineLayout;
const bool robustBufferAccess = true;
uint32_t dynamicStateFlags = 0;
VkPrimitiveTopology topology; VkPrimitiveTopology topology;
VkProvokingVertexModeEXT provokingVertexMode; VkProvokingVertexModeEXT provokingVertexMode;
bool stencilEnable; bool stencilEnable;
...@@ -105,27 +219,6 @@ public: ...@@ -105,27 +219,6 @@ public:
float depthBiasClamp; float depthBiasClamp;
bool depthRangeUnrestricted; bool depthRangeUnrestricted;
VkFormat renderTargetInternalFormat(int index) const;
int colorWriteActive(int index) const;
vk::DescriptorSet::Array descriptorSetObjects = {};
vk::DescriptorSet::Bindings descriptorSets = {};
vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};
Stream input[MAX_INTERFACE_COMPONENTS / 4];
bool robustBufferAccess;
vk::ImageView *renderTarget[RENDERTARGETS];
vk::ImageView *depthBuffer;
vk::ImageView *stencilBuffer;
vk::PipelineLayout const *pipelineLayout;
// Shaders
const SpirvShader *pixelShader;
const SpirvShader *vertexShader;
bool occlusionEnabled;
// Pixel processor states // Pixel processor states
bool rasterizerDiscard; bool rasterizerDiscard;
bool depthBoundsTestEnable; bool depthBoundsTestEnable;
...@@ -135,28 +228,19 @@ public: ...@@ -135,28 +228,19 @@ public:
float lineWidth; float lineWidth;
int colorWriteMask[RENDERTARGETS]; // RGBA int colorWriteMask[sw::RENDERTARGETS]; // RGBA
unsigned int sampleMask;
unsigned int multiSampleMask; unsigned int multiSampleMask;
int sampleCount; int sampleCount;
bool alphaToCoverage; bool alphaToCoverage;
private: bool primitiveRestartEnable = false;
bool colorWriteActive() const; VkRect2D scissor;
bool colorUsed() const; VkViewport viewport;
sw::float4 blendConstants;
bool alphaBlendActive(int index) const;
VkBlendFactor sourceBlendFactor(int index) const;
VkBlendFactor destBlendFactor(int index) const;
VkBlendOp blendOperation(int index) const;
VkBlendFactor sourceBlendFactorAlpha(int index) const; BlendState blendState[sw::RENDERTARGETS];
VkBlendFactor destBlendFactorAlpha(int index) const;
VkBlendOp blendOperationAlpha(int index) const;
BlendState blendState[RENDERTARGETS];
}; };
} // namespace sw } // namespace vk
#endif // sw_Context_hpp #endif // vk_Context_hpp
...@@ -82,17 +82,17 @@ void PixelProcessor::setRoutineCacheSize(int cacheSize) ...@@ -82,17 +82,17 @@ void PixelProcessor::setRoutineCacheSize(int cacheSize)
routineCache = std::make_unique<RoutineCacheType>(clamp(cacheSize, 1, 65536)); routineCache = std::make_unique<RoutineCacheType>(clamp(cacheSize, 1, 65536));
} }
const PixelProcessor::State PixelProcessor::update(const Context *context) const const PixelProcessor::State PixelProcessor::update(const vk::GraphicsState &pipelineState, const sw::SpirvShader *fragmentShader, const sw::SpirvShader *vertexShader, const vk::Attachments &attachments, bool occlusionEnabled) const
{ {
State state; State state;
state.numClipDistances = context->vertexShader->getNumOutputClipDistances(); state.numClipDistances = vertexShader->getNumOutputClipDistances();
state.numCullDistances = context->vertexShader->getNumOutputCullDistances(); state.numCullDistances = vertexShader->getNumOutputCullDistances();
if(context->pixelShader) if(fragmentShader)
{ {
state.shaderID = context->pixelShader->getSerialID(); state.shaderID = fragmentShader->getSerialID();
state.pipelineLayoutIdentifier = context->pipelineLayout->identifier; state.pipelineLayoutIdentifier = pipelineState.getPipelineLayout()->identifier;
} }
else else
{ {
...@@ -100,49 +100,50 @@ const PixelProcessor::State PixelProcessor::update(const Context *context) const ...@@ -100,49 +100,50 @@ const PixelProcessor::State PixelProcessor::update(const Context *context) const
state.pipelineLayoutIdentifier = 0; state.pipelineLayoutIdentifier = 0;
} }
state.alphaToCoverage = context->alphaToCoverage; state.alphaToCoverage = pipelineState.hasAlphaToCoverage();
state.depthWriteEnable = context->depthWriteActive(); state.depthWriteEnable = pipelineState.depthWriteActive(attachments);
if(context->stencilActive()) if(pipelineState.stencilActive(attachments))
{ {
state.stencilActive = true; state.stencilActive = true;
state.frontStencil = context->frontStencil; state.frontStencil = pipelineState.getFrontStencil();
state.backStencil = context->backStencil; state.backStencil = pipelineState.getBackStencil();
} }
if(context->depthBufferActive()) if(pipelineState.depthBufferActive(attachments))
{ {
state.depthTestActive = true; state.depthTestActive = true;
state.depthCompareMode = context->depthCompareMode; state.depthCompareMode = pipelineState.getDepthCompareMode();
state.depthFormat = context->depthBuffer->getFormat(); state.depthFormat = attachments.depthBuffer->getFormat();
state.depthBias = (context->constantDepthBias != 0.0f) || (context->slopeDepthBias != 0.0f); state.depthBias = (pipelineState.getConstantDepthBias() != 0.0f) || (pipelineState.getSlopeDepthBias() != 0.0f);
// "For fixed-point depth buffers, fragment depth values are always limited to the range [0,1] by clamping after depth bias addition is performed. // "For fixed-point depth buffers, fragment depth values are always limited to the range [0,1] by clamping after depth bias addition is performed.
// Unless the VK_EXT_depth_range_unrestricted extension is enabled, fragment depth values are clamped even when the depth buffer uses a floating-point representation." // Unless the VK_EXT_depth_range_unrestricted extension is enabled, fragment depth values are clamped even when the depth buffer uses a floating-point representation."
state.depthClamp = !state.depthFormat.isFloatFormat() || !context->depthRangeUnrestricted; state.depthClamp = !state.depthFormat.isFloatFormat() || !pipelineState.hasDepthRangeUnrestricted();
} }
state.occlusionEnabled = context->occlusionEnabled; state.occlusionEnabled = occlusionEnabled;
bool fragmentContainsKill = (fragmentShader && fragmentShader->getModes().ContainsKill);
for(int i = 0; i < RENDERTARGETS; i++) for(int i = 0; i < RENDERTARGETS; i++)
{ {
state.colorWriteMask |= context->colorWriteActive(i) << (4 * i); state.colorWriteMask |= pipelineState.colorWriteActive(i, attachments) << (4 * i);
state.targetFormat[i] = context->renderTargetInternalFormat(i); state.targetFormat[i] = attachments.renderTargetInternalFormat(i);
state.blendState[i] = context->getBlendState(i); state.blendState[i] = pipelineState.getBlendState(i, attachments, fragmentContainsKill);
} }
state.multiSampleCount = static_cast<unsigned int>(context->sampleCount); state.multiSampleCount = static_cast<unsigned int>(pipelineState.getSampleCount());
state.multiSampleMask = context->multiSampleMask; state.multiSampleMask = pipelineState.getMultiSampleMask();
state.enableMultiSampling = (state.multiSampleCount > 1) && state.enableMultiSampling = (state.multiSampleCount > 1) &&
!(context->isDrawLine(true) && (context->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT)); !(pipelineState.isDrawLine(true) && (pipelineState.getLineRasterizationMode() == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT));
if(state.enableMultiSampling && context->pixelShader) if(state.enableMultiSampling && fragmentShader)
{ {
state.centroid = context->pixelShader->getModes().NeedsCentroid; state.centroid = fragmentShader->getModes().NeedsCentroid;
} }
state.frontFace = context->frontFace; state.frontFace = pipelineState.getFrontFace();
state.hash = state.computeHash(); state.hash = state.computeHash();
...@@ -150,8 +151,8 @@ const PixelProcessor::State PixelProcessor::update(const Context *context) const ...@@ -150,8 +151,8 @@ const PixelProcessor::State PixelProcessor::update(const Context *context) const
} }
PixelProcessor::RoutineType PixelProcessor::routine(const State &state, PixelProcessor::RoutineType PixelProcessor::routine(const State &state,
vk::PipelineLayout const *pipelineLayout, const vk::PipelineLayout *pipelineLayout,
SpirvShader const *pixelShader, const SpirvShader *pixelShader,
const vk::DescriptorSet::Bindings &descriptorSets) const vk::DescriptorSet::Bindings &descriptorSets)
{ {
auto routine = routineCache->lookup(state); auto routine = routineCache->lookup(state);
......
...@@ -24,11 +24,9 @@ ...@@ -24,11 +24,9 @@
namespace sw { namespace sw {
class PixelShader;
class Rasterizer;
struct Texture;
struct DrawData; struct DrawData;
struct Primitive; struct Primitive;
class SpirvShader;
using RasterizerFunction = FunctionT<void(const Primitive *primitive, int count, int cluster, int clusterCount, DrawData *draw)>; using RasterizerFunction = FunctionT<void(const Primitive *primitive, int count, int cluster, int clusterCount, DrawData *draw)>;
...@@ -82,7 +80,7 @@ public: ...@@ -82,7 +80,7 @@ public:
bool occlusionEnabled; bool occlusionEnabled;
bool perspective; bool perspective;
BlendState blendState[RENDERTARGETS]; vk::BlendState blendState[RENDERTARGETS];
unsigned int colorWriteMask; unsigned int colorWriteMask;
vk::Format targetFormat[RENDERTARGETS]; vk::Format targetFormat[RENDERTARGETS];
...@@ -153,9 +151,9 @@ public: ...@@ -153,9 +151,9 @@ public:
void setBlendConstant(const float4 &blendConstant); void setBlendConstant(const float4 &blendConstant);
const State update(const Context *context) const; const State update(const vk::GraphicsState &pipelineState, const sw::SpirvShader *fragmentShader, const sw::SpirvShader *vertexShader, const vk::Attachments &attachments, bool occlusionEnabled) const;
RoutineType routine(const State &state, vk::PipelineLayout const *pipelineLayout, RoutineType routine(const State &state, const vk::PipelineLayout *pipelineLayout,
SpirvShader const *pixelShader, const vk::DescriptorSet::Bindings &descriptorSets); const SpirvShader *pixelShader, const vk::DescriptorSet::Bindings &descriptorSets);
void setRoutineCacheSize(int routineCacheSize); void setRoutineCacheSize(int routineCacheSize);
// Other semi-constants // Other semi-constants
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#ifndef sw_Rasterizer_hpp #ifndef sw_Rasterizer_hpp
#define sw_Rasterizer_hpp #define sw_Rasterizer_hpp
#include "Context.hpp"
#include "PixelProcessor.hpp" #include "PixelProcessor.hpp"
#include "Device/Config.hpp" #include "Device/Config.hpp"
......
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
#include "Primitive.hpp" #include "Primitive.hpp"
#include "SetupProcessor.hpp" #include "SetupProcessor.hpp"
#include "VertexProcessor.hpp" #include "VertexProcessor.hpp"
#include "Device/Config.hpp"
#include "Vulkan/VkDescriptorSet.hpp" #include "Vulkan/VkDescriptorSet.hpp"
#include "Vulkan/VkPipeline.hpp"
#include "marl/finally.h" #include "marl/finally.h"
#include "marl/pool.h" #include "marl/pool.h"
...@@ -114,7 +114,7 @@ struct DrawData ...@@ -114,7 +114,7 @@ struct DrawData
float4 a2c2; float4 a2c2;
float4 a2c3; float4 a2c3;
PushConstantStorage pushConstants; vk::Pipeline::PushConstantStorage pushConstants;
}; };
struct DrawCall struct DrawCall
...@@ -209,27 +209,16 @@ public: ...@@ -209,27 +209,16 @@ public:
bool hasOcclusionQuery() const { return occlusionQuery != nullptr; } bool hasOcclusionQuery() const { return occlusionQuery != nullptr; }
void draw(const sw::Context *context, VkIndexType indexType, unsigned int count, int baseVertex, void draw(const vk::GraphicsPipeline *pipeline, const vk::DynamicState &dynamicState, unsigned int count, int baseVertex,
CountedEvent *events, int instanceID, int viewID, void *indexBuffer, const VkExtent3D &framebufferExtent, CountedEvent *events, int instanceID, int viewID, void *indexBuffer, const VkExtent3D &framebufferExtent,
PushConstantStorage const &pushConstants, bool update = true); vk::Pipeline::PushConstantStorage const &pushConstants, bool update = true);
// Viewport & Clipper
void setViewport(const VkViewport &viewport);
void setScissor(const VkRect2D &scissor);
void setBlendConstant(const float4 &blendConstant);
void addQuery(vk::Query *query); void addQuery(vk::Query *query);
void removeQuery(vk::Query *query); void removeQuery(vk::Query *query);
void advanceInstanceAttributes(Stream *inputs);
void synchronize(); void synchronize();
private: private:
VkViewport viewport;
VkRect2D scissor;
DrawCall::Pool drawCallPool; DrawCall::Pool drawCallPool;
DrawCall::BatchData::Pool batchDataPool; DrawCall::BatchData::Pool batchDataPool;
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include "SetupProcessor.hpp" #include "SetupProcessor.hpp"
#include "Context.hpp"
#include "Polygon.hpp" #include "Polygon.hpp"
#include "Primitive.hpp" #include "Primitive.hpp"
#include "Renderer.hpp" #include "Renderer.hpp"
...@@ -56,37 +55,37 @@ SetupProcessor::SetupProcessor() ...@@ -56,37 +55,37 @@ SetupProcessor::SetupProcessor()
setRoutineCacheSize(1024); setRoutineCacheSize(1024);
} }
SetupProcessor::State SetupProcessor::update(const sw::Context *context) const SetupProcessor::State SetupProcessor::update(const vk::GraphicsState &pipelineState, const sw::SpirvShader *fragmentShader, const sw::SpirvShader *vertexShader, const vk::Attachments &attachments) const
{ {
State state; State state;
bool vPosZW = (context->pixelShader && context->pixelShader->hasBuiltinInput(spv::BuiltInFragCoord)); bool vPosZW = (fragmentShader && fragmentShader->hasBuiltinInput(spv::BuiltInFragCoord));
state.isDrawPoint = context->isDrawPoint(true); state.isDrawPoint = pipelineState.isDrawPoint(true);
state.isDrawLine = context->isDrawLine(true); state.isDrawLine = pipelineState.isDrawLine(true);
state.isDrawTriangle = context->isDrawTriangle(true); state.isDrawTriangle = pipelineState.isDrawTriangle(true);
state.fixedPointDepthBuffer = context->depthBuffer && !context->depthBuffer->getFormat(VK_IMAGE_ASPECT_DEPTH_BIT).isFloatFormat(); state.fixedPointDepthBuffer = attachments.depthBuffer && !attachments.depthBuffer->getFormat(VK_IMAGE_ASPECT_DEPTH_BIT).isFloatFormat();
state.applyConstantDepthBias = context->isDrawTriangle(false) && (context->constantDepthBias != 0.0f); state.applyConstantDepthBias = pipelineState.isDrawTriangle(false) && (pipelineState.getConstantDepthBias() != 0.0f);
state.applySlopeDepthBias = context->isDrawTriangle(false) && (context->slopeDepthBias != 0.0f); state.applySlopeDepthBias = pipelineState.isDrawTriangle(false) && (pipelineState.getSlopeDepthBias() != 0.0f);
state.applyDepthBiasClamp = context->isDrawTriangle(false) && (context->depthBiasClamp != 0.0f); state.applyDepthBiasClamp = pipelineState.isDrawTriangle(false) && (pipelineState.getDepthBiasClamp() != 0.0f);
state.interpolateZ = context->depthBufferActive() || vPosZW; state.interpolateZ = pipelineState.depthBufferActive(attachments) || vPosZW;
state.interpolateW = context->pixelShader != nullptr; state.interpolateW = fragmentShader != nullptr;
state.frontFace = context->frontFace; state.frontFace = pipelineState.getFrontFace();
state.cullMode = context->cullMode; state.cullMode = pipelineState.getCullMode();
state.multiSampleCount = context->sampleCount; state.multiSampleCount = pipelineState.getSampleCount();
state.enableMultiSampling = (state.multiSampleCount > 1) && state.enableMultiSampling = (state.multiSampleCount > 1) &&
!(context->isDrawLine(true) && (context->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT)); !(pipelineState.isDrawLine(true) && (pipelineState.getLineRasterizationMode() == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT));
state.rasterizerDiscard = context->rasterizerDiscard; state.rasterizerDiscard = pipelineState.hasRasterizerDiscard();
state.numClipDistances = context->vertexShader->getNumOutputClipDistances(); state.numClipDistances = vertexShader->getNumOutputClipDistances();
state.numCullDistances = context->vertexShader->getNumOutputCullDistances(); state.numCullDistances = vertexShader->getNumOutputCullDistances();
if(context->pixelShader) if(fragmentShader)
{ {
for(int interpolant = 0; interpolant < MAX_INTERFACE_COMPONENTS; interpolant++) for(int interpolant = 0; interpolant < MAX_INTERFACE_COMPONENTS; interpolant++)
{ {
state.gradient[interpolant] = context->pixelShader->inputs[interpolant]; state.gradient[interpolant] = fragmentShader->inputs[interpolant];
} }
} }
......
...@@ -76,7 +76,7 @@ public: ...@@ -76,7 +76,7 @@ public:
SetupProcessor(); SetupProcessor();
State update(const sw::Context *context) const; State update(const vk::GraphicsState &pipelineState, const sw::SpirvShader *fragmentShader, const sw::SpirvShader *vertexShader, const vk::Attachments &attachments) const;
RoutineType routine(const State &state); RoutineType routine(const State &state);
void setRoutineCacheSize(int cacheSize); void setRoutineCacheSize(int cacheSize);
......
...@@ -65,21 +65,21 @@ void VertexProcessor::setRoutineCacheSize(int cacheSize) ...@@ -65,21 +65,21 @@ void VertexProcessor::setRoutineCacheSize(int cacheSize)
routineCache = std::make_unique<RoutineCacheType>(clamp(cacheSize, 1, 65536)); routineCache = std::make_unique<RoutineCacheType>(clamp(cacheSize, 1, 65536));
} }
const VertexProcessor::State VertexProcessor::update(const sw::Context *context) const VertexProcessor::State VertexProcessor::update(const vk::GraphicsState &pipelineState, const sw::SpirvShader *vertexShader, const vk::Inputs &inputs)
{ {
State state; State state;
state.shaderID = context->vertexShader->getSerialID(); state.shaderID = vertexShader->getSerialID();
state.pipelineLayoutIdentifier = context->pipelineLayout->identifier; state.pipelineLayoutIdentifier = pipelineState.getPipelineLayout()->identifier;
state.robustBufferAccess = context->robustBufferAccess; state.robustBufferAccess = pipelineState.getRobustBufferAccess();
state.isPoint = context->topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST; state.isPoint = pipelineState.getTopology() == VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
for(int i = 0; i < MAX_INTERFACE_COMPONENTS / 4; i++) for(size_t i = 0; i < MAX_INTERFACE_COMPONENTS / 4; i++)
{ {
state.input[i].format = context->input[i].format; state.input[i].format = inputs.getStream(i).format;
// TODO: get rid of attribType -- just keep the VK format all the way through, this fully determines // TODO: get rid of attribType -- just keep the VK format all the way through, this fully determines
// how to handle the attribute. // how to handle the attribute.
state.input[i].attribType = context->vertexShader->inputs[i * 4].Type; state.input[i].attribType = vertexShader->inputs[i * 4].Type;
} }
state.hash = state.computeHash(); state.hash = state.computeHash();
......
...@@ -94,7 +94,7 @@ public: ...@@ -94,7 +94,7 @@ public:
VertexProcessor(); VertexProcessor();
const State update(const sw::Context *context); const State update(const vk::GraphicsState &pipelineState, const sw::SpirvShader *vertexShader, const vk::Inputs &inputs);
RoutineType routine(const State &state, vk::PipelineLayout const *pipelineLayout, RoutineType routine(const State &state, vk::PipelineLayout const *pipelineLayout,
SpirvShader const *vertexShader, const vk::DescriptorSet::Bindings &descriptorSets); SpirvShader const *vertexShader, const vk::DescriptorSet::Bindings &descriptorSets);
......
...@@ -209,7 +209,7 @@ void ComputeProgram::run( ...@@ -209,7 +209,7 @@ void ComputeProgram::run(
vk::DescriptorSet::Array const &descriptorSetObjects, vk::DescriptorSet::Array const &descriptorSetObjects,
vk::DescriptorSet::Bindings const &descriptorSets, vk::DescriptorSet::Bindings const &descriptorSets,
vk::DescriptorSet::DynamicOffsets const &descriptorDynamicOffsets, vk::DescriptorSet::DynamicOffsets const &descriptorDynamicOffsets,
PushConstantStorage const &pushConstants, vk::Pipeline::PushConstantStorage const &pushConstants,
uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ,
uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ) uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)
{ {
......
...@@ -17,9 +17,9 @@ ...@@ -17,9 +17,9 @@
#include "SpirvShader.hpp" #include "SpirvShader.hpp"
#include "Device/Context.hpp"
#include "Reactor/Coroutine.hpp" #include "Reactor/Coroutine.hpp"
#include "Vulkan/VkDescriptorSet.hpp" #include "Vulkan/VkDescriptorSet.hpp"
#include "Vulkan/VkPipeline.hpp"
#include <functional> #include <functional>
...@@ -58,7 +58,7 @@ public: ...@@ -58,7 +58,7 @@ public:
vk::DescriptorSet::Array const &descriptorSetObjects, vk::DescriptorSet::Array const &descriptorSetObjects,
vk::DescriptorSet::Bindings const &descriptorSetBindings, vk::DescriptorSet::Bindings const &descriptorSetBindings,
vk::DescriptorSet::DynamicOffsets const &descriptorDynamicOffsets, vk::DescriptorSet::DynamicOffsets const &descriptorDynamicOffsets,
PushConstantStorage const &pushConstants, vk::Pipeline::PushConstantStorage const &pushConstants,
uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ,
uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
...@@ -76,7 +76,7 @@ protected: ...@@ -76,7 +76,7 @@ protected:
uint32_t invocationsPerSubgroup; // SPIR-V: "SubgroupSize" uint32_t invocationsPerSubgroup; // SPIR-V: "SubgroupSize"
uint32_t subgroupsPerWorkgroup; // SPIR-V: "NumSubgroups" uint32_t subgroupsPerWorkgroup; // SPIR-V: "NumSubgroups"
uint32_t invocationsPerWorkgroup; // Total number of invocations per workgroup. uint32_t invocationsPerWorkgroup; // Total number of invocations per workgroup.
PushConstantStorage pushConstants; vk::Pipeline::PushConstantStorage pushConstants;
const Constants *constants; const Constants *constants;
}; };
......
...@@ -466,56 +466,6 @@ private: ...@@ -466,56 +466,6 @@ private:
class CmdDrawBase : public vk::CommandBuffer::Command class CmdDrawBase : public vk::CommandBuffer::Command
{ {
public: public:
int bytesPerIndex(vk::CommandBuffer::ExecutionState const &executionState)
{
return executionState.indexType == VK_INDEX_TYPE_UINT16 ? 2 : 4;
}
template<typename T>
void processPrimitiveRestart(T *indexBuffer,
uint32_t count,
vk::GraphicsPipeline *pipeline,
std::vector<std::pair<uint32_t, void *>> &indexBuffers)
{
static const T RestartIndex = static_cast<T>(-1);
T *indexBufferStart = indexBuffer;
uint32_t vertexCount = 0;
for(uint32_t i = 0; i < count; i++)
{
if(indexBuffer[i] == RestartIndex)
{
// Record previous segment
if(vertexCount > 0)
{
uint32_t primitiveCount = pipeline->computePrimitiveCount(vertexCount);
if(primitiveCount > 0)
{
indexBuffers.push_back({ primitiveCount, indexBufferStart });
}
}
vertexCount = 0;
}
else
{
if(vertexCount == 0)
{
indexBufferStart = indexBuffer + i;
}
vertexCount++;
}
}
// Record last segment
if(vertexCount > 0)
{
uint32_t primitiveCount = pipeline->computePrimitiveCount(vertexCount);
if(primitiveCount > 0)
{
indexBuffers.push_back({ primitiveCount, indexBufferStart });
}
}
}
void draw(vk::CommandBuffer::ExecutionState &executionState, bool indexed, void draw(vk::CommandBuffer::ExecutionState &executionState, bool indexed,
uint32_t count, uint32_t instanceCount, uint32_t first, int32_t vertexOffset, uint32_t firstInstance) uint32_t count, uint32_t instanceCount, uint32_t first, int32_t vertexOffset, uint32_t firstInstance)
{ {
...@@ -523,87 +473,21 @@ public: ...@@ -523,87 +473,21 @@ public:
auto *pipeline = static_cast<vk::GraphicsPipeline *>(pipelineState.pipeline); auto *pipeline = static_cast<vk::GraphicsPipeline *>(pipelineState.pipeline);
sw::Context context = pipeline->getContext(); vk::Attachments &attachments = pipeline->getAttachments();
executionState.bindAttachments(&attachments);
executionState.bindVertexInputs(context, firstInstance);
context.descriptorSetObjects = pipelineState.descriptorSetObjects;
context.descriptorSets = pipelineState.descriptorSets;
context.descriptorDynamicOffsets = pipelineState.descriptorDynamicOffsets;
// Apply either pipeline state or dynamic state
executionState.renderer->setScissor(pipeline->hasDynamicState(VK_DYNAMIC_STATE_SCISSOR) ? executionState.dynamicState.scissor : pipeline->getScissor());
executionState.renderer->setViewport(pipeline->hasDynamicState(VK_DYNAMIC_STATE_VIEWPORT) ? executionState.dynamicState.viewport : pipeline->getViewport());
executionState.renderer->setBlendConstant(pipeline->hasDynamicState(VK_DYNAMIC_STATE_BLEND_CONSTANTS) ? executionState.dynamicState.blendConstants : pipeline->getBlendConstants());
if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS))
{
context.constantDepthBias = executionState.dynamicState.depthBiasConstantFactor;
context.slopeDepthBias = executionState.dynamicState.depthBiasSlopeFactor;
context.depthBiasClamp = executionState.dynamicState.depthBiasClamp;
}
if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_DEPTH_BOUNDS) && context.depthBoundsTestEnable)
{
// Unless the VK_EXT_depth_range_unrestricted extension is enabled, minDepthBounds and maxDepthBounds must be between 0.0 and 1.0, inclusive
ASSERT(executionState.dynamicState.minDepthBounds >= 0.0f &&
executionState.dynamicState.minDepthBounds <= 1.0f);
ASSERT(executionState.dynamicState.maxDepthBounds >= 0.0f &&
executionState.dynamicState.maxDepthBounds <= 1.0f);
UNSUPPORTED("VkPhysicalDeviceFeatures::depthBounds");
}
if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK) && context.stencilEnable)
{
context.frontStencil.compareMask = executionState.dynamicState.compareMask[0];
context.backStencil.compareMask = executionState.dynamicState.compareMask[1];
}
if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK) && context.stencilEnable)
{
context.frontStencil.writeMask = executionState.dynamicState.writeMask[0];
context.backStencil.writeMask = executionState.dynamicState.writeMask[1];
}
if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE) && context.stencilEnable)
{
context.frontStencil.reference = executionState.dynamicState.reference[0];
context.backStencil.reference = executionState.dynamicState.reference[1];
}
executionState.bindAttachments(context); vk::Inputs &inputs = pipeline->getInputs();
inputs.updateDescriptorSets(pipelineState.descriptorSetObjects,
pipelineState.descriptorSets,
pipelineState.descriptorDynamicOffsets);
inputs.setVertexInputBinding(executionState.vertexInputBindings);
inputs.bindVertexInputs(firstInstance);
context.occlusionEnabled = executionState.renderer->hasOcclusionQuery(); vk::IndexBuffer &indexBuffer = pipeline->getIndexBuffer();
indexBuffer.setIndexBufferBinding(executionState.indexBufferBinding, executionState.indexType);
std::vector<std::pair<uint32_t, void *>> indexBuffers; std::vector<std::pair<uint32_t, void *>> indexBuffers;
if(indexed) pipeline->getIndexBuffers(count, first, indexed, &indexBuffers);
{
void *indexBuffer = executionState.indexBufferBinding.buffer->getOffsetPointer(
executionState.indexBufferBinding.offset + first * bytesPerIndex(executionState));
if(pipeline->hasPrimitiveRestartEnable())
{
switch(executionState.indexType)
{
case VK_INDEX_TYPE_UINT16:
processPrimitiveRestart(static_cast<uint16_t *>(indexBuffer), count, pipeline, indexBuffers);
break;
case VK_INDEX_TYPE_UINT32:
processPrimitiveRestart(static_cast<uint32_t *>(indexBuffer), count, pipeline, indexBuffers);
break;
default:
UNSUPPORTED("VkIndexType %d", int(executionState.indexType));
}
}
else
{
indexBuffers.push_back({ pipeline->computePrimitiveCount(count), indexBuffer });
}
}
else
{
indexBuffers.push_back({ pipeline->computePrimitiveCount(count), nullptr });
}
for(uint32_t instance = firstInstance; instance != firstInstance + instanceCount; instance++) for(uint32_t instance = firstInstance; instance != firstInstance + instanceCount; instance++)
{ {
...@@ -616,14 +500,14 @@ public: ...@@ -616,14 +500,14 @@ public:
for(auto indexBuffer : indexBuffers) for(auto indexBuffer : indexBuffers)
{ {
executionState.renderer->draw(&context, executionState.indexType, indexBuffer.first, vertexOffset, executionState.renderer->draw(pipeline, executionState.dynamicState, indexBuffer.first, vertexOffset,
executionState.events, instance, viewID, indexBuffer.second, executionState.events, instance, viewID, indexBuffer.second,
executionState.renderPassFramebuffer->getExtent(), executionState.renderPassFramebuffer->getExtent(),
executionState.pushConstants); executionState.pushConstants);
} }
} }
executionState.renderer->advanceInstanceAttributes(context.input); inputs.advanceInstanceAttributes();
} }
} }
}; };
...@@ -1840,25 +1724,7 @@ void CommandBuffer::submitSecondary(CommandBuffer::ExecutionState &executionStat ...@@ -1840,25 +1724,7 @@ void CommandBuffer::submitSecondary(CommandBuffer::ExecutionState &executionStat
} }
} }
void CommandBuffer::ExecutionState::bindVertexInputs(sw::Context &context, int firstInstance) void CommandBuffer::ExecutionState::bindAttachments(Attachments *attachments)
{
for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++)
{
auto &attrib = context.input[i];
if(attrib.format != VK_FORMAT_UNDEFINED)
{
const auto &vertexInput = vertexInputBindings[attrib.binding];
VkDeviceSize offset = attrib.offset + vertexInput.offset +
attrib.instanceStride * firstInstance;
attrib.buffer = vertexInput.buffer ? vertexInput.buffer->getOffsetPointer(offset) : nullptr;
VkDeviceSize size = vertexInput.buffer ? vertexInput.buffer->getSize() : 0;
attrib.robustnessSize = (size > offset) ? size - offset : 0;
}
}
}
void CommandBuffer::ExecutionState::bindAttachments(sw::Context &context)
{ {
// Binds all the attachments for the current subpass // Binds all the attachments for the current subpass
// Ideally this would be performed by BeginRenderPass and NextSubpass, but // Ideally this would be performed by BeginRenderPass and NextSubpass, but
...@@ -1872,7 +1738,7 @@ void CommandBuffer::ExecutionState::bindAttachments(sw::Context &context) ...@@ -1872,7 +1738,7 @@ void CommandBuffer::ExecutionState::bindAttachments(sw::Context &context)
auto attachmentReference = subpass.pColorAttachments[i]; auto attachmentReference = subpass.pColorAttachments[i];
if(attachmentReference.attachment != VK_ATTACHMENT_UNUSED) if(attachmentReference.attachment != VK_ATTACHMENT_UNUSED)
{ {
context.renderTarget[i] = renderPassFramebuffer->getAttachment(attachmentReference.attachment); attachments->renderTarget[i] = renderPassFramebuffer->getAttachment(attachmentReference.attachment);
} }
} }
...@@ -1882,11 +1748,11 @@ void CommandBuffer::ExecutionState::bindAttachments(sw::Context &context) ...@@ -1882,11 +1748,11 @@ void CommandBuffer::ExecutionState::bindAttachments(sw::Context &context)
auto attachment = renderPassFramebuffer->getAttachment(attachmentReference->attachment); auto attachment = renderPassFramebuffer->getAttachment(attachmentReference->attachment);
if(attachment->hasDepthAspect()) if(attachment->hasDepthAspect())
{ {
context.depthBuffer = attachment; attachments->depthBuffer = attachment;
} }
if(attachment->hasStencilAspect()) if(attachment->hasStencilAspect())
{ {
context.stencilBuffer = attachment; attachments->stencilBuffer = attachment;
} }
} }
} }
......
...@@ -17,8 +17,7 @@ ...@@ -17,8 +17,7 @@
#include "VkConfig.hpp" #include "VkConfig.hpp"
#include "VkDescriptorSet.hpp" #include "VkDescriptorSet.hpp"
#include "VkObject.hpp" #include "VkPipeline.hpp"
#include "Device/Context.hpp"
#include "System/Synchronization.hpp" #include "System/Synchronization.hpp"
#include <memory> #include <memory>
...@@ -155,38 +154,17 @@ public: ...@@ -155,38 +154,17 @@ public:
Framebuffer *renderPassFramebuffer = nullptr; Framebuffer *renderPassFramebuffer = nullptr;
std::array<PipelineState, vk::VK_PIPELINE_BIND_POINT_RANGE_SIZE> pipelineState; std::array<PipelineState, vk::VK_PIPELINE_BIND_POINT_RANGE_SIZE> pipelineState;
struct DynamicState vk::DynamicState dynamicState;
{
VkViewport viewport;
VkRect2D scissor;
sw::float4 blendConstants;
float depthBiasConstantFactor = 0.0f;
float depthBiasClamp = 0.0f;
float depthBiasSlopeFactor = 0.0f;
float minDepthBounds = 0.0f;
float maxDepthBounds = 0.0f;
uint32_t compareMask[2] = { 0 };
uint32_t writeMask[2] = { 0 };
uint32_t reference[2] = { 0 };
};
DynamicState dynamicState;
sw::PushConstantStorage pushConstants; vk::Pipeline::PushConstantStorage pushConstants;
struct VertexInputBinding
{
Buffer *buffer;
VkDeviceSize offset;
};
VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {}; VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {};
VertexInputBinding indexBufferBinding; VertexInputBinding indexBufferBinding;
VkIndexType indexType; VkIndexType indexType;
uint32_t subpassIndex = 0; uint32_t subpassIndex = 0;
void bindAttachments(sw::Context &context); void bindAttachments(Attachments *attachments);
void bindVertexInputs(sw::Context &context, int firstInstance);
}; };
void submit(CommandBuffer::ExecutionState &executionState); void submit(CommandBuffer::ExecutionState &executionState);
......
...@@ -15,9 +15,7 @@ ...@@ -15,9 +15,7 @@
#ifndef VK_PIPELINE_HPP_ #ifndef VK_PIPELINE_HPP_
#define VK_PIPELINE_HPP_ #define VK_PIPELINE_HPP_
#include "VkObject.hpp" #include "Device/Context.hpp"
#include "Device/Renderer.hpp"
#include "Vulkan/VkDescriptorSet.hpp"
#include "Vulkan/VkPipelineCache.hpp" #include "Vulkan/VkPipelineCache.hpp"
#include <memory> #include <memory>
...@@ -34,10 +32,7 @@ namespace dbg { ...@@ -34,10 +32,7 @@ namespace dbg {
class Context; class Context;
} // namespace dbg } // namespace dbg
class PipelineCache;
class PipelineLayout;
class ShaderModule; class ShaderModule;
class Device;
class Pipeline class Pipeline
{ {
...@@ -67,6 +62,11 @@ public: ...@@ -67,6 +62,11 @@ public:
return layout; return layout;
} }
struct PushConstantStorage
{
unsigned char data[vk::MAX_PUSH_CONSTANT_SIZE];
};
protected: protected:
PipelineLayout *layout = nullptr; PipelineLayout *layout = nullptr;
Device *const device; Device *const device;
...@@ -95,26 +95,31 @@ public: ...@@ -95,26 +95,31 @@ public:
void compileShaders(const VkAllocationCallbacks *pAllocator, const VkGraphicsPipelineCreateInfo *pCreateInfo, PipelineCache *pipelineCache); void compileShaders(const VkAllocationCallbacks *pAllocator, const VkGraphicsPipelineCreateInfo *pCreateInfo, PipelineCache *pipelineCache);
uint32_t computePrimitiveCount(uint32_t vertexCount) const; const GraphicsState getState(const DynamicState &ds) const { return state.combineStates(ds); }
const sw::Context &getContext() const;
const VkRect2D &getScissor() const; void getIndexBuffers(uint32_t count, uint32_t first, bool indexed, std::vector<std::pair<uint32_t, void *>> *indexBuffers) const;
const VkViewport &getViewport() const;
const sw::float4 &getBlendConstants() const; IndexBuffer &getIndexBuffer() { return indexBuffer; }
bool hasDynamicState(VkDynamicState dynamicState) const; const IndexBuffer &getIndexBuffer() const { return indexBuffer; }
bool hasPrimitiveRestartEnable() const { return primitiveRestartEnable; } Attachments &getAttachments() { return attachments; }
const Attachments &getAttachments() const { return attachments; }
Inputs &getInputs() { return inputs; }
const Inputs &getInputs() const { return inputs; }
bool containsImageWrite() const;
const std::shared_ptr<sw::SpirvShader> getShader(const VkShaderStageFlagBits &stage) const;
private: private:
void setShader(const VkShaderStageFlagBits &stage, const std::shared_ptr<sw::SpirvShader> spirvShader); void setShader(const VkShaderStageFlagBits &stage, const std::shared_ptr<sw::SpirvShader> spirvShader);
const std::shared_ptr<sw::SpirvShader> getShader(const VkShaderStageFlagBits &stage) const;
std::shared_ptr<sw::SpirvShader> vertexShader; std::shared_ptr<sw::SpirvShader> vertexShader;
std::shared_ptr<sw::SpirvShader> fragmentShader; std::shared_ptr<sw::SpirvShader> fragmentShader;
uint32_t dynamicStateFlags = 0; const GraphicsState state;
bool primitiveRestartEnable = false;
sw::Context context; IndexBuffer indexBuffer;
VkRect2D scissor; Attachments attachments;
VkViewport viewport; Inputs inputs;
sw::float4 blendConstants;
}; };
class ComputePipeline : public Pipeline, public ObjectBase<ComputePipeline, VkPipeline> class ComputePipeline : public Pipeline, public ObjectBase<ComputePipeline, VkPipeline>
...@@ -141,7 +146,7 @@ public: ...@@ -141,7 +146,7 @@ public:
vk::DescriptorSet::Array const &descriptorSetObjects, vk::DescriptorSet::Array const &descriptorSetObjects,
vk::DescriptorSet::Bindings const &descriptorSets, vk::DescriptorSet::Bindings const &descriptorSets,
vk::DescriptorSet::DynamicOffsets const &descriptorDynamicOffsets, vk::DescriptorSet::DynamicOffsets const &descriptorDynamicOffsets,
sw::PushConstantStorage const &pushConstants); vk::Pipeline::PushConstantStorage const &pushConstants);
protected: protected:
std::shared_ptr<sw::SpirvShader> shader; std::shared_ptr<sw::SpirvShader> shader;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment