Skip to content

Commit 4399701

Browse files
ShabbyXCommit Bot
authored andcommitted
Vulkan: fix non-float clear with draw
Instead of using one draw call that clears all attachments, multiple draw calls are issued that clear a single attachment each. This allows us to have a manageable number of variations for the ImageClear.frag shader, now that non-float format support is introduced. Bug: angleproject:3187 Change-Id: Ic0c1067a396250bd80f31d00cad5a272acff8be8 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1545523 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org>
1 parent f9f18ef commit 4399701

38 files changed

+1312
-256
lines changed

scripts/run_code_generation_hashes.json

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,53 @@
252252
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/FullScreenQuad.vert.00000000.inc":
253253
"287c50011ced97a7338b47a0a50127bf",
254254
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000000.inc":
255-
"94ccd6f202120a83e81202e5ce419fad",
255+
"4077a84919ded411495dcd8cb909643a",
256+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000001.inc":
257+
"2ef2728dbab59731bdab3a88ead0fc1c",
258+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000002.inc":
259+
"5f5522ac23707a2e1e53648902d61ca6",
260+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000003.inc":
261+
"3204f13c623168620febc7b81557530f",
262+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000004.inc":
263+
"9c312712dc92b1fa7c771f8113720efb",
264+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000005.inc":
265+
"cfd43f9d60b8010ef3d52839ab69e540",
266+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000006.inc":
267+
"b36b3630331f6f70a2169d3b6623bc0f",
268+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000007.inc":
269+
"c9f6bc29877173b6664b435fcdb2f610",
270+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000008.inc":
271+
"5c6aca2ab804ec3f5e95d011f158c95c",
272+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000009.inc":
273+
"d6c69cc95c078c4b5c3d6c493b08fdb3",
274+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.0000000A.inc":
275+
"beeaf71bca2da66f1025f0753a8ca81b",
276+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.0000000B.inc":
277+
"9b1e11074db5538fd5d0c3383c8eb359",
278+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.0000000C.inc":
279+
"f479120855db1e6bbb36c08d0e7edddb",
280+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.0000000D.inc":
281+
"122be5946488b2c1ef34f84e82f19840",
282+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.0000000E.inc":
283+
"ecf5f1195e302e1eafb968d9f869d931",
284+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.0000000F.inc":
285+
"9ee5a92cccc918895b53e39eb81d3047",
286+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000010.inc":
287+
"169c0fca15ddf8490387270db5448134",
288+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000011.inc":
289+
"3289e2c669f6bc9b8e9fc9b504dd8add",
290+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000012.inc":
291+
"8628f2a2db453b02c8b7113dd643bd6e",
292+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000013.inc":
293+
"dacc25053938fd7f44b658dcf4178661",
294+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000014.inc":
295+
"caf7c21e28d4475d282b054d83a6da5b",
296+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000015.inc":
297+
"6207b567604dbd32633b2c6d790b5150",
298+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000016.inc":
299+
"18b3e1cca51abcee403d6935e8983317",
300+
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000017.inc":
301+
"916cb41862a990c9247f5fe933afd5da",
256302
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000000.inc":
257303
"aa438413134a29ec32ae4551a04e60b5",
258304
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000001.inc":
@@ -296,13 +342,13 @@
296342
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/FullScreenQuad.vert":
297343
"1743adf55153edf91363fa7b4350d859",
298344
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/ImageClear.frag":
299-
"037fb888e77491bf7ae746069ea89a55",
345+
"7f562c60e5df018b0087ecb8642ac821",
300346
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/ImageCopy.frag":
301347
"9b9fd690321f53163221f1ebba9f006d",
302348
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.cpp":
303-
"959f09bfb979cdc240f1df50b56d8429",
349+
"751f3554fe613d9b4739c7a4ac87b037",
304350
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h":
305-
"e70f3fa32f5ff0e567ce4ed2a5dc759e",
351+
"930fc6f4a705a0d2121770377d3bc764",
306352
"Vulkan internal shader programs:third_party/glslang/src/glslang/Include/revision.h":
307353
"bdb498ea2b9699b584fa32f1195b5d01",
308354
"Vulkan mandatory format support table:src/libANGLE/renderer/angle_format.py":

src/libANGLE/renderer/vulkan/FramebufferVk.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,14 +1240,28 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
12401240
RendererVk *renderer = contextVk->getRenderer();
12411241

12421242
UtilsVk::ClearImageParameters params = {};
1243-
params.colorMaskFlags = colorMaskFlags;
12441243
params.renderAreaHeight = mState.getDimensions().height;
12451244
params.clearValue = clearColorValue;
1246-
params.alphaMask = &getEmulatedAlphaAttachmentMask();
1247-
params.clearBufferMask = &clearColorBuffers;
12481245
params.renderPassDesc = &getRenderPassDesc();
12491246

