mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Fix] (MG_Backend/DirectVulkan, MG_Impl): a malformed graphics pipeline shape skips the draw instead of faulting inside the driver
This commit is contained in:
@@ -4623,6 +4623,43 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shape gate. Behind the memo probe deliberately: only a pipeline that was created
|
||||||
|
// successfully is ever memoized, so a program refused here can never be sitting in the
|
||||||
|
// memo, and the steady-state draw keeps paying nothing for the check.
|
||||||
|
//
|
||||||
|
// vkCreateGraphicsPipelines is not a validating entry point: a stage set that a
|
||||||
|
// conformant implementation would reject with VK_ERROR_* is, on Adreno 830, a SIGSEGV
|
||||||
|
// inside the driver - process death instead of a failed draw. The separable-program path
|
||||||
|
// is what made these shapes reachable at all (a monolithic glUseProgram program cannot
|
||||||
|
// hold a compute stage together with graphics ones, a pipeline object can), so the three
|
||||||
|
// it can produce are named and refused here. Same philosophy as the VK_NULL_HANDLE gate
|
||||||
|
// in SetupDraw: hostile input degrades to a broken draw, never to a dead process. GL
|
||||||
|
// leaves all three undefined for a draw, so nothing legal is being turned away.
|
||||||
|
// MGLOG_I because the INFO builds CTS runs against keep only I and F.
|
||||||
|
{
|
||||||
|
Bool hasVertexStage = false;
|
||||||
|
for (const auto& stage : programObj.stages) {
|
||||||
|
if (stage.module == VK_NULL_HANDLE) {
|
||||||
|
MGLOG_I("GetOrCreatePipeline skipped: program=%u has a null shader module for stage 0x%x",
|
||||||
|
program.GetExternalIndex(), static_cast<unsigned>(stage.stage));
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
if (stage.stage == VK_SHADER_STAGE_COMPUTE_BIT) {
|
||||||
|
MGLOG_I("GetOrCreatePipeline skipped: program=%u carries a compute stage, which no graphics "
|
||||||
|
"pipeline may contain",
|
||||||
|
program.GetExternalIndex());
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
if (stage.stage == VK_SHADER_STAGE_VERTEX_BIT) {
|
||||||
|
hasVertexStage = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasVertexStage) {
|
||||||
|
MGLOG_I("GetOrCreatePipeline skipped: program=%u has no vertex stage", program.GetExternalIndex());
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG
|
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG
|
||||||
const auto& limits = m_physicalDevice.properties.limits;
|
const auto& limits = m_physicalDevice.properties.limits;
|
||||||
if (programObj.fragmentInputComponentCount != 0) {
|
if (programObj.fragmentInputComponentCount != 0) {
|
||||||
|
|||||||
@@ -670,6 +670,11 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
5 * sizeof(Uint32), __func__)) {
|
5 * sizeof(Uint32), __func__)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// The only two draw entry points that were missing this. Every backend draw path
|
||||||
|
// dereferences GetProgramForDraw() unconditionally, so "no current program" has to be
|
||||||
|
// stopped here or it is a null dereference rather than the INVALID_OPERATION the spec
|
||||||
|
// asks for - reachable through a bound pipeline that supplies no graphics stage.
|
||||||
|
if (!ValidateCurrentProgramForExecution(__func__)) return;
|
||||||
auto multiDrawElementsIndirectCount = MG_Backend::gBackendFunctionsTable.GL.MultiDrawElementsIndirectCount;
|
auto multiDrawElementsIndirectCount = MG_Backend::gBackendFunctionsTable.GL.MultiDrawElementsIndirectCount;
|
||||||
if (!multiDrawElementsIndirectCount) {
|
if (!multiDrawElementsIndirectCount) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
@@ -689,6 +694,8 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
4 * sizeof(Uint32), __func__)) {
|
4 * sizeof(Uint32), __func__)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// See MultiDrawElementsIndirectCount.
|
||||||
|
if (!ValidateCurrentProgramForExecution(__func__)) return;
|
||||||
auto multiDrawArraysIndirectCount = MG_Backend::gBackendFunctionsTable.GL.MultiDrawArraysIndirectCount;
|
auto multiDrawArraysIndirectCount = MG_Backend::gBackendFunctionsTable.GL.MultiDrawArraysIndirectCount;
|
||||||
if (!multiDrawArraysIndirectCount) {
|
if (!multiDrawArraysIndirectCount) {
|
||||||
MG_State::pGLContext->RecordError(
|
MG_State::pGLContext->RecordError(
|
||||||
|
|||||||
Reference in New Issue
Block a user