2 #include "state_tracker/graw.h"
4 #include "pipe/p_context.h"
5 #include "pipe/p_defines.h"
6 #include "pipe/p_screen.h"
7 #include "pipe/p_shader_tokens.h"
8 #include "pipe/p_state.h"
10 #include "util/u_box.h"
11 #include "util/u_debug.h"
12 #include "util/u_debug_image.h"
13 #include "util/u_draw_quad.h"
14 #include "util/u_format.h"
15 #include "util/u_inlines.h"
16 #include "util/u_memory.h"
21 struct pipe_screen
*screen
;
22 struct pipe_context
*ctx
;
23 struct pipe_resource
*color_buf
[PIPE_MAX_COLOR_BUFS
], *zs_buf
;
24 struct pipe_surface
*color_surf
[PIPE_MAX_COLOR_BUFS
], *zs_surf
;
31 graw_util_create_window(struct graw_info
*info
,
32 int width
, int height
,
33 int num_cbufs
, bool zstencil_buf
)
35 static const enum pipe_format formats
[] = {
36 PIPE_FORMAT_RGBA8888_UNORM
,
37 PIPE_FORMAT_BGRA8888_UNORM
,
40 enum pipe_format format
;
41 struct pipe_resource resource_temp
;
42 struct pipe_surface surface_temp
;
45 memset(info
, 0, sizeof(*info
));
47 /* It's hard to say whether window or screen should be created
48 * first. Different environments would prefer one or the other.
50 * Also, no easy way of querying supported formats if the screen
51 * cannot be created first.
53 for (i
= 0; info
->window
== NULL
&& formats
[i
] != PIPE_FORMAT_NONE
; i
++) {
54 info
->screen
= graw_create_window_and_screen(0, 0, width
, height
,
59 if (!info
->screen
|| !info
->window
) {
60 debug_printf("graw: Failed to create screen/window\n");
64 info
->ctx
= info
->screen
->context_create(info
->screen
, NULL
, 0);
65 if (info
->ctx
== NULL
) {
66 debug_printf("graw: Failed to create context\n");
70 for (i
= 0; i
< num_cbufs
; i
++) {
71 /* create color texture */
72 resource_temp
.target
= PIPE_TEXTURE_2D
;
73 resource_temp
.format
= format
;
74 resource_temp
.width0
= width
;
75 resource_temp
.height0
= height
;
76 resource_temp
.depth0
= 1;
77 resource_temp
.array_size
= 1;
78 resource_temp
.last_level
= 0;
79 resource_temp
.nr_samples
= 1;
80 resource_temp
.bind
= (PIPE_BIND_RENDER_TARGET
|
81 PIPE_BIND_DISPLAY_TARGET
);
82 info
->color_buf
[i
] = info
->screen
->resource_create(info
->screen
,
84 if (info
->color_buf
[i
] == NULL
) {
85 debug_printf("graw: Failed to create color texture\n");
89 /* create color surface */
90 surface_temp
.format
= resource_temp
.format
;
91 surface_temp
.u
.tex
.level
= 0;
92 surface_temp
.u
.tex
.first_layer
= 0;
93 surface_temp
.u
.tex
.last_layer
= 0;
94 info
->color_surf
[i
] = info
->ctx
->create_surface(info
->ctx
,
97 if (info
->color_surf
[i
] == NULL
) {
98 debug_printf("graw: Failed to get color surface\n");
103 /* create Z texture (XXX try other Z/S formats if needed) */
104 resource_temp
.target
= PIPE_TEXTURE_2D
;
105 resource_temp
.format
= PIPE_FORMAT_S8_UINT_Z24_UNORM
;
106 resource_temp
.width0
= width
;
107 resource_temp
.height0
= height
;
108 resource_temp
.depth0
= 1;
109 resource_temp
.array_size
= 1;
110 resource_temp
.last_level
= 0;
111 resource_temp
.nr_samples
= 1;
112 resource_temp
.bind
= PIPE_BIND_DEPTH_STENCIL
;
113 info
->zs_buf
= info
->screen
->resource_create(info
->screen
, &resource_temp
);
115 debug_printf("graw: Failed to create Z texture\n");
119 /* create z surface */
120 surface_temp
.format
= resource_temp
.format
;
121 surface_temp
.u
.tex
.level
= 0;
122 surface_temp
.u
.tex
.first_layer
= 0;
123 surface_temp
.u
.tex
.last_layer
= 0;
124 info
->zs_surf
= info
->ctx
->create_surface(info
->ctx
,
127 if (info
->zs_surf
== NULL
) {
128 debug_printf("graw: Failed to get Z surface\n");
133 struct pipe_framebuffer_state fb
;
134 memset(&fb
, 0, sizeof fb
);
135 fb
.nr_cbufs
= num_cbufs
;
138 for (i
= 0; i
< num_cbufs
; i
++)
139 fb
.cbufs
[i
] = info
->color_surf
[i
];
140 fb
.zsbuf
= info
->zs_surf
;
141 info
->ctx
->set_framebuffer_state(info
->ctx
, &fb
);
149 graw_util_default_state(struct graw_info
*info
, boolean depth_test
)
152 struct pipe_blend_state blend
;
154 memset(&blend
, 0, sizeof blend
);
155 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
156 handle
= info
->ctx
->create_blend_state(info
->ctx
, &blend
);
157 info
->ctx
->bind_blend_state(info
->ctx
, handle
);
161 struct pipe_depth_stencil_alpha_state depthStencilAlpha
;
163 memset(&depthStencilAlpha
, 0, sizeof depthStencilAlpha
);
164 depthStencilAlpha
.depth
.enabled
= depth_test
;
165 depthStencilAlpha
.depth
.writemask
= 1;
166 depthStencilAlpha
.depth
.func
= PIPE_FUNC_LESS
;
167 handle
= info
->ctx
->create_depth_stencil_alpha_state(info
->ctx
,
169 info
->ctx
->bind_depth_stencil_alpha_state(info
->ctx
, handle
);
173 struct pipe_rasterizer_state rasterizer
;
175 memset(&rasterizer
, 0, sizeof rasterizer
);
176 rasterizer
.cull_face
= PIPE_FACE_NONE
;
177 rasterizer
.half_pixel_center
= 1;
178 rasterizer
.bottom_edge_rule
= 1;
179 handle
= info
->ctx
->create_rasterizer_state(info
->ctx
, &rasterizer
);
180 info
->ctx
->bind_rasterizer_state(info
->ctx
, handle
);
186 graw_util_viewport(struct graw_info
*info
,
188 float width
, float height
,
189 float zNear
, float zFar
)
192 float half_width
= width
/ 2.0f
;
193 float half_height
= height
/ 2.0f
;
194 float half_depth
= (zFar
- zNear
) / 2.0f
;
195 struct pipe_viewport_state vp
;
197 vp
.scale
[0] = half_width
;
198 vp
.scale
[1] = half_height
;
199 vp
.scale
[2] = half_depth
;
201 vp
.translate
[0] = half_width
+ x
;
202 vp
.translate
[1] = half_height
+ y
;
203 vp
.translate
[2] = half_depth
+ z
;
205 info
->ctx
->set_viewport_states(info
->ctx
, 0, 1, &vp
);
210 graw_util_flush_front(const struct graw_info
*info
)
212 info
->screen
->flush_frontbuffer(info
->screen
, info
->color_buf
[0],
213 0, 0, info
->window
, NULL
);
217 static inline struct pipe_resource
*
218 graw_util_create_tex2d(const struct graw_info
*info
,
219 int width
, int height
, enum pipe_format format
,
222 const int row_stride
= width
* util_format_get_blocksize(format
);
223 const int image_bytes
= row_stride
* height
;
224 struct pipe_resource temp
, *tex
;
227 temp
.target
= PIPE_TEXTURE_2D
;
228 temp
.format
= format
;
230 temp
.height0
= height
;
235 temp
.bind
= PIPE_BIND_SAMPLER_VIEW
;
237 tex
= info
->screen
->resource_create(info
->screen
, &temp
);
239 debug_printf("graw: failed to create texture\n");
243 u_box_2d(0, 0, width
, height
, &box
);
245 info
->ctx
->transfer_inline_write(info
->ctx
,
254 /* Possibly read back & compare against original data:
258 struct pipe_transfer
*t
;
260 t
= pipe_transfer_map(info
->ctx
, samptex
,
261 0, 0, /* level, layer */
263 0, 0, SIZE
, SIZE
); /* x, y, width, height */
265 ptr
= info
->ctx
->transfer_map(info
->ctx
, t
);
267 if (memcmp(ptr
, tex2d
, sizeof tex2d
) != 0) {
272 info
->ctx
->transfer_unmap(info
->ctx
, t
);
274 info
->ctx
->transfer_destroy(info
->ctx
, t
);
283 graw_util_create_simple_sampler(const struct graw_info
*info
,
287 struct pipe_sampler_state sampler_desc
;
290 memset(&sampler_desc
, 0, sizeof sampler_desc
);
291 sampler_desc
.wrap_s
=
292 sampler_desc
.wrap_t
=
293 sampler_desc
.wrap_r
= wrap_mode
;
294 sampler_desc
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
295 sampler_desc
.min_img_filter
=
296 sampler_desc
.mag_img_filter
= img_filter
;
297 sampler_desc
.compare_mode
= PIPE_TEX_COMPARE_NONE
;
298 sampler_desc
.compare_func
= 0;
299 sampler_desc
.normalized_coords
= 1;
300 sampler_desc
.max_anisotropy
= 0;
302 sampler
= info
->ctx
->create_sampler_state(info
->ctx
, &sampler_desc
);
308 static inline struct pipe_sampler_view
*
309 graw_util_create_simple_sampler_view(const struct graw_info
*info
,
310 struct pipe_resource
*texture
)
312 struct pipe_sampler_view sv_temp
;
313 struct pipe_sampler_view
*sv
;
315 memset(&sv_temp
, 0, sizeof(sv_temp
));
316 sv_temp
.format
= texture
->format
;
317 sv_temp
.texture
= texture
;
318 sv_temp
.swizzle_r
= PIPE_SWIZZLE_RED
;
319 sv_temp
.swizzle_g
= PIPE_SWIZZLE_GREEN
;
320 sv_temp
.swizzle_b
= PIPE_SWIZZLE_BLUE
;
321 sv_temp
.swizzle_a
= PIPE_SWIZZLE_ALPHA
;
323 sv
= info
->ctx
->create_sampler_view(info
->ctx
, texture
, &sv_temp
);