2 Copyright © 2009-2019, The AROS Development Team. All rights reserved.
6 #include <aros/debug.h>
8 #include "util/os_misc.h"
9 #include "pipe/p_defines.h"
10 #include "pipe/p_screen.h"
11 #include "pipe/p_state.h"
13 #include "util/u_inlines.h"
15 #include "main/context.h"
17 #include <proto/utility.h>
18 #include <proto/exec.h>
19 #include <proto/gallium.h>
21 #include "mesa3dgl_support.h"
22 #include "mesa3dgl_gallium.h"
24 static BOOL
MESA3DGLSelectColorFormat(enum pipe_format
* colorFormat
,
25 struct pipe_screen
* screen
, GLint bpp
)
27 D(bug("[MESA3DGL] %s()\n", __func__
));
29 *colorFormat
= PIPE_FORMAT_NONE
;
33 /* Try PIPE_FORMAT_B5G6R5_UNORM */
34 if (screen
->is_format_supported(screen
,
35 PIPE_FORMAT_B5G6R5_UNORM
,
39 PIPE_BIND_RENDER_TARGET
))
41 *colorFormat
= PIPE_FORMAT_B5G6R5_UNORM
;
48 /* Try PIPE_FORMAT_B8G8R8A8_UNORM */
49 if (screen
->is_format_supported(screen
,
50 PIPE_FORMAT_B8G8R8A8_UNORM
,
54 PIPE_BIND_RENDER_TARGET
))
56 *colorFormat
= PIPE_FORMAT_B8G8R8A8_UNORM
;
64 static BOOL
MESA3DGLSelectDepthStencilFormat(enum pipe_format
* depthStencilFormat
,
65 struct pipe_screen
* screen
, BOOL noDepth
, BOOL noStencil
)
67 D(bug("[MESA3DGL] %s()\n", __func__
));
70 *depthStencilFormat
= PIPE_FORMAT_NONE
;
75 /* Try PIPE_FORMAT_S8_UINT_Z24_UNORM */
76 if(!noStencil
&& (screen
->is_format_supported(screen
,
77 PIPE_FORMAT_S8_UINT_Z24_UNORM
,
81 PIPE_BIND_DEPTH_STENCIL
)))
83 *depthStencilFormat
= PIPE_FORMAT_S8_UINT_Z24_UNORM
;
87 /* Try PIPE_FORMAT_X8Z24_UNORM */
88 if(noStencil
&& (screen
->is_format_supported(screen
,
89 PIPE_FORMAT_X8Z24_UNORM
,
93 PIPE_BIND_DEPTH_STENCIL
)))
95 *depthStencilFormat
= PIPE_FORMAT_X8Z24_UNORM
;
99 /* Try PIPE_FORMAT_Z24X8_UNORM */
100 if(noStencil
&& (screen
->is_format_supported(screen
,
101 PIPE_FORMAT_Z24X8_UNORM
,
105 PIPE_BIND_DEPTH_STENCIL
)))
107 *depthStencilFormat
= PIPE_FORMAT_Z24X8_UNORM
;
111 /* Try PIPE_FORMAT_Z16_UNORM */
112 if(screen
->is_format_supported(screen
,
113 PIPE_FORMAT_Z16_UNORM
,
117 PIPE_BIND_DEPTH_STENCIL
))
119 *depthStencilFormat
= PIPE_FORMAT_Z16_UNORM
;
126 BOOL
MESA3DGLFillVisual(struct st_visual
* stvis
, struct pipe_screen
* screen
, int bpp
, struct TagItem
*tagList
)
128 BOOL noDepth
, noStencil
, noAccum
;
130 D(bug("[MESA3DGL] %s()\n", __func__
));
132 noStencil
= GetTagData(GLA_NoStencil
, GL_FALSE
, tagList
);
133 noAccum
= GetTagData(GLA_NoAccum
, GL_FALSE
, tagList
);
134 noDepth
= GetTagData(GLA_NoDepth
, GL_FALSE
, tagList
);
136 stvis
->color_format
= PIPE_FORMAT_NONE
;
137 stvis
->depth_stencil_format
= PIPE_FORMAT_NONE
;
138 stvis
->accum_format
= PIPE_FORMAT_NONE
;
139 stvis
->buffer_mask
= ST_ATTACHMENT_FRONT_LEFT_MASK
;
140 stvis
->render_buffer
= ST_ATTACHMENT_FRONT_LEFT
;
144 if (!MESA3DGLSelectColorFormat(&stvis
->color_format
, screen
, bpp
))
146 D(bug("[MESA3DGL] %s: ERROR - No supported color format found\n", __func__
));
150 /* Z-buffer / Stencil buffer */
151 if (!MESA3DGLSelectDepthStencilFormat(&stvis
->depth_stencil_format
, screen
, noDepth
, noStencil
))
153 D(bug("[MESA3DGL] %s: ERROR - No supported depth/stencil format found\n", __func__
));
159 stvis
->accum_format
= PIPE_FORMAT_NONE
;
162 stvis
->accum_format
= PIPE_FORMAT_R16G16B16A16_SNORM
;
163 stvis
->buffer_mask
|= ST_ATTACHMENT_ACCUM
;
166 /* Buffers */ /* MESA3DGL uses front buffer as back buffer */
167 if (!noDepth
|| !noStencil
)
168 stvis
->buffer_mask
|= ST_ATTACHMENT_DEPTH_STENCIL_MASK
;
173 static VOID
MESA3DGLFrameBufferCreateResource(struct mesa3dgl_framebuffer
* amfb
,
174 const enum st_attachment_type statt
)
176 struct pipe_resource templ
;
178 D(bug("[MESA3DGL] %s()\n", __func__
));
180 memset(&templ
, 0, sizeof(templ
));
182 if(amfb
->screen
->get_param(amfb
->screen
, PIPE_CAP_NPOT_TEXTURES
))
183 templ
.target
= PIPE_TEXTURE_2D
;
185 templ
.target
= PIPE_TEXTURE_RECT
;
186 templ
.width0
= amfb
->width
;
187 templ
.height0
= amfb
->height
;
189 templ
.last_level
= 0;
190 templ
.array_size
= 1;
193 case ST_ATTACHMENT_FRONT_LEFT
:
194 case ST_ATTACHMENT_BACK_LEFT
:
195 case ST_ATTACHMENT_FRONT_RIGHT
:
196 case ST_ATTACHMENT_BACK_RIGHT
:
197 templ
.format
= amfb
->stvis
.color_format
;
198 templ
.bind
= PIPE_BIND_RENDER_TARGET
| PIPE_BIND_SAMPLER_VIEW
;
200 case ST_ATTACHMENT_DEPTH_STENCIL
:
201 templ
.format
= amfb
->stvis
.depth_stencil_format
;
202 templ
.bind
= PIPE_BIND_DEPTH_STENCIL
;
205 return; /* Failure */
208 /* Create resource */
209 amfb
->textures
[statt
] = amfb
->screen
->resource_create(amfb
->screen
, &templ
);
212 static boolean
MESA3DGLFrameBufferValidate(struct st_context_iface
*stctx
,
213 struct st_framebuffer_iface
*stfbi
,
214 const enum st_attachment_type
*statts
,
216 struct pipe_resource
**out
)
218 struct mesa3dgl_framebuffer
* amfb
= (struct mesa3dgl_framebuffer
*)stfbi
;
221 D(bug("[MESA3DGL] %s()\n", __func__
));
223 /* Check for resize */
226 amfb
->resized
= FALSE
;
227 /* Detach "front surface" */
228 pipe_resource_reference(&amfb
->render_resource
, NULL
);
230 /* Detach all resources */
231 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++)
232 pipe_resource_reference(&amfb
->textures
[i
], NULL
);
235 /* Create new resources */
236 for (i
= 0; i
< count
; i
++)
238 if (amfb
->textures
[statts
[i
]] == NULL
)
240 MESA3DGLFrameBufferCreateResource(amfb
, statts
[i
]);
241 if (statts
[i
] == ST_ATTACHMENT_FRONT_LEFT
)
243 pipe_resource_reference(&amfb
->render_resource
, amfb
->textures
[ST_ATTACHMENT_FRONT_LEFT
]);
251 for (i
= 0; i
< count
; i
++)
254 pipe_resource_reference(&out
[i
], amfb
->textures
[statts
[i
]]);
260 static boolean
MESA3DGLFrameBufferFlushFront(struct st_context_iface
*stctx
,
261 struct st_framebuffer_iface
*stfbi
,
262 enum st_attachment_type statt
)
264 D(bug("[MESA3DGL] %s()\n", __func__
));
270 struct mesa3dgl_framebuffer
* MESA3DGLNewFrameBuffer(struct mesa3dgl_context
* ctx
, struct st_visual
* stvis
)
272 D(bug("[MESA3DGL] %s()\n", __func__
));
274 struct mesa3dgl_framebuffer
* framebuffer
=
275 AllocVec(sizeof(struct mesa3dgl_framebuffer
), MEMF_PUBLIC
| MEMF_CLEAR
);
280 CopyMem(stvis
, &framebuffer
->stvis
, sizeof(struct st_visual
));
282 framebuffer
->base
.visual
= &framebuffer
->stvis
;
283 framebuffer
->base
.flush_front
= MESA3DGLFrameBufferFlushFront
;
284 framebuffer
->base
.validate
= MESA3DGLFrameBufferValidate
;
285 framebuffer
->base
.state_manager
= ctx
->stmanager
;
287 framebuffer
->base
.stamp
= 1;
288 framebuffer
->base
.ID
= 1; // p_atomic_inc_return(&osmesa_fb_ID);
290 framebuffer
->screen
= ctx
->stmanager
->screen
;
295 VOID
MESA3DGLFreeFrameBuffer(struct mesa3dgl_framebuffer
* framebuffer
)
297 D(bug("[MESA3DGL] %s()\n", __func__
));
303 pipe_resource_reference(&framebuffer
->render_resource
, NULL
);
305 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++)
306 pipe_resource_reference(&framebuffer
->textures
[i
], NULL
);
308 FreeVec(framebuffer
);
312 VOID
MESA3DGLCheckAndUpdateBufferSize(struct mesa3dgl_context
* ctx
)
314 D(bug("[MESA3DGL] %s()\n", __func__
));
316 MESA3DGLRecalculateBufferWidthHeight(ctx
);
317 if (ctx
->framebuffer
->resized
)
319 p_atomic_set(&ctx
->framebuffer
->base
.stamp
, 1);
323 static int MESA3DGLStManagerGetParam(struct st_manager
*smapi
,
324 enum st_manager_param param
)
326 D(bug("[MESA3DGL] %s()\n", __func__
));
331 struct st_manager
* MESA3DGLNewStManager(struct pipe_screen
* pscreen
)
333 D(bug("[MESA3DGL] %s()\n", __func__
));
335 struct st_manager
* stmanager
=
336 (struct st_manager
*)AllocVec(sizeof(struct st_manager
), MEMF_PUBLIC
| MEMF_CLEAR
);
340 stmanager
->screen
= pscreen
;
341 stmanager
->get_param
= MESA3DGLStManagerGetParam
;
347 VOID
MESA3DGLFreeStManager(APTR pipe
, struct st_manager
* stmanager
)
349 D(bug("[MESA3DGL] %s()\n", __func__
));
353 if (stmanager
->screen
)
354 DestroyPipeScreen(pipe
, stmanager
->screen
);