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
15 #include "pipe/p_format.h"
16 #include "util/u_atomic.h"
17 #include "util/u_format.h"
18 #include "util/u_memory.h"
19 #include "util/u_inlines.h"
21 #include "hgl_context.h"
25 # define TRACE(x...) printf("hgl:state_tracker: " x)
26 # define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
31 #define ERROR(x...) printf("hgl:state_tracker: " x)
34 // Perform a safe void to hgl_context cast
35 static INLINE
struct hgl_context
*
36 hgl_st_context(struct st_context_iface
*stctxi
)
38 struct hgl_context
* context
;
40 context
= (struct hgl_context
*)stctxi
->st_manager_private
;
46 // Perform a safe void to hgl_buffer cast
47 static INLINE
struct hgl_buffer
*
48 hgl_st_framebuffer(struct st_framebuffer_iface
*stfbi
)
50 struct hgl_buffer
* buffer
;
52 buffer
= (struct hgl_buffer
*)stfbi
->st_manager_private
;
59 hgl_st_framebuffer_flush_front(struct st_context_iface
*stctxi
,
60 struct st_framebuffer_iface
* stfbi
, enum st_attachment_type statt
)
64 //struct hgl_context* context = hgl_st_context(stctxi);
65 //struct hgl_buffer* buffer = hgl_st_context(stfbi);
68 struct stw_st_framebuffer
*stwfb
= stw_st_framebuffer(stfb
);
69 pipe_mutex_lock(stwfb
->fb
->mutex
);
71 struct pipe_resource
* resource
= textures
[statt
];
73 stw_framebuffer_present_locked(...);
81 hgl_st_framebuffer_validate_textures(struct st_framebuffer_iface
*stfbi
,
82 unsigned width
, unsigned height
, unsigned mask
)
84 struct hgl_buffer
* buffer
;
85 enum st_attachment_type i
;
86 struct pipe_resource templat
;
90 buffer
= hgl_st_framebuffer(stfbi
);
92 if (buffer
->width
!= width
|| buffer
->height
!= height
) {
93 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++)
94 pipe_resource_reference(&buffer
->textures
[i
], NULL
);
97 memset(&templat
, 0, sizeof(templat
));
98 templat
.target
= buffer
->target
;
99 templat
.width0
= width
;
100 templat
.height0
= height
;
102 templat
.array_size
= 1;
103 templat
.last_level
= 0;
105 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++) {
106 enum pipe_format format
;
110 case ST_ATTACHMENT_FRONT_LEFT
:
111 case ST_ATTACHMENT_BACK_LEFT
:
112 case ST_ATTACHMENT_FRONT_RIGHT
:
113 case ST_ATTACHMENT_BACK_RIGHT
:
114 format
= buffer
->visual
->color_format
;
115 bind
= PIPE_BIND_DISPLAY_TARGET
| PIPE_BIND_RENDER_TARGET
;
117 case ST_ATTACHMENT_DEPTH_STENCIL
:
118 format
= buffer
->visual
->depth_stencil_format
;
119 bind
= PIPE_BIND_DEPTH_STENCIL
;
122 format
= PIPE_FORMAT_NONE
;
127 if (format
!= PIPE_FORMAT_NONE
) {
128 templat
.format
= format
;
130 buffer
->textures
[i
] = buffer
->screen
->resource_create(buffer
->screen
,
132 if (!buffer
->textures
[i
])
137 buffer
->width
= width
;
138 buffer
->height
= height
;
146 * Called by the st manager to validate the framebuffer (allocate
150 hgl_st_framebuffer_validate(struct st_context_iface
*stctxi
,
151 struct st_framebuffer_iface
*stfbi
, const enum st_attachment_type
*statts
,
152 unsigned count
, struct pipe_resource
**out
)
154 struct hgl_context
* context
;
155 struct hgl_buffer
* buffer
;
156 unsigned stAttachmentMask
, newMask
;
162 context
= hgl_st_context(stctxi
);
163 buffer
= hgl_st_framebuffer(stfbi
);
167 //get_bitmap_size(context->bitmap, &width, &height);
169 // Build mask of current attachments
170 stAttachmentMask
= 0;
171 for (i
= 0; i
< count
; i
++)
172 stAttachmentMask
|= 1 << statts
[i
];
174 newMask
= stAttachmentMask
& ~buffer
->mask
;
176 resized
= (buffer
->width
!= context
->width
)
177 || (buffer
->height
!= context
->height
);
179 if (resized
|| newMask
) {
181 TRACE("%s: resize event. old: %d x %d; new: %d x %d\n", __func__
,
182 buffer
->width
, buffer
->height
, context
->width
, context
->height
);
184 ret
= hgl_st_framebuffer_validate_textures(stfbi
,
185 context
->width
, context
->height
, stAttachmentMask
);
190 // TODO: Simply update attachments
196 for (i
= 0; i
< count
; i
++) {
198 pipe_resource_reference(&out
[i
], buffer
->textures
[statts
[i
]]);
206 hgl_st_manager_get_param(struct st_manager
*smapi
, enum st_manager_param param
)
211 case ST_MANAGER_BROKEN_INVALIDATE
:
220 * Create new framebuffer
223 hgl_create_st_framebuffer(struct hgl_context
* context
)
225 struct hgl_buffer
*buffer
;
228 // Our requires before creating a framebuffer
230 assert(context
->screen
);
231 assert(context
->stVisual
);
233 buffer
= CALLOC_STRUCT(hgl_buffer
);
236 // calloc and configure our st_framebuffer interface
237 buffer
->stfbi
= CALLOC_STRUCT(st_framebuffer_iface
);
238 assert(buffer
->stfbi
);
240 // Prepare our buffer
241 buffer
->visual
= context
->stVisual
;
242 buffer
->screen
= context
->screen
;
244 if (context
->screen
->get_param(buffer
->screen
, PIPE_CAP_NPOT_TEXTURES
))
245 buffer
->target
= PIPE_TEXTURE_2D
;
247 buffer
->target
= PIPE_TEXTURE_RECT
;
249 // Prepare our state_tracker interface
250 buffer
->stfbi
->flush_front
= hgl_st_framebuffer_flush_front
;
251 buffer
->stfbi
->validate
= hgl_st_framebuffer_validate
;
252 buffer
->stfbi
->visual
= context
->stVisual
;
254 p_atomic_set(&buffer
->stfbi
->stamp
, 1);
255 buffer
->stfbi
->st_manager_private
= (void*)buffer
;
262 hgl_create_st_manager(struct hgl_context
* context
)
264 struct st_manager
* manager
;
270 assert(context
->screen
);
272 manager
= CALLOC_STRUCT(st_manager
);
275 //manager->display = dpy;
276 manager
->screen
= context
->screen
;
277 manager
->get_param
= hgl_st_manager_get_param
;
284 hgl_destroy_st_manager(struct st_manager
*manager
)
293 hgl_create_st_visual(ulong options
)
295 struct st_visual
* visual
;
299 visual
= CALLOC_STRUCT(st_visual
);
302 // Determine color format
303 if ((options
& BGL_INDEX
) != 0) {
305 visual
->color_format
= PIPE_FORMAT_B5G6R5_UNORM
;
306 // TODO: Indexed color depth buffer?
307 visual
->depth_stencil_format
= PIPE_FORMAT_NONE
;
310 visual
->color_format
= (options
& BGL_ALPHA
)
311 ? PIPE_FORMAT_BGRA8888_UNORM
: PIPE_FORMAT_BGRX8888_UNORM
;
312 // TODO: Determine additional stencil formats
313 visual
->depth_stencil_format
= (options
& BGL_DEPTH
)
314 ? PIPE_FORMAT_Z24_UNORM_S8_UINT
: PIPE_FORMAT_NONE
;
317 visual
->accum_format
= (options
& BGL_ACCUM
)
318 ? PIPE_FORMAT_R16G16B16A16_SNORM
: PIPE_FORMAT_NONE
;
320 visual
->buffer_mask
|= ST_ATTACHMENT_FRONT_LEFT_MASK
;
321 visual
->render_buffer
= ST_ATTACHMENT_FRONT_LEFT
;
323 if ((options
& BGL_DOUBLE
) != 0) {
324 visual
->buffer_mask
|= ST_ATTACHMENT_BACK_LEFT_MASK
;
325 visual
->render_buffer
= ST_ATTACHMENT_BACK_LEFT
;
329 if ((options
& BGL_STEREO
) != 0) {
330 visual
->buffer_mask
|= ST_ATTACHMENT_FRONT_RIGHT_MASK
;
331 if ((options
& BGL_DOUBLE
) != 0)
332 visual
->buffer_mask
|= ST_ATTACHMENT_BACK_RIGHT_MASK
;
336 if ((options
& BGL_DEPTH
) || (options
& BGL_STENCIL
))
337 visual
->buffer_mask
|= ST_ATTACHMENT_DEPTH_STENCIL_MASK
;
339 TRACE("%s: Visual color format: %s\n", __func__
,
340 util_format_name(visual
->color_format
));
347 hgl_destroy_st_visual(struct st_visual
* visual
)