Metal: Fixed sampling textures through a sampler of another type, such as a 2D texture as a 2D array. (#4076)

This commit is contained in:
Branimir Karadžić
2026-10-20 22:26:20 -07:00
committed by GitHub
parent 09997c0805
commit 21a5cf8fc0
2 changed files with 60 additions and 45 deletions

View File

@@ -3052,11 +3052,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
: PipelineStateMtl::BindToVertexShader
;
if (MTL::TextureType2DMultisample == arg->textureType()
|| MTL::TextureType2DMultisampleArray == arg->textureType() )
{
ps->m_bindingTypes[arg->index()] |= PipelineStateMtl::BindMultisample;
}
ps->m_textureTypes[arg->index()] = uint8_t(arg->textureType() );
const UniformRegInfo* info = s_renderMtl->m_uniformReg.find(name);
@@ -4815,7 +4811,23 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
;
}
void TextureMtl::commit(uint8_t _stage, bool _vertex, bool _fragment, uint32_t _flags, uint8_t _mip, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, uint8_t _lodMin, uint8_t _lodMax, bool _multisample)
MTL::Texture* TextureMtl::getSampledView(uint8_t _textureType, uint32_t _flags, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, bool _stencil)
{
if (MTL::TextureType2DMultisample == _textureType
|| MTL::TextureType2DMultisampleArray == _textureType)
{
MTL::Texture* ptr = getMultisampleView(_flags);
if (NULL != ptr)
{
return ptr;
}
}
return getTextureView(_firstLayer, _numLayers, _firstMip, _numMips, _stencil, useAltFormat(_flags, BGFX_SAMPLER_SRGB), _textureType);
}
void TextureMtl::commit(uint8_t _stage, bool _vertex, bool _fragment, uint32_t _flags, uint8_t _mip, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, uint8_t _lodMin, uint8_t _lodMax, uint8_t _textureType)
{
if (!_vertex
&& !_fragment)
@@ -4829,19 +4841,11 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
;
const bool sampleStencil = 0 != (flags & BGFX_SAMPLER_SAMPLE_STENCIL);
MTL::Texture* ptr = _multisample && _mip == UINT8_MAX
? getMultisampleView(flags)
: NULL
MTL::Texture* ptr = _mip != UINT8_MAX
? getTextureImage(_mip, _firstLayer, _numLayers)
: getSampledView(_textureType, flags, _firstLayer, _numLayers, _firstMip, _numMips, sampleStencil)
;
if (NULL == ptr)
{
ptr = _mip != UINT8_MAX
? getTextureImage(_mip, _firstLayer, _numLayers)
: getTextureView(_firstLayer, _numLayers, _firstMip, _numMips, sampleStencil, useAltFormat(flags, BGFX_SAMPLER_SRGB) )
;
}
if (_vertex)
{
s_renderMtl->m_renderCommandEncoder->setVertexTexture(ptr, _stage);
@@ -4884,7 +4888,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
;
}
MTL::Texture* TextureMtl::getTextureView(uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, bool _stencil, bool _alt)
MTL::Texture* TextureMtl::getTextureView(uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, bool _stencil, bool _alt, uint8_t _textureType)
{
MTL::Texture* ptr = _stencil && NULL != m_ptrStencil
? m_ptrStencil
@@ -4931,10 +4935,37 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
const uint32_t firstLayer = firstUnit * rangeScale;
const uint32_t numLayers = numUnits * rangeScale;
MTL::TextureType type = ptr->textureType();
if (isCube)
{
type = 1 == numUnits
? (MTL::TextureType)MTL::TextureTypeCube
: (MTL::TextureType)MTL::TextureTypeCubeArray
;
}
else if (MTL::TextureType2DArray == type
&& 1 == numLayers)
{
type = (MTL::TextureType)MTL::TextureType2D;
}
const bool arrayOf2D = MTL::TextureType2D == type || MTL::TextureType2DArray == type;
const bool arrayOfCube = MTL::TextureTypeCube == type || MTL::TextureTypeCubeArray == type;
const bool wants2D = MTL::TextureType2D == _textureType || MTL::TextureType2DArray == _textureType;
const bool wantsCube = MTL::TextureTypeCube == _textureType || MTL::TextureTypeCubeArray == _textureType;
if ( (arrayOf2D && wants2D && (MTL::TextureType2DArray == _textureType || 1 == numLayers) )
|| (arrayOfCube && wantsCube && (MTL::TextureTypeCubeArray == _textureType || 1 == numUnits ) ) )
{
type = MTL::TextureType(_textureType);
}
const bool fullRange = 0 == firstMip
&& 0 == firstLayer
&& numMips >= m_numMips
&& numLayers >= totalLayers
&& type == ptr->textureType()
;
if (fullRange
@@ -4954,6 +4985,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
| (uint64_t(numMips) << 8)
| (uint64_t(firstLayer) << 16)
| (uint64_t(numLayers) << 32)
| (uint64_t(type) << 48)
| (uint64_t(alt) << 62)
| (uint64_t(_stencil) << 63)
;
@@ -4964,21 +4996,6 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
return it->second;
}
MTL::TextureType type = ptr->textureType();
if (isCube)
{
type = 1 == numUnits
? (MTL::TextureType)MTL::TextureTypeCube
: (MTL::TextureType)MTL::TextureTypeCubeArray
;
}
else if (MTL::TextureType2DArray == type
&& 1 == numLayers)
{
type = (MTL::TextureType)MTL::TextureType2D;
}
MTL::Texture* view = ptr->newTextureView(
format
, type
@@ -6820,14 +6837,8 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
: uint32_t(texture.m_flags)
;
MTL::Texture* ptr = 0 != (currentPso->m_bindingTypes[stage] & PipelineStateMtl::BindMultisample)
? texture.getMultisampleView(resolvedFlags)
: NULL
;
m_computeCommandEncoder->setTexture(NULL != ptr
? ptr
: texture.getTextureView(bind.m_firstLayer, bind.m_numLayers, bind.m_firstMip, bind.m_numMips, 0 != (resolvedFlags & BGFX_SAMPLER_SAMPLE_STENCIL) )
m_computeCommandEncoder->setTexture(
texture.getSampledView(currentPso->m_textureTypes[stage], resolvedFlags, bind.m_firstLayer, bind.m_numLayers, bind.m_firstMip, bind.m_numMips, 0 != (resolvedFlags & BGFX_SAMPLER_SAMPLE_STENCIL) )
, stage
);
m_computeCommandEncoder->setSamplerState(
@@ -7271,7 +7282,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
, bind.m_numMips
, bind.m_lod.min
, bind.m_lod.max
, 0 != (bindingTypes[stage] & PipelineStateMtl::BindMultisample)
, currentPso->m_textureTypes[stage]
);
}
break;

View File

@@ -397,6 +397,7 @@ namespace bgfx { namespace mtl
for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++ii)
{
m_bindingTypes[ii] = 0;
m_textureTypes[ii] = kTextureTypeAny;
}
}
@@ -430,10 +431,12 @@ namespace bgfx { namespace mtl
{
BindToVertexShader = 1 << 0,
BindToFragmentShader = 1 << 1,
BindMultisample = 1 << 2,
};
uint8_t m_bindingTypes[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
static constexpr uint8_t kTextureTypeAny = UINT8_MAX;
uint8_t m_textureTypes[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
uint16_t m_numThreads[3];
PredefinedUniform m_predefined[PredefinedUniform::Count*2];
@@ -512,13 +515,14 @@ namespace bgfx { namespace mtl
, uint8_t _numMips = UINT8_MAX
, uint8_t _lodMin = 0
, uint8_t _lodMax = UINT8_MAX
, bool _multisample = false
, uint8_t _textureType = UINT8_MAX
);
MTL::Texture* getMultisampleView(uint32_t _flags) const;
MTL::Texture* getSampledView(uint8_t _textureType, uint32_t _flags, uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, bool _stencil);
MTL::Texture* getTextureImage(uint8_t _mip, uint16_t _firstLayer = 0, uint16_t _numLayers = UINT16_MAX);
MTL::Texture* getTextureView(uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, bool _stencil = false, bool _alt = false);
MTL::Texture* getTextureView(uint16_t _firstLayer, uint16_t _numLayers, uint8_t _firstMip, uint8_t _numMips, bool _stencil = false, bool _alt = false, uint8_t _textureType = UINT8_MAX);
bool useAltFormat(uint32_t _flags, uint32_t _bit) const;
MTL::PixelFormat getAttachmentPixelFormat(uint8_t _flags) const;