1/*
2 * Copyright © 2014 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission.  The copyright holders make no representations
11 * about the suitability of this software for any purpose.  It is provided "as
12 * is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THIS SOFTWARE.
21 */
22
23#ifndef _INTEL_UXA_H_
24#define _INTEL_UXA_H_
25
26#include "intel_video.h"
27#include "uxa.h"
28
29struct intel_uxa_pixmap {
30	dri_bo *bo;
31
32	struct list batch;
33
34	uint8_t tiling;
35	int8_t busy :2;
36	uint8_t dirty :1;
37	uint8_t offscreen :1;
38	uint8_t pinned :5;
39#define PIN_SCANOUT 0x1
40#define PIN_DRI2 0x2
41#define PIN_DRI3 0x4
42#define PIN_PRIME 0x8
43};
44
45#if HAS_DEVPRIVATEKEYREC
46extern DevPrivateKeyRec uxa_pixmap_index;
47#else
48extern int uxa_pixmap_index;
49#endif
50
51static inline struct intel_uxa_pixmap *intel_uxa_get_pixmap_private(PixmapPtr pixmap)
52{
53#if HAS_DEVPRIVATEKEYREC
54	return dixGetPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
55#else
56	return dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
57#endif
58}
59
60static inline Bool intel_uxa_pixmap_is_busy(struct intel_uxa_pixmap *priv)
61{
62	if (priv->busy == -1)
63		priv->busy = drm_intel_bo_busy(priv->bo);
64	return priv->busy;
65}
66
67static inline void intel_uxa_set_pixmap_private(PixmapPtr pixmap, struct intel_uxa_pixmap *intel)
68{
69	dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, intel);
70}
71
72static inline Bool intel_uxa_pixmap_is_dirty(PixmapPtr pixmap)
73{
74	return pixmap && intel_uxa_get_pixmap_private(pixmap)->dirty;
75}
76
77static inline Bool intel_uxa_pixmap_tiled(PixmapPtr pixmap)
78{
79	return intel_uxa_get_pixmap_private(pixmap)->tiling != I915_TILING_NONE;
80}
81
82dri_bo *intel_uxa_get_pixmap_bo(PixmapPtr pixmap);
83void intel_uxa_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo);
84
85Bool intel_uxa_init(ScreenPtr pScreen);
86Bool intel_uxa_create_screen_resources(ScreenPtr pScreen);
87void intel_uxa_block_handler(intel_screen_private *intel);
88
89static inline Bool intel_uxa_pixmap_is_offscreen(PixmapPtr pixmap)
90{
91	struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap);
92	return priv && priv->offscreen;
93}
94
95/* Batchbuffer support macros and functions */
96#include "intel_batchbuffer.h"
97
98/* I830 specific functions */
99extern void IntelEmitInvarientState(ScrnInfoPtr scrn);
100extern void I830EmitInvarientState(ScrnInfoPtr scrn);
101extern void I915EmitInvarientState(ScrnInfoPtr scrn);
102
103extern void I830EmitFlush(ScrnInfoPtr scrn);
104
105/* i830_render.c */
106Bool i830_check_composite(int op,
107			  PicturePtr sourcec, PicturePtr mask, PicturePtr dest,
108			  int width, int height);
109Bool i830_check_composite_target(PixmapPtr pixmap);
110Bool i830_check_composite_texture(ScreenPtr screen, PicturePtr picture);
111Bool i830_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
112			    PicturePtr dest, PixmapPtr sourcecPixmap,
113			    PixmapPtr maskPixmap, PixmapPtr destPixmap);
114void i830_composite(PixmapPtr dest, int srcX, int srcY,
115		    int maskX, int maskY, int dstX, int dstY, int w, int h);
116void i830_vertex_flush(intel_screen_private *intel);
117
118/* i915_render.c */
119Bool i915_check_composite(int op,
120			  PicturePtr sourcec, PicturePtr mask, PicturePtr dest,
121			  int width, int height);
122Bool i915_check_composite_target(PixmapPtr pixmap);
123Bool i915_check_composite_texture(ScreenPtr screen, PicturePtr picture);
124Bool i915_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
125			    PicturePtr dest, PixmapPtr sourcecPixmap,
126			    PixmapPtr maskPixmap, PixmapPtr destPixmap);
127void i915_composite(PixmapPtr dest, int srcX, int srcY,
128		    int maskX, int maskY, int dstX, int dstY, int w, int h);
129void i915_vertex_flush(intel_screen_private *intel);
130void i915_batch_commit_notify(intel_screen_private *intel);
131void i830_batch_commit_notify(intel_screen_private *intel);
132/* i965_render.c */
133unsigned int gen4_render_state_size(ScrnInfoPtr scrn);
134void gen4_render_state_init(ScrnInfoPtr scrn);
135void gen4_render_state_cleanup(ScrnInfoPtr scrn);
136Bool i965_check_composite(int op,
137			  PicturePtr sourcec, PicturePtr mask, PicturePtr dest,
138			  int width, int height);
139Bool i965_check_composite_texture(ScreenPtr screen, PicturePtr picture);
140Bool i965_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
141			    PicturePtr dest, PixmapPtr sourcecPixmap,
142			    PixmapPtr maskPixmap, PixmapPtr destPixmap);
143void i965_composite(PixmapPtr dest, int srcX, int srcY,
144		    int maskX, int maskY, int dstX, int dstY, int w, int h);
145
146void i965_vertex_flush(intel_screen_private *intel);
147void i965_batch_flush(intel_screen_private *intel);
148void i965_batch_commit_notify(intel_screen_private *intel);
149
150/* i965_3d.c */
151void gen6_upload_invariant_states(intel_screen_private *intel);
152void gen6_upload_viewport_state_pointers(intel_screen_private *intel,
153					 drm_intel_bo *cc_vp_bo);
154void gen7_upload_viewport_state_pointers(intel_screen_private *intel,
155					 drm_intel_bo *cc_vp_bo);
156void gen6_upload_urb(intel_screen_private *intel);
157void gen7_upload_urb(intel_screen_private *intel);
158void gen6_upload_cc_state_pointers(intel_screen_private *intel,
159				   drm_intel_bo *blend_bo, drm_intel_bo *cc_bo,
160				   drm_intel_bo *depth_stencil_bo,
161				   uint32_t blend_offset);
162void gen7_upload_cc_state_pointers(intel_screen_private *intel,
163				   drm_intel_bo *blend_bo, drm_intel_bo *cc_bo,
164				   drm_intel_bo *depth_stencil_bo,
165				   uint32_t blend_offset);
166void gen6_upload_sampler_state_pointers(intel_screen_private *intel,
167					drm_intel_bo *sampler_bo);
168void gen7_upload_sampler_state_pointers(intel_screen_private *intel,
169					drm_intel_bo *sampler_bo);
170void gen7_upload_bypass_states(intel_screen_private *intel);
171void gen6_upload_gs_state(intel_screen_private *intel);
172void gen6_upload_vs_state(intel_screen_private *intel);
173void gen6_upload_clip_state(intel_screen_private *intel);
174void gen6_upload_sf_state(intel_screen_private *intel, int num_sf_outputs, int read_offset);
175void gen7_upload_sf_state(intel_screen_private *intel, int num_sf_outputs, int read_offset);
176void gen6_upload_binding_table(intel_screen_private *intel, uint32_t ps_binding_table_offset);
177void gen7_upload_binding_table(intel_screen_private *intel, uint32_t ps_binding_table_offset);
178void gen6_upload_depth_buffer_state(intel_screen_private *intel);
179void gen7_upload_depth_buffer_state(intel_screen_private *intel);
180
181Bool intel_uxa_transform_is_affine(PictTransformPtr t);
182
183Bool
184intel_uxa_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
185				 float *x_out, float *y_out);
186
187Bool
188intel_uxa_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
189				    float *x_out, float *y_out, float *z_out);
190
191static inline void
192intel_uxa_debug_fallback(ScrnInfoPtr scrn, const char *format, ...) _X_ATTRIBUTE_PRINTF(2, 3);
193
194static inline void
195intel_uxa_debug_fallback(ScrnInfoPtr scrn, const char *format, ...)
196{
197	intel_screen_private *intel = intel_get_screen_private(scrn);
198	va_list ap;
199
200	va_start(ap, format);
201	if (intel->fallback_debug) {
202		xf86DrvMsg(scrn->scrnIndex, X_INFO, "fallback: ");
203		LogVMessageVerb(X_INFO, 1, format, ap);
204	}
205	va_end(ap);
206}
207
208static inline Bool
209intel_uxa_check_pitch_2d(PixmapPtr pixmap)
210{
211	uint32_t pitch = intel_pixmap_pitch(pixmap);
212	if (pitch > KB(32)) {
213		ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
214		intel_uxa_debug_fallback(scrn, "pitch exceeds 2d limit 32K\n");
215		return FALSE;
216	}
217	return TRUE;
218}
219
220/* For pre-965 chip only, as they have 8KB limit for 3D */
221static inline Bool
222intel_uxa_check_pitch_3d(PixmapPtr pixmap)
223{
224	uint32_t pitch = intel_pixmap_pitch(pixmap);
225	if (pitch > KB(8)) {
226		ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
227		intel_uxa_debug_fallback(scrn, "pitch exceeds 3d limit 8K\n");
228		return FALSE;
229	}
230	return TRUE;
231}
232
233/**
234 * Little wrapper around drm_intel_bo_reloc to return the initial value you
235 * should stuff into the relocation entry.
236 *
237 * If only we'd done this before settling on the library API.
238 */
239static inline uint32_t
240intel_uxa_emit_reloc(drm_intel_bo * bo, uint32_t offset,
241		 drm_intel_bo * target_bo, uint32_t target_offset,
242		 uint32_t read_domains, uint32_t write_domain)
243{
244	drm_intel_bo_emit_reloc(bo, offset, target_bo, target_offset,
245				read_domains, write_domain);
246
247	return target_bo->offset + target_offset;
248}
249
250static inline drm_intel_bo *intel_uxa_bo_alloc_for_data(intel_screen_private *intel,
251						    const void *data,
252						    unsigned int size,
253						    const char *name)
254{
255	drm_intel_bo *bo;
256	int ret;
257
258	bo = drm_intel_bo_alloc(intel->bufmgr, name, size, 4096);
259	assert(bo);
260
261	ret = drm_intel_bo_subdata(bo, 0, size, data);
262	assert(ret == 0);
263
264	return bo;
265	(void)ret;
266}
267
268void intel_uxa_debug_flush(ScrnInfoPtr scrn);
269
270
271Bool intel_uxa_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table,
272                                  int num_bos);
273
274XF86VideoAdaptorPtr intel_uxa_video_setup_image_textured(ScreenPtr screen);
275
276void I915DisplayVideoTextured(ScrnInfoPtr scrn,
277			      intel_adaptor_private *adaptor_priv,
278			      int id, RegionPtr dstRegion, short width,
279			      short height, int video_pitch, int video_pitch2,
280			      short src_w, short src_h,
281			      short drw_w, short drw_h, PixmapPtr pixmap);
282
283void I965DisplayVideoTextured(ScrnInfoPtr scrn,
284			      intel_adaptor_private *adaptor_priv,
285			      int id, RegionPtr dstRegion, short width,
286			      short height, int video_pitch, int video_pitch2,
287			      short src_w, short src_h,
288			      short drw_w, short drw_h, PixmapPtr pixmap);
289
290void Gen6DisplayVideoTextured(ScrnInfoPtr scrn,
291			      intel_adaptor_private *adaptor_priv,
292			      int id, RegionPtr dstRegion, short width,
293			      short height, int video_pitch, int video_pitch2,
294			      short src_w, short src_h,
295			      short drw_w, short drw_h, PixmapPtr pixmap);
296
297void i965_free_video(ScrnInfoPtr scrn);
298
299#endif /* _INTEL_UXA_H_ */
300