33//! Provides `OffscreenTarget` and `OffscreenTargetBuilder` for render‑to‑texture
44//! workflows without exposing platform texture types at call sites.
55
6- use logging;
7-
8- use super :: {
6+ use crate :: render:: {
7+ gpu:: Gpu ,
98 surface,
109 texture,
10+ validation,
1111 RenderContext ,
1212} ;
13- use crate :: render:: validation;
1413
1514#[ derive( Debug ) ]
1615/// Offscreen render target with color and optional depth attachments.
@@ -27,7 +26,6 @@ pub struct OffscreenTarget {
2726 depth_format : Option < texture:: DepthFormat > ,
2827 sample_count : u32 ,
2928 label : Option < String > ,
30- defaulted_from_surface_size : bool ,
3129}
3230
3331impl OffscreenTarget {
@@ -81,10 +79,6 @@ impl OffscreenTarget {
8179 return self . label . as_deref ( ) ;
8280 }
8381
84- pub ( crate ) fn defaulted_from_surface_size ( & self ) -> bool {
85- return self . defaulted_from_surface_size ;
86- }
87-
8882 /// Explicitly destroy this render target.
8983 ///
9084 /// Dropping the value also releases the underlying GPU resources; this
@@ -97,7 +91,7 @@ impl OffscreenTarget {
9791pub enum OffscreenTargetError {
9892 /// Color attachment was not configured.
9993 MissingColorAttachment ,
100- /// Width or height was zero after resolving defaults .
94+ /// Width or height was zero.
10195 InvalidSize { width : u32 , height : u32 } ,
10296 /// Sample count is not supported for the chosen format or device limits.
10397 UnsupportedSampleCount { requested : u32 } ,
@@ -131,10 +125,6 @@ impl OffscreenTargetBuilder {
131125 }
132126
133127 /// Configure the color attachment format and size.
134- ///
135- /// When `width` or `height` is zero, the builder falls back to the current
136- /// `RenderContext` surface size during `build`. A resolved size of zero in
137- /// either dimension is treated as an error.
138128 pub fn with_color (
139129 mut self ,
140130 format : texture:: TextureFormat ,
@@ -154,7 +144,6 @@ impl OffscreenTargetBuilder {
154144 }
155145
156146 /// Configure multi‑sampling for this target.
157- ///
158147 pub fn with_multi_sample ( mut self , samples : u32 ) -> Self {
159148 self . sample_count = samples. max ( 1 ) ;
160149 return self ;
@@ -169,16 +158,14 @@ impl OffscreenTargetBuilder {
169158 /// Create the render target color (and optional depth) attachments.
170159 pub fn build (
171160 self ,
172- render_context : & mut RenderContext ,
161+ gpu : & Gpu ,
173162 ) -> Result < OffscreenTarget , OffscreenTargetError > {
174163 let format = match self . color_format {
175164 Some ( format) => format,
176165 None => return Err ( OffscreenTargetError :: MissingColorAttachment ) ,
177166 } ;
178167
179- let surface_size = render_context. surface_size ( ) ;
180- let defaulted_from_surface_size = self . width == 0 || self . height == 0 ;
181- let ( width, height) = self . resolve_size ( surface_size) ?;
168+ let ( width, height) = self . resolve_size ( ) ?;
182169
183170 let sample_count = self . sample_count . max ( 1 ) ;
184171 if let Err ( _) = validation:: validate_sample_count ( sample_count) {
@@ -188,9 +175,7 @@ impl OffscreenTargetBuilder {
188175 }
189176
190177 if sample_count > 1
191- && !render_context
192- . gpu ( )
193- . supports_sample_count_for_format ( format, sample_count)
178+ && !gpu. supports_sample_count_for_format ( format, sample_count)
194179 {
195180 return Err ( OffscreenTargetError :: UnsupportedSampleCount {
196181 requested : sample_count,
@@ -199,9 +184,7 @@ impl OffscreenTargetBuilder {
199184
200185 if let Some ( depth_format) = self . depth_format {
201186 if sample_count > 1
202- && !render_context
203- . gpu ( )
204- . supports_sample_count_for_depth ( depth_format, sample_count)
187+ && !gpu. supports_sample_count_for_depth ( depth_format, sample_count)
205188 {
206189 return Err ( OffscreenTargetError :: UnsupportedSampleCount {
207190 requested : sample_count,
@@ -221,7 +204,7 @@ impl OffscreenTargetBuilder {
221204 }
222205 }
223206
224- let resolve_texture = match color_builder. build ( render_context . gpu ( ) ) {
207+ let resolve_texture = match color_builder. build ( gpu) {
225208 Ok ( texture) => texture,
226209 Err ( message) => {
227210 return Err ( OffscreenTargetError :: DeviceError ( message. to_string ( ) ) ) ;
@@ -236,7 +219,7 @@ impl OffscreenTargetBuilder {
236219 if let Some ( ref label) = self . label {
237220 msaa_builder = msaa_builder. with_label ( & format ! ( "{}-msaa" , label) ) ;
238221 }
239- Some ( msaa_builder. build ( render_context . gpu ( ) ) )
222+ Some ( msaa_builder. build ( gpu) )
240223 } else {
241224 None
242225 } ;
@@ -251,7 +234,7 @@ impl OffscreenTargetBuilder {
251234 depth_builder = depth_builder. with_label ( & format ! ( "{}-depth" , label) ) ;
252235 }
253236
254- Some ( depth_builder. build ( render_context . gpu ( ) ) )
237+ Some ( depth_builder. build ( gpu) )
255238 } else {
256239 None
257240 } ;
@@ -265,26 +248,14 @@ impl OffscreenTargetBuilder {
265248 depth_format : self . depth_format ,
266249 sample_count,
267250 label : self . label ,
268- defaulted_from_surface_size,
269251 } ) ;
270252 }
271253
272- /// Resolve the final size using an optional explicit size and surface default.
273- ///
274- /// When no explicit size was provided, the builder falls back to
275- /// `surface_size`. A resolved size with zero width or height is treated as
276- /// an error.
277254 pub ( crate ) fn resolve_size (
278255 & self ,
279- surface_size : ( u32 , u32 ) ,
280256 ) -> Result < ( u32 , u32 ) , OffscreenTargetError > {
281- let mut width = self . width ;
282- let mut height = self . height ;
283- if width == 0 || height == 0 {
284- width = surface_size. 0 ;
285- height = surface_size. 1 ;
286- }
287-
257+ let width = self . width ;
258+ let height = self . height ;
288259 if width == 0 || height == 0 {
289260 return Err ( OffscreenTargetError :: InvalidSize { width, height } ) ;
290261 }
@@ -294,47 +265,34 @@ impl OffscreenTargetBuilder {
294265}
295266
296267#[ deprecated(
297- note = "Use `lambda::render::target:: OffscreenTarget` to avoid confusion with `lambda::render::render_target ::RenderTarget`."
268+ note = "Use `lambda::render::targets::offscreen:: OffscreenTarget` to avoid confusion with `lambda::render::targets::surface ::RenderTarget`."
298269) ]
299270pub type RenderTarget = OffscreenTarget ;
300271
301272#[ deprecated(
302- note = "Use `lambda::render::target:: OffscreenTargetBuilder` to avoid confusion with `lambda::render::render_target ::RenderTarget`."
273+ note = "Use `lambda::render::targets::offscreen:: OffscreenTargetBuilder` to avoid confusion with `lambda::render::targets::surface ::RenderTarget`."
303274) ]
304275pub type RenderTargetBuilder = OffscreenTargetBuilder ;
305276
306- #[ deprecated( note = "Use `lambda::render::target::OffscreenTargetError`." ) ]
277+ #[ deprecated(
278+ note = "Use `lambda::render::targets::offscreen::OffscreenTargetError`."
279+ ) ]
307280pub type RenderTargetError = OffscreenTargetError ;
308281
309282#[ cfg( test) ]
310283mod tests {
311284 use super :: * ;
312285
313- /// Defaults size to the surface when no explicit dimensions are provided.
314- #[ test]
315- fn resolve_size_defaults_to_surface_size ( ) {
316- let builder = OffscreenTargetBuilder :: new ( ) . with_color (
317- texture:: TextureFormat :: Rgba8Unorm ,
318- 0 ,
319- 0 ,
320- ) ;
321- let surface_size = ( 800 , 600 ) ;
322-
323- let resolved = builder. resolve_size ( surface_size) . unwrap ( ) ;
324- assert_eq ! ( resolved, surface_size) ;
325- }
326-
327- /// Fails when the resolved size has a zero dimension.
286+ /// Fails when the builder has a zero dimension.
328287 #[ test]
329288 fn resolve_size_rejects_zero_dimensions ( ) {
330289 let builder = OffscreenTargetBuilder :: new ( ) . with_color (
331290 texture:: TextureFormat :: Rgba8Unorm ,
332291 0 ,
333292 0 ,
334293 ) ;
335- let surface_size = ( 0 , 0 ) ;
336294
337- let resolved = builder. resolve_size ( surface_size ) ;
295+ let resolved = builder. resolve_size ( ) ;
338296 assert_eq ! (
339297 resolved,
340298 Err ( OffscreenTargetError :: InvalidSize {
0 commit comments