Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

u_blitter.c 44KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256
  1. /**************************************************************************
  2. *
  3. * Copyright 2009 Marek Olšák <maraeo@gmail.com>
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sub license, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * The above copyright notice and this permission notice (including the
  14. * next paragraph) shall be included in all copies or substantial portions
  15. * of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  20. * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  21. * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  22. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  23. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. *
  25. **************************************************************************/
  26. /**
  27. * @file
  28. * Blitter utility to facilitate acceleration of the clear, clear_render_target,
  29. * clear_depth_stencil, and resource_copy_region functions.
  30. *
  31. * @author Marek Olšák
  32. */
  33. #include "pipe/p_context.h"
  34. #include "pipe/p_defines.h"
  35. #include "util/u_inlines.h"
  36. #include "pipe/p_shader_tokens.h"
  37. #include "pipe/p_state.h"
  38. #include "util/u_format.h"
  39. #include "util/u_memory.h"
  40. #include "util/u_math.h"
  41. #include "util/u_blitter.h"
  42. #include "util/u_draw_quad.h"
  43. #include "util/u_sampler.h"
  44. #include "util/u_simple_shaders.h"
  45. #include "util/u_surface.h"
  46. #include "util/u_texture.h"
  47. #define INVALID_PTR ((void*)~0)
  48. struct blitter_context_priv
  49. {
  50. struct blitter_context base;
  51. struct pipe_resource *vbuf; /**< quad */
  52. float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */
  53. /* Templates for various state objects. */
  54. /* Constant state objects. */
  55. /* Vertex shaders. */
  56. void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/
  57. void *vs_pos_only; /**< Vertex shader which passes pos to the output.*/
  58. /* Fragment shaders. */
  59. /* The shader at index i outputs color to color buffers 0,1,...,i-1. */
  60. void *fs_col[PIPE_MAX_COLOR_BUFS+1];
  61. void *fs_col_int[PIPE_MAX_COLOR_BUFS+1];
  62. /* FS which outputs a color from a texture,
  63. where the index is PIPE_TEXTURE_* to be sampled. */
  64. void *fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES];
  65. /* FS which outputs a depth from a texture,
  66. where the index is PIPE_TEXTURE_* to be sampled. */
  67. void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES];
  68. /* Blend state. */
  69. void *blend_write_color; /**< blend state with writemask of RGBA */
  70. void *blend_keep_color; /**< blend state with writemask of 0 */
  71. /* Depth stencil alpha state. */
  72. void *dsa_write_depth_stencil;
  73. void *dsa_write_depth_keep_stencil;
  74. void *dsa_keep_depth_stencil;
  75. void *dsa_keep_depth_write_stencil;
  76. /* Vertex elements states. */
  77. void *velem_state;
  78. void *velem_uint_state;
  79. void *velem_sint_state;
  80. void *velem_state_readbuf;
  81. /* Sampler state. */
  82. void *sampler_state;
  83. /* Rasterizer state. */
  84. void *rs_state;
  85. void *rs_discard_state;
  86. /* Viewport state. */
  87. struct pipe_viewport_state viewport;
  88. /* Destination surface dimensions. */
  89. unsigned dst_width;
  90. unsigned dst_height;
  91. boolean has_geometry_shader;
  92. boolean vertex_has_integers;
  93. boolean has_stream_out;
  94. };
  95. static void blitter_draw_rectangle(struct blitter_context *blitter,
  96. unsigned x, unsigned y,
  97. unsigned width, unsigned height,
  98. float depth,
  99. enum blitter_attrib_type type,
  100. const union pipe_color_union *attrib);
  101. struct blitter_context *util_blitter_create(struct pipe_context *pipe)
  102. {
  103. struct blitter_context_priv *ctx;
  104. struct pipe_blend_state blend;
  105. struct pipe_depth_stencil_alpha_state dsa;
  106. struct pipe_rasterizer_state rs_state;
  107. struct pipe_sampler_state sampler_state;
  108. struct pipe_vertex_element velem[2];
  109. unsigned i;
  110. ctx = CALLOC_STRUCT(blitter_context_priv);
  111. if (!ctx)
  112. return NULL;
  113. ctx->base.pipe = pipe;
  114. ctx->base.draw_rectangle = blitter_draw_rectangle;
  115. /* init state objects for them to be considered invalid */
  116. ctx->base.saved_blend_state = INVALID_PTR;
  117. ctx->base.saved_dsa_state = INVALID_PTR;
  118. ctx->base.saved_rs_state = INVALID_PTR;
  119. ctx->base.saved_fs = INVALID_PTR;
  120. ctx->base.saved_vs = INVALID_PTR;
  121. ctx->base.saved_gs = INVALID_PTR;
  122. ctx->base.saved_velem_state = INVALID_PTR;
  123. ctx->base.saved_fb_state.nr_cbufs = ~0;
  124. ctx->base.saved_num_sampler_views = ~0;
  125. ctx->base.saved_num_sampler_states = ~0;
  126. ctx->base.saved_num_vertex_buffers = ~0;
  127. ctx->base.saved_num_so_targets = ~0;
  128. ctx->has_geometry_shader =
  129. pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY,
  130. PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0;
  131. ctx->vertex_has_integers =
  132. pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_VERTEX,
  133. PIPE_SHADER_CAP_INTEGERS);
  134. ctx->has_stream_out =
  135. pipe->screen->get_param(pipe->screen,
  136. PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0;
  137. /* blend state objects */
  138. memset(&blend, 0, sizeof(blend));
  139. ctx->blend_keep_color = pipe->create_blend_state(pipe, &blend);
  140. blend.rt[0].colormask = PIPE_MASK_RGBA;
  141. ctx->blend_write_color = pipe->create_blend_state(pipe, &blend);
  142. /* depth stencil alpha state objects */
  143. memset(&dsa, 0, sizeof(dsa));
  144. ctx->dsa_keep_depth_stencil =
  145. pipe->create_depth_stencil_alpha_state(pipe, &dsa);
  146. dsa.depth.enabled = 1;
  147. dsa.depth.writemask = 1;
  148. dsa.depth.func = PIPE_FUNC_ALWAYS;
  149. ctx->dsa_write_depth_keep_stencil =
  150. pipe->create_depth_stencil_alpha_state(pipe, &dsa);
  151. dsa.stencil[0].enabled = 1;
  152. dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
  153. dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
  154. dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
  155. dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
  156. dsa.stencil[0].valuemask = 0xff;
  157. dsa.stencil[0].writemask = 0xff;
  158. ctx->dsa_write_depth_stencil =
  159. pipe->create_depth_stencil_alpha_state(pipe, &dsa);
  160. dsa.depth.enabled = 0;
  161. dsa.depth.writemask = 0;
  162. ctx->dsa_keep_depth_write_stencil =
  163. pipe->create_depth_stencil_alpha_state(pipe, &dsa);
  164. /* sampler state */
  165. memset(&sampler_state, 0, sizeof(sampler_state));
  166. sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  167. sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  168. sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  169. sampler_state.normalized_coords = 1;
  170. ctx->sampler_state = pipe->create_sampler_state(pipe, &sampler_state);
  171. /* rasterizer state */
  172. memset(&rs_state, 0, sizeof(rs_state));
  173. rs_state.cull_face = PIPE_FACE_NONE;
  174. rs_state.gl_rasterization_rules = 1;
  175. rs_state.flatshade = 1;
  176. rs_state.depth_clip = 1;
  177. ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
  178. if (ctx->has_stream_out) {
  179. rs_state.rasterizer_discard = 1;
  180. ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state);
  181. }
  182. /* vertex elements states */
  183. memset(&velem[0], 0, sizeof(velem[0]) * 2);
  184. for (i = 0; i < 2; i++) {
  185. velem[i].src_offset = i * 4 * sizeof(float);
  186. velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  187. }
  188. ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
  189. if (ctx->vertex_has_integers) {
  190. memset(&velem[0], 0, sizeof(velem[0]) * 2);
  191. velem[0].src_offset = 0;
  192. velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  193. velem[1].src_offset = 4 * sizeof(float);
  194. velem[1].src_format = PIPE_FORMAT_R32G32B32A32_SINT;
  195. ctx->velem_sint_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
  196. memset(&velem[0], 0, sizeof(velem[0]) * 2);
  197. velem[0].src_offset = 0;
  198. velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  199. velem[1].src_offset = 4 * sizeof(float);
  200. velem[1].src_format = PIPE_FORMAT_R32G32B32A32_UINT;
  201. ctx->velem_uint_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
  202. }
  203. if (ctx->has_stream_out) {
  204. velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  205. ctx->velem_state_readbuf = pipe->create_vertex_elements_state(pipe, 1, &velem[0]);
  206. }
  207. /* fragment shaders are created on-demand */
  208. /* vertex shaders */
  209. {
  210. const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
  211. TGSI_SEMANTIC_GENERIC };
  212. const uint semantic_indices[] = { 0, 0 };
  213. ctx->vs =
  214. util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
  215. semantic_indices);
  216. }
  217. if (ctx->has_stream_out) {
  218. struct pipe_stream_output_info so;
  219. const uint semantic_names[] = { TGSI_SEMANTIC_POSITION };
  220. const uint semantic_indices[] = { 0 };
  221. memset(&so, 0, sizeof(so));
  222. so.num_outputs = 1;
  223. so.output[0].register_mask = TGSI_WRITEMASK_XYZW;
  224. so.stride = 4;
  225. ctx->vs_pos_only =
  226. util_make_vertex_passthrough_shader_with_so(pipe, 1, semantic_names,
  227. semantic_indices, &so);
  228. }
  229. /* set invariant vertex coordinates */
  230. for (i = 0; i < 4; i++)
  231. ctx->vertices[i][0][3] = 1; /*v.w*/
  232. /* create the vertex buffer */
  233. ctx->vbuf = pipe_user_buffer_create(ctx->base.pipe->screen,
  234. ctx->vertices,
  235. sizeof(ctx->vertices),
  236. PIPE_BIND_VERTEX_BUFFER);
  237. return &ctx->base;
  238. }
  239. void util_blitter_destroy(struct blitter_context *blitter)
  240. {
  241. struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
  242. struct pipe_context *pipe = blitter->pipe;
  243. int i;
  244. pipe->delete_blend_state(pipe, ctx->blend_write_color);
  245. pipe->delete_blend_state(pipe, ctx->blend_keep_color);
  246. pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
  247. pipe->delete_depth_stencil_alpha_state(pipe,
  248. ctx->dsa_write_depth_keep_stencil);
  249. pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
  250. pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
  251. pipe->delete_rasterizer_state(pipe, ctx->rs_state);
  252. if (ctx->rs_discard_state)
  253. pipe->delete_rasterizer_state(pipe, ctx->rs_discard_state);
  254. pipe->delete_vs_state(pipe, ctx->vs);
  255. if (ctx->vs_pos_only)
  256. pipe->delete_vs_state(pipe, ctx->vs_pos_only);
  257. pipe->delete_vertex_elements_state(pipe, ctx->velem_state);
  258. if (ctx->vertex_has_integers) {
  259. pipe->delete_vertex_elements_state(pipe, ctx->velem_sint_state);
  260. pipe->delete_vertex_elements_state(pipe, ctx->velem_uint_state);
  261. }
  262. if (ctx->velem_state_readbuf)
  263. pipe->delete_vertex_elements_state(pipe, ctx->velem_state_readbuf);
  264. for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
  265. if (ctx->fs_texfetch_col[i])
  266. pipe->delete_fs_state(pipe, ctx->fs_texfetch_col[i]);
  267. if (ctx->fs_texfetch_depth[i])
  268. pipe->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]);
  269. }
  270. for (i = 0; i <= PIPE_MAX_COLOR_BUFS; i++) {
  271. if (ctx->fs_col[i])
  272. pipe->delete_fs_state(pipe, ctx->fs_col[i]);
  273. if (ctx->fs_col_int[i])
  274. pipe->delete_fs_state(pipe, ctx->fs_col_int[i]);
  275. }
  276. pipe->delete_sampler_state(pipe, ctx->sampler_state);
  277. pipe_resource_reference(&ctx->vbuf, NULL);
  278. FREE(ctx);
  279. }
  280. static void blitter_set_running_flag(struct blitter_context_priv *ctx)
  281. {
  282. if (ctx->base.running) {
  283. _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
  284. __LINE__);
  285. }
  286. ctx->base.running = TRUE;
  287. }
  288. static void blitter_unset_running_flag(struct blitter_context_priv *ctx)
  289. {
  290. if (!ctx->base.running) {
  291. _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
  292. __LINE__);
  293. }
  294. ctx->base.running = FALSE;
  295. }
  296. static void blitter_check_saved_vertex_states(struct blitter_context_priv *ctx)
  297. {
  298. assert(ctx->base.saved_num_vertex_buffers != ~0 &&
  299. ctx->base.saved_velem_state != INVALID_PTR &&
  300. ctx->base.saved_vs != INVALID_PTR &&
  301. (!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR) &&
  302. (!ctx->has_stream_out || ctx->base.saved_num_so_targets != ~0) &&
  303. ctx->base.saved_rs_state != INVALID_PTR);
  304. }
  305. static void blitter_restore_vertex_states(struct blitter_context_priv *ctx)
  306. {
  307. struct pipe_context *pipe = ctx->base.pipe;
  308. unsigned i;
  309. /* Vertex buffers. */
  310. pipe->set_vertex_buffers(pipe,
  311. ctx->base.saved_num_vertex_buffers,
  312. ctx->base.saved_vertex_buffers);
  313. for (i = 0; i < ctx->base.saved_num_vertex_buffers; i++) {
  314. if (ctx->base.saved_vertex_buffers[i].buffer) {
  315. pipe_resource_reference(&ctx->base.saved_vertex_buffers[i].buffer,
  316. NULL);
  317. }
  318. }
  319. ctx->base.saved_num_vertex_buffers = ~0;
  320. /* Vertex elements. */
  321. pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state);
  322. ctx->base.saved_velem_state = INVALID_PTR;
  323. /* Vertex shader. */
  324. pipe->bind_vs_state(pipe, ctx->base.saved_vs);
  325. ctx->base.saved_vs = INVALID_PTR;
  326. /* Geometry shader. */
  327. if (ctx->has_geometry_shader) {
  328. pipe->bind_gs_state(pipe, ctx->base.saved_gs);
  329. ctx->base.saved_gs = INVALID_PTR;
  330. }
  331. /* Stream outputs. */
  332. if (ctx->has_stream_out) {
  333. pipe->set_stream_output_targets(pipe,
  334. ctx->base.saved_num_so_targets,
  335. ctx->base.saved_so_targets, ~0);
  336. for (i = 0; i < ctx->base.saved_num_so_targets; i++)
  337. pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL);
  338. ctx->base.saved_num_so_targets = ~0;
  339. }
  340. /* Rasterizer. */
  341. pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state);
  342. ctx->base.saved_rs_state = INVALID_PTR;
  343. }
  344. static void blitter_check_saved_fragment_states(struct blitter_context_priv *ctx)
  345. {
  346. assert(ctx->base.saved_fs != INVALID_PTR &&
  347. ctx->base.saved_dsa_state != INVALID_PTR &&
  348. ctx->base.saved_blend_state != INVALID_PTR);
  349. }
  350. static void blitter_restore_fragment_states(struct blitter_context_priv *ctx)
  351. {
  352. struct pipe_context *pipe = ctx->base.pipe;
  353. /* Fragment shader. */
  354. pipe->bind_fs_state(pipe, ctx->base.saved_fs);
  355. ctx->base.saved_fs = INVALID_PTR;
  356. /* Depth, stencil, alpha. */
  357. pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state);
  358. ctx->base.saved_dsa_state = INVALID_PTR;
  359. /* Blend state. */
  360. pipe->bind_blend_state(pipe, ctx->base.saved_blend_state);
  361. ctx->base.saved_blend_state = INVALID_PTR;
  362. /* Miscellaneous states. */
  363. /* XXX check whether these are saved and whether they need to be restored
  364. * (depending on the operation) */
  365. pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref);
  366. pipe->set_viewport_state(pipe, &ctx->base.saved_viewport);
  367. }
  368. static void blitter_check_saved_fb_state(struct blitter_context_priv *ctx)
  369. {
  370. assert(ctx->base.saved_fb_state.nr_cbufs != ~0);
  371. }
  372. static void blitter_restore_fb_state(struct blitter_context_priv *ctx)
  373. {
  374. struct pipe_context *pipe = ctx->base.pipe;
  375. pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state);
  376. util_unreference_framebuffer_state(&ctx->base.saved_fb_state);
  377. }
  378. static void blitter_check_saved_textures(struct blitter_context_priv *ctx)
  379. {
  380. assert(ctx->base.saved_num_sampler_states != ~0 &&
  381. ctx->base.saved_num_sampler_views != ~0);
  382. }
  383. static void blitter_restore_textures(struct blitter_context_priv *ctx)
  384. {
  385. struct pipe_context *pipe = ctx->base.pipe;
  386. unsigned i;
  387. /* Fragment sampler states. */
  388. pipe->bind_fragment_sampler_states(pipe,
  389. ctx->base.saved_num_sampler_states,
  390. ctx->base.saved_sampler_states);
  391. ctx->base.saved_num_sampler_states = ~0;
  392. /* Fragment sampler views. */
  393. pipe->set_fragment_sampler_views(pipe,
  394. ctx->base.saved_num_sampler_views,
  395. ctx->base.saved_sampler_views);
  396. for (i = 0; i < ctx->base.saved_num_sampler_views; i++)
  397. pipe_sampler_view_reference(&ctx->base.saved_sampler_views[i], NULL);
  398. ctx->base.saved_num_sampler_views = ~0;
  399. }
  400. static void blitter_set_rectangle(struct blitter_context_priv *ctx,
  401. unsigned x1, unsigned y1,
  402. unsigned x2, unsigned y2,
  403. float depth)
  404. {
  405. int i;
  406. /* set vertex positions */
  407. ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/
  408. ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/
  409. ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/
  410. ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/
  411. ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/
  412. ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/
  413. ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/
  414. ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/
  415. for (i = 0; i < 4; i++)
  416. ctx->vertices[i][0][2] = depth; /*z*/
  417. /* viewport */
  418. ctx->viewport.scale[0] = 0.5f * ctx->dst_width;
  419. ctx->viewport.scale[1] = 0.5f * ctx->dst_height;
  420. ctx->viewport.scale[2] = 1.0f;
  421. ctx->viewport.scale[3] = 1.0f;
  422. ctx->viewport.translate[0] = 0.5f * ctx->dst_width;
  423. ctx->viewport.translate[1] = 0.5f * ctx->dst_height;
  424. ctx->viewport.translate[2] = 0.0f;
  425. ctx->viewport.translate[3] = 0.0f;
  426. ctx->base.pipe->set_viewport_state(ctx->base.pipe, &ctx->viewport);
  427. }
  428. static void blitter_set_clear_color(struct blitter_context_priv *ctx,
  429. const union pipe_color_union *color)
  430. {
  431. int i;
  432. if (color) {
  433. for (i = 0; i < 4; i++) {
  434. uint32_t *uiverts = (uint32_t *)ctx->vertices[i][1];
  435. uiverts[0] = color->ui[0];
  436. uiverts[1] = color->ui[1];
  437. uiverts[2] = color->ui[2];
  438. uiverts[3] = color->ui[3];
  439. }
  440. } else {
  441. for (i = 0; i < 4; i++) {
  442. ctx->vertices[i][1][0] = 0;
  443. ctx->vertices[i][1][1] = 0;
  444. ctx->vertices[i][1][2] = 0;
  445. ctx->vertices[i][1][3] = 0;
  446. }
  447. }
  448. }
  449. static void get_texcoords(struct pipe_sampler_view *src,
  450. unsigned src_width0, unsigned src_height0,
  451. unsigned x1, unsigned y1,
  452. unsigned x2, unsigned y2,
  453. float out[4])
  454. {
  455. struct pipe_resource *tex = src->texture;
  456. unsigned level = src->u.tex.first_level;
  457. boolean normalized = tex->target != PIPE_TEXTURE_RECT;
  458. if (normalized) {
  459. out[0] = x1 / (float)u_minify(src_width0, level);
  460. out[1] = y1 / (float)u_minify(src_height0, level);
  461. out[2] = x2 / (float)u_minify(src_width0, level);
  462. out[3] = y2 / (float)u_minify(src_height0, level);
  463. } else {
  464. out[0] = x1;
  465. out[1] = y1;
  466. out[2] = x2;
  467. out[3] = y2;
  468. }
  469. }
  470. static void set_texcoords_in_vertices(const float coord[4],
  471. float *out, unsigned stride)
  472. {
  473. out[0] = coord[0]; /*t0.s*/
  474. out[1] = coord[1]; /*t0.t*/
  475. out += stride;
  476. out[0] = coord[2]; /*t1.s*/
  477. out[1] = coord[1]; /*t1.t*/
  478. out += stride;
  479. out[0] = coord[2]; /*t2.s*/
  480. out[1] = coord[3]; /*t2.t*/
  481. out += stride;
  482. out[0] = coord[0]; /*t3.s*/
  483. out[1] = coord[3]; /*t3.t*/
  484. }
  485. static void blitter_set_texcoords(struct blitter_context_priv *ctx,
  486. struct pipe_sampler_view *src,
  487. unsigned src_width0, unsigned src_height0,
  488. unsigned layer,
  489. unsigned x1, unsigned y1,
  490. unsigned x2, unsigned y2)
  491. {
  492. unsigned i;
  493. float coord[4];
  494. float face_coord[4][2];
  495. get_texcoords(src, src_width0, src_height0, x1, y1, x2, y2, coord);
  496. if (src->texture->target == PIPE_TEXTURE_CUBE) {
  497. set_texcoords_in_vertices(coord, &face_coord[0][0], 2);
  498. util_map_texcoords2d_onto_cubemap(layer,
  499. /* pointer, stride in floats */
  500. &face_coord[0][0], 2,
  501. &ctx->vertices[0][1][0], 8);
  502. } else {
  503. set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8);
  504. }
  505. /* Set the layer. */
  506. switch (src->texture->target) {
  507. case PIPE_TEXTURE_3D:
  508. {
  509. float r = layer / (float)u_minify(src->texture->depth0,
  510. src->u.tex.first_level);
  511. for (i = 0; i < 4; i++)
  512. ctx->vertices[i][1][2] = r; /*r*/
  513. }
  514. break;
  515. case PIPE_TEXTURE_1D_ARRAY:
  516. for (i = 0; i < 4; i++)
  517. ctx->vertices[i][1][1] = layer; /*t*/
  518. break;
  519. case PIPE_TEXTURE_2D_ARRAY:
  520. for (i = 0; i < 4; i++)
  521. ctx->vertices[i][1][2] = layer; /*r*/
  522. break;
  523. default:;
  524. }
  525. }
  526. static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
  527. unsigned width, unsigned height)
  528. {
  529. ctx->dst_width = width;
  530. ctx->dst_height = height;
  531. }
  532. static INLINE
  533. void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs,
  534. boolean int_format)
  535. {
  536. struct pipe_context *pipe = ctx->base.pipe;
  537. assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
  538. if (int_format) {
  539. if (!ctx->fs_col_int[num_cbufs])
  540. ctx->fs_col_int[num_cbufs] =
  541. util_make_fragment_cloneinput_shader(pipe, num_cbufs,
  542. TGSI_SEMANTIC_GENERIC,
  543. TGSI_INTERPOLATE_CONSTANT);
  544. return ctx->fs_col_int[num_cbufs];
  545. } else {
  546. if (!ctx->fs_col[num_cbufs])
  547. ctx->fs_col[num_cbufs] =
  548. util_make_fragment_cloneinput_shader(pipe, num_cbufs,
  549. TGSI_SEMANTIC_GENERIC,
  550. TGSI_INTERPOLATE_LINEAR);
  551. return ctx->fs_col[num_cbufs];
  552. }
  553. }
  554. /** Convert PIPE_TEXTURE_x to TGSI_TEXTURE_x */
  555. static unsigned
  556. pipe_tex_to_tgsi_tex(enum pipe_texture_target pipe_tex_target)
  557. {
  558. switch (pipe_tex_target) {
  559. case PIPE_TEXTURE_1D:
  560. return TGSI_TEXTURE_1D;
  561. case PIPE_TEXTURE_2D:
  562. return TGSI_TEXTURE_2D;
  563. case PIPE_TEXTURE_RECT:
  564. return TGSI_TEXTURE_RECT;
  565. case PIPE_TEXTURE_3D:
  566. return TGSI_TEXTURE_3D;
  567. case PIPE_TEXTURE_CUBE:
  568. return TGSI_TEXTURE_CUBE;
  569. case PIPE_TEXTURE_1D_ARRAY:
  570. return TGSI_TEXTURE_1D_ARRAY;
  571. case PIPE_TEXTURE_2D_ARRAY:
  572. return TGSI_TEXTURE_2D_ARRAY;
  573. default:
  574. assert(0 && "unexpected texture target");
  575. return TGSI_TEXTURE_UNKNOWN;
  576. }
  577. }
  578. static INLINE
  579. void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
  580. unsigned tex_target)
  581. {
  582. struct pipe_context *pipe = ctx->base.pipe;
  583. assert(tex_target < PIPE_MAX_TEXTURE_TYPES);
  584. /* Create the fragment shader on-demand. */
  585. if (!ctx->fs_texfetch_col[tex_target]) {
  586. unsigned tgsi_tex = pipe_tex_to_tgsi_tex(tex_target);
  587. ctx->fs_texfetch_col[tex_target] =
  588. util_make_fragment_tex_shader(pipe, tgsi_tex, TGSI_INTERPOLATE_LINEAR);
  589. }
  590. return ctx->fs_texfetch_col[tex_target];
  591. }
  592. static INLINE
  593. void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
  594. unsigned tex_target)
  595. {
  596. struct pipe_context *pipe = ctx->base.pipe;
  597. assert(tex_target < PIPE_MAX_TEXTURE_TYPES);
  598. /* Create the fragment shader on-demand. */
  599. if (!ctx->fs_texfetch_depth[tex_target]) {
  600. unsigned tgsi_tex = pipe_tex_to_tgsi_tex(tex_target);
  601. ctx->fs_texfetch_depth[tex_target] =
  602. util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex,
  603. TGSI_INTERPOLATE_LINEAR);
  604. }
  605. return ctx->fs_texfetch_depth[tex_target];
  606. }
  607. static void blitter_draw_rectangle(struct blitter_context *blitter,
  608. unsigned x1, unsigned y1,
  609. unsigned x2, unsigned y2,
  610. float depth,
  611. enum blitter_attrib_type type,
  612. const union pipe_color_union *attrib)
  613. {
  614. struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
  615. switch (type) {
  616. case UTIL_BLITTER_ATTRIB_COLOR:
  617. blitter_set_clear_color(ctx, attrib);
  618. break;
  619. case UTIL_BLITTER_ATTRIB_TEXCOORD:
  620. set_texcoords_in_vertices(attrib->f, &ctx->vertices[0][1][0], 8);
  621. break;
  622. default:;
  623. }
  624. blitter_set_rectangle(ctx, x1, y1, x2, y2, depth);
  625. ctx->base.pipe->redefine_user_buffer(ctx->base.pipe, ctx->vbuf,
  626. 0, ctx->vbuf->width0);
  627. util_draw_vertex_buffer(ctx->base.pipe, NULL, ctx->vbuf, 0,
  628. PIPE_PRIM_TRIANGLE_FAN, 4, 2);
  629. }
  630. static void util_blitter_clear_custom(struct blitter_context *blitter,
  631. unsigned width, unsigned height,
  632. unsigned num_cbufs,
  633. unsigned clear_buffers,
  634. enum pipe_format cbuf_format,
  635. const union pipe_color_union *color,
  636. double depth, unsigned stencil,
  637. void *custom_blend, void *custom_dsa)
  638. {
  639. struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
  640. struct pipe_context *pipe = ctx->base.pipe;
  641. struct pipe_stencil_ref sr = { { 0 } };
  642. boolean int_format = util_format_is_pure_integer(cbuf_format);
  643. assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
  644. blitter_set_running_flag(ctx);
  645. blitter_check_saved_vertex_states(ctx);
  646. blitter_check_saved_fragment_states(ctx);
  647. /* bind states */
  648. if (custom_blend) {
  649. pipe->bind_blend_state(pipe, custom_blend);
  650. } else if (clear_buffers & PIPE_CLEAR_COLOR) {
  651. pipe->bind_blend_state(pipe, ctx->blend_write_color);
  652. } else {
  653. pipe->bind_blend_state(pipe, ctx->blend_keep_color);
  654. }
  655. if (custom_dsa) {
  656. pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa);
  657. } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
  658. pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
  659. } else if (clear_buffers & PIPE_CLEAR_DEPTH) {
  660. pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
  661. } else if (clear_buffers & PIPE_CLEAR_STENCIL) {
  662. pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
  663. } else {
  664. pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
  665. }
  666. sr.ref_value[0] = stencil & 0xff;
  667. pipe->set_stencil_ref(pipe, &sr);
  668. pipe->bind_rasterizer_state(pipe, ctx->rs_state);
  669. if (util_format_is_pure_sint(cbuf_format)) {
  670. pipe->bind_vertex_elements_state(pipe, ctx->velem_sint_state);
  671. } else if (util_format_is_pure_uint(cbuf_format)) {
  672. pipe->bind_vertex_elements_state(pipe, ctx->velem_uint_state);
  673. } else {
  674. pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
  675. }
  676. pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs, int_format));
  677. pipe->bind_vs_state(pipe, ctx->vs);
  678. if (ctx->has_geometry_shader)
  679. pipe->bind_gs_state(pipe, NULL);
  680. blitter_set_dst_dimensions(ctx, width, height);
  681. blitter->draw_rectangle(blitter, 0, 0, width, height, depth,
  682. UTIL_BLITTER_ATTRIB_COLOR, color);
  683. blitter_restore_vertex_states(ctx);
  684. blitter_restore_fragment_states(ctx);
  685. blitter_unset_running_flag(ctx);
  686. }
  687. void util_blitter_clear(struct blitter_context *blitter,
  688. unsigned width, unsigned height,
  689. unsigned num_cbufs,
  690. unsigned clear_buffers,
  691. enum pipe_format cbuf_format,
  692. const union pipe_color_union *color,
  693. double depth, unsigned stencil)
  694. {
  695. util_blitter_clear_custom(blitter, width, height, num_cbufs,
  696. clear_buffers, cbuf_format, color, depth, stencil,
  697. NULL, NULL);
  698. }
  699. void util_blitter_clear_depth_custom(struct blitter_context *blitter,
  700. unsigned width, unsigned height,
  701. double depth, void *custom_dsa)
  702. {
  703. static const union pipe_color_union color;
  704. util_blitter_clear_custom(blitter, width, height, 0,
  705. 0, PIPE_FORMAT_NONE, &color, depth, 0, NULL, custom_dsa);
  706. }
  707. static
  708. boolean is_overlap(unsigned sx1, unsigned sx2, unsigned sy1, unsigned sy2,
  709. unsigned dx1, unsigned dx2, unsigned dy1, unsigned dy2)
  710. {
  711. return sx1 < dx2 && sx2 > dx1 && sy1 < dy2 && sy2 > dy1;
  712. }
  713. void util_blitter_copy_texture(struct blitter_context *blitter,
  714. struct pipe_resource *dst,
  715. unsigned dstlevel,
  716. unsigned dstx, unsigned dsty, unsigned dstz,
  717. struct pipe_resource *src,
  718. unsigned srclevel,
  719. const struct pipe_box *srcbox,
  720. boolean ignore_stencil)
  721. {
  722. struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
  723. struct pipe_context *pipe = ctx->base.pipe;
  724. struct pipe_screen *screen = pipe->screen;
  725. struct pipe_surface *dstsurf, surf_templ;
  726. struct pipe_sampler_view viewTempl, *view;
  727. unsigned bind;
  728. boolean is_stencil, is_depth;
  729. /* Give up if textures are not set. */
  730. assert(dst && src);
  731. if (!dst || !src)
  732. return;
  733. assert(src->target < PIPE_MAX_TEXTURE_TYPES);
  734. /* Is this a ZS format? */
  735. is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
  736. is_stencil = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 1) != 0;
  737. if (is_depth || is_stencil)
  738. bind = PIPE_BIND_DEPTH_STENCIL;
  739. else
  740. bind = PIPE_BIND_RENDER_TARGET;
  741. /* Check if we can sample from and render to the surfaces. */
  742. /* (assuming copying a stencil buffer is not possible) */
  743. if ((!ignore_stencil && is_stencil) ||
  744. !screen->is_format_supported(screen, dst->format, dst->target,
  745. dst->nr_samples, bind) ||
  746. !screen->is_format_supported(screen, src->format, src->target,
  747. src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
  748. blitter_set_running_flag(ctx);
  749. util_resource_copy_region(pipe, dst, dstlevel, dstx, dsty, dstz,
  750. src, srclevel, srcbox);
  751. blitter_unset_running_flag(ctx);
  752. return;
  753. }
  754. /* Initialize the surface. */
  755. memset(&surf_templ, 0, sizeof(surf_templ));
  756. u_surface_default_template(&surf_templ, dst, bind);
  757. surf_templ.format = util_format_linear(dst->format);
  758. surf_templ.u.tex.level = dstlevel;
  759. surf_templ.u.tex.first_layer = dstz;
  760. surf_templ.u.tex.last_layer = dstz + srcbox->depth - 1;
  761. dstsurf = pipe->create_surface(pipe, dst, &surf_templ);
  762. /* Initialize the sampler view. */
  763. u_sampler_view_default_template(&viewTempl, src,
  764. util_format_linear(src->format));
  765. viewTempl.u.tex.first_level = srclevel;
  766. viewTempl.u.tex.last_level = srclevel;
  767. view = pipe->create_sampler_view(pipe, src, &viewTempl);
  768. /* Copy. */
  769. util_blitter_copy_texture_view(blitter, dstsurf, dstx, dsty, view, srcbox,
  770. src->width0, src->height0);
  771. pipe_surface_reference(&dstsurf, NULL);
  772. pipe_sampler_view_reference(&view, NULL);
  773. }
  774. void util_blitter_copy_texture_view(struct blitter_context *blitter,
  775. struct pipe_surface *dst,
  776. unsigned dstx, unsigned dsty,
  777. struct pipe_sampler_view *src,
  778. const struct pipe_box *srcbox,
  779. unsigned src_width0, unsigned src_height0)
  780. {
  781. struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
  782. struct pipe_context *pipe = ctx->base.pipe;
  783. struct pipe_framebuffer_state fb_state;
  784. enum pipe_texture_target src_target = src->texture->target;
  785. unsigned width = srcbox->width;
  786. unsigned height = srcbox->height;
  787. /* Sanity checks. */
  788. if (dst->texture == src->texture &&
  789. dst->u.tex.level == src->u.tex.first_level) {
  790. assert(!is_overlap(srcbox->x, srcbox->x + width, srcbox->y, srcbox->y + height,
  791. dstx, dstx + width, dsty, dsty + height));
  792. }
  793. /* XXX should handle 3d regions */
  794. assert(srcbox->depth == 1);
  795. /* Check whether the states are properly saved. */
  796. blitter_set_running_flag(ctx);
  797. blitter_check_saved_vertex_states(ctx);
  798. blitter_check_saved_fragment_states(ctx);
  799. blitter_check_saved_textures(ctx);
  800. blitter_check_saved_fb_state(ctx);
  801. /* Initialize framebuffer state. */
  802. fb_state.width = dst->width;
  803. fb_state.height = dst->height;
  804. if (util_format_is_depth_or_stencil(dst->format)) {
  805. pipe->bind_blend_state(pipe, ctx->blend_keep_color);
  806. pipe->bind_depth_stencil_alpha_state(pipe,
  807. ctx->dsa_write_depth_keep_stencil);
  808. pipe->bind_fs_state(pipe,
  809. blitter_get_fs_texfetch_depth(ctx, src_target));
  810. fb_state.nr_cbufs = 0;
  811. fb_state.zsbuf = dst;
  812. } else {
  813. pipe->bind_blend_state(pipe, ctx->blend_write_color);
  814. pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
  815. pipe->bind_fs_state(pipe,
  816. blitter_get_fs_texfetch_col(ctx, src_target));
  817. fb_state.nr_cbufs = 1;
  818. fb_state.cbufs[0] = dst;
  819. fb_state.zsbuf = 0;
  820. }
  821. /* Set rasterizer state, shaders, and textures. */
  822. pipe->bind_rasterizer_state(pipe, ctx->rs_state);
  823. pipe->bind_vs_state(pipe, ctx->vs);
  824. if (ctx->has_geometry_shader)
  825. pipe->bind_gs_state(pipe, NULL);
  826. pipe->bind_fragment_sampler_states(pipe, 1, &ctx->sampler_state);
  827. pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
  828. pipe->set_fragment_sampler_views(pipe, 1, &src);
  829. pipe->set_framebuffer_state(pipe, &fb_state);
  830. blitter_set_dst_dimensions(ctx, dst->width, dst->height);
  831. switch (src_target) {
  832. /* Draw the quad with the draw_rectangle callback. */
  833. case PIPE_TEXTURE_1D:
  834. case PIPE_TEXTURE_2D:
  835. case PIPE_TEXTURE_RECT:
  836. {
  837. /* Set texture coordinates. - use a pipe color union
  838. * for interface purposes.
  839. * XXX pipe_color_union is a wrong name since we use that to set
  840. * texture coordinates too.
  841. */
  842. union pipe_color_union coord;
  843. get_texcoords(src, src_width0, src_height0, srcbox->x, srcbox->y,
  844. srcbox->x+width, srcbox->y+height, coord.f);
  845. /* Draw. */
  846. blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
  847. UTIL_BLITTER_ATTRIB_TEXCOORD, &coord);
  848. }
  849. break;
  850. /* Draw the quad with the generic codepath. */
  851. default:
  852. /* Set texture coordinates. */
  853. switch (src_target) {
  854. case PIPE_TEXTURE_1D_ARRAY:
  855. case PIPE_TEXTURE_2D_ARRAY:
  856. case PIPE_TEXTURE_3D:
  857. case PIPE_TEXTURE_CUBE:
  858. blitter_set_texcoords(ctx, src, src_width0, src_height0, srcbox->z,
  859. srcbox->y, srcbox->x,
  860. srcbox->x + width, srcbox->y + height);
  861. break;
  862. default:
  863. assert(0);
  864. }
  865. /* Draw. */
  866. blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
  867. ctx->base.pipe->redefine_user_buffer(ctx->base.pipe, ctx->vbuf,
  868. 0, ctx->vbuf->width0);
  869. util_draw_vertex_buffer(ctx->base.pipe, NULL, ctx->vbuf, 0,
  870. PIPE_PRIM_TRIANGLE_FAN, 4, 2);
  871. break;
  872. }
  873. blitter_restore_vertex_states(ctx);
  874. blitter_restore_fragment_states(ctx);
  875. blitter_restore_textures(ctx);
  876. blitter_restore_fb_state(ctx);
  877. blitter_unset_running_flag(ctx);
  878. }
  879. /* Clear a region of a color surface to a constant value. */
  880. void util_blitter_clear_render_target(struct blitter_context *blitter,
  881. struct pipe_surface *dstsurf,
  882. const union pipe_color_union *color,
  883. unsigned dstx, unsigned dsty,
  884. unsigned width, unsigned height)
  885. {
  886. struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
  887. struct pipe_context *pipe = ctx->base.pipe;
  888. struct pipe_framebuffer_state fb_state;
  889. assert(dstsurf->texture);
  890. if (!dstsurf->texture)
  891. return;
  892. /* check the saved state */
  893. blitter_set_running_flag(ctx);
  894. blitter_check_saved_vertex_states(ctx);
  895. blitter_check_saved_fragment_states(ctx);
  896. blitter_check_saved_fb_state(ctx);
  897. /* bind states */
  898. pipe->bind_blend_state(pipe, ctx->blend_write_color);
  899. pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
  900. pipe->bind_rasterizer_state(pipe, ctx->rs_state);
  901. pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE));
  902. pipe->bind_vs_state(pipe, ctx->vs);
  903. if (ctx->has_geometry_shader)
  904. pipe->bind_gs_state(pipe, NULL);
  905. pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
  906. /* set a framebuffer state */
  907. fb_state.width = dstsurf->width;
  908. fb_state.height = dstsurf->height;
  909. fb_state.nr_cbufs = 1;
  910. fb_state.cbufs[0] = dstsurf;
  911. fb_state.zsbuf = 0;
  912. pipe->set_framebuffer_state(pipe, &fb_state);
  913. blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
  914. blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
  915. UTIL_BLITTER_ATTRIB_COLOR, color);
  916. blitter_restore_vertex_states(ctx);
  917. blitter_restore_fragment_states(ctx);
  918. blitter_restore_fb_state(ctx);
  919. blitter_unset_running_flag(ctx);
  920. }
  921. /* Clear a region of a depth stencil surface. */
  922. void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
  923. struct pipe_surface *dstsurf,
  924. unsigned clear_flags,
  925. double depth,
  926. unsigned stencil,
  927. unsigned dstx, unsigned dsty,
  928. unsigned width, unsigned height)
  929. {
  930. struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
  931. struct pipe_context *pipe = ctx->base.pipe;
  932. struct pipe_framebuffer_state fb_state;
  933. struct pipe_stencil_ref sr = { { 0 } };
  934. assert(dstsurf->texture);
  935. if (!dstsurf->texture)
  936. return;
  937. /* check the saved state */
  938. blitter_set_running_flag(ctx);
  939. blitter_check_saved_vertex_states(ctx);
  940. blitter_check_saved_fragment_states(ctx);
  941. blitter_check_saved_fb_state(ctx);
  942. /* bind states */
  943. pipe->bind_blend_state(pipe, ctx->blend_keep_color);
  944. if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
  945. sr.ref_value[0] = stencil & 0xff;
  946. pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
  947. pipe->set_stencil_ref(pipe, &sr);
  948. }
  949. else if (clear_flags & PIPE_CLEAR_DEPTH) {
  950. pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
  951. }
  952. else if (clear_flags & PIPE_CLEAR_STENCIL) {
  953. sr.ref_value[0] = stencil & 0xff;
  954. pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
  955. pipe->set_stencil_ref(pipe, &sr);
  956. }
  957. else
  958. /* hmm that should be illegal probably, or make it a no-op somewhere */
  959. pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
  960. pipe->bind_rasterizer_state(pipe, ctx->rs_state);
  961. pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE));
  962. pipe->bind_vs_state(pipe, ctx->vs);
  963. if (ctx->has_geometry_shader)
  964. pipe->bind_gs_state(pipe, NULL);
  965. pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
  966. /* set a framebuffer state */
  967. fb_state.width = dstsurf->width;
  968. fb_state.height = dstsurf->height;
  969. fb_state.nr_cbufs = 0;
  970. fb_state.cbufs[0] = 0;
  971. fb_state.zsbuf = dstsurf;
  972. pipe->set_framebuffer_state(pipe, &fb_state);
  973. blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
  974. blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, depth,
  975. UTIL_BLITTER_ATTRIB_NONE, NULL);
  976. blitter_restore_vertex_states(ctx);
  977. blitter_restore_fragment_states(ctx);
  978. blitter_restore_fb_state(ctx);
  979. blitter_unset_running_flag(ctx);
  980. }
  981. /* draw a rectangle across a region using a custom dsa stage - for r600g */
  982. void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
  983. struct pipe_surface *zsurf,
  984. struct pipe_surface *cbsurf,
  985. void *dsa_stage, float depth)
  986. {
  987. struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
  988. struct pipe_context *pipe = ctx->base.pipe;
  989. struct pipe_framebuffer_state fb_state;
  990. assert(zsurf->texture);
  991. if (!zsurf->texture)
  992. return;
  993. /* check the saved state */
  994. blitter_set_running_flag(ctx);
  995. blitter_check_saved_vertex_states(ctx);
  996. blitter_check_saved_fragment_states(ctx);
  997. blitter_check_saved_fb_state(ctx);
  998. /* bind states */
  999. pipe->bind_blend_state(pipe, ctx->blend_write_color);
  1000. pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage);
  1001. pipe->bind_rasterizer_state(pipe, ctx->rs_state);
  1002. pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE));
  1003. pipe->bind_vs_state(pipe, ctx->vs);
  1004. if (ctx->has_geometry_shader)
  1005. pipe->bind_gs_state(pipe, NULL);
  1006. pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
  1007. /* set a framebuffer state */
  1008. fb_state.width = zsurf->width;
  1009. fb_state.height = zsurf->height;
  1010. fb_state.nr_cbufs = 1;
  1011. if (cbsurf) {
  1012. fb_state.cbufs[0] = cbsurf;
  1013. fb_state.nr_cbufs = 1;
  1014. } else {
  1015. fb_state.cbufs[0] = NULL;
  1016. fb_state.nr_cbufs = 0;
  1017. }
  1018. fb_state.zsbuf = zsurf;
  1019. pipe->set_framebuffer_state(pipe, &fb_state);
  1020. blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height);
  1021. blitter->draw_rectangle(blitter, 0, 0, zsurf->width, zsurf->height, depth,
  1022. UTIL_BLITTER_ATTRIB_NONE, NULL);
  1023. blitter_restore_vertex_states(ctx);
  1024. blitter_restore_fragment_states(ctx);
  1025. blitter_restore_fb_state(ctx);
  1026. blitter_unset_running_flag(ctx);
  1027. }
  1028. void util_blitter_copy_buffer(struct blitter_context *blitter,
  1029. struct pipe_resource *dst,
  1030. unsigned dstx,
  1031. struct pipe_resource *src,
  1032. unsigned srcx,
  1033. unsigned size)
  1034. {
  1035. struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
  1036. struct pipe_context *pipe = ctx->base.pipe;
  1037. struct pipe_vertex_buffer vb;
  1038. struct pipe_stream_output_target *so_target;
  1039. /* Drivers not capable of Stream Out should not call this function
  1040. * in the first place. */
  1041. assert(ctx->has_stream_out);
  1042. /* Some alignment is required. */
  1043. if (srcx % 4 != 0 || dstx % 4 != 0 || size % 16 != 0 ||
  1044. !ctx->has_stream_out) {
  1045. struct pipe_box box;
  1046. u_box_1d(srcx, size, &box);
  1047. util_resource_copy_region(pipe, dst, 0, dstx, 0, 0, src, 0, &box);
  1048. return;
  1049. }
  1050. blitter_set_running_flag(ctx);
  1051. blitter_check_saved_vertex_states(ctx);
  1052. vb.buffer = src;
  1053. vb.buffer_offset = srcx;
  1054. vb.stride = 4;
  1055. pipe->set_vertex_buffers(pipe, 1, &vb);
  1056. pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf);
  1057. pipe->bind_vs_state(pipe, ctx->vs_pos_only);
  1058. if (ctx->has_geometry_shader)
  1059. pipe->bind_gs_state(pipe, NULL);
  1060. pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
  1061. so_target = pipe->create_stream_output_target(pipe, dst, dstx, size);
  1062. pipe->set_stream_output_targets(pipe, 1, &so_target, 0);
  1063. util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 16);
  1064. blitter_restore_vertex_states(ctx);
  1065. blitter_unset_running_flag(ctx);
  1066. pipe_so_target_reference(&so_target, NULL);
  1067. }