1250-
return renderer->getUtils().clearImage(contextVk, this, params);
1247+
const auto &colorRenderTargets = mRenderTargetCache.getColors();
1248+
for (size_t colorIndex : clearColorBuffers)
1249+
{
1250+
const RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
1251+
ASSERT(colorRenderTarget);
1252+
1253+
params.format = &colorRenderTarget->getImage().getFormat().textureFormat();
1254+
params.attachmentIndex = colorIndex;
1255+
params.colorMaskFlags = colorMaskFlags;
1256+
if (mEmulatedAlphaAttachmentMask[colorIndex])
1257+
{
1258+
params.colorMaskFlags &= ~VK_COLOR_COMPONENT_A_BIT;
1259+
}
1260+
1261+
ANGLE_TRY(renderer->getUtils().clearImage(contextVk, this, params));
1262+
}
1263+
1264+
return angle::Result::Continue;
12511265
}
12521266

12531267
angle::Result FramebufferVk::getSamplePosition(const gl::Context *context,

src/libANGLE/renderer/vulkan/RendererVk.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -976,9 +976,12 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
976976
// Select additional features to be enabled
977977
VkPhysicalDeviceFeatures2KHR enabledFeatures = {};
978978
enabledFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
979-
enabledFeatures.features.inheritedQueries = mPhysicalDeviceFeatures.inheritedQueries;
979+
enabledFeatures.features.independentBlend = mPhysicalDeviceFeatures.independentBlend;
980980
enabledFeatures.features.robustBufferAccess = mPhysicalDeviceFeatures.robustBufferAccess;
981981
enabledFeatures.features.samplerAnisotropy = mPhysicalDeviceFeatures.samplerAnisotropy;
982+
#if !ANGLE_USE_CUSTOM_VULKAN_CMD_BUFFERS
983+
enabledFeatures.features.inheritedQueries = mPhysicalDeviceFeatures.inheritedQueries;
984+
#endif
982985

983986
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT divisorFeatures = {};
984987
divisorFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
@@ -1171,6 +1174,14 @@ gl::Version RendererVk::getMaxSupportedESVersion() const
11711174
maxVersion = std::max(maxVersion, gl::Version(2, 0));
11721175
}
11731176

1177+
// If independentBlend is not supported, we can't have a mix of has-alpha and emulated-alpha
1178+
// render targets in a framebuffer. We also cannot perform masked clears of multiple render
1179+
// targets.
1180+
if (!mPhysicalDeviceFeatures.independentBlend)
1181+
{
1182+
maxVersion = std::max(maxVersion, gl::Version(2, 0));
1183+
}
1184+
11741185
return maxVersion;
11751186
}
11761187

src/libANGLE/renderer/vulkan/UtilsVk.cpp

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ namespace rx
1818

1919
namespace BufferUtils_comp = vk::InternalShader::BufferUtils_comp;
2020
namespace ConvertVertex_comp = vk::InternalShader::ConvertVertex_comp;
21+
namespace ImageClear_frag = vk::InternalShader::ImageClear_frag;
2122
namespace ImageCopy_frag = vk::InternalShader::ImageCopy_frag;
2223

2324
namespace
@@ -117,6 +118,25 @@ uint32_t GetConvertVertexFlags(const UtilsVk::ConvertVertexParameters &params)
117118
return flags;
118119
}
119120

