2 * Copyright 2012-2014, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Artur Wyszynski, harakash@gmail.com
7 * Alexander von Gluck IV, kallisti5@unixzen.com
13 #include "pipe/p_format.h"
14 #include "util/u_atomic.h"
15 #include "util/u_format.h"
16 #include "util/u_memory.h"
17 #include "util/u_inlines.h"
19 #include "hgl_context.h"
23 # define TRACE(x...) printf("hgl:state_tracker: " x)
24 # define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
29 #define ERROR(x...) printf("hgl:state_tracker: " x)
32 // Perform a safe void to hgl_context cast
33 static INLINE
struct hgl_context
*
34 hgl_st_context(struct st_context_iface
*stctxi
)
36 struct hgl_context
* context
;
38 context
= (struct hgl_context
*)stctxi
->st_manager_private
;
44 // Perform a safe void to hgl_buffer cast
45 static INLINE
struct hgl_buffer
*
46 hgl_st_framebuffer(struct st_framebuffer_iface
*stfbi
)
48 struct hgl_buffer
* buffer
;
50 buffer
= (struct hgl_buffer
*)stfbi
->st_manager_private
;
57 hgl_st_framebuffer_flush_front(struct st_context_iface
*stctxi
,
58 struct st_framebuffer_iface
* stfbi
, enum st_attachment_type statt
)
62 //struct hgl_context* context = hgl_st_context(stctxi);
63 //struct hgl_buffer* buffer = hgl_st_context(stfbi);
66 struct stw_st_framebuffer
*stwfb
= stw_st_framebuffer(stfb
);
67 pipe_mutex_lock(stwfb
->fb
->mutex
);
69 struct pipe_resource
* resource
= textures
[statt
];
71 stw_framebuffer_present_locked(...);
79 hgl_st_framebuffer_validate_textures(struct st_framebuffer_iface
*stfbi
,
80 unsigned width
, unsigned height
, unsigned mask
)
82 struct hgl_buffer
* buffer
;
83 enum st_attachment_type i
;
84 struct pipe_resource templat
;
88 buffer
= hgl_st_framebuffer(stfbi
);
90 if (buffer
->width
!= width
|| buffer
->height
!= height
) {
91 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++)
92 pipe_resource_reference(&buffer
->textures
[i
], NULL
);
95 memset(&templat
, 0, sizeof(templat
));
96 templat
.target
= buffer
->target
;
97 templat
.width0
= width
;
98 templat
.height0
= height
;
100 templat
.array_size
= 1;
101 templat
.last_level
= 0;
103 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++) {
104 enum pipe_format format
;
108 case ST_ATTACHMENT_FRONT_LEFT
:
109 case ST_ATTACHMENT_BACK_LEFT
:
110 case ST_ATTACHMENT_FRONT_RIGHT
:
111 case ST_ATTACHMENT_BACK_RIGHT
:
112 format
= buffer
->visual
->color_format
;
113 bind
= PIPE_BIND_DISPLAY_TARGET
| PIPE_BIND_RENDER_TARGET
;
115 case ST_ATTACHMENT_DEPTH_STENCIL
:
116 format
= buffer
->visual
->depth_stencil_format
;
117 bind
= PIPE_BIND_DEPTH_STENCIL
;
120 format
= PIPE_FORMAT_NONE
;
125 if (format
!= PIPE_FORMAT_NONE
) {
126 templat
.format
= format
;
128 buffer
->textures
[i
] = buffer
->screen
->resource_create(buffer
->screen
,
130 if (!buffer
->textures
[i
])
135 buffer
->width
= width
;
136 buffer
->height
= height
;
144 * Called by the st manager to validate the framebuffer (allocate
148 hgl_st_framebuffer_validate(struct st_context_iface
*stctxi
,
149 struct st_framebuffer_iface
*stfbi
, const enum st_attachment_type
*statts
,
150 unsigned count
, struct pipe_resource
**out
)
152 struct hgl_context
* context
;
153 struct hgl_buffer
* buffer
;
154 unsigned stAttachmentMask
, newMask
;
160 context
= hgl_st_context(stctxi
);
161 buffer
= hgl_st_framebuffer(stfbi
);
165 //get_bitmap_size(context->bitmap, &width, &height);
167 // Build mask of current attachments
168 stAttachmentMask
= 0;
169 for (i
= 0; i
< count
; i
++)
170 stAttachmentMask
|= 1 << statts
[i
];
172 newMask
= stAttachmentMask
& ~buffer
->mask
;
174 resized
= (buffer
->width
!= context
->width
)
175 || (buffer
->height
!= context
->height
);
177 if (resized
|| newMask
) {
179 TRACE("%s: resize event. old: %d x %d; new: %d x %d\n", __func__
,
180 buffer
->width
, buffer
->height
, context
->width
, context
->height
);
182 ret
= hgl_st_framebuffer_validate_textures(stfbi
,
183 context
->width
, context
->height
, stAttachmentMask
);
188 // TODO: Simply update attachments
194 for (i
= 0; i
< count
; i
++) {
196 pipe_resource_reference(&out
[i
], buffer
->textures
[statts
[i
]]);
204 hgl_st_manager_get_param(struct st_manager
*smapi
, enum st_manager_param param
)
209 case ST_MANAGER_BROKEN_INVALIDATE
:
218 * Create new framebuffer
221 hgl_create_st_framebuffer(struct hgl_context
* context
)
223 struct hgl_buffer
*buffer
;
226 // Our requires before creating a framebuffer
228 assert(context
->screen
);
229 assert(context
->stVisual
);
231 buffer
= CALLOC_STRUCT(hgl_buffer
);
234 // calloc and configure our st_framebuffer interface
235 buffer
->stfbi
= CALLOC_STRUCT(st_framebuffer_iface
);
236 assert(buffer
->stfbi
);
238 // Prepare our buffer
239 buffer
->visual
= context
->stVisual
;
240 buffer
->screen
= context
->screen
;
242 if (context
->screen
->get_param(buffer
->screen
, PIPE_CAP_NPOT_TEXTURES
))
243 buffer
->target
= PIPE_TEXTURE_2D
;
245 buffer
->target
= PIPE_TEXTURE_RECT
;
247 // Prepare our state_tracker interface
248 buffer
->stfbi
->flush_front
= hgl_st_framebuffer_flush_front
;
249 buffer
->stfbi
->validate
= hgl_st_framebuffer_validate
;
250 buffer
->stfbi
->visual
= context
->stVisual
;
252 p_atomic_set(&buffer
->stfbi
->stamp
, 1);
253 buffer
->stfbi
->st_manager_private
= (void*)buffer
;
260 hgl_create_st_manager(struct hgl_context
* context
)
262 struct st_manager
* manager
;
268 assert(context
->screen
);
270 manager
= CALLOC_STRUCT(st_manager
);
273 //manager->display = dpy;
274 manager
->screen
= context
->screen
;
275 manager
->get_param
= hgl_st_manager_get_param
;
282 hgl_destroy_st_manager(struct st_manager
*manager
)
291 hgl_create_st_visual(ulong options
)
293 struct st_visual
* visual
;
297 visual
= CALLOC_STRUCT(st_visual
);
300 // Determine color format
301 if ((options
& BGL_INDEX
) != 0) {
303 visual
->color_format
= PIPE_FORMAT_B5G6R5_UNORM
;
304 // TODO: Indexed color depth buffer?
305 visual
->depth_stencil_format
= PIPE_FORMAT_NONE
;
308 visual
->color_format
= (options
& BGL_ALPHA
)
309 ? PIPE_FORMAT_BGRA8888_UNORM
: PIPE_FORMAT_BGRX8888_UNORM
;
310 // TODO: Determine additional stencil formats
311 visual
->depth_stencil_format
= (options
& BGL_DEPTH
)
312 ? PIPE_FORMAT_Z24_UNORM_S8_UINT
: PIPE_FORMAT_NONE
;
315 visual
->accum_format
= (options
& BGL_ACCUM
)
316 ? PIPE_FORMAT_R16G16B16A16_SNORM
: PIPE_FORMAT_NONE
;
318 visual
->buffer_mask
|= ST_ATTACHMENT_FRONT_LEFT_MASK
;
319 visual
->render_buffer
= ST_ATTACHMENT_FRONT_LEFT
;
321 if ((options
& BGL_DOUBLE
) != 0) {
322 visual
->buffer_mask
|= ST_ATTACHMENT_BACK_LEFT_MASK
;
323 visual
->render_buffer
= ST_ATTACHMENT_BACK_LEFT
;
327 if ((options
& BGL_STEREO
) != 0) {
328 visual
->buffer_mask
|= ST_ATTACHMENT_FRONT_RIGHT_MASK
;
329 if ((options
& BGL_DOUBLE
) != 0)
330 visual
->buffer_mask
|= ST_ATTACHMENT_BACK_RIGHT_MASK
;
334 if ((options
& BGL_DEPTH
) || (options
& BGL_STENCIL
))
335 visual
->buffer_mask
|= ST_ATTACHMENT_DEPTH_STENCIL_MASK
;
337 TRACE("%s: Visual color format: %s\n", __func__
,
338 util_format_name(visual
->color_format
));
345 hgl_destroy_st_visual(struct st_visual
* visual
)