Modify MVKVector with feedback from cdavis5e

This commit is contained in:
aerofly 2018-12-14 14:19:30 +01:00
parent 6aad9dc0ba
commit fba2eefa5e
21 changed files with 155 additions and 65 deletions

View File

@ -295,6 +295,14 @@ VkExtent3D mvkMipmapBaseSizeFromLevelSize3D(VkExtent3D levelSize, uint32_t level
*/
MTLSamplerAddressMode mvkMTLSamplerAddressModeFromVkSamplerAddressMode(VkSamplerAddressMode vkMode);
#if MVK_MACOS
/**
* Returns the Metal MTLSamplerBorderColor corresponding to the specified Vulkan VkBorderColor,
* or returns MTLSamplerBorderColorTransparentBlack if no corresponding MTLSamplerBorderColor exists.
*/
MTLSamplerBorderColor mvkMTLSamplerBorderColorFromVkBorderColor(VkBorderColor vkColor);
#endif
/**
* Returns the Metal MTLSamplerMinMagFilter corresponding to the specified Vulkan VkFilter,
* or returns MTLSamplerMinMagFilterNearest if no corresponding MTLSamplerMinMagFilter exists.

View File

@ -54,7 +54,7 @@ extern "C" {
#define MVK_VERSION MVK_MAKE_VERSION(MVK_VERSION_MAJOR, MVK_VERSION_MINOR, MVK_VERSION_PATCH)
#define VK_MVK_MOLTENVK_SPEC_VERSION 12
#define VK_MVK_MOLTENVK_SPEC_VERSION 13
#define VK_MVK_MOLTENVK_EXTENSION_NAME "VK_MVK_moltenvk"
/**
@ -261,6 +261,7 @@ typedef struct {
VkBool32 presentModeImmediate; /**< If true, immediate surface present mode (VK_PRESENT_MODE_IMMEDIATE_KHR), allowing a swapchain image to be presented immediately, without waiting for the vertical sync period of the display, is supported. */
VkBool32 stencilViews; /**< If true, stencil aspect views are supported through the MTLPixelFormatX24_Stencil8 and MTLPixelFormatX32_Stencil8 formats. */
VkBool32 multisampleArrayTextures; /**< If true, MTLTextureType2DMultisampleArray is supported. */
VkBool32 samplerClampToBorder; /**< If true, the border color set when creating a sampler will be respected. */
uint32_t maxTextureDimension; /**< The maximum size of each texture dimension (width, height, or depth). */
uint32_t maxPerStageBufferCount; /**< The total number of per-stage Metal buffers available for shader uniform content and attributes. */
uint32_t maxPerStageTextureCount; /**< The total number of per-stage Metal textures available for shader uniform content. */

View File

@ -21,6 +21,7 @@
#include "MVKCommand.h"
#include "MVKMTLResourceBindings.h"
#include "MVKVector.h"
#import <Metal/Metal.h>
class MVKDevice;

View File

@ -21,6 +21,7 @@
#include "MVKCommand.h"
#include "MVKVector.h"
#include <vector>
class MVKCommandBuffer;
class MVKPipeline;
class MVKPipelineLayout;

View File

@ -159,13 +159,8 @@ void MVKCmdPushConstants::setContent(VkPipelineLayout layout,
_stageFlags = stageFlags;
_offset = offset;
_pushConstants.clear();
for( uint32_t i=0; i<size; ++i)
{
_pushConstants.push_back( reinterpret_cast<const char*>( pValues)[i] );
}
//_pushConstants.resize(size);
//copy_n((char*)pValues, size, _pushConstants.begin());
_pushConstants.resize(size);
std::copy_n((char*)pValues, size, _pushConstants.begin());
}
void MVKCmdPushConstants::encode(MVKCommandEncoder* cmdEncoder) {

View File

@ -403,7 +403,7 @@ protected:
uint32_t _renderSubpassIndex;
VkRect2D _renderArea;
MVKActivatedQueries* _pActivatedQueries;
std::vector<VkClearValue> _clearValues;
MVKVector<VkClearValue> _clearValues;
id<MTLComputeCommandEncoder> _mtlComputeEncoder;
MVKCommandUse _mtlComputeEncoderUse;
id<MTLBlitCommandEncoder> _mtlBlitEncoder;

View File

@ -225,13 +225,7 @@ void MVKCommandEncoder::beginRenderpass(VkSubpassContents subpassContents,
_renderArea = renderArea;
_isRenderingEntireAttachment = (mvkVkOffset2DsAreEqual(_renderArea.offset, {0,0}) &&
mvkVkExtent2DsAreEqual(_renderArea.extent, _framebuffer->getExtent2D()));
_clearValues.clear();
for( auto cv : *clearValues )
{
_clearValues.push_back( cv );
}
//_clearValues.assign(clearValues->begin(), clearValues->end());
_clearValues.assign(clearValues->begin(), clearValues->end());
setSubpass(subpassContents, 0);
}

View File

@ -113,11 +113,7 @@ void MVKScissorCommandEncoderState::setScissors(const MVKVector<MTLScissorRect>
void MVKScissorCommandEncoderState::encodeImpl() {
MVKAssert(!_mtlScissors.empty(), "Must specify at least one scissor rect");
MVKVector<MTLScissorRect> clippedScissors;
for ( const auto &scissor : _mtlScissors)
{
clippedScissors.emplace_back( scissor );
}
auto clippedScissors(_mtlScissors);
std::for_each(clippedScissors.begin(), clippedScissors.end(), [this](MTLScissorRect& scissor) {
scissor = _cmdEncoder->clipToRenderArea(scissor);
});

View File

@ -27,15 +27,6 @@ static NSString* _MVKStaticCmdShaderSource = @"
#include <metal_stdlib> \n\
using namespace metal; \n\
\n\
typedef struct { \n\
float4 a_position [[attribute(0)]]; \n\
} AttributesPos; \n\
\n\
typedef struct { \n\
float4 v_position [[position]]; \n\
uint layer%s; \n\
} VaryingsPos; \n\
\n\
typedef struct { \n\
float2 a_position [[attribute(0)]]; \n\
float2 a_texCoord [[attribute(1)]]; \n\
@ -53,18 +44,6 @@ vertex VaryingsPosTex vtxCmdBlitImage(AttributesPosTex attributes [[stage_in]])
return varyings; \n\
} \n\
\n\
typedef struct { \n\
float4 colors[9]; \n\
} ClearColorsIn; \n\
\n\
vertex VaryingsPos vtxCmdClearAttachments(AttributesPos attributes [[stage_in]], \n\
constant ClearColorsIn& ccIn [[buffer(0)]]) { \n\
VaryingsPos varyings; \n\
varyings.v_position = float4(attributes.a_position.x, -attributes.a_position.y, ccIn.colors[8].r, 1.0); \n\
varyings.layer = uint(attributes.a_position.w); \n\
return varyings; \n\
} \n\
\n\
typedef struct { \n\
uint32_t srcOffset; \n\
uint32_t dstOffset; \n\
@ -93,11 +72,3 @@ kernel void cmdFillBuffer(device uint32_t* dst [[ buffer(0) ]],
\n\
";
/** Returns MSL shader source code containing static functions to be used for various Vulkan commands. */
static inline NSString* mvkStaticCmdShaderSource(MVKDevice* device) {
const char* rtaiStr = device->_pMetalFeatures->layeredRendering ? " [[render_target_array_index]]" : "";
return [NSString stringWithFormat: _MVKStaticCmdShaderSource, rtaiStr];
}

View File

@ -324,6 +324,7 @@ protected:
void initMTLLibrary();
void initImageDeviceMemory();
id<MTLFunction> getBlitFragFunction(MVKRPSKeyBlitImg& blitKey);
id<MTLFunction> getClearVertFunction(MVKRPSKeyClearAtt& attKey);
id<MTLFunction> getClearFragFunction(MVKRPSKeyClearAtt& attKey);
NSString* getMTLFormatTypeString(MTLPixelFormat mtlPixFmt);
id<MTLFunction> getFunctionNamed(const char* funcName);

View File

@ -87,7 +87,7 @@ id<MTLSamplerState> MVKCommandResourceFactory::newCmdBlitImageMTLSamplerState(MT
id<MTLRenderPipelineState> MVKCommandResourceFactory::newCmdClearMTLRenderPipelineState(MVKRPSKeyClearAtt& attKey) {
MTLRenderPipelineDescriptor* plDesc = [[[MTLRenderPipelineDescriptor alloc] init] autorelease];
plDesc.label = @"CmdClearAttachments";
plDesc.vertexFunction = getFunctionNamed("vtxCmdClearAttachments");
plDesc.vertexFunction = getClearVertFunction(attKey);
plDesc.fragmentFunction = getClearFragFunction(attKey);
plDesc.sampleCount = attKey.mtlSampleCount;
plDesc.inputPrimitiveTopologyMVK = MTLPrimitiveTopologyClassTriangle;
@ -176,6 +176,43 @@ id<MTLFunction> MVKCommandResourceFactory::getBlitFragFunction(MVKRPSKeyBlitImg&
return [mtlFunc autorelease];
}
id<MTLFunction> MVKCommandResourceFactory::getClearVertFunction(MVKRPSKeyClearAtt& attKey) {
id<MTLFunction> mtlFunc = nil;
bool allowLayers = _device->_pMetalFeatures->layeredRendering && (attKey.mtlSampleCount == 1 || _device->_pMetalFeatures->multisampleArrayTextures);
@autoreleasepool {
NSMutableString* msl = [NSMutableString stringWithCapacity: (2 * KIBI) ];
[msl appendLineMVK: @"#include <metal_stdlib>"];
[msl appendLineMVK: @"using namespace metal;"];
[msl appendLineMVK];
[msl appendLineMVK: @"typedef struct {"];
[msl appendLineMVK: @" float4 a_position [[attribute(0)]];"];
[msl appendLineMVK: @"} AttributesPos;"];
[msl appendLineMVK];
[msl appendLineMVK: @"typedef struct {"];
[msl appendLineMVK: @" float4 colors[9];"];
[msl appendLineMVK: @"} ClearColorsIn;"];
[msl appendLineMVK];
[msl appendLineMVK: @"typedef struct {"];
[msl appendLineMVK: @" float4 v_position [[position]];"];
[msl appendFormat: @" uint layer%s;", allowLayers ? " [[render_target_array_index]]" : ""];
[msl appendLineMVK: @"} VaryingsPos;"];
[msl appendLineMVK];
NSString* funcName = @"vertClear";
[msl appendFormat: @"vertex VaryingsPos %@(AttributesPos attributes [[stage_in]], constant ClearColorsIn& ccIn [[buffer(0)]]) {", funcName];
[msl appendLineMVK];
[msl appendLineMVK: @" VaryingsPos varyings;"];
[msl appendLineMVK: @" varyings.v_position = float4(attributes.a_position.x, -attributes.a_position.y, ccIn.colors[8].r, 1.0);"];
[msl appendLineMVK: @" varyings.layer = uint(attributes.a_position.w);"];
[msl appendLineMVK: @" return varyings;"];
[msl appendLineMVK: @"}"];
mtlFunc = newMTLFunction(msl, funcName);
// MVKLogDebug("\n%s", msl.UTF8String);
}
return [mtlFunc autorelease];
}
id<MTLFunction> MVKCommandResourceFactory::getClearFragFunction(MVKRPSKeyClearAtt& attKey) {
id<MTLFunction> mtlFunc = nil;
@autoreleasepool {
@ -368,7 +405,7 @@ void MVKCommandResourceFactory::initMTLLibrary() {
uint64_t startTime = _device->getPerformanceTimestamp();
@autoreleasepool {
NSError* err = nil;
_mtlLibrary = [getMTLDevice() newLibraryWithSource: mvkStaticCmdShaderSource(_device)
_mtlLibrary = [getMTLDevice() newLibraryWithSource: _MVKStaticCmdShaderSource
options: getDevice()->getMTLCompileOptions()
error: &err]; // retained
MVKAssert( !err, "Could not compile command shaders %s (code %li) %s", err.localizedDescription.UTF8String, (long)err.code, err.localizedFailureReason.UTF8String);

View File

@ -562,6 +562,7 @@ void MVKPhysicalDevice::initMetalFeatures() {
_metalFeatures.dynamicMTLBuffers = true;
_metalFeatures.shaderSpecialization = true;
_metalFeatures.stencilViews = true;
_metalFeatures.samplerClampToBorder = true;
_metalFeatures.maxMTLBufferSize = (1 * GIBI);
}

View File

@ -931,6 +931,20 @@ MTLSamplerDescriptor* MVKSampler::getMTLSamplerDescriptor(const VkSamplerCreateI
mtlSampDesc.compareFunctionMVK = (pCreateInfo->compareEnable
? mvkMTLCompareFunctionFromVkCompareOp(pCreateInfo->compareOp)
: MTLCompareFunctionNever);
#if MVK_MACOS
mtlSampDesc.borderColorMVK = mvkMTLSamplerBorderColorFromVkBorderColor(pCreateInfo->borderColor);
if (_device->getPhysicalDevice()->getMetalFeatures()->samplerClampToBorder) {
if (pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) {
mtlSampDesc.sAddressMode = MTLSamplerAddressModeClampToBorderColor;
}
if (pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) {
mtlSampDesc.tAddressMode = MTLSamplerAddressModeClampToBorderColor;
}
if (pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) {
mtlSampDesc.rAddressMode = MTLSamplerAddressModeClampToBorderColor;
}
}
#endif
return [mtlSampDesc autorelease];
}

View File

@ -108,9 +108,6 @@ void MVKPipelineLayout::populateShaderConverterContext(SPIRVToMSLConverterContex
kPushConstDescSet,
kPushConstBinding);
_auxBufferIndex.vertex = _pushConstantsMTLResourceIndexes.vertexStage.bufferIndex + 1;
_auxBufferIndex.fragment = _pushConstantsMTLResourceIndexes.fragmentStage.bufferIndex + 1;
_auxBufferIndex.compute = _pushConstantsMTLResourceIndexes.computeStage.bufferIndex + 1;
}
MVKPipelineLayout::MVKPipelineLayout(MVKDevice* device,
@ -140,6 +137,11 @@ MVKPipelineLayout::MVKPipelineLayout(MVKDevice* device,
for (uint32_t i = 0; i < pCreateInfo->pushConstantRangeCount; i++) {
_pushConstants.push_back(pCreateInfo->pPushConstantRanges[i]);
}
// Set auxiliary buffer offsets
_auxBufferIndex.vertex = _pushConstantsMTLResourceIndexes.vertexStage.bufferIndex + 1;
_auxBufferIndex.fragment = _pushConstantsMTLResourceIndexes.fragmentStage.bufferIndex + 1;
_auxBufferIndex.compute = _pushConstantsMTLResourceIndexes.computeStage.bufferIndex + 1;
}

View File

@ -19,6 +19,7 @@
#pragma once
#include "MVKDevice.h"
#include "MVKVector.h"
#include <vector>
#import <Metal/Metal.h>
@ -56,7 +57,7 @@ public:
*/
void populateMTLRenderPassDescriptor(MTLRenderPassDescriptor* mtlRPDesc,
MVKFramebuffer* framebuffer,
std::vector<VkClearValue>& clearValues,
MVKVector<VkClearValue>& clearValues,
bool isRenderingEntireAttachment);
/**
@ -64,7 +65,7 @@ public:
* when the render area is smaller than the full framebuffer size.
*/
void populateClearAttachments(std::vector<VkClearAttachment>& clearAtts,
std::vector<VkClearValue>& clearValues);
MVKVector<VkClearValue>& clearValues);
/** Constructs an instance for the specified parent renderpass. */
MVKRenderSubpass(MVKRenderPass* renderPass, const VkSubpassDescription* pCreateInfo);

View File

@ -67,7 +67,7 @@ VkSampleCountFlagBits MVKRenderSubpass::getSampleCount() {
void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor* mtlRPDesc,
MVKFramebuffer* framebuffer,
vector<VkClearValue>& clearValues,
MVKVector<VkClearValue>& clearValues,
bool isRenderingEntireAttachment) {
// Populate the Metal color attachments
uint32_t caCnt = getColorAttachmentCount();
@ -157,7 +157,7 @@ void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor*
}
void MVKRenderSubpass::populateClearAttachments(vector<VkClearAttachment>& clearAtts,
vector<VkClearValue>& clearValues) {
MVKVector<VkClearValue>& clearValues) {
VkClearAttachment cAtt;
uint32_t attIdx;

View File

@ -32,4 +32,13 @@
*/
@property(nonatomic, readwrite) MTLCompareFunction compareFunctionMVK;
/**
* Replacement for the borderColor property.
*
* This property allows support under all OS versions. Delegates to the borderColor
* property if it is available. otherwise, returns MTLSamplerBorderColorTransparentBlack when read and
* does nothing when set.
*/
@property(nonatomic, readwrite) /*MTLSamplerBorderColor*/ NSUInteger borderColorMVK;
@end

View File

@ -30,4 +30,17 @@
if ( [self respondsToSelector: @selector(setCompareFunction:)] ) { self.compareFunction = cmpFunc; }
}
-(NSUInteger) borderColorMVK {
#if MVK_MACOS
if ( [self respondsToSelector: @selector(borderColor)] ) { return self.borderColor; }
#endif
return /*MTLSamplerBorderColorTransparentBlack*/ 0;
}
-(void) setBorderColorMVK: (NSUInteger) color {
#if MVK_MACOS
if ( [self respondsToSelector: @selector(setBorderColor:)] ) { self.borderColor = (MTLSamplerBorderColor) color; }
#endif
}
@end

View File

@ -18,6 +18,16 @@
#pragma once
//
// in case MVKVector should use std::vector
//
#if 0
template<typename T>
using MVKVector = std::vector<T>;
#else
//
// a simple std::vector like container with a configurable extra stack space
// this class supports just the necessary members to be compatible with MoltenVK
@ -55,7 +65,12 @@ public:
return &vector->alc.ptr[index];
}
operator Type*( ) const
Type &operator*() const
{
return vector->alc.ptr[index];
}
operator Type*() const
{
return &vector->alc.ptr[index];
}
@ -91,11 +106,16 @@ public:
return &vector->alc.ptr[index];
}
operator Type*( ) const
Type &operator*() const
{
return vector->alc.ptr[index];
}
operator Type*() const
{
return &vector->alc.ptr[index];
}
bool operator==( const reverse_iterator &it ) const
{
return vector == it.vector && index == it.index;
@ -216,7 +236,7 @@ public:
}
else
{
alc.destruct_all();
alc.template destruct_all<Type>();
}
for( size_t i = 0; i < n; ++i )
@ -369,6 +389,18 @@ public:
alc.num_elements_used = new_size;
}
template <class InputIterator>
void assign( InputIterator first, InputIterator last )
{
clear();
while( first != last )
{
emplace_back( *first );
++first;
}
}
void resize( const size_t new_size, const Type t = { } )
{
if( new_size == alc.num_elements_used )
@ -492,5 +524,5 @@ public:
}
};
#endif

View File

@ -74,7 +74,6 @@ public:
{
}
template<class S> typename std::enable_if< !std::is_trivially_destructible<S>::value >::type
destruct_all()
{

View File

@ -941,6 +941,20 @@ MVK_PUBLIC_SYMBOL MTLSamplerAddressMode mvkMTLSamplerAddressModeFromVkSamplerAdd
}
}
#if MVK_MACOS
MVK_PUBLIC_SYMBOL MTLSamplerBorderColor mvkMTLSamplerBorderColorFromVkBorderColor(VkBorderColor vkColor) {
switch (vkColor) {
case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK: return MTLSamplerBorderColorTransparentBlack;
case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK: return MTLSamplerBorderColorTransparentBlack;
case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK: return MTLSamplerBorderColorOpaqueBlack;
case VK_BORDER_COLOR_INT_OPAQUE_BLACK: return MTLSamplerBorderColorOpaqueBlack;
case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE: return MTLSamplerBorderColorOpaqueWhite;
case VK_BORDER_COLOR_INT_OPAQUE_WHITE: return MTLSamplerBorderColorOpaqueWhite;
default: return MTLSamplerBorderColorTransparentBlack;
}
}
#endif
MVK_PUBLIC_SYMBOL MTLSamplerMinMagFilter mvkMTLSamplerMinMagFilterFromVkFilter(VkFilter vkFilter) {
switch (vkFilter) {
case VK_FILTER_NEAREST: return MTLSamplerMinMagFilterNearest;