121+
uint32_t GetImageClearFlags(const angle::Format &format, uint32_t attachmentIndex)
122+
{
123+
constexpr uint32_t kAttachmentFlagStep =
124+
ImageClear_frag::kAttachment1 - ImageClear_frag::kAttachment0;
125+
126+
static_assert(gl::IMPLEMENTATION_MAX_DRAW_BUFFERS == 8,
127+
"ImageClear shader assumes maximum 8 draw buffers");
128+
static_assert(
129+
ImageClear_frag::kAttachment0 + 7 * kAttachmentFlagStep == ImageClear_frag::kAttachment7,
130+
"ImageClear AttachmentN flag calculation needs correction");
131+
132+
uint32_t flags = ImageClear_frag::kAttachment0 + attachmentIndex * kAttachmentFlagStep;
133+
134+
flags |= format.isInt()
135+
? ImageClear_frag::kIsInt
136+
: format.isUint() ? ImageClear_frag::kIsUint : ImageClear_frag::kIsFloat;
137+
138+
return flags;
139+
}
120140
uint32_t GetImageCopyFlags(const vk::Format &srcFormat, const vk::Format &destFormat)
121141
{
122142
const angle::Format &srcAngleFormat = srcFormat.angleFormat();
@@ -180,7 +200,10 @@ void UtilsVk::destroy(VkDevice device)
180200
{
181201
program.destroy(device);
182202
}
183-
mImageClearProgram.destroy(device);
203+
for (vk::ShaderProgramHelper &program : mImageClearProgram)
204+
{
205+
program.destroy(device);
206+
}
184207
for (vk::ShaderProgramHelper &program : mImageCopyPrograms)
185208
{
186209
program.destroy(device);
@@ -631,31 +654,16 @@ angle::Result UtilsVk::clearImage(ContextVk *contextVk,
631654
ImageClearShaderParams shaderParams;
632655
shaderParams.clearValue = params.clearValue;
633656

634-
// TODO(syoussefi): Currently, this only supports float clears. Having the shader as-is support
635-
// a mixture of types results in a large number of shader variations. The solution would be to
636-
// clear the render targets one by one. However, we don't want to recreate the render pass for
637-
// each one, so the shader should be able to select the render target to clear. The variations
638-
// of the shader could look like:
639-
//
640-
// "RenderTarget": [
641-
// "RT0",
642-
// "RT1",
643-
// ...
644-
// "RT7",
645-
// ],
646-
// "Format": [
647-
// "IsFloat",
648-
// "IsInt",
649-
// "IsUint"
650-
// ]
651-
//
652-
// http://anglebug.com/3187
653-
shaderParams.clearBufferMask = static_cast<uint32_t>(params.clearBufferMask->bits());
657+
uint32_t flags = GetImageClearFlags(*params.format, params.attachmentIndex);
654658

655659
vk::GraphicsPipelineDesc pipelineDesc;
656660
pipelineDesc.initDefaults();
657-
pipelineDesc.setColorWriteMask(params.colorMaskFlags, *params.alphaMask);
661+
pipelineDesc.setColorWriteMask(0, gl::DrawBufferMask());
662+
pipelineDesc.setSingleColorWriteMask(params.attachmentIndex, params.colorMaskFlags);
658663
pipelineDesc.setRenderPassDesc(*params.renderPassDesc);
664+
// Note: depth test is disabled by default so this should be unnecessary, but works around an
665+
// Intel bug on windows. http://anglebug.com/3348
666+
pipelineDesc.setDepthWriteEnabled(false);
659667

660668
const gl::Rectangle &renderArea = framebuffer->getFramebuffer()->getRenderPassRenderArea();
661669
bool invertViewport = contextVk->isViewportFlipEnabledForDrawFBO();
@@ -673,10 +681,10 @@ angle::Result UtilsVk::clearImage(ContextVk *contextVk,
673681
vk::RefCounted<vk::ShaderAndSerial> *vertexShader = nullptr;
674682
vk::RefCounted<vk::ShaderAndSerial> *fragmentShader = nullptr;
675683
ANGLE_TRY(shaderLibrary.getFullScreenQuad_vert(contextVk, 0, &vertexShader));
676-
ANGLE_TRY(shaderLibrary.getImageClear_frag(contextVk, 0, &fragmentShader));
684+
ANGLE_TRY(shaderLibrary.getImageClear_frag(contextVk, flags, &fragmentShader));
677685

678686
ANGLE_TRY(setupProgram(contextVk, Function::ImageClear, fragmentShader, vertexShader,
679-
&mImageClearProgram, &pipelineDesc, VK_NULL_HANDLE, &shaderParams,
687+
&mImageClearProgram[flags], &pipelineDesc, VK_NULL_HANDLE, &shaderParams,
680688
sizeof(shaderParams), commandBuffer));
681689
commandBuffer->draw(6, 0);
682690
return angle::Result::Continue;

src/libANGLE/renderer/vulkan/UtilsVk.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ class UtilsVk : angle::NonCopyable
6464
VkClearColorValue clearValue;
6565
VkColorComponentFlags colorMaskFlags;
6666
GLint renderAreaHeight;
67-
const gl::DrawBufferMask *alphaMask;
68-
const gl::DrawBufferMask *clearBufferMask;
6967
const vk::RenderPassDesc *renderPassDesc;
68+
const angle::Format *format;
69+
uint32_t attachmentIndex;
7070
};
7171

7272
struct CopyImageParameters
@@ -143,7 +143,6 @@ class UtilsVk : angle::NonCopyable
143143
{
144144
// Structure matching PushConstants in ImageClear.frag
145145
VkClearColorValue clearValue = {};
146-
uint32_t clearBufferMask = 0;
147146
};
148147

149148
struct ImageCopyShaderParams
@@ -233,7 +232,9 @@ class UtilsVk : angle::NonCopyable
233232
vk::ShaderProgramHelper
234233
mConvertVertexPrograms[vk::InternalShader::ConvertVertex_comp::kFlagsMask |
235234
vk::InternalShader::ConvertVertex_comp::kConversionMask];
236-
vk::ShaderProgramHelper mImageClearProgram;
235+
vk::ShaderProgramHelper
236+
mImageClearProgram[vk::InternalShader::ImageClear_frag::kAttachmentIndexMask |
237+
vk::InternalShader::ImageClear_frag::kFormatMask];
237238
vk::ShaderProgramHelper mImageCopyPrograms[vk::InternalShader::ImageCopy_frag::kFlagsMask |
238239
vk::InternalShader::ImageCopy_frag::kSrcFormatMask |
239240
vk::InternalShader::ImageCopy_frag::kDestFormatMask];

0 commit comments

Comments
 (0)