1 #include <pipe/p_screen.h>
2 #include <pipe/p_context.h>
3 #include <pipe/p_state.h>
4 #include <pipe/p_format.h>
5 #include <pipe/p_context.h>
6 #include <pipe/p_inlines.h>
7 #include <pipe/internal/p_winsys_screen.h>
8 #include <softpipe/sp_winsys.h>
9 #include <trace/tr_context.h>
10 #include <state_tracker/drm_api.h>
12 struct _cairo_gpu_texture
14 CAIRO_GPU_BASE_TEXTURE_T
;
16 struct pipe_texture
* texture
;
17 struct pipe_surface
* surface
;
20 // only have non-MSAA and MSAA
23 struct _cairo_gpu_surface
25 CAIRO_GPU_BASE_SURFACE_T
;
26 cairo_rectangle_int_t bbox
[MAX_SURFS
];
28 cairo_gpu_texture_t texture
;
31 typedef struct _cairo_gpu_context cairo_gpu_context_t
;
33 struct _cairo_gpu_geometry
45 unsigned char velem_pad
;
50 struct pipe_vertex_buffer vbuffer
;
53 #define TABLE_FRAG (0 << 30)
54 #define TABLE_VERT (1 << 30)
55 #define TABLE_BLEND (2 << 30)
56 #define TABLE_SAMPLER (3 << 30)
57 #define TABLE_MASK (3 << 30)
61 cairo_hash_entry_t base
;
63 } cairo_gpu_ptr_entry_t
;;
65 #define API_SOFTPIPE 0
69 struct _cairo_gpu_space
71 CAIRO_GPU_BASE_SPACE_T
;
73 struct pipe_screen
* screen
;
74 struct pipe_screen
* real_screen
;
82 struct pipe_context
* (*context_create
)(void*, struct pipe_screen
*);
90 // currently only used in _destroy
97 cairo_hash_table_t
* table
;
102 #define MAX_SMALL_WIDTH 16
103 #define MAX_TEXTURE_UNITS 6
106 struct _cairo_gpu_context
108 // these are redundant, but we currently keep them for simplicity
109 cairo_gpu_space_t
* space
;
110 cairo_gpu_space_tls_t
* tls
;
112 struct pipe_context
* pipe
;
115 struct pipe_vertex_buffer vbuffer
;
117 unsigned samplers
[MAX_OPERANDS
];
118 void* ssamplers
[MAX_OPERANDS
];
119 struct pipe_texture
* textures
[MAX_OPERANDS
];
126 float vert_constants
[VERTENV_COUNT
* 4];
127 float frag_constants
[FRAGENV_COUNT
* 4];
129 struct pipe_constant_buffer vert_cbuffer
;
130 struct pipe_constant_buffer frag_cbuffer
;
132 char ssamplers_dirty
: 1;
133 char textures_dirty
: 1;
134 char vert_constants_dirty
: 1;
135 char frag_constants_dirty
: 1;
136 char matrix_dirty
: 1;
152 struct pipe_surface
* surface
;
156 struct pipe_surface
* read_surface
;
157 cairo_gpu_texture_t
* read_texture
;
160 struct _cairo_gpu_space_tls
162 CAIRO_GPU_BASE_SPACE_TLS_T
;
163 cairo_gpu_context_t context
;
167 _cairo_gpu_space__lookup_ptr_unlocked(cairo_gpu_space_t
* space
, unsigned hash
)
169 cairo_hash_entry_t entry
;
170 cairo_gpu_ptr_entry_t
* p
;
173 p
= (cairo_gpu_ptr_entry_t
*)_cairo_hash_table_lookup(space
->table
, &entry
);
180 _cairo_gpu_space__lookup_ptr(cairo_gpu_space_t
* space
, unsigned hash
)
183 CAIRO_MUTEX_LOCK(space
->mutex
);
184 p
= _cairo_gpu_space__lookup_ptr_unlocked(space
, hash
);
185 CAIRO_MUTEX_UNLOCK(space
->mutex
);
189 static inline cairo_bool_t
190 _cairo_gpu_space_store_ptr_unlocked(cairo_gpu_space_t
* space
, unsigned hash
, void* p
)
192 cairo_gpu_ptr_entry_t
* e
= malloc(sizeof(cairo_gpu_ptr_entry_t
));
195 if(_cairo_hash_table_insert(space
->table
, &e
->base
))
203 static inline void _cairo_gpu_texture_fini(cairo_gpu_context_t
* ctx
, cairo_gpu_texture_t
* texture
)
206 pipe_texture_reference(&texture
->texture
, 0);
208 pipe_surface_reference(&texture
->surface
, 0);
211 // you must fill target_idx
212 static inline void _cairo_gpu_texture_init(cairo_gpu_space_t
* space
, cairo_gpu_texture_t
* texture
, int width
, int height
)
214 texture
->texture
= 0;
215 texture
->surface
= 0;
217 if(space
->tex_npot
|| (is_pow2(width
) && is_pow2(height
)))
218 texture
->target_idx
= TARGET_2D
;
221 texture
->target_idx
= TARGET_2D
;
222 width
= higher_pow2(width
- 1);
223 height
= higher_pow2(height
- 1);
226 texture
->width
= width
;
227 texture
->height
= height
;
230 static inline void _cairo_gpu_texture_realize(cairo_gpu_context_t
* ctx
, cairo_gpu_texture_t
* texture
)
232 struct pipe_texture templ
;
233 memset(&templ
, 0, sizeof(templ
));
234 templ
.target
= PIPE_TEXTURE_2D
;
236 // TODO: choose appropriate format
237 templ
.format
= PIPE_FORMAT_A8R8G8B8_UNORM
;
239 pf_get_block(templ
.format
, &templ
.block
);
240 templ
.width
[0] = texture
->width
;
241 templ
.height
[0] = texture
->height
;
243 templ
.last_level
= 0;
244 // PIPE_TEXTURE_USAGE_DISPLAY_TARGET | PIPE_TEXTURE_USAGE_RENDER_TARGET
245 templ
.tex_usage
= PIPE_TEXTURE_USAGE_SAMPLER
;
246 texture
->texture
= ctx
->space
->screen
->texture_create(ctx
->space
->screen
, &templ
);
247 texture
->surface
= ctx
->space
->screen
->get_tex_surface(ctx
->space
->screen
, texture
->texture
, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
);
250 // you must fill target_idx
251 static inline void _cairo_gpu_texture_create(cairo_gpu_context_t
* ctx
, cairo_gpu_texture_t
* texture
, int width
, int height
)
253 _cairo_gpu_texture_init(ctx
->space
, texture
, width
, height
);
254 _cairo_gpu_texture_realize(ctx
, texture
);
258 _cairo_gpu_texture_adjust_matrix(cairo_gpu_texture_t
* texture
, cairo_matrix_t
* matrix
)
260 if(texture
->target_idx
== TARGET_2D
)
262 double xm
= 1.0 / texture
->width
;
263 double ym
= 1.0 / texture
->height
;