Skip to content

Commit 450c4fb

Browse files
committed
mantle: create a graphics pipeline immediately if all dynamic states are supported
Unfortunately Battlefield 4 does use invalid depth stencil format when creating the pipeline, so the game needs a quirk to create a pipeline later, despite working properly without it on RADV.
1 parent c1dd7d8 commit 450c4fb

File tree

3 files changed

+282
-54
lines changed

3 files changed

+282
-54
lines changed

src/mantle/mantle_shader_pipeline.c

Lines changed: 277 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,11 @@ VkPipeline grPipelineFindOrCreateVkPipeline(
607607
GrDevice* grDevice = GET_OBJ_DEVICE(grPipeline);
608608
VkPipeline vkPipeline = VK_NULL_HANDLE;
609609

610+
if (grDevice->singleSlotGraphicsPipelineSupported && !quirkHas(QUIRK_GRAPHICS_PIPELINE_FORMAT_MISMATCH)) {
611+
assert(grPipeline->pipelineSlotCount > 0);
612+
return grPipeline->pipelineSlots[0].pipeline;
613+
}
614+
610615
AcquireSRWLockShared(&grPipeline->pipelineSlotsLock);
611616
// Assume that the attachment formats never change to reduce pipeline lookup overhead
612617
for (unsigned i = 0; i < grPipeline->pipelineSlotCount; i++) {
@@ -838,7 +843,7 @@ GR_RESULT GR_STDCALL grCreateGraphicsPipeline(
838843
.stage = stage->flags,
839844
.module = shaderModules[stageCount],
840845
.pName = "main",
841-
.pSpecializationInfo = NULL,
846+
.pSpecializationInfo = &specInfos[stageCount],
842847
};
843848

844849
stageCount++;
@@ -898,74 +903,290 @@ GR_RESULT GR_STDCALL grCreateGraphicsPipeline(
898903
LOGW("dual source blend is not implemented\n");
899904
}
900905

901-
unsigned attachmentCount = 0;
906+
descriptorSetCount = 0;
907+
for (unsigned i = 0; i < GR_MAX_DESCRIPTOR_SETS; i++) {
908+
descriptorSetCount += descriptorSetCounts[i];
909+
}
910+
pipelineLayout = getVkPipelineLayout(grDevice, descriptorSetCount, VK_PIPELINE_BIND_POINT_GRAPHICS);
911+
if (pipelineLayout == VK_NULL_HANDLE) {
912+
res = GR_ERROR_OUT_OF_MEMORY;
913+
goto bail;
914+
}
915+
902916
VkColorComponentFlags colorWriteMasks[GR_MAX_COLOR_TARGETS];
903917

904-
for (int i = 0; i < GR_MAX_COLOR_TARGETS; i++) {
905-
const GR_PIPELINE_CB_TARGET_STATE* target = &pCreateInfo->cbState.target[i];
918+
PipelineCreateInfo* pipelineCreateInfo = NULL;
919+
VkPipeline vkPipeline = VK_NULL_HANDLE;
920+
PipelineSlot* pipelineSlot = NULL;
921+
if (grDevice->singleSlotGraphicsPipelineSupported && !quirkHas(QUIRK_GRAPHICS_PIPELINE_FORMAT_MISMATCH) && !hasTessellation) {
922+
const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
923+
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
924+
.pNext = NULL,
925+
.flags = 0,
926+
.vertexBindingDescriptionCount = 0,
927+
.pVertexBindingDescriptions = NULL,
928+
.vertexAttributeDescriptionCount = 0,
929+
.pVertexAttributeDescriptions = NULL,
930+
};
931+
932+
const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = {
933+
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
934+
.pNext = NULL,
935+
.flags = 0,
936+
.topology = getVkPrimitiveTopology(pCreateInfo->iaState.topology),
937+
.primitiveRestartEnable = VK_FALSE,
938+
};
939+
940+
// Ignored if no tessellation shaders are present
941+
const VkPipelineTessellationStateCreateInfo tessellationStateCreateInfo = {
942+
.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
943+
.pNext = NULL,
944+
.flags = 0,
945+
.patchControlPoints = pCreateInfo->tessState.patchControlPoints,
946+
};
947+
948+
const VkPipelineViewportStateCreateInfo viewportStateCreateInfo = {
949+
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
950+
.pNext = NULL,
951+
.flags = 0,
952+
.viewportCount = 0, // Dynamic state
953+
.pViewports = NULL, // Dynamic state
954+
.scissorCount = 0, // Dynamic state
955+
.pScissors = NULL, // Dynamic state
956+
};
957+
958+
const VkPipelineRasterizationDepthClipStateCreateInfoEXT depthClipStateCreateInfo = {
959+
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT,
960+
.pNext = NULL,
961+
.flags = 0,
962+
.depthClipEnable = !!pCreateInfo->rsState.depthClipEnable,
963+
};
906964

907-
if (!target->blendEnable &&
908-
target->format.channelFormat == GR_CH_FMT_UNDEFINED &&
909-
target->format.numericFormat == GR_NUM_FMT_UNDEFINED &&
910-
target->channelWriteMask == 0) {
911-
colorWriteMasks[attachmentCount] = ~0u;
912-
} else {
913-
colorWriteMasks[attachmentCount] = getVkColorComponentFlags(target->channelWriteMask);
965+
const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = {
966+
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
967+
.pNext = &depthClipStateCreateInfo,
968+
.flags = 0,
969+
.depthClampEnable = VK_TRUE,
970+
.rasterizerDiscardEnable = VK_FALSE,
971+
.polygonMode = 0, // Dynamic state
972+
.cullMode = 0, // Dynamic state
973+
.frontFace = 0, // Dynamic state
974+
.depthBiasEnable = VK_TRUE,
975+
.depthBiasConstantFactor = 0.f, // Dynamic state
976+
.depthBiasClamp = 0.f, // Dynamic state
977+
.depthBiasSlopeFactor = 0.f, // Dynamic state
978+
.lineWidth = 1.f,
979+
};
980+
981+
const VkPipelineMultisampleStateCreateInfo msaaStateCreateInfo = {
982+
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
983+
.pNext = NULL,
984+
.flags = 0,
985+
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
986+
.sampleShadingEnable = VK_FALSE,
987+
.minSampleShading = 0.f,
988+
.pSampleMask = NULL,// Dynamic state
989+
.alphaToCoverageEnable = !!pCreateInfo->cbState.alphaToCoverageEnable,
990+
.alphaToOneEnable = VK_FALSE,
991+
};
992+
993+
const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo = {
994+
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
995+
.pNext = NULL,
996+
.flags = 0,
997+
.depthTestEnable = 0, // Dynamic state
998+
.depthWriteEnable = 0, // Dynamic state
999+
.depthCompareOp = 0, // Dynamic state
1000+
.depthBoundsTestEnable = 0, // Dynamic state
1001+
.stencilTestEnable = 0, // Dynamic state
1002+
.front = { 0 }, // Dynamic state
1003+
.back = { 0 }, // Dynamic state
1004+
.minDepthBounds = 0.f, // Dynamic state
1005+
.maxDepthBounds = 0.f, // Dynamic state
1006+
};
1007+
1008+
unsigned attachmentCount = 0;
1009+
VkPipelineColorBlendAttachmentState attachments[GR_MAX_COLOR_TARGETS];
1010+
VkFormat colorFormats[GR_MAX_COLOR_TARGETS];
1011+
VkFormat depthStencilFormat = getVkFormat(pCreateInfo->dbState.format);
1012+
1013+
for (unsigned i = 0; i < GR_MAX_COLOR_TARGETS; i++) {
1014+
const GR_PIPELINE_CB_TARGET_STATE* target = &pCreateInfo->cbState.target[i];
1015+
if (!target->blendEnable &&
1016+
target->format.channelFormat == GR_CH_FMT_UNDEFINED &&
1017+
target->format.numericFormat == GR_NUM_FMT_UNDEFINED &&
1018+
target->channelWriteMask == 0) {
1019+
continue;
1020+
}
1021+
1022+
attachments[attachmentCount] = (VkPipelineColorBlendAttachmentState) {
1023+
.blendEnable = VK_FALSE,// Dynamic state
1024+
.srcColorBlendFactor = 0,// Dynamic state
1025+
.dstColorBlendFactor = 0,// Dynamic state
1026+
.colorBlendOp = 0,// Dynamic state
1027+
.srcAlphaBlendFactor = 0,// Dynamic state
1028+
.dstAlphaBlendFactor = 0,// Dynamic state
1029+
.alphaBlendOp = 0,// Dynamic state
1030+
.colorWriteMask = getVkColorComponentFlags(target->channelWriteMask),
1031+
};
1032+
colorFormats[attachmentCount] = getVkFormat(target->format);
1033+
attachmentCount++;
9141034
}
9151035

916-
attachmentCount++;
917-
}
1036+
assert(attachmentCount < GR_MAX_COLOR_TARGETS);
1037+
const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = {
1038+
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1039+
.pNext = NULL,
1040+
.flags = 0,
1041+
.logicOpEnable = pCreateInfo->cbState.logicOp != GR_LOGIC_OP_COPY,
1042+
.logicOp = getVkLogicOp(pCreateInfo->cbState.logicOp),
1043+
.attachmentCount = attachmentCount,
1044+
.pAttachments = attachments,
1045+
.blendConstants = { 0.f }, // Dynamic state
1046+
};
9181047

919-
PipelineCreateInfo* pipelineCreateInfo = malloc(sizeof(PipelineCreateInfo));
920-
*pipelineCreateInfo = (PipelineCreateInfo) {
921-
.createFlags =
922-
((pCreateInfo->flags & GR_PIPELINE_CREATE_DISABLE_OPTIMIZATION) != 0 ?
923-
VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT : 0) |
924-
(grDevice->descriptorBufferSupported ? VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT : 0),
925-
.stageCount = stageCount,
926-
.stageCreateInfos = { { 0 } }, // Initialized below
927-
.specInfos = { { 0 } }, // Initialized below
928-
.specData = { NULL }, // Initialized below
929-
.mapEntries = { NULL }, // Initialized below
930-
.topology = getVkPrimitiveTopology(pCreateInfo->iaState.topology),
931-
.patchControlPoints = pCreateInfo->tessState.patchControlPoints,
932-
.depthClipEnable = !!pCreateInfo->rsState.depthClipEnable,
933-
.alphaToCoverageEnable = !!pCreateInfo->cbState.alphaToCoverageEnable,
934-
.logicOpEnable = pCreateInfo->cbState.logicOp != GR_LOGIC_OP_COPY,
935-
.logicOp = getVkLogicOp(pCreateInfo->cbState.logicOp),
936-
.colorWriteMasks = { 0 }, // Initialized below
937-
};
1048+
VkDynamicState dynamicStates[] = {
1049+
VK_DYNAMIC_STATE_DEPTH_BIAS,
1050+
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
1051+
VK_DYNAMIC_STATE_DEPTH_BOUNDS,
1052+
VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
1053+
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
1054+
VK_DYNAMIC_STATE_STENCIL_REFERENCE,
1055+
VK_DYNAMIC_STATE_CULL_MODE_EXT,
1056+
VK_DYNAMIC_STATE_FRONT_FACE_EXT,
1057+
VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT,
1058+
VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT,
1059+
VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
1060+
VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,
1061+
VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,
1062+
VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT,
1063+
VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT,
1064+
VK_DYNAMIC_STATE_STENCIL_OP_EXT,
1065+
VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
1066+
VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT,
1067+
VK_DYNAMIC_STATE_SAMPLE_MASK_EXT,
1068+
VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
1069+
VK_DYNAMIC_STATE_POLYGON_MODE_EXT,
1070+
};
9381071

939-
memcpy(pipelineCreateInfo->stageCreateInfos, shaderStageCreateInfo,
940-
stageCount * sizeof(VkPipelineShaderStageCreateInfo));
941-
memcpy(pipelineCreateInfo->specInfos, specInfos, sizeof(specInfos));
942-
memcpy(pipelineCreateInfo->specData, specData, sizeof(specData));
943-
memcpy(pipelineCreateInfo->mapEntries, mapEntries, sizeof(mapEntries));
944-
memcpy(pipelineCreateInfo->colorWriteMasks, colorWriteMasks,
945-
GR_MAX_COLOR_TARGETS * sizeof(VkColorComponentFlags));
1072+
const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = {
1073+
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1074+
.pNext = NULL,
1075+
.flags = 0,
1076+
.dynamicStateCount = COUNT_OF(dynamicStates),
1077+
.pDynamicStates = dynamicStates,
1078+
};
9461079

947-
for (unsigned i = 0; i < MAX_STAGE_COUNT; i++) {
948-
pipelineCreateInfo->stageCreateInfos[i].pSpecializationInfo = &pipelineCreateInfo->specInfos[i];
949-
}
1080+
const VkPipelineRenderingCreateInfoKHR renderingCreateInfo = {
1081+
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
1082+
.pNext = NULL,
1083+
.viewMask = 0,
1084+
.colorAttachmentCount = attachmentCount,
1085+
.pColorAttachmentFormats = colorFormats,
1086+
.depthAttachmentFormat = vkFormatSupportsDepth(depthStencilFormat) ? depthStencilFormat : VK_FORMAT_UNDEFINED,
1087+
.stencilAttachmentFormat = vkFormatSupportsStencil(depthStencilFormat) ? depthStencilFormat : VK_FORMAT_UNDEFINED,
1088+
};
9501089

951-
descriptorSetCount = 0;
952-
for (unsigned i = 0; i < GR_MAX_DESCRIPTOR_SETS; i++) {
953-
descriptorSetCount += descriptorSetCounts[i];
954-
}
955-
pipelineLayout = getVkPipelineLayout(grDevice, descriptorSetCount, VK_PIPELINE_BIND_POINT_GRAPHICS);
956-
if (pipelineLayout == VK_NULL_HANDLE) {
957-
res = GR_ERROR_OUT_OF_MEMORY;
958-
goto bail;
1090+
const VkGraphicsPipelineCreateInfo pipelineCreateInfo = {
1091+
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1092+
.pNext = &renderingCreateInfo,
1093+
.flags = ((pCreateInfo->flags & GR_PIPELINE_CREATE_DISABLE_OPTIMIZATION) != 0 ?
1094+
VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT : 0) |
1095+
(grDevice->descriptorBufferSupported ? VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT : 0),
1096+
.stageCount = stageCount,
1097+
.pStages = shaderStageCreateInfo,
1098+
.pVertexInputState = &vertexInputStateCreateInfo,
1099+
.pInputAssemblyState = &inputAssemblyStateCreateInfo,
1100+
.pTessellationState = &tessellationStateCreateInfo,
1101+
.pViewportState = &viewportStateCreateInfo,
1102+
.pRasterizationState = &rasterizationStateCreateInfo,
1103+
.pMultisampleState = &msaaStateCreateInfo,
1104+
.pDepthStencilState = &depthStencilStateCreateInfo,
1105+
.pColorBlendState = &colorBlendStateCreateInfo,
1106+
.pDynamicState = &dynamicStateCreateInfo,
1107+
.layout = pipelineLayout,
1108+
.renderPass = VK_NULL_HANDLE,
1109+
.subpass = 0,
1110+
.basePipelineHandle = VK_NULL_HANDLE,
1111+
.basePipelineIndex = 0,
1112+
};
1113+
vkRes = VKD.vkCreateGraphicsPipelines(grDevice->device, VK_NULL_HANDLE, 1, &pipelineCreateInfo,
1114+
NULL, &vkPipeline);
1115+
if (vkRes != VK_SUCCESS) {
1116+
res = getGrResult(vkRes);
1117+
goto bail;
1118+
}
1119+
pipelineSlot = malloc(sizeof(PipelineSlot));
1120+
*pipelineSlot = (PipelineSlot) {
1121+
.pipeline = vkPipeline,
1122+
.grColorBlendState = NULL,
1123+
};
1124+
1125+
for (uint32_t i = 0; i < MAX_STAGE_COUNT; i++) {
1126+
VKD.vkDestroyShaderModule(grDevice->device, shaderModules[i], NULL);
1127+
free(specData[i]);
1128+
free(mapEntries[i]);
1129+
}
1130+
1131+
} else {
1132+
unsigned attachmentCount = 0;
1133+
for (int i = 0; i < GR_MAX_COLOR_TARGETS; i++) {
1134+
const GR_PIPELINE_CB_TARGET_STATE* target = &pCreateInfo->cbState.target[i];
1135+
1136+
if (!target->blendEnable &&
1137+
target->format.channelFormat == GR_CH_FMT_UNDEFINED &&
1138+
target->format.numericFormat == GR_NUM_FMT_UNDEFINED &&
1139+
target->channelWriteMask == 0) {
1140+
colorWriteMasks[attachmentCount] = ~0u;
1141+
} else {
1142+
colorWriteMasks[attachmentCount] = getVkColorComponentFlags(target->channelWriteMask);
1143+
}
1144+
1145+
attachmentCount++;
1146+
}
1147+
1148+
pipelineCreateInfo = malloc(sizeof(PipelineCreateInfo));
1149+
*pipelineCreateInfo = (PipelineCreateInfo) {
1150+
.createFlags =
1151+
((pCreateInfo->flags & GR_PIPELINE_CREATE_DISABLE_OPTIMIZATION) != 0 ?
1152+
VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT : 0) |
1153+
(grDevice->descriptorBufferSupported ? VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT : 0),
1154+
.stageCount = stageCount,
1155+
.stageCreateInfos = { { 0 } }, // Initialized below
1156+
.specInfos = { { 0 } }, // Initialized below
1157+
.specData = { NULL }, // Initialized below
1158+
.mapEntries = { NULL }, // Initialized below
1159+
.topology = getVkPrimitiveTopology(pCreateInfo->iaState.topology),
1160+
.patchControlPoints = pCreateInfo->tessState.patchControlPoints,
1161+
.depthClipEnable = !!pCreateInfo->rsState.depthClipEnable,
1162+
.alphaToCoverageEnable = !!pCreateInfo->cbState.alphaToCoverageEnable,
1163+
.logicOpEnable = pCreateInfo->cbState.logicOp != GR_LOGIC_OP_COPY,
1164+
.logicOp = getVkLogicOp(pCreateInfo->cbState.logicOp),
1165+
.colorWriteMasks = { 0 }, // Initialized below
1166+
};
1167+
1168+
memcpy(pipelineCreateInfo->stageCreateInfos, shaderStageCreateInfo,
1169+
stageCount * sizeof(VkPipelineShaderStageCreateInfo));
1170+
memcpy(pipelineCreateInfo->specInfos, specInfos, sizeof(specInfos));
1171+
memcpy(pipelineCreateInfo->specData, specData, sizeof(specData));
1172+
memcpy(pipelineCreateInfo->mapEntries, mapEntries, sizeof(mapEntries));
1173+
memcpy(pipelineCreateInfo->colorWriteMasks, colorWriteMasks,
1174+
GR_MAX_COLOR_TARGETS * sizeof(VkColorComponentFlags));
1175+
1176+
for (unsigned i = 0; i < MAX_STAGE_COUNT; i++) {
1177+
pipelineCreateInfo->stageCreateInfos[i].pSpecializationInfo = &pipelineCreateInfo->specInfos[i];
1178+
}
9591179
}
1180+
9601181
// TODO keep track of rectangle shader module
9611182
GrPipeline* grPipeline = malloc(sizeof(GrPipeline));
9621183
*grPipeline = (GrPipeline) {
9631184
.grObj = { GR_OBJ_TYPE_PIPELINE, grDevice },
9641185
.shaderModules = { VK_NULL_HANDLE },
9651186
.createInfo = pipelineCreateInfo,
9661187
.hasTessellation = hasTessellation,
967-
.pipelineSlotCount = 0,
968-
.pipelineSlots = NULL,
1188+
.pipelineSlotCount = pipelineSlot == NULL ? 0 : 1,
1189+
.pipelineSlots = pipelineSlot,
9691190
.pipelineSlotsLock = SRWLOCK_INIT,
9701191
.pipelineLayout = pipelineLayout,
9711192
.stageCount = COUNT_OF(stages),
@@ -975,7 +1196,9 @@ GR_RESULT GR_STDCALL grCreateGraphicsPipeline(
9751196
.descriptorSlots = { NULL }, // Initialized below
9761197
};
9771198

978-
memcpy(grPipeline->shaderModules, shaderModules, sizeof(grPipeline->shaderModules));
1199+
if (!(grDevice->singleSlotGraphicsPipelineSupported && !quirkHas(QUIRK_GRAPHICS_PIPELINE_FORMAT_MISMATCH))) {
1200+
memcpy(grPipeline->shaderModules, shaderModules, sizeof(grPipeline->shaderModules));
1201+
}
9791202

9801203
memcpy(grPipeline->descriptorSetCounts, descriptorSetCounts,
9811204
sizeof(grPipeline->descriptorSetCounts));
@@ -998,6 +1221,7 @@ GR_RESULT GR_STDCALL grCreateGraphicsPipeline(
9981221
free(specData[i]);
9991222
free(mapEntries[i]);
10001223
}
1224+
free(pipelineSlot);
10011225
return res;
10021226
}
10031227

src/mantle/quirk.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ void quirkInit(
1616
QUIRK_DESCRIPTOR_SET_USE_DEDICATED_ALLOCATION |
1717
QUIRK_DESCRIPTOR_SET_INTERNAL_SYNCHRONIZED;
1818
} else if (!strcmp(appInfo->pAppName, "Battlefield")) {
19-
mQuirks = QUIRK_TARGET_AND_SHADER_READ_ONLY_IMAGE_STATE_MISMATCH;
19+
mQuirks = QUIRK_TARGET_AND_SHADER_READ_ONLY_IMAGE_STATE_MISMATCH |
20+
QUIRK_GRAPHICS_PIPELINE_FORMAT_MISMATCH;
2021
} else if (!strcmp(appInfo->pEngineName, "CivTech")) {
2122
mQuirks = QUIRK_NON_ZERO_MEM_REQ |
2223
QUIRK_READ_ONLY_IMAGE_STATE_MISMATCH |

0 commit comments

Comments
 (0)