DoF: don't rely on texture swizzle being supported

This commit is contained in:
Mathias Agopian
2021-03-30 13:40:00 -07:00
committed by Mathias Agopian
parent e5bfe81d0c
commit e7364cdcb3
5 changed files with 74 additions and 1 deletions

View File

@@ -163,6 +163,7 @@ set(MATERIAL_SRCS
src/materials/dof/dofDownsample.mat
src/materials/dof/dofCombine.mat
src/materials/dof/dofTiles.mat
src/materials/dof/dofTilesSwizzle.mat
src/materials/dof/dofDilate.mat
src/materials/dof/dofMipmap.mat
src/materials/dof/dofMedian.mat

View File

@@ -551,6 +551,7 @@ bool MetalDriver::isTextureFormatSupported(TextureFormat format) {
}
bool MetalDriver::isTextureSwizzleSupported() {
return false; // FIXME: reenable once textures used as attachments are supported
if (@available(macOS 10.15, iOS 13, *)) {
return true;
} else {

View File

@@ -212,6 +212,7 @@ static const MaterialInfo sMaterialList[] = {
{ "dofCoc", MATERIAL(DOFCOC) },
{ "dofMipmap", MATERIAL(DOFMIPMAP) },
{ "dofTiles", MATERIAL(DOFTILES) },
{ "dofTilesSwizzle", MATERIAL(DOFTILESSWIZZLE) },
{ "dofDilate", MATERIAL(DOFDILATE) },
{ "dof", MATERIAL(DOF) },
{ "dofMedian", MATERIAL(DOFMEDIAN) },
@@ -1064,6 +1065,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> outTilesCocMinMax;
};
const bool textureSwizzleSupported = Texture::isTextureSwizzleSupported(mEngine);
for (size_t i = 0; i < tileReductionCount; i++) {
auto& ppDoFTiling = fg.addPass<PostProcessDofTiling1>("DoF Tiling",
[&](FrameGraph::Builder& builder, auto& data) {
@@ -1083,7 +1085,9 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
auto const& outputDesc = resources.getDescriptor(data.outTilesCocMinMax);
auto const& out = resources.getRenderPassInfo();
auto inCocMinMax = resources.getTexture(data.inCocMinMax);
auto const& material = getPostProcessMaterial("dofTiles");
auto const& material = (!textureSwizzleSupported && (i == 0)) ?
getPostProcessMaterial("dofTilesSwizzle") :
getPostProcessMaterial("dofTiles");
FMaterialInstance* const mi = material.getMaterialInstance();
mi->setParameter("cocMinMax", inCocMinMax, { .filterMin = SamplerMinFilter::NEAREST });
mi->setParameter("uvscale", float4{

View File

@@ -47,6 +47,7 @@ void postProcess(inout PostProcessInputs postProcess) {
ivec2 i = ivec2(uv * size - 0.5);
// note: the first time, the source texture is swizzled -- so .r and .g are the same channel
// if swizzling is not supported, we use dofTilesSwizzle instead.
#if defined(TARGET_VULKAN_ENVIRONMENT) || !defined(TARGET_MOBILE)
vec4 mi = textureGather(materialParams_cocMinMax, uv, 0); // 01, 11, 10, 00
vec4 ma = textureGather(materialParams_cocMinMax, uv, 1); // 01, 11, 10, 00

View File

@@ -0,0 +1,66 @@
material {
name : dofTilesSwizzle,
parameters : [
{
type : sampler2d,
name : cocMinMax,
precision: medium
},
{
type : float4,
name : uvscale,
precision: high
}
],
variables : [
vertex
],
domain : postprocess,
depthWrite : false,
depthCulling : false
}
vertex {
void postProcessVertex(inout PostProcessVertexInputs postProcess) {
postProcess.vertex.xy = (postProcess.normalizedUV * materialParams.uvscale.xy * 2.0 - 0.5) * materialParams.uvscale.zw;
}
}
fragment {
void dummy(){}
float max4(const vec4 f) {
vec2 t = max(f.xy, f.zw);
return max(t.x, t.y);
}
float min4(const vec4 f) {
vec2 t = min(f.xy, f.zw);
return min(t.x, t.y);
}
void postProcess(inout PostProcessInputs postProcess) {
highp vec2 uv = variable_vertex.xy;
highp vec2 size = vec2(textureSize(materialParams_cocMinMax, 0));
ivec2 i = ivec2(uv * size - 0.5);
#if defined(TARGET_VULKAN_ENVIRONMENT) || !defined(TARGET_MOBILE)
vec4 mi = textureGather(materialParams_cocMinMax, uv, 0); // 01, 11, 10, 00
#else
vec4 mi;
mi[0] = texelFetchOffset(materialParams_cocMinMax, i, 0, ivec2(0, 1)).r;
mi[1] = texelFetchOffset(materialParams_cocMinMax, i, 0, ivec2(1, 1)).r;
mi[2] = texelFetchOffset(materialParams_cocMinMax, i, 0, ivec2(1, 0)).r;
mi[3] = texelFetchOffset(materialParams_cocMinMax, i, 0, ivec2(0, 0)).r;
#endif
// compute tile's min CoC
postProcess.color.r = min4(mi);
// compute tile's max CoC
postProcess.color.g = max4(mi);
}
}