| #ifndef _VKTSHADERRENDER_HPP |
| #define _VKTSHADERRENDER_HPP |
| /*------------------------------------------------------------------------ |
| * Vulkan Conformance Tests |
| * ------------------------ |
| * |
| * Copyright (c) 2015 The Khronos Group Inc. |
| * Copyright (c) 2015 Samsung Electronics Co., Ltd. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Vulkan ShaderRenderCase |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "tcuTexture.hpp" |
| #include "tcuSurface.hpp" |
| |
| #include "deMemory.h" |
| #include "deSharedPtr.hpp" |
| #include "deUniquePtr.hpp" |
| |
| #include "vkDefs.hpp" |
| #include "vkRefUtil.hpp" |
| #include "vkPrograms.hpp" |
| #include "vkRef.hpp" |
| #include "vkMemUtil.hpp" |
| #include "vkBuilderUtil.hpp" |
| #include "vkTypeUtil.hpp" |
| #include "vkPlatform.hpp" |
| |
| #include "vktTestCaseUtil.hpp" |
| |
| namespace vkt |
| { |
| namespace sr |
| { |
| |
| class LineStream |
| { |
| public: |
| LineStream (int indent = 0) { m_indent = indent; } |
| ~LineStream (void) {} |
| |
| const char* str (void) const { m_string = m_stream.str(); return m_string.c_str(); } |
| LineStream& operator<< (const char* line) { for (int i = 0; i < m_indent; i++) { m_stream << "\t"; } m_stream << line << "\n"; return *this; } |
| |
| private: |
| int m_indent; |
| std::ostringstream m_stream; |
| mutable std::string m_string; |
| }; |
| |
| class QuadGrid; |
| class ShaderRenderCaseInstance; |
| |
| class TextureBinding |
| { |
| public: |
| enum Type |
| { |
| TYPE_NONE = 0, |
| TYPE_1D, |
| TYPE_2D, |
| TYPE_3D, |
| TYPE_CUBE_MAP, |
| TYPE_1D_ARRAY, |
| TYPE_2D_ARRAY, |
| TYPE_CUBE_ARRAY, |
| |
| TYPE_LAST |
| }; |
| |
| enum Init |
| { |
| INIT_UPLOAD_DATA, |
| INIT_CLEAR, |
| |
| INIT_LAST |
| }; |
| |
| struct Parameters |
| { |
| deUint32 baseMipLevel; |
| vk::VkComponentMapping componentMapping; |
| vk::VkSampleCountFlagBits samples; |
| Init initialization; |
| |
| Parameters (deUint32 baseMipLevel_ = 0, |
| vk::VkComponentMapping componentMapping_ = vk::makeComponentMappingRGBA(), |
| vk::VkSampleCountFlagBits samples_ = vk::VK_SAMPLE_COUNT_1_BIT, |
| Init initialization_ = INIT_UPLOAD_DATA) |
| : baseMipLevel (baseMipLevel_) |
| , componentMapping (componentMapping_) |
| , samples (samples_) |
| , initialization (initialization_) |
| { |
| } |
| }; |
| |
| TextureBinding (const tcu::Archive& archive, |
| const char* filename, |
| const Type type, |
| const tcu::Sampler& sampler); |
| |
| TextureBinding (const tcu::Texture1D* tex1D, const tcu::Sampler& sampler); |
| TextureBinding (const tcu::Texture2D* tex2D, const tcu::Sampler& sampler); |
| TextureBinding (const tcu::Texture3D* tex3D, const tcu::Sampler& sampler); |
| TextureBinding (const tcu::TextureCube* texCube, const tcu::Sampler& sampler); |
| TextureBinding (const tcu::Texture1DArray* tex1DArray, const tcu::Sampler& sampler); |
| TextureBinding (const tcu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler); |
| TextureBinding (const tcu::TextureCubeArray* texCubeArray, const tcu::Sampler& sampler); |
| |
| ~TextureBinding (void); |
| |
| Type getType (void) const { return m_type; } |
| const tcu::Sampler& getSampler (void) const { return m_sampler; } |
| |
| const tcu::Texture1D& get1D (void) const { DE_ASSERT(getType() == TYPE_1D && m_binding.tex1D != NULL); return *m_binding.tex1D; } |
| const tcu::Texture2D& get2D (void) const { DE_ASSERT(getType() == TYPE_2D && m_binding.tex2D != NULL); return *m_binding.tex2D; } |
| const tcu::Texture3D& get3D (void) const { DE_ASSERT(getType() == TYPE_3D && m_binding.tex3D != NULL); return *m_binding.tex3D; } |
| const tcu::TextureCube& getCube (void) const { DE_ASSERT(getType() == TYPE_CUBE_MAP && m_binding.texCube != NULL); return *m_binding.texCube; } |
| const tcu::Texture1DArray& get1DArray (void) const { DE_ASSERT(getType() == TYPE_1D_ARRAY && m_binding.tex1DArray != NULL); return *m_binding.tex1DArray; } |
| const tcu::Texture2DArray& get2DArray (void) const { DE_ASSERT(getType() == TYPE_2D_ARRAY && m_binding.tex2DArray != NULL); return *m_binding.tex2DArray; } |
| const tcu::TextureCubeArray& getCubeArray (void) const { DE_ASSERT(getType() == TYPE_CUBE_ARRAY && m_binding.texCubeArray != NULL); return *m_binding.texCubeArray; } |
| |
| void setParameters (const Parameters& params) { m_params = params; } |
| const Parameters& getParameters (void) const { return m_params; } |
| |
| private: |
| TextureBinding (const TextureBinding&); // not allowed! |
| TextureBinding& operator= (const TextureBinding&); // not allowed! |
| |
| static de::MovePtr<tcu::Texture2D> loadTexture2D (const tcu::Archive& archive, const char* filename); |
| |
| Type m_type; |
| tcu::Sampler m_sampler; |
| Parameters m_params; |
| |
| union |
| { |
| const tcu::Texture1D* tex1D; |
| const tcu::Texture2D* tex2D; |
| const tcu::Texture3D* tex3D; |
| const tcu::TextureCube* texCube; |
| const tcu::Texture1DArray* tex1DArray; |
| const tcu::Texture2DArray* tex2DArray; |
| const tcu::TextureCubeArray* texCubeArray; |
| } m_binding; |
| }; |
| |
| typedef de::SharedPtr<TextureBinding> TextureBindingSp; |
| |
| // ShaderEvalContext. |
| |
| class ShaderEvalContext |
| { |
| public: |
| // Limits. |
| enum |
| { |
| MAX_USER_ATTRIBS = 4, |
| MAX_TEXTURES = 4 |
| }; |
| |
| struct ShaderSampler |
| { |
| tcu::Sampler sampler; |
| const tcu::Texture1D* tex1D; |
| const tcu::Texture2D* tex2D; |
| const tcu::Texture3D* tex3D; |
| const tcu::TextureCube* texCube; |
| const tcu::Texture1DArray* tex1DArray; |
| const tcu::Texture2DArray* tex2DArray; |
| const tcu::TextureCubeArray* texCubeArray; |
| |
| inline ShaderSampler (void) |
| : tex1D (DE_NULL) |
| , tex2D (DE_NULL) |
| , tex3D (DE_NULL) |
| , texCube (DE_NULL) |
| , tex1DArray (DE_NULL) |
| , tex2DArray (DE_NULL) |
| , texCubeArray (DE_NULL) |
| { |
| } |
| }; |
| |
| ShaderEvalContext (const QuadGrid& quadGrid); |
| ~ShaderEvalContext (void); |
| |
| void reset (float sx, float sy); |
| |
| // Inputs. |
| tcu::Vec4 coords; |
| tcu::Vec4 unitCoords; |
| tcu::Vec4 constCoords; |
| |
| tcu::Vec4 in[MAX_USER_ATTRIBS]; |
| ShaderSampler textures[MAX_TEXTURES]; |
| |
| // Output. |
| tcu::Vec4 color; |
| bool isDiscarded; |
| |
| // Functions. |
| inline void discard (void) { isDiscarded = true; } |
| tcu::Vec4 texture2D (int unitNdx, const tcu::Vec2& coords); |
| |
| private: |
| const QuadGrid& m_quadGrid; |
| }; |
| |
| typedef void (*ShaderEvalFunc) (ShaderEvalContext& c); |
| |
| inline void evalCoordsPassthroughX (ShaderEvalContext& c) { c.color.x() = c.coords.x(); } |
| inline void evalCoordsPassthroughXY (ShaderEvalContext& c) { c.color.xy() = c.coords.swizzle(0,1); } |
| inline void evalCoordsPassthroughXYZ (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); } |
| inline void evalCoordsPassthrough (ShaderEvalContext& c) { c.color = c.coords; } |
| inline void evalCoordsSwizzleWZYX (ShaderEvalContext& c) { c.color = c.coords.swizzle(3,2,1,0); } |
| |
| // ShaderEvaluator |
| // Either inherit a class with overridden evaluate() or just pass in an evalFunc. |
| |
| class ShaderEvaluator |
| { |
| public: |
| ShaderEvaluator (void); |
| ShaderEvaluator (const ShaderEvalFunc evalFunc); |
| virtual ~ShaderEvaluator (void); |
| |
| virtual void evaluate (ShaderEvalContext& ctx) const; |
| |
| private: |
| ShaderEvaluator (const ShaderEvaluator&); // not allowed! |
| ShaderEvaluator& operator= (const ShaderEvaluator&); // not allowed! |
| |
| const ShaderEvalFunc m_evalFunc; |
| }; |
| |
| // UniformSetup |
| |
| typedef void (*UniformSetupFunc) (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords); |
| |
| class UniformSetup |
| { |
| public: |
| UniformSetup (void); |
| UniformSetup (const UniformSetupFunc setup); |
| virtual ~UniformSetup (void); |
| virtual void setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const; |
| |
| private: |
| UniformSetup (const UniformSetup&); // not allowed! |
| UniformSetup& operator= (const UniformSetup&); // not allowed! |
| |
| const UniformSetupFunc m_setupFunc; |
| }; |
| |
| typedef void (*AttributeSetupFunc) (ShaderRenderCaseInstance& instance, deUint32 numVertices); |
| |
| class ShaderRenderCase : public vkt::TestCase |
| { |
| public: |
| ShaderRenderCase (tcu::TestContext& testCtx, |
| const std::string& name, |
| const std::string& description, |
| const bool isVertexCase, |
| const ShaderEvalFunc evalFunc, |
| const UniformSetup* uniformSetup, |
| const AttributeSetupFunc attribFunc); |
| |
| ShaderRenderCase (tcu::TestContext& testCtx, |
| const std::string& name, |
| const std::string& description, |
| const bool isVertexCase, |
| const ShaderEvaluator* evaluator, |
| const UniformSetup* uniformSetup, |
| const AttributeSetupFunc attribFunc); |
| |
| virtual ~ShaderRenderCase (void); |
| virtual void initPrograms (vk::SourceCollections& programCollection) const; |
| virtual TestInstance* createInstance (Context& context) const; |
| |
| protected: |
| std::string m_vertShaderSource; |
| std::string m_fragShaderSource; |
| |
| const bool m_isVertexCase; |
| const de::UniquePtr<const ShaderEvaluator> m_evaluator; |
| const de::UniquePtr<const UniformSetup> m_uniformSetup; |
| const AttributeSetupFunc m_attribFunc; |
| }; |
| |
| enum BaseUniformType |
| { |
| // Bool |
| UB_FALSE, |
| UB_TRUE, |
| |
| // BVec4 |
| UB4_FALSE, |
| UB4_TRUE, |
| |
| // Integers |
| UI_ZERO, |
| UI_ONE, |
| UI_TWO, |
| UI_THREE, |
| UI_FOUR, |
| UI_FIVE, |
| UI_SIX, |
| UI_SEVEN, |
| UI_EIGHT, |
| UI_ONEHUNDREDONE, |
| |
| // IVec2 |
| UI2_MINUS_ONE, |
| UI2_ZERO, |
| UI2_ONE, |
| UI2_TWO, |
| UI2_THREE, |
| UI2_FOUR, |
| UI2_FIVE, |
| |
| // IVec3 |
| UI3_MINUS_ONE, |
| UI3_ZERO, |
| UI3_ONE, |
| UI3_TWO, |
| UI3_THREE, |
| UI3_FOUR, |
| UI3_FIVE, |
| |
| // IVec4 |
| UI4_MINUS_ONE, |
| UI4_ZERO, |
| UI4_ONE, |
| UI4_TWO, |
| UI4_THREE, |
| UI4_FOUR, |
| UI4_FIVE, |
| |
| // Float |
| UF_ZERO, |
| UF_ONE, |
| UF_TWO, |
| UF_THREE, |
| UF_FOUR, |
| UF_FIVE, |
| UF_SIX, |
| UF_SEVEN, |
| UF_EIGHT, |
| |
| UF_HALF, |
| UF_THIRD, |
| UF_FOURTH, |
| UF_FIFTH, |
| UF_SIXTH, |
| UF_SEVENTH, |
| UF_EIGHTH, |
| |
| // Vec2 |
| UV2_MINUS_ONE, |
| UV2_ZERO, |
| UV2_ONE, |
| UV2_TWO, |
| UV2_THREE, |
| |
| UV2_HALF, |
| |
| // Vec3 |
| UV3_MINUS_ONE, |
| UV3_ZERO, |
| UV3_ONE, |
| UV3_TWO, |
| UV3_THREE, |
| |
| UV3_HALF, |
| |
| // Vec4 |
| UV4_MINUS_ONE, |
| UV4_ZERO, |
| UV4_ONE, |
| UV4_TWO, |
| UV4_THREE, |
| |
| UV4_HALF, |
| |
| UV4_BLACK, |
| UV4_GRAY, |
| UV4_WHITE, |
| |
| // Last |
| U_LAST |
| }; |
| |
| enum BaseAttributeType |
| { |
| // User attributes |
| A_IN0, |
| A_IN1, |
| A_IN2, |
| A_IN3, |
| |
| // Matrices |
| MAT2, |
| MAT2x3, |
| MAT2x4, |
| MAT3x2, |
| MAT3, |
| MAT3x4, |
| MAT4x2, |
| MAT4x3, |
| MAT4 |
| }; |
| |
| // ShaderRenderCaseInstance. |
| |
| class ShaderRenderCaseInstance : public vkt::TestInstance |
| { |
| public: |
| enum ImageBackingMode |
| { |
| IMAGE_BACKING_MODE_REGULAR = 0, |
| IMAGE_BACKING_MODE_SPARSE, |
| }; |
| |
| // Default wertex and fragment grid sizes are used by a large collection of tests |
| // to generate input sets. Some tests might change their behavior if the |
| // default grid size values are altered, so care should be taken to confirm that |
| // any changes to default values do not produce regressions. |
| // If a particular tests needs to use a different grid size value, rather than |
| // modifying the default grid size values for all tests, it is recommended that |
| // the test specifies the required grid size using the gridSize parameter in the |
| // ShaderRenderCaseInstance constuctor instead. |
| enum |
| { |
| GRID_SIZE_DEFAULTS = 0, |
| GRID_SIZE_DEFAULT_VERTEX = 90, |
| GRID_SIZE_DEFAULT_FRAGMENT = 4, |
| }; |
| |
| ShaderRenderCaseInstance (Context& context); |
| ShaderRenderCaseInstance (Context& context, |
| const bool isVertexCase, |
| const ShaderEvaluator& evaluator, |
| const UniformSetup& uniformSetup, |
| const AttributeSetupFunc attribFunc, |
| const ImageBackingMode imageBackingMode = IMAGE_BACKING_MODE_REGULAR, |
| const deUint32 gridSize = static_cast<deUint32>(GRID_SIZE_DEFAULTS), |
| const bool fuzzyCompare = true); |
| |
| virtual ~ShaderRenderCaseInstance (void); |
| virtual tcu::TestStatus iterate (void); |
| |
| void addAttribute (deUint32 bindingLocation, |
| vk::VkFormat format, |
| deUint32 sizePerElement, |
| deUint32 count, |
| const void* data); |
| void useAttribute (deUint32 bindingLocation, |
| BaseAttributeType type); |
| |
| template<typename T> |
| void addUniform (deUint32 bindingLocation, |
| vk::VkDescriptorType descriptorType, |
| const T& data); |
| void addUniform (deUint32 bindingLocation, |
| vk::VkDescriptorType descriptorType, |
| size_t dataSize, |
| const void* data); |
| void useUniform (deUint32 bindingLocation, |
| BaseUniformType type); |
| void useSampler (deUint32 bindingLocation, |
| deUint32 textureId); |
| |
| static const tcu::Vec4 getDefaultConstCoords (void) { return tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f); } |
| void setPushConstantRanges (const deUint32 rangeCount, const vk::VkPushConstantRange* const pcRanges); |
| virtual void updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout); |
| |
| protected: |
| ShaderRenderCaseInstance (Context& context, |
| const bool isVertexCase, |
| const ShaderEvaluator* evaluator, |
| const UniformSetup* uniformSetup, |
| const AttributeSetupFunc attribFunc, |
| const ImageBackingMode imageBackingMode = IMAGE_BACKING_MODE_REGULAR, |
| const deUint32 gridSize = static_cast<deUint32>(GRID_SIZE_DEFAULTS)); |
| |
| virtual void setup (void); |
| virtual void setupUniforms (const tcu::Vec4& constCoords); |
| virtual void setupDefaultInputs (void); |
| |
| void render (deUint32 numVertices, |
| deUint32 numTriangles, |
| const deUint16* indices, |
| const tcu::Vec4& constCoords = getDefaultConstCoords()); |
| |
| void render (deUint32 numVertices, |
| deUint32 numIndices, |
| const deUint16* indices, |
| vk::VkPrimitiveTopology topology, |
| const tcu::Vec4& constCoords = getDefaultConstCoords()); |
| |
| const tcu::TextureLevel& getResultImage (void) const { return m_resultImage; } |
| |
| const tcu::UVec2 getViewportSize (void) const; |
| |
| void setSampleCount (vk::VkSampleCountFlagBits sampleCount); |
| |
| bool isMultiSampling (void) const; |
| |
| ImageBackingMode m_imageBackingMode; |
| |
| deUint32 m_quadGridSize; |
| |
| protected: |
| vk::Allocator& m_memAlloc; |
| const tcu::Vec4 m_clearColor; |
| const bool m_isVertexCase; |
| |
| std::vector<tcu::Mat4> m_userAttribTransforms; |
| std::vector<TextureBindingSp> m_textures; |
| |
| std::string m_vertexShaderName; |
| std::string m_fragmentShaderName; |
| tcu::UVec2 m_renderSize; |
| vk::VkFormat m_colorFormat; |
| |
| private: |
| typedef std::vector<tcu::ConstPixelBufferAccess> TextureLayerData; |
| typedef std::vector<TextureLayerData> TextureData; |
| |
| void uploadImage (const tcu::TextureFormat& texFormat, |
| const TextureData& textureData, |
| const tcu::Sampler& refSampler, |
| deUint32 mipLevels, |
| deUint32 arrayLayers, |
| vk::VkImage destImage); |
| |
| void clearImage (const tcu::Sampler& refSampler, |
| deUint32 mipLevels, |
| deUint32 arrayLayers, |
| vk::VkImage destImage); |
| |
| void checkSparseSupport (const vk::VkImageCreateInfo& imageInfo) const; |
| |
| void uploadSparseImage (const tcu::TextureFormat& texFormat, |
| const TextureData& textureData, |
| const tcu::Sampler& refSampler, |
| const deUint32 mipLevels, |
| const deUint32 arrayLayers, |
| const vk::VkImage sparseImage, |
| const vk::VkImageCreateInfo& imageCreateInfo, |
| const tcu::UVec3 texSize); |
| |
| void createSamplerUniform (deUint32 bindingLocation, |
| TextureBinding::Type textureType, |
| TextureBinding::Init textureInit, |
| const tcu::TextureFormat& texFormat, |
| const tcu::UVec3 texSize, |
| const TextureData& textureData, |
| const tcu::Sampler& refSampler, |
| deUint32 mipLevels, |
| deUint32 arrayLayers, |
| TextureBinding::Parameters textureParams); |
| |
| void setupUniformData (deUint32 bindingLocation, size_t size, const void* dataPtr); |
| |
| void computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid); |
| void computeFragmentReference (tcu::Surface& result, const QuadGrid& quadGrid); |
| bool compareImages (const tcu::Surface& resImage, |
| const tcu::Surface& refImage, |
| float errorThreshold); |
| |
| private: |
| const ShaderEvaluator* m_evaluator; |
| const UniformSetup* m_uniformSetup; |
| const AttributeSetupFunc m_attribFunc; |
| de::MovePtr<QuadGrid> m_quadGrid; |
| tcu::TextureLevel m_resultImage; |
| |
| struct EnabledBaseAttribute |
| { |
| deUint32 location; |
| BaseAttributeType type; |
| }; |
| std::vector<EnabledBaseAttribute> m_enabledBaseAttributes; |
| |
| de::MovePtr<vk::DescriptorSetLayoutBuilder> m_descriptorSetLayoutBuilder; |
| de::MovePtr<vk::DescriptorPoolBuilder> m_descriptorPoolBuilder; |
| de::MovePtr<vk::DescriptorSetUpdateBuilder> m_descriptorSetUpdateBuilder; |
| |
| typedef de::SharedPtr<vk::Unique<vk::VkBuffer> > VkBufferSp; |
| typedef de::SharedPtr<vk::Unique<vk::VkImage> > VkImageSp; |
| typedef de::SharedPtr<vk::Unique<vk::VkImageView> > VkImageViewSp; |
| typedef de::SharedPtr<vk::Unique<vk::VkSampler> > VkSamplerSp; |
| typedef de::SharedPtr<vk::Allocation> AllocationSp; |
| |
| class UniformInfo |
| { |
| public: |
| UniformInfo (void) {} |
| virtual ~UniformInfo (void) {} |
| |
| vk::VkDescriptorType type; |
| deUint32 location; |
| }; |
| |
| class BufferUniform : public UniformInfo |
| { |
| public: |
| BufferUniform (void) {} |
| virtual ~BufferUniform (void) {} |
| |
| VkBufferSp buffer; |
| AllocationSp alloc; |
| vk::VkDescriptorBufferInfo descriptor; |
| }; |
| |
| class SamplerUniform : public UniformInfo |
| { |
| public: |
| SamplerUniform (void) {} |
| virtual ~SamplerUniform (void) {} |
| |
| VkImageSp image; |
| VkImageViewSp imageView; |
| VkSamplerSp sampler; |
| AllocationSp alloc; |
| vk::VkDescriptorImageInfo descriptor; |
| }; |
| |
| typedef de::SharedPtr<de::UniquePtr<UniformInfo> > UniformInfoSp; |
| std::vector<UniformInfoSp> m_uniformInfos; |
| |
| std::vector< de::SharedPtr<vk::Allocation> > m_allocations; |
| |
| std::vector<vk::VkVertexInputBindingDescription> m_vertexBindingDescription; |
| std::vector<vk::VkVertexInputAttributeDescription> m_vertexAttributeDescription; |
| |
| std::vector<VkBufferSp> m_vertexBuffers; |
| std::vector<AllocationSp> m_vertexBufferAllocs; |
| |
| vk::VkSampleCountFlagBits m_sampleCount; |
| std::vector<vk::VkPushConstantRange> m_pushConstantRanges; |
| |
| bool m_fuzzyCompare; |
| |
| vk::VkDevice getDevice (void) const; |
| deUint32 getUniversalQueueFamilyIndex (void) const; |
| deUint32 getSparseQueueFamilyIndex (void) const; |
| const vk::DeviceInterface& getDeviceInterface (void) const; |
| vk::VkQueue getUniversalQueue (void) const; |
| vk::VkQueue getSparseQueue (void) const; |
| vk::VkPhysicalDevice getPhysicalDevice (void) const; |
| const vk::InstanceInterface& getInstanceInterface (void) const; |
| vk::Allocator& getAllocator (void) const; |
| }; |
| |
| template<typename T> |
| void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, const T& data) |
| { |
| addUniform(bindingLocation, descriptorType, sizeof(T), &data); |
| } |
| |
| } // sr |
| } // vkt |
| |
| #endif // _VKTSHADERRENDER_HPP |