1 //
2 // Copyright 2019 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #include "pxr/imaging/hdx/presentTask.h"
25
26 #include "pxr/imaging/hd/aov.h"
27 #include "pxr/imaging/hd/tokens.h"
28
29 #include "pxr/imaging/hgi/hgi.h"
30 #include "pxr/imaging/hgi/tokens.h"
31
32
33 PXR_NAMESPACE_OPEN_SCOPE
34
35 bool
_IsIntegerFormat(HgiFormat format)36 _IsIntegerFormat(HgiFormat format)
37 {
38 return (format == HgiFormatUInt16 ||
39 format == HgiFormatUInt16Vec2 ||
40 format == HgiFormatUInt16Vec3 ||
41 format == HgiFormatUInt16Vec4 ||
42 format == HgiFormatInt32 ||
43 format == HgiFormatInt32Vec2 ||
44 format == HgiFormatInt32Vec3 ||
45 format == HgiFormatInt32Vec4);
46 }
47
48 /*static*/
49 bool
IsFormatSupported(HgiFormat aovFormat)50 HdxPresentTask::IsFormatSupported(HgiFormat aovFormat)
51 {
52 // Integer formats are not supported (this requires the GL interop to
53 // support additional sampler types), nor are compressed formats.
54 return !_IsIntegerFormat(aovFormat) && !HgiIsCompressed(aovFormat);
55 }
56
HdxPresentTask(HdSceneDelegate * delegate,SdfPath const & id)57 HdxPresentTask::HdxPresentTask(HdSceneDelegate* delegate, SdfPath const& id)
58 : HdxTask(id)
59 {
60 }
61
62 HdxPresentTask::~HdxPresentTask() = default;
63
64 void
_Sync(HdSceneDelegate * delegate,HdTaskContext * ctx,HdDirtyBits * dirtyBits)65 HdxPresentTask::_Sync(
66 HdSceneDelegate* delegate,
67 HdTaskContext* ctx,
68 HdDirtyBits* dirtyBits)
69 {
70 HD_TRACE_FUNCTION();
71 HF_MALLOC_TAG_FUNCTION();
72
73 if ((*dirtyBits) & HdChangeTracker::DirtyParams) {
74 HdxPresentTaskParams params;
75
76 if (_GetTaskParams(delegate, ¶ms)) {
77 _params = params;
78 }
79 }
80 *dirtyBits = HdChangeTracker::Clean;
81 }
82
83 void
Prepare(HdTaskContext * ctx,HdRenderIndex * renderIndex)84 HdxPresentTask::Prepare(HdTaskContext* ctx, HdRenderIndex *renderIndex)
85 {
86 }
87
88 void
Execute(HdTaskContext * ctx)89 HdxPresentTask::Execute(HdTaskContext* ctx)
90 {
91 HD_TRACE_FUNCTION();
92 HF_MALLOC_TAG_FUNCTION();
93
94 // The present task can be disabled in case an application does offscreen
95 // rendering or doesn't use Hgi interop (e.g. directly access AOV results).
96 // But we still need to call Hgi::EndFrame.
97
98 if (_params.enabled && _HasTaskContextData(ctx, HdAovTokens->color)) {
99 // The color and depth aovs have the results we want to blit to the
100 // application. Depth is optional. When we are previewing a custom aov
101 // we may not have a depth buffer.
102
103 HgiTextureHandle aovTexture;
104 _GetTaskContextData(ctx, HdAovTokens->color, &aovTexture);
105 if (aovTexture) {
106 HgiTextureDesc texDesc = aovTexture->GetDescriptor();
107 if (!IsFormatSupported(texDesc.format)) {
108 // Warn, but don't bail.
109 TF_WARN("Aov texture format %d may not be correctly supported "
110 "for presentation via HgiInterop.", texDesc.format);
111 }
112 }
113
114 HgiTextureHandle depthTexture;
115 if (_HasTaskContextData(ctx, HdAovTokens->depth)) {
116 _GetTaskContextData(ctx, HdAovTokens->depth, &depthTexture);
117 }
118
119 // Use HgiInterop to composite the Hgi textures over the application's
120 // framebuffer contents.
121 // Eg. This allows us to render with HgiMetal and present the images
122 // into a opengl based application (such as usdview).
123 _interop.TransferToApp(
124 _hgi,
125 aovTexture, depthTexture,
126 _params.dstApi,
127 _params.dstFramebuffer, _params.dstRegion);
128 }
129
130 // Wrap one HdEngine::Execute frame with Hgi StartFrame and EndFrame.
131 // StartFrame is currently called in the AovInputTask.
132 // This is important for Hgi garbage collection to run.
133 _GetHgi()->EndFrame();
134 }
135
136
137 // --------------------------------------------------------------------------- //
138 // VtValue Requirements
139 // --------------------------------------------------------------------------- //
140
operator <<(std::ostream & out,const HdxPresentTaskParams & pv)141 std::ostream& operator<<(std::ostream& out, const HdxPresentTaskParams& pv)
142 {
143 out << "PresentTask Params: (...) "
144 << pv.dstApi;
145 return out;
146 }
147
operator ==(const HdxPresentTaskParams & lhs,const HdxPresentTaskParams & rhs)148 bool operator==(const HdxPresentTaskParams& lhs,
149 const HdxPresentTaskParams& rhs)
150 {
151 return lhs.dstApi == rhs.dstApi &&
152 lhs.dstFramebuffer == rhs.dstFramebuffer &&
153 lhs.dstRegion == rhs.dstRegion &&
154 lhs.enabled == rhs.enabled;
155 }
156
operator !=(const HdxPresentTaskParams & lhs,const HdxPresentTaskParams & rhs)157 bool operator!=(const HdxPresentTaskParams& lhs,
158 const HdxPresentTaskParams& rhs)
159 {
160 return !(lhs == rhs);
161 }
162
163 PXR_NAMESPACE_CLOSE_SCOPE
164