This commit is contained in:
Бранимир Караџић 2019-01-10 13:07:32 -08:00
parent ce625e784e
commit 490ecf1602
2 changed files with 100 additions and 97 deletions

View File

@ -227,7 +227,7 @@ namespace bgfx { namespace mtl
{
[m_obj dispatchThreadgroups:_threadgroupsPerGrid threadsPerThreadgroup:_threadsPerThreadgroup];
}
void dispatchThreadgroupsWithIndirectBuffer(id <MTLBuffer> _indirectBuffer,
NSUInteger _indirectBufferOffset, MTLSize _threadsPerThreadgroup)
{
@ -351,14 +351,14 @@ namespace bgfx { namespace mtl
{
NSError* error;
id <MTLComputePipelineState> state = [m_obj newComputePipelineStateWithFunction:_computeFunction options:_options reflection:_reflection error:&error];
BX_WARN(NULL == error
, "newComputePipelineStateWithFunction failed: %s"
, [error.localizedDescription cStringUsingEncoding:NSASCIIStringEncoding]
);
return state;
}
bool supportsTextureSampleCount(int sampleCount)
{
if (BX_ENABLED(BX_PLATFORM_IOS) && !iOSVersionEqualOrGreater("9.0.0") )
@ -511,7 +511,7 @@ namespace bgfx { namespace mtl
{
[m_obj drawPrimitives:_primitiveType vertexStart:_vertexStart vertexCount:_vertexCount instanceCount:_instanceCount];
}
void drawPrimitives(
MTLPrimitiveType _primitiveType
, id <MTLBuffer> _indirectBuffer
@ -519,7 +519,7 @@ namespace bgfx { namespace mtl
{
[m_obj drawPrimitives:_primitiveType indirectBuffer:_indirectBuffer indirectBufferOffset:_indirectBufferOffset];
}
void drawIndexedPrimitives(
MTLPrimitiveType _primitiveType
, MTLIndexType _indexType
@ -570,7 +570,7 @@ namespace bgfx { namespace mtl
{
return [m_obj newTextureViewWithPixelFormat:_pixelFormat];
}
id<MTLTexture> newTextureViewWithPixelFormat(MTLPixelFormat _pixelFormat, MTLTextureType _textureType, NSRange _levelRange, NSRange _sliceRange)
{
return [m_obj newTextureViewWithPixelFormat:_pixelFormat textureType:_textureType levels:_levelRange slices:_sliceRange];
@ -586,12 +586,12 @@ namespace bgfx { namespace mtl
{
return (uint32_t)m_obj.height;
}
uint32_t arrayLength() const
{
return (uint32_t)m_obj.arrayLength;
}
MTLPixelFormat pixelFormat() const
{
return m_obj.pixelFormat;
@ -841,7 +841,7 @@ namespace bgfx { namespace mtl
};
struct PipelineStateMtl;
struct ProgramMtl
{
ProgramMtl()
@ -860,7 +860,7 @@ namespace bgfx { namespace mtl
const ShaderMtl* m_vsh;
const ShaderMtl* m_fsh;
PipelineStateMtl* m_computePS;
};
@ -896,7 +896,7 @@ namespace bgfx { namespace mtl
UniformBuffer::destroy(m_fshConstantBuffer);
m_fshConstantBuffer = NULL;
}
release(m_rps);
release(m_cps);
}
@ -911,7 +911,7 @@ namespace bgfx { namespace mtl
SamplerInfo m_samplers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
uint32_t m_samplerCount;
uint32_t m_numThreads[3];
PredefinedUniform m_predefined[PredefinedUniform::Count*2];
@ -946,8 +946,10 @@ namespace bgfx { namespace mtl
, m_depth(0)
, m_numMips(0)
{
for(int i=0;i<BX_COUNTOF(m_ptrMips);++i)
m_ptrMips[i] = NULL;
for(uint32_t ii = 0; ii < BX_COUNTOF(m_ptrMips); ++ii)
{
m_ptrMips[ii] = NULL;
}
}
void create(const Memory* _mem, uint64_t _flags, uint8_t _skip);
@ -956,8 +958,10 @@ namespace bgfx { namespace mtl
{
MTL_RELEASE(m_ptr);
MTL_RELEASE(m_ptrStencil);
for(int i=0;i<m_numMips;++i)
MTL_RELEASE(m_ptrMips[i]);
for (uint32_t ii = 0; ii < m_numMips; ++ii)
{
MTL_RELEASE(m_ptrMips[ii]);
}
}
void update(
@ -978,7 +982,7 @@ namespace bgfx { namespace mtl
);
Texture getTextureMipLevel(int _mip);
Texture m_ptr;
Texture m_ptrMsaa;
Texture m_ptrStencil; // for emulating packed depth/stencil formats - only for iOS8...

View File

@ -1236,7 +1236,7 @@ namespace bgfx { namespace mtl
m_computeCommandEncoder = NULL;
}
}
void updateCapture()
{
if (m_resolution.reset&BGFX_RESET_CAPTURE)
@ -1713,7 +1713,7 @@ namespace bgfx { namespace mtl
m_renderCommandEncoder.setDepthStencilState(dss);
m_renderCommandEncoder.setStencilReferenceValue(ref);
}
void processArguments(PipelineStateMtl* ps,
NSArray <MTLArgument *>* _vertexArgs,
NSArray <MTLArgument *>* _fragmentArgs)
@ -1726,7 +1726,7 @@ namespace bgfx { namespace mtl
: ps->m_fshConstantBuffer
;
uint8_t fragmentBit = (1 == shaderType ? BGFX_UNIFORM_FRAGMENTBIT : 0);
for (MTLArgument* arg in (shaderType == 0 ? _vertexArgs : _fragmentArgs) )
{
BX_TRACE("arg: %s type:%d", utf8String(arg.name), arg.type);
@ -1737,7 +1737,7 @@ namespace bgfx { namespace mtl
{
BX_CHECK( arg.index == 0, "Uniform buffer must be in the buffer slot 0.");
BX_CHECK( MTLDataTypeStruct == arg.bufferDataType, "%s's type must be a struct",SHADER_UNIFORM_NAME );
if (MTLDataTypeStruct == arg.bufferDataType)
{
if (shaderType == 0)
@ -1750,15 +1750,15 @@ namespace bgfx { namespace mtl
ps->m_fshConstantBufferSize = (uint32_t)arg.bufferDataSize;
ps->m_fshConstantBufferAlignmentMask = (uint32_t)arg.bufferAlignment - 1;
}
for (MTLStructMember* uniform in arg.bufferStructType.members )
{
const char* name = utf8String(uniform.name);
BX_TRACE("uniform: %s type:%d", name, uniform.dataType);
MTLDataType dataType = uniform.dataType;
uint32_t num = 1;
if ( dataType == MTLDataTypeInt && bx::strLen(name) > 14
&& 0 == bx::strCmp(name, "NUM_THREADS_", 12) )
{
@ -1768,24 +1768,24 @@ namespace bgfx { namespace mtl
bx::fromString(&ps->m_numThreads[dim], bx::StringView(name, 14, INT_MAX));
}
}
if (dataType == MTLDataTypeArray)
{
dataType = uniform.arrayType.elementType;
num = (uint32_t)uniform.arrayType.arrayLength;
}
switch (dataType)
{
case MTLDataTypeFloat4: num *= 1; break;
case MTLDataTypeFloat4x4: num *= 4; break;
case MTLDataTypeFloat3x3: num *= 3; break;
default:
BX_WARN(0, "Unsupported uniform MTLDataType: %d", uniform.dataType);
break;
}
PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
if (PredefinedUniform::Count != predefined)
{
@ -1798,14 +1798,14 @@ namespace bgfx { namespace mtl
{
const UniformRegInfo* info = s_renderMtl->m_uniformReg.find(name);
BX_WARN(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name);
if (NULL != info)
{
if (NULL == constantBuffer)
{
constantBuffer = UniformBuffer::create(1024);
}
UniformType::Enum type = convertMtlType(dataType);
constantBuffer->writeUniformHandle( (UniformType::Enum)(type|fragmentBit), uint32_t(uniform.offset), info->m_handle, uint16_t(num) );
BX_TRACE("store %s %d offset:%d", name, info->m_handle, uint32_t(uniform.offset) );
@ -1819,7 +1819,7 @@ namespace bgfx { namespace mtl
const char* name = utf8String(arg.name);
const UniformRegInfo* info = s_renderMtl->m_uniformReg.find(name);
BX_WARN(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name);
if (NULL != info)
{
if (ps->m_samplerCount >= BGFX_CONFIG_MAX_TEXTURE_SAMPLERS)
@ -1842,14 +1842,14 @@ namespace bgfx { namespace mtl
}
}
}
if (NULL != constantBuffer)
{
constantBuffer->finish();
}
}
}
PipelineStateMtl* getPipelineState(
uint64_t _state
@ -2128,24 +2128,24 @@ namespace bgfx { namespace mtl
, _numInstanceData
);
}
PipelineStateMtl* getComputePipelineState(ProgramHandle _program)
{
ProgramMtl& program = m_program[_program.idx];
if (NULL == program.m_computePS)
{
PipelineStateMtl* pso = BX_NEW(g_allocator, PipelineStateMtl);
program.m_computePS = pso;
ComputePipelineReflection reflection = NULL;
pso->m_cps = m_device.newComputePipelineStateWithFunction(program.m_vsh->m_function, MTLPipelineOptionBufferTypeInfo, &reflection);
processArguments(pso, reflection.arguments, NULL);
}
return program.m_computePS;
}
SamplerState getSamplerState(uint32_t _flags)
{
@ -2210,15 +2210,15 @@ namespace bgfx { namespace mtl
m_renderCommandEncoder.endEncoding();
m_renderCommandEncoder = 0;
}
if (0 != m_computeCommandEncoder)
{
m_computeCommandEncoder.endEncoding();
m_computeCommandEncoder = 0;
}
}
Device m_device;
OcclusionQueryMTL m_occlusionQuery;
TimerQueryMtl m_gpuTimer;
@ -2864,7 +2864,7 @@ namespace bgfx { namespace mtl
);
}
}
Texture TextureMtl::getTextureMipLevel(int _mip)
{
if ( _mip >= 0 && _mip < m_numMips && NULL != m_ptr)
@ -2873,10 +2873,10 @@ namespace bgfx { namespace mtl
{
m_ptrMips[_mip] = m_ptr.newTextureViewWithPixelFormat(m_ptr.pixelFormat(), m_ptr.textureType(), NSMakeRange(_mip,1), NSMakeRange(0,m_ptr.arrayLength()));
}
return m_ptrMips[_mip];
}
return 0;
}
@ -3613,37 +3613,37 @@ namespace bgfx { namespace mtl
|| fbh.idx != _render->m_view[view].m_fbh.idx))
{
endEncoding();
RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor();
renderPassDescriptor.visibilityResultBuffer = m_occlusionQuery.m_buffer;
fbh = _render->m_view[view].m_fbh;
uint32_t width = m_resolution.width;
uint32_t height = m_resolution.height;
if (isValid(fbh) )
{
FrameBufferMtl& frameBuffer = m_frameBuffers[fbh.idx];
width = frameBuffer.m_width;
height = frameBuffer.m_height;
}
clearWithRenderPass = true
&& 0 == viewRect.m_x
&& 0 == viewRect.m_y
&& width == viewRect.m_width
&& height == viewRect.m_height
;
setFrameBuffer(renderPassDescriptor, fbh);
if (clearWithRenderPass)
{
for (uint32_t ii = 0; ii < g_caps.limits.maxFBAttachments; ++ii)
{
MTLRenderPassColorAttachmentDescriptor* desc = renderPassDescriptor.colorAttachments[ii];
if (desc.texture != NULL)
{
if (0 != (BGFX_CLEAR_COLOR & clr.m_flags) )
@ -3666,20 +3666,20 @@ namespace bgfx { namespace mtl
float aa = clr.m_index[3]*1.0f/255.0f;
desc.clearColor = MTLClearColorMake(rr, gg, bb, aa);
}
desc.loadAction = MTLLoadActionClear;
}
else
{
desc.loadAction = MTLLoadActionLoad;
}
desc.storeAction = desc.texture.sampleCount > 1 ? MTLStoreActionMultisampleResolve : MTLStoreActionStore;
}
}
RenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.depthAttachment;
if (NULL != depthAttachment.texture)
{
depthAttachment.clearDepth = clr.m_depth;
@ -3692,9 +3692,9 @@ namespace bgfx { namespace mtl
: MTLStoreActionStore
;
}
RenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.stencilAttachment;
if (NULL != stencilAttachment.texture)
{
stencilAttachment.clearStencil = clr.m_stencil;
@ -3718,24 +3718,24 @@ namespace bgfx { namespace mtl
desc.loadAction = MTLLoadActionLoad;
}
}
RenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.depthAttachment;
if (NULL != depthAttachment.texture)
{
depthAttachment.loadAction = MTLLoadActionLoad;
depthAttachment.storeAction = MTLStoreActionStore;
}
RenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.stencilAttachment;
if (NULL != stencilAttachment.texture)
{
stencilAttachment.loadAction = MTLLoadActionLoad;
stencilAttachment.storeAction = MTLStoreActionStore;
}
}
rce = m_commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor);
m_renderCommandEncoder = rce;
m_renderCommandEncoderFrameBufferHandle = fbh;
@ -3745,14 +3745,14 @@ namespace bgfx { namespace mtl
{
rce.popDebugGroup();
}
if (BX_ENABLED(BGFX_CONFIG_DEBUG_MTL) )
{
rce.pushDebugGroup(s_viewName[view]);
}
rce.setTriangleFillMode(wireframe ? MTLTriangleFillModeLines : MTLTriangleFillModeFill);
MTLViewport vp;
vp.originX = viewState.m_rect.m_x;
vp.originY = viewState.m_rect.m_y;
@ -3761,7 +3761,7 @@ namespace bgfx { namespace mtl
vp.znear = 0.0f;
vp.zfar = 1.0f;
rce.setViewport(vp);
if (BGFX_CLEAR_NONE != (clr.m_flags & BGFX_CLEAR_MASK)
&& !clearWithRenderPass)
{
@ -3769,65 +3769,64 @@ namespace bgfx { namespace mtl
}
}
}
if (isCompute)
{
if (!wasCompute)
{
wasCompute = true;
endEncoding();
rce = NULL;
m_computeCommandEncoder = m_commandBuffer.computeCommandEncoder();
}
else if (viewChanged && BX_ENABLED(BGFX_CONFIG_DEBUG_MTL))
{
m_computeCommandEncoder.popDebugGroup();
}
if ( viewChanged && BX_ENABLED(BGFX_CONFIG_DEBUG_MTL))
{
s_viewName[view][3] = L'C';
m_computeCommandEncoder.pushDebugGroup(s_viewName[view]);
s_viewName[view][3] = L' ';
}
const RenderCompute& compute = renderItem.compute;
bool programChanged = false;
bool constantsChanged = compute.m_uniformBegin < compute.m_uniformEnd;
rendererUpdateUniforms(this, _render->m_uniformBuffer[compute.m_uniformIdx], compute.m_uniformBegin, compute.m_uniformEnd);
if (key.m_program.idx != currentProgram.idx)
{
currentProgram = key.m_program;
currentPso = getComputePipelineState(currentProgram);
if (NULL == currentPso)
{
currentProgram = BGFX_INVALID_HANDLE;
continue;
}
m_computeCommandEncoder.setComputePipelineState(currentPso->m_cps);
programChanged =
constantsChanged = true;
constantsChanged = true;
}
if (isValid(currentProgram) && NULL != currentPso)
if (isValid(currentProgram)
&& NULL != currentPso)
{
ProgramMtl& program = m_program[currentProgram.idx];
uint32_t vertexUniformBufferSize = currentPso->m_vshConstantBufferSize;
if (0 != vertexUniformBufferSize)
{
m_uniformBufferVertexOffset = BX_ALIGN_MASK(m_uniformBufferVertexOffset, currentPso->m_vshConstantBufferAlignmentMask);
m_computeCommandEncoder.setBuffer(m_uniformBuffer, m_uniformBufferVertexOffset, 0);
}
if (constantsChanged)
{
UniformBuffer* vcb = currentPso->m_vshConstantBuffer;
@ -3836,13 +3835,13 @@ namespace bgfx { namespace mtl
commit(*vcb);
}
}
viewState.setPredefined<4>(this, view, *currentPso, _render, compute);
m_uniformBufferVertexOffset += vertexUniformBufferSize;
}
BX_UNUSED(programChanged);
for (uint8_t stage = 0; stage < maxComputeBindings; ++stage)
{
const Binding& bind = renderBind.m_bind[stage];
@ -3856,12 +3855,12 @@ namespace bgfx { namespace mtl
m_computeCommandEncoder.setTexture(texture.getTextureMipLevel(bind.m_mip), stage);
}
break;
case Binding::Texture:
{
TextureMtl& texture = m_textures[bind.m_idx];
uint32_t flags = bind.m_samplerFlags;
m_computeCommandEncoder.setTexture(texture.m_ptr, stage);
m_computeCommandEncoder.setSamplerState(
0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & flags)
@ -3871,7 +3870,7 @@ namespace bgfx { namespace mtl
);
}
break;
case Binding::IndexBuffer:
case Binding::VertexBuffer:
{
@ -3885,18 +3884,18 @@ namespace bgfx { namespace mtl
}
}
}
MTLSize threadsPerGroup = MTLSizeMake(currentPso->m_numThreads[0], currentPso->m_numThreads[1], currentPso->m_numThreads[2]);
if (isValid(compute.m_indirectBuffer) )
{
const VertexBufferMtl& vb = m_vertexBuffers[compute.m_indirectBuffer.idx];
uint32_t numDrawIndirect = UINT16_MAX == compute.m_numIndirect
? vb.m_size/BGFX_CONFIG_DRAW_INDIRECT_STRIDE
: compute.m_numIndirect
;
uint32_t args = compute.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
for (uint32_t ii = 0; ii < numDrawIndirect; ++ii)
{
@ -3911,7 +3910,7 @@ namespace bgfx { namespace mtl
}
continue;
}
bool resetState = viewChanged || wasCompute;
@ -4259,17 +4258,17 @@ namespace bgfx { namespace mtl
if (isValid(draw.m_indirectBuffer) )
{
const VertexBufferMtl& vb = m_vertexBuffers[draw.m_indirectBuffer.idx];
if (isValid(draw.m_indexBuffer) )
{
const IndexBufferMtl& ib = m_indexBuffers[draw.m_indexBuffer.idx];
MTLIndexType indexType = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32) ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32;
numDrawIndirect = UINT16_MAX == draw.m_numIndirect
? vb.m_size/BGFX_CONFIG_DRAW_INDIRECT_STRIDE
: draw.m_numIndirect
;
for (uint32_t ii = 0; ii < numDrawIndirect; ++ii)
{
rce.drawIndexedPrimitives(prim.m_type,indexType, ib.getBuffer(), 0, vb.getBuffer(), (draw.m_startIndirect + ii )* BGFX_CONFIG_DRAW_INDIRECT_STRIDE);