Add Toggles to disable base vertex and base instance rendering
These are not supported on some older OpenGL, OpenGL ES, and iOS devices. Bug: dawn:343 Change-Id: I70def749ae57fcfe2895f8556674dd241941d3d3 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/16163 Reviewed-by: Austin Eng <enga@chromium.org> Reviewed-by: Jiawei Shao <jiawei.shao@intel.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
2f0f850da8
commit
a9d7d47842
|
@ -27,13 +27,17 @@
|
||||||
namespace dawn_native {
|
namespace dawn_native {
|
||||||
|
|
||||||
RenderEncoderBase::RenderEncoderBase(DeviceBase* device, EncodingContext* encodingContext)
|
RenderEncoderBase::RenderEncoderBase(DeviceBase* device, EncodingContext* encodingContext)
|
||||||
: ProgrammablePassEncoder(device, encodingContext) {
|
: ProgrammablePassEncoder(device, encodingContext),
|
||||||
|
mDisableBaseVertex(device->IsToggleEnabled(Toggle::DisableBaseVertex)),
|
||||||
|
mDisableBaseInstance(device->IsToggleEnabled(Toggle::DisableBaseInstance)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderEncoderBase::RenderEncoderBase(DeviceBase* device,
|
RenderEncoderBase::RenderEncoderBase(DeviceBase* device,
|
||||||
EncodingContext* encodingContext,
|
EncodingContext* encodingContext,
|
||||||
ErrorTag errorTag)
|
ErrorTag errorTag)
|
||||||
: ProgrammablePassEncoder(device, encodingContext, errorTag) {
|
: ProgrammablePassEncoder(device, encodingContext, errorTag),
|
||||||
|
mDisableBaseVertex(device->IsToggleEnabled(Toggle::DisableBaseVertex)),
|
||||||
|
mDisableBaseInstance(device->IsToggleEnabled(Toggle::DisableBaseInstance)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderEncoderBase::Draw(uint32_t vertexCount,
|
void RenderEncoderBase::Draw(uint32_t vertexCount,
|
||||||
|
@ -41,6 +45,10 @@ namespace dawn_native {
|
||||||
uint32_t firstVertex,
|
uint32_t firstVertex,
|
||||||
uint32_t firstInstance) {
|
uint32_t firstInstance) {
|
||||||
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
|
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
|
||||||
|
if (mDisableBaseInstance && firstInstance != 0) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Non-zero first instance not supported");
|
||||||
|
}
|
||||||
|
|
||||||
DrawCmd* draw = allocator->Allocate<DrawCmd>(Command::Draw);
|
DrawCmd* draw = allocator->Allocate<DrawCmd>(Command::Draw);
|
||||||
draw->vertexCount = vertexCount;
|
draw->vertexCount = vertexCount;
|
||||||
draw->instanceCount = instanceCount;
|
draw->instanceCount = instanceCount;
|
||||||
|
@ -57,6 +65,13 @@ namespace dawn_native {
|
||||||
int32_t baseVertex,
|
int32_t baseVertex,
|
||||||
uint32_t firstInstance) {
|
uint32_t firstInstance) {
|
||||||
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
|
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
|
||||||
|
if (mDisableBaseInstance && firstInstance != 0) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Non-zero first instance not supported");
|
||||||
|
}
|
||||||
|
if (mDisableBaseInstance && baseVertex != 0) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Non-zero base vertex not supported");
|
||||||
|
}
|
||||||
|
|
||||||
DrawIndexedCmd* draw = allocator->Allocate<DrawIndexedCmd>(Command::DrawIndexed);
|
DrawIndexedCmd* draw = allocator->Allocate<DrawIndexedCmd>(Command::DrawIndexed);
|
||||||
draw->indexCount = indexCount;
|
draw->indexCount = indexCount;
|
||||||
draw->instanceCount = instanceCount;
|
draw->instanceCount = instanceCount;
|
||||||
|
|
|
@ -45,6 +45,10 @@ namespace dawn_native {
|
||||||
protected:
|
protected:
|
||||||
// Construct an "error" render encoder base.
|
// Construct an "error" render encoder base.
|
||||||
RenderEncoderBase(DeviceBase* device, EncodingContext* encodingContext, ErrorTag errorTag);
|
RenderEncoderBase(DeviceBase* device, EncodingContext* encodingContext, ErrorTag errorTag);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const bool mDisableBaseVertex;
|
||||||
|
const bool mDisableBaseInstance;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
|
|
@ -106,6 +106,13 @@ namespace dawn_native {
|
||||||
{"metal_disable_sampler_compare",
|
{"metal_disable_sampler_compare",
|
||||||
"Disables the use of sampler compare on Metal. This is unsupported before A9 "
|
"Disables the use of sampler compare on Metal. This is unsupported before A9 "
|
||||||
"processors."}},
|
"processors."}},
|
||||||
|
{Toggle::DisableBaseVertex,
|
||||||
|
{"disable_base_vertex",
|
||||||
|
"Disables the use of non-zero base vertex which is unsupported on some platforms."}},
|
||||||
|
{Toggle::DisableBaseInstance,
|
||||||
|
{"disable_base_instance",
|
||||||
|
"Disables the use of non-zero base instance which is unsupported on some "
|
||||||
|
"platforms."}},
|
||||||
}};
|
}};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
|
@ -37,6 +37,8 @@ namespace dawn_native {
|
||||||
UseSpvcParser,
|
UseSpvcParser,
|
||||||
VulkanUseD32S8,
|
VulkanUseD32S8,
|
||||||
MetalDisableSamplerCompare,
|
MetalDisableSamplerCompare,
|
||||||
|
DisableBaseVertex,
|
||||||
|
DisableBaseInstance,
|
||||||
|
|
||||||
EnumCount,
|
EnumCount,
|
||||||
InvalidEnum = EnumCount,
|
InvalidEnum = EnumCount,
|
||||||
|
|
|
@ -1018,11 +1018,19 @@ namespace dawn_native { namespace metal {
|
||||||
|
|
||||||
// The instance count must be non-zero, otherwise no-op
|
// The instance count must be non-zero, otherwise no-op
|
||||||
if (draw->instanceCount != 0) {
|
if (draw->instanceCount != 0) {
|
||||||
[encoder drawPrimitives:lastPipeline->GetMTLPrimitiveTopology()
|
// MTLFeatureSet_iOS_GPUFamily3_v1 does not support baseInstance
|
||||||
vertexStart:draw->firstVertex
|
if (draw->firstInstance == 0) {
|
||||||
vertexCount:draw->vertexCount
|
[encoder drawPrimitives:lastPipeline->GetMTLPrimitiveTopology()
|
||||||
instanceCount:draw->instanceCount
|
vertexStart:draw->firstVertex
|
||||||
baseInstance:draw->firstInstance];
|
vertexCount:draw->vertexCount
|
||||||
|
instanceCount:draw->instanceCount];
|
||||||
|
} else {
|
||||||
|
[encoder drawPrimitives:lastPipeline->GetMTLPrimitiveTopology()
|
||||||
|
vertexStart:draw->firstVertex
|
||||||
|
vertexCount:draw->vertexCount
|
||||||
|
instanceCount:draw->instanceCount
|
||||||
|
baseInstance:draw->firstInstance];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -1037,15 +1045,27 @@ namespace dawn_native { namespace metal {
|
||||||
|
|
||||||
// The index and instance count must be non-zero, otherwise no-op
|
// The index and instance count must be non-zero, otherwise no-op
|
||||||
if (draw->indexCount != 0 && draw->instanceCount != 0) {
|
if (draw->indexCount != 0 && draw->instanceCount != 0) {
|
||||||
[encoder drawIndexedPrimitives:lastPipeline->GetMTLPrimitiveTopology()
|
// MTLFeatureSet_iOS_GPUFamily3_v1 does not support baseInstance and
|
||||||
indexCount:draw->indexCount
|
// baseVertex.
|
||||||
indexType:lastPipeline->GetMTLIndexType()
|
if (draw->baseVertex == 0 && draw->firstInstance == 0) {
|
||||||
indexBuffer:indexBuffer
|
[encoder drawIndexedPrimitives:lastPipeline->GetMTLPrimitiveTopology()
|
||||||
indexBufferOffset:indexBufferBaseOffset +
|
indexCount:draw->indexCount
|
||||||
draw->firstIndex * formatSize
|
indexType:lastPipeline->GetMTLIndexType()
|
||||||
instanceCount:draw->instanceCount
|
indexBuffer:indexBuffer
|
||||||
baseVertex:draw->baseVertex
|
indexBufferOffset:indexBufferBaseOffset +
|
||||||
baseInstance:draw->firstInstance];
|
draw->firstIndex * formatSize
|
||||||
|
instanceCount:draw->instanceCount];
|
||||||
|
} else {
|
||||||
|
[encoder drawIndexedPrimitives:lastPipeline->GetMTLPrimitiveTopology()
|
||||||
|
indexCount:draw->indexCount
|
||||||
|
indexType:lastPipeline->GetMTLIndexType()
|
||||||
|
indexBuffer:indexBuffer
|
||||||
|
indexBufferOffset:indexBufferBaseOffset +
|
||||||
|
draw->firstIndex * formatSize
|
||||||
|
instanceCount:draw->instanceCount
|
||||||
|
baseVertex:draw->baseVertex
|
||||||
|
baseInstance:draw->firstInstance];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,15 @@ namespace dawn_native { namespace metal {
|
||||||
#endif
|
#endif
|
||||||
// TODO(crbug.com/dawn/342): Investigate emulation -- possibly expensive.
|
// TODO(crbug.com/dawn/342): Investigate emulation -- possibly expensive.
|
||||||
SetToggle(Toggle::MetalDisableSamplerCompare, !haveSamplerCompare);
|
SetToggle(Toggle::MetalDisableSamplerCompare, !haveSamplerCompare);
|
||||||
|
|
||||||
|
bool haveBaseVertexBaseInstance = true;
|
||||||
|
#if defined(DAWN_PLATFORM_IOS)
|
||||||
|
haveBaseVertexBaseInstance =
|
||||||
|
[mMtlDevice supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v1];
|
||||||
|
#endif
|
||||||
|
// TODO(crbug.com/dawn/343): Investigate emulation.
|
||||||
|
SetToggle(Toggle::DisableBaseVertex, !haveBaseVertexBaseInstance);
|
||||||
|
SetToggle(Toggle::DisableBaseInstance, !haveBaseVertexBaseInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(jiawei.shao@intel.com): tighten this workaround when the driver bug is fixed.
|
// TODO(jiawei.shao@intel.com): tighten this workaround when the driver bug is fixed.
|
||||||
|
|
|
@ -869,12 +869,23 @@ namespace dawn_native { namespace opengl {
|
||||||
indexBufferBaseOffset),
|
indexBufferBaseOffset),
|
||||||
draw->instanceCount, draw->baseVertex, draw->firstInstance);
|
draw->instanceCount, draw->baseVertex, draw->firstInstance);
|
||||||
} else {
|
} else {
|
||||||
// This branch is only needed on OpenGL < 4.2
|
// This branch is only needed on OpenGL < 4.2; ES < 3.2
|
||||||
gl.DrawElementsInstancedBaseVertex(
|
if (draw->baseVertex != 0) {
|
||||||
lastPipeline->GetGLPrimitiveTopology(), draw->indexCount, formatType,
|
gl.DrawElementsInstancedBaseVertex(
|
||||||
reinterpret_cast<void*>(draw->firstIndex * formatSize +
|
lastPipeline->GetGLPrimitiveTopology(), draw->indexCount,
|
||||||
indexBufferBaseOffset),
|
formatType,
|
||||||
draw->instanceCount, draw->baseVertex);
|
reinterpret_cast<void*>(draw->firstIndex * formatSize +
|
||||||
|
indexBufferBaseOffset),
|
||||||
|
draw->instanceCount, draw->baseVertex);
|
||||||
|
} else {
|
||||||
|
// This branch is only needed on OpenGL < 3.2; ES < 3.2
|
||||||
|
gl.DrawElementsInstanced(
|
||||||
|
lastPipeline->GetGLPrimitiveTopology(), draw->indexCount,
|
||||||
|
formatType,
|
||||||
|
reinterpret_cast<void*>(draw->firstIndex * formatSize +
|
||||||
|
indexBufferBaseOffset),
|
||||||
|
draw->instanceCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ namespace dawn_native { namespace opengl {
|
||||||
const DeviceDescriptor* descriptor,
|
const DeviceDescriptor* descriptor,
|
||||||
const OpenGLFunctions& functions)
|
const OpenGLFunctions& functions)
|
||||||
: DeviceBase(adapter, descriptor), gl(functions) {
|
: DeviceBase(adapter, descriptor), gl(functions) {
|
||||||
|
InitTogglesFromDriver();
|
||||||
if (descriptor != nullptr) {
|
if (descriptor != nullptr) {
|
||||||
ApplyToggleOverrides(descriptor);
|
ApplyToggleOverrides(descriptor);
|
||||||
}
|
}
|
||||||
|
@ -46,6 +47,30 @@ namespace dawn_native { namespace opengl {
|
||||||
BaseDestructor();
|
BaseDestructor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Device::InitTogglesFromDriver() {
|
||||||
|
bool supportsBaseVertex = gl.IsAtLeastGLES(3, 2) || gl.IsAtLeastGL(3, 2);
|
||||||
|
|
||||||
|
bool supportsBaseInstance = gl.IsAtLeastGLES(3, 2) || gl.IsAtLeastGL(4, 2);
|
||||||
|
|
||||||
|
// TODO(crbug.com/dawn/343): We can support the extension variants, but need to load the EXT
|
||||||
|
// procs without the extension suffix.
|
||||||
|
// We'll also need emulation of shader builtins gl_BaseVertex and gl_BaseInstance.
|
||||||
|
|
||||||
|
// supportsBaseVertex |=
|
||||||
|
// (gl.IsAtLeastGLES(2, 0) &&
|
||||||
|
// (gl.IsGLExtensionSupported("OES_draw_elements_base_vertex") ||
|
||||||
|
// gl.IsGLExtensionSupported("EXT_draw_elements_base_vertex"))) ||
|
||||||
|
// (gl.IsAtLeastGL(3, 1) && gl.IsGLExtensionSupported("ARB_draw_elements_base_vertex"));
|
||||||
|
|
||||||
|
// supportsBaseInstance |=
|
||||||
|
// (gl.IsAtLeastGLES(3, 1) && gl.IsGLExtensionSupported("EXT_base_instance")) ||
|
||||||
|
// (gl.IsAtLeastGL(3, 1) && gl.IsGLExtensionSupported("ARB_base_instance"));
|
||||||
|
|
||||||
|
// TODO(crbug.com/dawn/343): Investigate emulation.
|
||||||
|
SetToggle(Toggle::DisableBaseVertex, !supportsBaseVertex);
|
||||||
|
SetToggle(Toggle::DisableBaseInstance, !supportsBaseInstance);
|
||||||
|
}
|
||||||
|
|
||||||
const GLFormat& Device::GetGLFormat(const Format& format) {
|
const GLFormat& Device::GetGLFormat(const Format& format) {
|
||||||
ASSERT(format.isSupported);
|
ASSERT(format.isSupported);
|
||||||
ASSERT(format.GetIndex() < mFormatTable.size());
|
ASSERT(format.GetIndex() < mFormatTable.size());
|
||||||
|
|
|
@ -89,6 +89,7 @@ namespace dawn_native { namespace opengl {
|
||||||
TextureBase* texture,
|
TextureBase* texture,
|
||||||
const TextureViewDescriptor* descriptor) override;
|
const TextureViewDescriptor* descriptor) override;
|
||||||
|
|
||||||
|
void InitTogglesFromDriver();
|
||||||
void CheckPassedFences();
|
void CheckPassedFences();
|
||||||
void Destroy() override;
|
void Destroy() override;
|
||||||
MaybeError WaitForIdleForDestruction() override;
|
MaybeError WaitForIdleForDestruction() override;
|
||||||
|
|
|
@ -74,12 +74,12 @@ namespace dawn_native { namespace opengl {
|
||||||
return mSupportedGLExtensionsSet.count(extension) != 0;
|
return mSupportedGLExtensionsSet.count(extension) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLFunctions::IsAtLeastGL(uint32_t majorVersion, uint32_t minorVersion) {
|
bool OpenGLFunctions::IsAtLeastGL(uint32_t majorVersion, uint32_t minorVersion) const {
|
||||||
return mStandard == Standard::Desktop &&
|
return mStandard == Standard::Desktop &&
|
||||||
std::tie(mMajorVersion, mMinorVersion) >= std::tie(majorVersion, minorVersion);
|
std::tie(mMajorVersion, mMinorVersion) >= std::tie(majorVersion, minorVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLFunctions::IsAtLeastGLES(uint32_t majorVersion, uint32_t minorVersion) {
|
bool OpenGLFunctions::IsAtLeastGLES(uint32_t majorVersion, uint32_t minorVersion) const {
|
||||||
return mStandard == Standard::ES &&
|
return mStandard == Standard::ES &&
|
||||||
std::tie(mMajorVersion, mMinorVersion) >= std::tie(majorVersion, minorVersion);
|
std::tie(mMajorVersion, mMinorVersion) >= std::tie(majorVersion, minorVersion);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,8 @@ namespace dawn_native { namespace opengl {
|
||||||
public:
|
public:
|
||||||
MaybeError Initialize(GetProcAddress getProc);
|
MaybeError Initialize(GetProcAddress getProc);
|
||||||
|
|
||||||
bool IsAtLeastGL(uint32_t majorVersion, uint32_t minorVersion);
|
bool IsAtLeastGL(uint32_t majorVersion, uint32_t minorVersion) const;
|
||||||
bool IsAtLeastGLES(uint32_t majorVersion, uint32_t minorVersion);
|
bool IsAtLeastGLES(uint32_t majorVersion, uint32_t minorVersion) const;
|
||||||
|
|
||||||
bool IsGLExtensionSupported(const char* extension) const;
|
bool IsGLExtensionSupported(const char* extension) const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue