Rev 3769 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3769 | Rev 4251 | ||
---|---|---|---|
Line 277... | Line 277... | ||
277 | return -1; |
277 | return -1; |
278 | case PICT_a8r8g8b8: |
278 | case PICT_a8r8g8b8: |
279 | return GEN5_SURFACEFORMAT_B8G8R8A8_UNORM; |
279 | return GEN5_SURFACEFORMAT_B8G8R8A8_UNORM; |
280 | case PICT_x8r8g8b8: |
280 | case PICT_x8r8g8b8: |
281 | return GEN5_SURFACEFORMAT_B8G8R8X8_UNORM; |
281 | return GEN5_SURFACEFORMAT_B8G8R8X8_UNORM; |
- | 282 | case PICT_a8b8g8r8: |
|
- | 283 | return GEN5_SURFACEFORMAT_R8G8B8A8_UNORM; |
|
- | 284 | case PICT_x8b8g8r8: |
|
- | 285 | return GEN5_SURFACEFORMAT_R8G8B8X8_UNORM; |
|
- | 286 | case PICT_a2r10g10b10: |
|
- | 287 | return GEN5_SURFACEFORMAT_B10G10R10A2_UNORM; |
|
- | 288 | case PICT_x2r10g10b10: |
|
- | 289 | return GEN5_SURFACEFORMAT_B10G10R10X2_UNORM; |
|
- | 290 | case PICT_r8g8b8: |
|
- | 291 | return GEN5_SURFACEFORMAT_R8G8B8_UNORM; |
|
- | 292 | case PICT_r5g6b5: |
|
- | 293 | return GEN5_SURFACEFORMAT_B5G6R5_UNORM; |
|
- | 294 | case PICT_a1r5g5b5: |
|
- | 295 | return GEN5_SURFACEFORMAT_B5G5R5A1_UNORM; |
|
282 | case PICT_a8: |
296 | case PICT_a8: |
283 | return GEN5_SURFACEFORMAT_A8_UNORM; |
297 | return GEN5_SURFACEFORMAT_A8_UNORM; |
- | 298 | case PICT_a4r4g4b4: |
|
- | 299 | return GEN5_SURFACEFORMAT_B4G4R4A4_UNORM; |
|
284 | } |
300 | } |
285 | } |
301 | } |
Line 286... | Line 302... | ||
286 | 302 | ||
287 | static uint32_t gen5_get_dest_format(PictFormat format) |
303 | static uint32_t gen5_get_dest_format(PictFormat format) |
Line 290... | Line 306... | ||
290 | default: |
306 | default: |
291 | return -1; |
307 | return -1; |
292 | case PICT_a8r8g8b8: |
308 | case PICT_a8r8g8b8: |
293 | case PICT_x8r8g8b8: |
309 | case PICT_x8r8g8b8: |
294 | return GEN5_SURFACEFORMAT_B8G8R8A8_UNORM; |
310 | return GEN5_SURFACEFORMAT_B8G8R8A8_UNORM; |
- | 311 | case PICT_a8b8g8r8: |
|
- | 312 | case PICT_x8b8g8r8: |
|
- | 313 | return GEN5_SURFACEFORMAT_R8G8B8A8_UNORM; |
|
- | 314 | case PICT_a2r10g10b10: |
|
- | 315 | case PICT_x2r10g10b10: |
|
- | 316 | return GEN5_SURFACEFORMAT_B10G10R10A2_UNORM; |
|
- | 317 | case PICT_r5g6b5: |
|
- | 318 | return GEN5_SURFACEFORMAT_B5G6R5_UNORM; |
|
- | 319 | case PICT_x1r5g5b5: |
|
- | 320 | case PICT_a1r5g5b5: |
|
- | 321 | return GEN5_SURFACEFORMAT_B5G5R5A1_UNORM; |
|
295 | case PICT_a8: |
322 | case PICT_a8: |
296 | return GEN5_SURFACEFORMAT_A8_UNORM; |
323 | return GEN5_SURFACEFORMAT_A8_UNORM; |
- | 324 | case PICT_a4r4g4b4: |
|
- | 325 | case PICT_x4r4g4b4: |
|
- | 326 | return GEN5_SURFACEFORMAT_B4G4R4A4_UNORM; |
|
297 | } |
327 | } |
298 | } |
328 | } |
299 | typedef struct gen5_surface_state_padded { |
329 | typedef struct gen5_surface_state_padded { |
300 | struct gen5_surface_state state; |
330 | struct gen5_surface_state state; |
301 | char pad[32 - sizeof(struct gen5_surface_state)]; |
331 | char pad[32 - sizeof(struct gen5_surface_state)]; |
Line 382... | Line 412... | ||
382 | uint16_t offset; |
412 | uint16_t offset; |
383 | uint32_t *ss; |
413 | uint32_t *ss; |
Line 384... | Line 414... | ||
384 | 414 | ||
385 | /* After the first bind, we manage the cache domains within the batch */ |
415 | /* After the first bind, we manage the cache domains within the batch */ |
386 | if (!DBG_NO_SURFACE_CACHE) { |
416 | if (!DBG_NO_SURFACE_CACHE) { |
387 | offset = kgem_bo_get_binding(bo, format); |
417 | offset = kgem_bo_get_binding(bo, format | is_dst << 31); |
388 | if (offset) { |
418 | if (offset) { |
389 | if (is_dst) |
419 | if (is_dst) |
390 | kgem_bo_mark_dirty(bo); |
420 | kgem_bo_mark_dirty(bo); |
391 | return offset * sizeof(uint32_t); |
421 | return offset * sizeof(uint32_t); |
Line 398... | Line 428... | ||
398 | 428 | ||
399 | ss[0] = (GEN5_SURFACE_2D << GEN5_SURFACE_TYPE_SHIFT | |
429 | ss[0] = (GEN5_SURFACE_2D << GEN5_SURFACE_TYPE_SHIFT | |
400 | GEN5_SURFACE_BLEND_ENABLED | |
430 | GEN5_SURFACE_BLEND_ENABLED | |
Line 401... | Line 431... | ||
401 | format << GEN5_SURFACE_FORMAT_SHIFT); |
431 | format << GEN5_SURFACE_FORMAT_SHIFT); |
- | 432 | ||
402 | 433 | if (is_dst) { |
|
403 | if (is_dst) |
434 | ss[0] |= GEN5_SURFACE_RC_READ_WRITE; |
404 | domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER; |
435 | domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER; |
405 | else |
436 | } else |
Line 406... | Line 437... | ||
406 | domains = I915_GEM_DOMAIN_SAMPLER << 16; |
437 | domains = I915_GEM_DOMAIN_SAMPLER << 16; |
407 | ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0); |
438 | ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0); |
408 | 439 | ||
409 | ss[2] = ((width - 1) << GEN5_SURFACE_WIDTH_SHIFT | |
440 | ss[2] = ((width - 1) << GEN5_SURFACE_WIDTH_SHIFT | |
410 | (height - 1) << GEN5_SURFACE_HEIGHT_SHIFT); |
441 | (height - 1) << GEN5_SURFACE_HEIGHT_SHIFT); |
411 | ss[3] = (gen5_tiling_bits(bo->tiling) | |
442 | ss[3] = (gen5_tiling_bits(bo->tiling) | |
Line 412... | Line 443... | ||
412 | (bo->pitch - 1) << GEN5_SURFACE_PITCH_SHIFT); |
443 | (bo->pitch - 1) << GEN5_SURFACE_PITCH_SHIFT); |
Line 413... | Line 444... | ||
413 | ss[4] = 0; |
444 | ss[4] = 0; |
414 | ss[5] = 0; |
445 | ss[5] = 0; |
415 | 446 | ||
416 | kgem_bo_set_binding(bo, format, offset); |
447 | kgem_bo_set_binding(bo, format | is_dst << 31, offset); |
Line 539... | Line 570... | ||
539 | goto flush; |
570 | goto flush; |
540 | else |
571 | else |
541 | goto start; |
572 | goto start; |
542 | } |
573 | } |
Line 543... | Line -... | ||
543 | - | ||
544 | assert(op->floats_per_rect >= vertex_space(sna)); |
574 | |
- | 575 | assert(rem <= vertex_space(sna)); |
|
545 | assert(rem <= vertex_space(sna)); |
576 | assert(op->floats_per_rect <= rem); |
546 | if (want > 1 && want * op->floats_per_rect > rem) |
577 | if (want > 1 && want * op->floats_per_rect > rem) |
Line 547... | Line 578... | ||
547 | want = rem / op->floats_per_rect; |
578 | want = rem / op->floats_per_rect; |
548 | 579 | ||
Line 647... | Line 678... | ||
647 | /* Ironlake errata workaround: Before disabling the clipper, |
678 | /* Ironlake errata workaround: Before disabling the clipper, |
648 | * you have to MI_FLUSH to get the pipeline idle. |
679 | * you have to MI_FLUSH to get the pipeline idle. |
649 | * |
680 | * |
650 | * However, the kernel flushes the pipeline between batches, |
681 | * However, the kernel flushes the pipeline between batches, |
651 | * so we should be safe.... |
682 | * so we should be safe.... |
- | 683 | * |
|
652 | * OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH); |
684 | * On the other hand, after using BLT we must use a non-pipelined |
- | 685 | * operation... |
|
653 | */ |
686 | */ |
- | 687 | if (sna->kgem.nreloc) |
|
- | 688 | OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH); |
|
- | 689 | ||
654 | OUT_BATCH(GEN5_PIPELINE_SELECT | PIPELINE_SELECT_3D); |
690 | OUT_BATCH(GEN5_PIPELINE_SELECT | PIPELINE_SELECT_3D); |
Line 655... | Line 691... | ||
655 | 691 | ||
Line 656... | Line 692... | ||
656 | gen5_emit_state_base_address(sna); |
692 | gen5_emit_state_base_address(sna); |
Line 730... | Line 766... | ||
730 | sp = SAMPLER_OFFSET(op->src.filter, op->src.repeat, |
766 | sp = SAMPLER_OFFSET(op->src.filter, op->src.repeat, |
731 | op->mask.filter, op->mask.repeat, |
767 | op->mask.filter, op->mask.repeat, |
732 | kernel); |
768 | kernel); |
733 | bp = gen5_get_blend(blend, op->has_component_alpha, op->dst.format); |
769 | bp = gen5_get_blend(blend, op->has_component_alpha, op->dst.format); |
Line 734... | Line -... | ||
734 | - | ||
735 | DBG(("%s: sp=%d, bp=%d\n", __FUNCTION__, sp, bp)); |
770 | |
- | 771 | key = sp | (uint32_t)bp << 16 | (op->mask.bo != NULL) << 31; |
|
- | 772 | DBG(("%s: sp=%d, bp=%d, key=%08x (current sp=%d, bp=%d, key=%08x)\n", |
|
- | 773 | __FUNCTION__, sp, bp, key, |
|
- | 774 | sna->render_state.gen5.last_pipelined_pointers & 0xffff, |
|
- | 775 | (sna->render_state.gen5.last_pipelined_pointers >> 16) & 0x7fff, |
|
736 | key = sp | (uint32_t)bp << 16 | (op->mask.bo != NULL) << 31; |
776 | sna->render_state.gen5.last_pipelined_pointers)); |
737 | if (key == sna->render_state.gen5.last_pipelined_pointers) |
777 | if (key == sna->render_state.gen5.last_pipelined_pointers) |
Line 738... | Line -... | ||
738 | return false; |
- | |
739 | 778 | return false; |
|
740 | 779 | ||
741 | OUT_BATCH(GEN5_3DSTATE_PIPELINED_POINTERS | 5); |
780 | OUT_BATCH(GEN5_3DSTATE_PIPELINED_POINTERS | 5); |
742 | OUT_BATCH(sna->render_state.gen5.vs); |
781 | OUT_BATCH(sna->render_state.gen5.vs); |
743 | OUT_BATCH(GEN5_GS_DISABLE); /* passthrough */ |
782 | OUT_BATCH(GEN5_GS_DISABLE); /* passthrough */ |
744 | OUT_BATCH(GEN5_CLIP_DISABLE); /* passthrough */ |
783 | OUT_BATCH(GEN5_CLIP_DISABLE); /* passthrough */ |
745 | OUT_BATCH(sna->render_state.gen5.sf[op->mask.bo != NULL]); |
784 | OUT_BATCH(sna->render_state.gen5.sf[op->mask.bo != NULL]); |
Line -... | Line 785... | ||
- | 785 | OUT_BATCH(sna->render_state.gen5.wm + sp); |
|
746 | OUT_BATCH(sna->render_state.gen5.wm + sp); |
786 | OUT_BATCH(sna->render_state.gen5.cc + bp); |
- | 787 | ||
- | 788 | bp = (sna->render_state.gen5.last_pipelined_pointers & 0x7fff0000) != ((uint32_t)bp << 16); |
|
- | 789 | sna->render_state.gen5.last_pipelined_pointers = key; |
|
747 | OUT_BATCH(sna->render_state.gen5.cc + bp); |
790 | |
748 | 791 | gen5_emit_urb(sna); |
|
Line 749... | Line 792... | ||
749 | sna->render_state.gen5.last_pipelined_pointers = key; |
792 | |
750 | return true; |
793 | return bp; |
751 | } |
794 | } |
752 | 795 | ||
753 | static void |
796 | static bool |
Line 760... | Line 803... | ||
760 | assert(!too_large(op->dst.width, op->dst.height)); |
803 | assert(!too_large(op->dst.width, op->dst.height)); |
Line 761... | Line 804... | ||
761 | 804 | ||
762 | if (!DBG_NO_STATE_CACHE && |
805 | if (!DBG_NO_STATE_CACHE && |
763 | sna->render_state.gen5.drawrect_limit == limit && |
806 | sna->render_state.gen5.drawrect_limit == limit && |
764 | sna->render_state.gen5.drawrect_offset == offset) |
807 | sna->render_state.gen5.drawrect_offset == offset) |
Line 765... | Line 808... | ||
765 | return; |
808 | return false; |
766 | 809 | ||
Line 767... | Line 810... | ||
767 | sna->render_state.gen5.drawrect_offset = offset; |
810 | sna->render_state.gen5.drawrect_offset = offset; |
768 | sna->render_state.gen5.drawrect_limit = limit; |
811 | sna->render_state.gen5.drawrect_limit = limit; |
769 | 812 | ||
770 | OUT_BATCH(GEN5_3DSTATE_DRAWING_RECTANGLE | (4 - 2)); |
813 | OUT_BATCH(GEN5_3DSTATE_DRAWING_RECTANGLE | (4 - 2)); |
- | 814 | OUT_BATCH(0x00000000); |
|
771 | OUT_BATCH(0x00000000); |
815 | OUT_BATCH(limit); |
Line 772... | Line 816... | ||
772 | OUT_BATCH(limit); |
816 | OUT_BATCH(offset); |
773 | OUT_BATCH(offset); |
817 | return true; |
774 | } |
818 | } |
Line 890... | Line 934... | ||
890 | format | offset << VE0_OFFSET_SHIFT); |
934 | format | offset << VE0_OFFSET_SHIFT); |
891 | OUT_BATCH(dw); |
935 | OUT_BATCH(dw); |
892 | } |
936 | } |
893 | } |
937 | } |
Line -... | Line 938... | ||
- | 938 | ||
- | 939 | inline static void |
|
- | 940 | gen5_emit_pipe_flush(struct sna *sna) |
|
- | 941 | { |
|
- | 942 | OUT_BATCH(GEN5_PIPE_CONTROL | (4 - 2)); |
|
- | 943 | OUT_BATCH(GEN5_PIPE_CONTROL_WC_FLUSH); |
|
- | 944 | OUT_BATCH(0); |
|
- | 945 | OUT_BATCH(0); |
|
- | 946 | } |
|
894 | 947 | ||
895 | static void |
948 | static void |
896 | gen5_emit_state(struct sna *sna, |
949 | gen5_emit_state(struct sna *sna, |
897 | const struct sna_composite_op *op, |
950 | const struct sna_composite_op *op, |
898 | uint16_t offset) |
951 | uint16_t offset) |
- | 952 | { |
|
- | 953 | bool flush = false; |
|
- | 954 | ||
- | 955 | assert(op->dst.bo->exec); |
|
- | 956 | ||
- | 957 | /* drawrect must be first for Ironlake BLT workaround */ |
|
- | 958 | if (gen5_emit_drawing_rectangle(sna, op)) |
|
- | 959 | offset &= ~1; |
|
- | 960 | gen5_emit_binding_table(sna, offset & ~1); |
|
- | 961 | if (gen5_emit_pipelined_pointers(sna, op, op->op, op->u.gen5.wm_kernel)){ |
|
- | 962 | DBG(("%s: changed blend state, flush required? %d\n", |
|
- | 963 | __FUNCTION__, (offset & 1) && op->op > PictOpSrc)); |
|
- | 964 | flush = (offset & 1) && op->op > PictOpSrc; |
|
- | 965 | } |
|
- | 966 | gen5_emit_vertex_elements(sna, op); |
|
899 | { |
967 | |
900 | if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) { |
968 | if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) { |
901 | DBG(("%s: flushing dirty (%d, %d)\n", __FUNCTION__, |
969 | DBG(("%s: flushing dirty (%d, %d)\n", __FUNCTION__, |
902 | kgem_bo_is_dirty(op->src.bo), |
970 | kgem_bo_is_dirty(op->src.bo), |
903 | kgem_bo_is_dirty(op->mask.bo))); |
971 | kgem_bo_is_dirty(op->mask.bo))); |
904 | OUT_BATCH(MI_FLUSH); |
972 | OUT_BATCH(MI_FLUSH); |
905 | kgem_clear_dirty(&sna->kgem); |
973 | kgem_clear_dirty(&sna->kgem); |
- | 974 | kgem_bo_mark_dirty(op->dst.bo); |
|
- | 975 | flush = false; |
|
- | 976 | } |
|
- | 977 | if (flush) { |
|
- | 978 | DBG(("%s: forcing flush\n", __FUNCTION__)); |
|
906 | kgem_bo_mark_dirty(op->dst.bo); |
979 | gen5_emit_pipe_flush(sna); |
907 | } |
- | |
908 | - | ||
909 | /* drawrect must be first for Ironlake BLT workaround */ |
- | |
910 | gen5_emit_drawing_rectangle(sna, op); |
- | |
911 | gen5_emit_binding_table(sna, offset); |
- | |
912 | if (gen5_emit_pipelined_pointers(sna, op, op->op, op->u.gen5.wm_kernel)) |
- | |
913 | gen5_emit_urb(sna); |
- | |
914 | gen5_emit_vertex_elements(sna, op); |
980 | } |
Line 915... | Line 981... | ||
915 | } |
981 | } |
916 | 982 | ||
917 | static void gen5_bind_surfaces(struct sna *sna, |
983 | static void gen5_bind_surfaces(struct sna *sna, |
- | 984 | const struct sna_composite_op *op) |
|
918 | const struct sna_composite_op *op) |
985 | { |
919 | { |
986 | bool dirty = kgem_bo_is_dirty(op->dst.bo); |
Line 920... | Line 987... | ||
920 | uint32_t *binding_table; |
987 | uint32_t *binding_table; |
Line 951... | Line 1018... | ||
951 | sna->kgem.batch[sna->render_state.gen5.surface_table+2] == binding_table[2])) { |
1018 | sna->kgem.batch[sna->render_state.gen5.surface_table+2] == binding_table[2])) { |
952 | sna->kgem.surface += sizeof(struct gen5_surface_state_padded) / sizeof(uint32_t); |
1019 | sna->kgem.surface += sizeof(struct gen5_surface_state_padded) / sizeof(uint32_t); |
953 | offset = sna->render_state.gen5.surface_table; |
1020 | offset = sna->render_state.gen5.surface_table; |
954 | } |
1021 | } |
Line 955... | Line 1022... | ||
955 | 1022 | ||
956 | gen5_emit_state(sna, op, offset); |
1023 | gen5_emit_state(sna, op, offset | dirty); |
Line 957... | Line 1024... | ||
957 | } |
1024 | } |
958 | 1025 | ||
959 | fastcall static void |
1026 | fastcall static void |
Line 970... | Line 1037... | ||
970 | 1037 | ||
971 | gen5_get_rectangles(sna, op, 1, gen5_bind_surfaces); |
1038 | gen5_get_rectangles(sna, op, 1, gen5_bind_surfaces); |
972 | op->prim_emit(sna, op, r); |
1039 | op->prim_emit(sna, op, r); |
Line -... | Line 1040... | ||
- | 1040 | } |
|
- | 1041 | ||
- | 1042 | #if 0 |
|
- | 1043 | fastcall static void |
|
- | 1044 | gen5_render_composite_box(struct sna *sna, |
|
- | 1045 | const struct sna_composite_op *op, |
|
- | 1046 | const BoxRec *box) |
|
- | 1047 | { |
|
- | 1048 | struct sna_composite_rectangles r; |
|
- | 1049 | ||
- | 1050 | DBG((" %s: (%d, %d), (%d, %d)\n", |
|
- | 1051 | __FUNCTION__, |
|
- | 1052 | box->x1, box->y1, box->x2, box->y2)); |
|
- | 1053 | ||
- | 1054 | gen5_get_rectangles(sna, op, 1, gen5_bind_surfaces); |
|
- | 1055 | ||
- | 1056 | r.dst.x = box->x1; |
|
- | 1057 | r.dst.y = box->y1; |
|
- | 1058 | r.width = box->x2 - box->x1; |
|
- | 1059 | r.height = box->y2 - box->y1; |
|
- | 1060 | r.mask = r.src = r.dst; |
|
- | 1061 | ||
- | 1062 | op->prim_emit(sna, op, &r); |
|
- | 1063 | } |
|
- | 1064 | ||
- | 1065 | static void |
|
- | 1066 | gen5_render_composite_boxes__blt(struct sna *sna, |
|
- | 1067 | const struct sna_composite_op *op, |
|
- | 1068 | const BoxRec *box, int nbox) |
|
- | 1069 | { |
|
- | 1070 | DBG(("%s(%d) delta=(%d, %d), src=(%d, %d)/(%d, %d), mask=(%d, %d)/(%d, %d)\n", |
|
- | 1071 | __FUNCTION__, nbox, op->dst.x, op->dst.y, |
|
- | 1072 | op->src.offset[0], op->src.offset[1], |
|
- | 1073 | op->src.width, op->src.height, |
|
- | 1074 | op->mask.offset[0], op->mask.offset[1], |
|
- | 1075 | op->mask.width, op->mask.height)); |
|
- | 1076 | ||
- | 1077 | do { |
|
- | 1078 | int nbox_this_time; |
|
- | 1079 | ||
- | 1080 | nbox_this_time = gen5_get_rectangles(sna, op, nbox, |
|
- | 1081 | gen5_bind_surfaces); |
|
- | 1082 | nbox -= nbox_this_time; |
|
- | 1083 | ||
- | 1084 | do { |
|
- | 1085 | struct sna_composite_rectangles r; |
|
- | 1086 | ||
- | 1087 | DBG((" %s: (%d, %d), (%d, %d)\n", |
|
- | 1088 | __FUNCTION__, |
|
- | 1089 | box->x1, box->y1, box->x2, box->y2)); |
|
- | 1090 | ||
- | 1091 | r.dst.x = box->x1; |
|
- | 1092 | r.dst.y = box->y1; |
|
- | 1093 | r.width = box->x2 - box->x1; |
|
- | 1094 | r.height = box->y2 - box->y1; |
|
- | 1095 | r.mask = r.src = r.dst; |
|
- | 1096 | op->prim_emit(sna, op, &r); |
|
- | 1097 | box++; |
|
- | 1098 | } while (--nbox_this_time); |
|
- | 1099 | } while (nbox); |
|
- | 1100 | } |
|
- | 1101 | ||
- | 1102 | static void |
|
- | 1103 | gen5_render_composite_boxes(struct sna *sna, |
|
- | 1104 | const struct sna_composite_op *op, |
|
- | 1105 | const BoxRec *box, int nbox) |
|
- | 1106 | { |
|
- | 1107 | DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); |
|
- | 1108 | ||
- | 1109 | do { |
|
- | 1110 | int nbox_this_time; |
|
- | 1111 | float *v; |
|
- | 1112 | ||
- | 1113 | nbox_this_time = gen5_get_rectangles(sna, op, nbox, |
|
- | 1114 | gen5_bind_surfaces); |
|
- | 1115 | assert(nbox_this_time); |
|
- | 1116 | nbox -= nbox_this_time; |
|
- | 1117 | ||
- | 1118 | v = sna->render.vertices + sna->render.vertex_used; |
|
- | 1119 | sna->render.vertex_used += nbox_this_time * op->floats_per_rect; |
|
- | 1120 | ||
- | 1121 | op->emit_boxes(op, box, nbox_this_time, v); |
|
- | 1122 | box += nbox_this_time; |
|
- | 1123 | } while (nbox); |
|
- | 1124 | } |
|
- | 1125 | ||
- | 1126 | static void |
|
- | 1127 | gen5_render_composite_boxes__thread(struct sna *sna, |
|
- | 1128 | const struct sna_composite_op *op, |
|
- | 1129 | const BoxRec *box, int nbox) |
|
- | 1130 | { |
|
- | 1131 | DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); |
|
- | 1132 | ||
- | 1133 | sna_vertex_lock(&sna->render); |
|
- | 1134 | do { |
|
- | 1135 | int nbox_this_time; |
|
- | 1136 | float *v; |
|
- | 1137 | ||
- | 1138 | nbox_this_time = gen5_get_rectangles(sna, op, nbox, |
|
- | 1139 | gen5_bind_surfaces); |
|
- | 1140 | assert(nbox_this_time); |
|
- | 1141 | nbox -= nbox_this_time; |
|
- | 1142 | ||
- | 1143 | v = sna->render.vertices + sna->render.vertex_used; |
|
- | 1144 | sna->render.vertex_used += nbox_this_time * op->floats_per_rect; |
|
- | 1145 | ||
- | 1146 | sna_vertex_acquire__locked(&sna->render); |
|
- | 1147 | sna_vertex_unlock(&sna->render); |
|
- | 1148 | ||
- | 1149 | op->emit_boxes(op, box, nbox_this_time, v); |
|
- | 1150 | box += nbox_this_time; |
|
- | 1151 | ||
- | 1152 | sna_vertex_lock(&sna->render); |
|
- | 1153 | sna_vertex_release__locked(&sna->render); |
|
- | 1154 | } while (nbox); |
|
- | 1155 | sna_vertex_unlock(&sna->render); |
|
- | 1156 | } |
|
- | 1157 | ||
- | 1158 | #ifndef MAX |
|
- | 1159 | #define MAX(a,b) ((a) > (b) ? (a) : (b)) |
|
- | 1160 | #endif |
|
- | 1161 | ||
- | 1162 | static uint32_t gen5_bind_video_source(struct sna *sna, |
|
- | 1163 | struct kgem_bo *src_bo, |
|
- | 1164 | uint32_t src_offset, |
|
- | 1165 | int src_width, |
|
- | 1166 | int src_height, |
|
- | 1167 | int src_pitch, |
|
- | 1168 | uint32_t src_surf_format) |
|
- | 1169 | { |
|
- | 1170 | struct gen5_surface_state *ss; |
|
- | 1171 | ||
- | 1172 | sna->kgem.surface -= sizeof(struct gen5_surface_state_padded) / sizeof(uint32_t); |
|
- | 1173 | ||
- | 1174 | ss = memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(*ss)); |
|
- | 1175 | ss->ss0.surface_type = GEN5_SURFACE_2D; |
|
- | 1176 | ss->ss0.surface_format = src_surf_format; |
|
- | 1177 | ss->ss0.color_blend = 1; |
|
- | 1178 | ||
- | 1179 | ss->ss1.base_addr = |
|
- | 1180 | kgem_add_reloc(&sna->kgem, |
|
- | 1181 | sna->kgem.surface + 1, |
|
- | 1182 | src_bo, |
|
- | 1183 | I915_GEM_DOMAIN_SAMPLER << 16, |
|
- | 1184 | src_offset); |
|
- | 1185 | ||
- | 1186 | ss->ss2.width = src_width - 1; |
|
- | 1187 | ss->ss2.height = src_height - 1; |
|
- | 1188 | ss->ss3.pitch = src_pitch - 1; |
|
- | 1189 | ||
- | 1190 | return sna->kgem.surface * sizeof(uint32_t); |
|
- | 1191 | } |
|
- | 1192 | ||
- | 1193 | static void gen5_video_bind_surfaces(struct sna *sna, |
|
- | 1194 | const struct sna_composite_op *op) |
|
- | 1195 | { |
|
- | 1196 | bool dirty = kgem_bo_is_dirty(op->dst.bo); |
|
- | 1197 | struct sna_video_frame *frame = op->priv; |
|
- | 1198 | uint32_t src_surf_format; |
|
- | 1199 | uint32_t src_surf_base[6]; |
|
- | 1200 | int src_width[6]; |
|
- | 1201 | int src_height[6]; |
|
- | 1202 | int src_pitch[6]; |
|
- | 1203 | uint32_t *binding_table; |
|
- | 1204 | uint16_t offset; |
|
- | 1205 | int n_src, n; |
|
- | 1206 | ||
- | 1207 | src_surf_base[0] = 0; |
|
- | 1208 | src_surf_base[1] = 0; |
|
- | 1209 | src_surf_base[2] = frame->VBufOffset; |
|
- | 1210 | src_surf_base[3] = frame->VBufOffset; |
|
- | 1211 | src_surf_base[4] = frame->UBufOffset; |
|
- | 1212 | src_surf_base[5] = frame->UBufOffset; |
|
- | 1213 | ||
- | 1214 | if (is_planar_fourcc(frame->id)) { |
|
- | 1215 | src_surf_format = GEN5_SURFACEFORMAT_R8_UNORM; |
|
- | 1216 | src_width[1] = src_width[0] = frame->width; |
|
- | 1217 | src_height[1] = src_height[0] = frame->height; |
|
- | 1218 | src_pitch[1] = src_pitch[0] = frame->pitch[1]; |
|
- | 1219 | src_width[4] = src_width[5] = src_width[2] = src_width[3] = |
|
- | 1220 | frame->width / 2; |
|
- | 1221 | src_height[4] = src_height[5] = src_height[2] = src_height[3] = |
|
- | 1222 | frame->height / 2; |
|
- | 1223 | src_pitch[4] = src_pitch[5] = src_pitch[2] = src_pitch[3] = |
|
- | 1224 | frame->pitch[0]; |
|
- | 1225 | n_src = 6; |
|
- | 1226 | } else { |
|
- | 1227 | if (frame->id == FOURCC_UYVY) |
|
- | 1228 | src_surf_format = GEN5_SURFACEFORMAT_YCRCB_SWAPY; |
|
- | 1229 | else |
|
- | 1230 | src_surf_format = GEN5_SURFACEFORMAT_YCRCB_NORMAL; |
|
- | 1231 | ||
- | 1232 | src_width[0] = frame->width; |
|
- | 1233 | src_height[0] = frame->height; |
|
- | 1234 | src_pitch[0] = frame->pitch[0]; |
|
- | 1235 | n_src = 1; |
|
- | 1236 | } |
|
- | 1237 | ||
- | 1238 | gen5_get_batch(sna, op); |
|
- | 1239 | ||
- | 1240 | binding_table = gen5_composite_get_binding_table(sna, &offset); |
|
- | 1241 | binding_table[0] = |
|
- | 1242 | gen5_bind_bo(sna, |
|
- | 1243 | op->dst.bo, op->dst.width, op->dst.height, |
|
- | 1244 | gen5_get_dest_format(op->dst.format), |
|
- | 1245 | true); |
|
- | 1246 | for (n = 0; n < n_src; n++) { |
|
- | 1247 | binding_table[1+n] = |
|
- | 1248 | gen5_bind_video_source(sna, |
|
- | 1249 | frame->bo, |
|
- | 1250 | src_surf_base[n], |
|
- | 1251 | src_width[n], |
|
- | 1252 | src_height[n], |
|
- | 1253 | src_pitch[n], |
|
- | 1254 | src_surf_format); |
|
- | 1255 | } |
|
- | 1256 | ||
- | 1257 | gen5_emit_state(sna, op, offset | dirty); |
|
- | 1258 | } |
|
- | 1259 | ||
- | 1260 | static bool |
|
- | 1261 | gen5_render_video(struct sna *sna, |
|
- | 1262 | struct sna_video *video, |
|
- | 1263 | struct sna_video_frame *frame, |
|
- | 1264 | RegionPtr dstRegion, |
|
- | 1265 | PixmapPtr pixmap) |
|
- | 1266 | { |
|
- | 1267 | struct sna_composite_op tmp; |
|
- | 1268 | int dst_width = dstRegion->extents.x2 - dstRegion->extents.x1; |
|
- | 1269 | int dst_height = dstRegion->extents.y2 - dstRegion->extents.y1; |
|
- | 1270 | int src_width = frame->src.x2 - frame->src.x1; |
|
- | 1271 | int src_height = frame->src.y2 - frame->src.y1; |
|
- | 1272 | float src_offset_x, src_offset_y; |
|
- | 1273 | float src_scale_x, src_scale_y; |
|
- | 1274 | int nbox, pix_xoff, pix_yoff; |
|
- | 1275 | struct sna_pixmap *priv; |
|
- | 1276 | BoxPtr box; |
|
- | 1277 | ||
- | 1278 | DBG(("%s: %dx%d -> %dx%d\n", __FUNCTION__, |
|
- | 1279 | src_width, src_height, dst_width, dst_height)); |
|
- | 1280 | ||
- | 1281 | priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_WRITE); |
|
- | 1282 | if (priv == NULL) |
|
- | 1283 | return false; |
|
- | 1284 | ||
- | 1285 | memset(&tmp, 0, sizeof(tmp)); |
|
- | 1286 | ||
- | 1287 | tmp.op = PictOpSrc; |
|
- | 1288 | tmp.dst.pixmap = pixmap; |
|
- | 1289 | tmp.dst.width = pixmap->drawable.width; |
|
- | 1290 | tmp.dst.height = pixmap->drawable.height; |
|
- | 1291 | tmp.dst.format = sna_format_for_depth(pixmap->drawable.depth); |
|
- | 1292 | tmp.dst.bo = priv->gpu_bo; |
|
- | 1293 | ||
- | 1294 | if (src_width == dst_width && src_height == dst_height) |
|
- | 1295 | tmp.src.filter = SAMPLER_FILTER_NEAREST; |
|
- | 1296 | else |
|
- | 1297 | tmp.src.filter = SAMPLER_FILTER_BILINEAR; |
|
- | 1298 | tmp.src.repeat = SAMPLER_EXTEND_PAD; |
|
- | 1299 | tmp.src.bo = frame->bo; |
|
- | 1300 | tmp.mask.bo = NULL; |
|
- | 1301 | tmp.u.gen5.wm_kernel = |
|
- | 1302 | is_planar_fourcc(frame->id) ? WM_KERNEL_VIDEO_PLANAR : WM_KERNEL_VIDEO_PACKED; |
|
- | 1303 | tmp.u.gen5.ve_id = 2; |
|
- | 1304 | tmp.is_affine = true; |
|
- | 1305 | tmp.floats_per_vertex = 3; |
|
- | 1306 | tmp.floats_per_rect = 9; |
|
- | 1307 | tmp.priv = frame; |
|
- | 1308 | ||
- | 1309 | if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) { |
|
- | 1310 | kgem_submit(&sna->kgem); |
|
- | 1311 | assert(kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)); |
|
- | 1312 | } |
|
- | 1313 | ||
- | 1314 | gen5_video_bind_surfaces(sna, &tmp); |
|
- | 1315 | gen5_align_vertex(sna, &tmp); |
|
- | 1316 | ||
- | 1317 | /* Set up the offset for translating from the given region (in screen |
|
- | 1318 | * coordinates) to the backing pixmap. |
|
- | 1319 | */ |
|
- | 1320 | #ifdef COMPOSITE |
|
- | 1321 | pix_xoff = -pixmap->screen_x + pixmap->drawable.x; |
|
- | 1322 | pix_yoff = -pixmap->screen_y + pixmap->drawable.y; |
|
- | 1323 | #else |
|
- | 1324 | pix_xoff = 0; |
|
- | 1325 | pix_yoff = 0; |
|
- | 1326 | #endif |
|
- | 1327 | ||
- | 1328 | src_scale_x = (float)src_width / dst_width / frame->width; |
|
- | 1329 | src_offset_x = (float)frame->src.x1 / frame->width - dstRegion->extents.x1 * src_scale_x; |
|
- | 1330 | ||
- | 1331 | src_scale_y = (float)src_height / dst_height / frame->height; |
|
- | 1332 | src_offset_y = (float)frame->src.y1 / frame->height - dstRegion->extents.y1 * src_scale_y; |
|
- | 1333 | ||
- | 1334 | box = REGION_RECTS(dstRegion); |
|
- | 1335 | nbox = REGION_NUM_RECTS(dstRegion); |
|
- | 1336 | while (nbox--) { |
|
- | 1337 | BoxRec r; |
|
- | 1338 | ||
- | 1339 | r.x1 = box->x1 + pix_xoff; |
|
- | 1340 | r.x2 = box->x2 + pix_xoff; |
|
- | 1341 | r.y1 = box->y1 + pix_yoff; |
|
- | 1342 | r.y2 = box->y2 + pix_yoff; |
|
- | 1343 | ||
- | 1344 | gen5_get_rectangles(sna, &tmp, 1, gen5_video_bind_surfaces); |
|
- | 1345 | ||
- | 1346 | OUT_VERTEX(r.x2, r.y2); |
|
- | 1347 | OUT_VERTEX_F(box->x2 * src_scale_x + src_offset_x); |
|
- | 1348 | OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); |
|
- | 1349 | ||
- | 1350 | OUT_VERTEX(r.x1, r.y2); |
|
- | 1351 | OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); |
|
- | 1352 | OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); |
|
- | 1353 | ||
- | 1354 | OUT_VERTEX(r.x1, r.y1); |
|
- | 1355 | OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); |
|
- | 1356 | OUT_VERTEX_F(box->y1 * src_scale_y + src_offset_y); |
|
- | 1357 | ||
- | 1358 | if (!DAMAGE_IS_ALL(priv->gpu_damage)) { |
|
- | 1359 | sna_damage_add_box(&priv->gpu_damage, &r); |
|
- | 1360 | sna_damage_subtract_box(&priv->cpu_damage, &r); |
|
- | 1361 | } |
|
- | 1362 | box++; |
|
- | 1363 | } |
|
- | 1364 | ||
- | 1365 | gen4_vertex_flush(sna); |
|
- | 1366 | return true; |
|
Line 973... | Line 1367... | ||
973 | } |
1367 | } |
974 | 1368 | #endif |
|
975 | 1369 | ||
976 | static void |
1370 | static void |
Line 984... | Line 1378... | ||
984 | 1378 | ||
Line 985... | Line 1379... | ||
985 | DBG(("%s()\n", __FUNCTION__)); |
1379 | DBG(("%s()\n", __FUNCTION__)); |
Line -... | Line 1380... | ||
- | 1380 | ||
- | 1381 | } |
|
- | 1382 | ||
- | 1383 | #if 0 |
|
- | 1384 | static bool |
|
- | 1385 | gen5_composite_set_target(struct sna *sna, |
|
- | 1386 | struct sna_composite_op *op, |
|
- | 1387 | PicturePtr dst, |
|
- | 1388 | int x, int y, int w, int h, |
|
- | 1389 | bool partial) |
|
- | 1390 | { |
|
- | 1391 | BoxRec box; |
|
- | 1392 | ||
- | 1393 | op->dst.pixmap = get_drawable_pixmap(dst->pDrawable); |
|
- | 1394 | op->dst.width = op->dst.pixmap->drawable.width; |
|
- | 1395 | op->dst.height = op->dst.pixmap->drawable.height; |
|
- | 1396 | op->dst.format = dst->format; |
|
- | 1397 | if (w && h) { |
|
- | 1398 | box.x1 = x; |
|
- | 1399 | box.y1 = y; |
|
- | 1400 | box.x2 = x + w; |
|
- | 1401 | box.y2 = y + h; |
|
- | 1402 | } else |
|
- | 1403 | sna_render_picture_extents(dst, &box); |
|
- | 1404 | ||
- | 1405 | op->dst.bo = sna_drawable_use_bo (dst->pDrawable, |
|
- | 1406 | PREFER_GPU | FORCE_GPU | RENDER_GPU, |
|
- | 1407 | &box, &op->damage); |
|
- | 1408 | if (op->dst.bo == NULL) |
|
- | 1409 | return false; |
|
- | 1410 | ||
- | 1411 | get_drawable_deltas(dst->pDrawable, op->dst.pixmap, |
|
- | 1412 | &op->dst.x, &op->dst.y); |
|
- | 1413 | ||
- | 1414 | DBG(("%s: pixmap=%p, format=%08x, size=%dx%d, pitch=%d, delta=(%d,%d),damage=%p\n", |
|
- | 1415 | __FUNCTION__, |
|
- | 1416 | op->dst.pixmap, (int)op->dst.format, |
|
- | 1417 | op->dst.width, op->dst.height, |
|
- | 1418 | op->dst.bo->pitch, |
|
- | 1419 | op->dst.x, op->dst.y, |
|
- | 1420 | op->damage ? *op->damage : (void *)-1)); |
|
- | 1421 | ||
- | 1422 | assert(op->dst.bo->proxy == NULL); |
|
- | 1423 | ||
- | 1424 | if (too_large(op->dst.width, op->dst.height) && |
|
- | 1425 | !sna_render_composite_redirect(sna, op, x, y, w, h, partial)) |
|
- | 1426 | return false; |
|
Line 986... | Line 1427... | ||
986 | 1427 | ||
987 | } |
1428 | return true; |
988 | 1429 | } |
|
989 | 1430 | ||
990 | static bool |
1431 | static bool |
991 | gen5_blit_tex(struct sna *sna, |
1432 | gen5_render_composite(struct sna *sna, |
992 | uint8_t op, bool scale, |
1433 | uint8_t op, |
993 | PixmapPtr src, struct kgem_bo *src_bo, |
1434 | PicturePtr src, |
994 | PixmapPtr mask,struct kgem_bo *mask_bo, |
1435 | PicturePtr mask, |
995 | PixmapPtr dst, struct kgem_bo *dst_bo, |
1436 | PicturePtr dst, |
996 | int32_t src_x, int32_t src_y, |
1437 | int16_t src_x, int16_t src_y, |
997 | int32_t msk_x, int32_t msk_y, |
1438 | int16_t msk_x, int16_t msk_y, |
998 | int32_t dst_x, int32_t dst_y, |
1439 | int16_t dst_x, int16_t dst_y, |
999 | int32_t width, int32_t height, |
1440 | int16_t width, int16_t height, |
Line -... | Line 1441... | ||
- | 1441 | struct sna_composite_op *tmp) |
|
- | 1442 | { |
|
1000 | struct sna_composite_op *tmp) |
1443 | DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__, |
- | 1444 | width, height, sna->kgem.mode)); |
|
Line 1001... | Line 1445... | ||
1001 | { |
1445 | |
- | 1446 | if (op >= ARRAY_SIZE(gen5_blend_op)) { |
|
1002 | DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__, |
1447 | DBG(("%s: unhandled blend op %d\n", __FUNCTION__, op)); |
- | 1448 | return false; |
|
- | 1449 | } |
|
1003 | width, height, sna->kgem.mode)); |
1450 | |
1004 | 1451 | if (mask == NULL && |
|
1005 | tmp->op = PictOpSrc; |
1452 | try_blt(sna, dst, src, width, height) && |
- | 1453 | sna_blt_composite(sna, op, |
|
Line -... | Line 1454... | ||
- | 1454 | src, dst, |
|
- | 1455 | src_x, src_y, |
|
Line -... | Line 1456... | ||
- | 1456 | dst_x, dst_y, |
|
- | 1457 | width, height, |
|
- | 1458 | tmp, false)) |
|
- | 1459 | return true; |
|
- | 1460 | ||
1006 | 1461 | if (gen5_composite_fallback(sna, src, mask, dst)) |
|
- | 1462 | return false; |
|
- | 1463 | ||
1007 | tmp->dst.pixmap = dst; |
1464 | if (need_tiling(sna, width, height)) |
1008 | tmp->dst.bo = dst_bo; |
1465 | return sna_tiling_composite(op, src, mask, dst, |
- | 1466 | src_x, src_y, |
|
- | 1467 | msk_x, msk_y, |
|
- | 1468 | dst_x, dst_y, |
|
- | 1469 | width, height, |
|
Line -... | Line 1470... | ||
- | 1470 | tmp); |
|
- | 1471 | ||
- | 1472 | if (!gen5_composite_set_target(sna, tmp, dst, |
|
1009 | tmp->dst.width = dst->drawable.width; |
1473 | dst_x, dst_y, width, height, |
- | 1474 | op > PictOpSrc || dst->pCompositeClip->data)) { |
|
- | 1475 | DBG(("%s: failed to set composite target\n", __FUNCTION__)); |
|
1010 | tmp->dst.height = dst->drawable.height; |
1476 | return false; |
- | 1477 | } |
|
1011 | tmp->dst.format = PICT_x8r8g8b8; |
1478 | |
- | 1479 | DBG(("%s: preparing source\n", __FUNCTION__)); |
|
- | 1480 | tmp->op = op; |
|
- | 1481 | switch (gen5_composite_picture(sna, src, &tmp->src, |
|
- | 1482 | src_x, src_y, |
|
- | 1483 | width, height, |
|
- | 1484 | dst_x, dst_y, |
|
- | 1485 | dst->polyMode == PolyModePrecise)) { |
|
1012 | 1486 | case -1: |
|
1013 | 1487 | DBG(("%s: failed to prepare source picture\n", __FUNCTION__)); |
|
- | 1488 | goto cleanup_dst; |
|
- | 1489 | case 0: |
|
Line -... | Line 1490... | ||
- | 1490 | if (!gen4_channel_init_solid(sna, &tmp->src, 0)) |
|
- | 1491 | goto cleanup_dst; |
|
- | 1492 | /* fall through to fixup */ |
|
Line 1014... | Line 1493... | ||
1014 | tmp->src.repeat = RepeatNone; |
1493 | case 1: |
1015 | tmp->src.filter = PictFilterNearest; |
1494 | if (mask == NULL && |
1016 | tmp->src.is_affine = true; |
1495 | sna_blt_composite__convert(sna, |
Line -... | Line 1496... | ||
- | 1496 | dst_x, dst_y, width, height, |
|
- | 1497 | tmp)) |
|
1017 | 1498 | return true; |
|
- | 1499 | ||
1018 | tmp->src.bo = src_bo; |
1500 | gen5_composite_channel_convert(&tmp->src); |
1019 | tmp->src.pict_format = PICT_x8r8g8b8; |
1501 | break; |
1020 | tmp->src.card_format = gen5_get_card_format(tmp->src.pict_format); |
1502 | } |
- | 1503 | ||
1021 | tmp->src.width = src->drawable.width; |
1504 | tmp->is_affine = tmp->src.is_affine; |
1022 | tmp->src.height = src->drawable.height; |
1505 | tmp->has_component_alpha = false; |
1023 | 1506 | tmp->need_magic_ca_pass = false; |
|
1024 | 1507 | ||
- | 1508 | if (mask) { |
|
- | 1509 | if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) { |
|
1025 | tmp->is_affine = tmp->src.is_affine; |
1510 | tmp->has_component_alpha = true; |
1026 | tmp->has_component_alpha = false; |
- | |
1027 | tmp->need_magic_ca_pass = false; |
- | |
1028 | 1511 | ||
1029 | tmp->mask.is_affine = true; |
1512 | /* Check if it's component alpha that relies on a source alpha and on |
1030 | tmp->mask.repeat = SAMPLER_EXTEND_NONE; |
1513 | * the source value. We can only get one of those into the single |
1031 | tmp->mask.filter = SAMPLER_FILTER_NEAREST; |
- | |
1032 | tmp->mask.bo = mask_bo; |
- | |
1033 | tmp->mask.pict_format = PIXMAN_a8; |
- | |
1034 | tmp->mask.card_format = gen5_get_card_format(tmp->mask.pict_format); |
- | |
1035 | tmp->mask.width = mask->drawable.width; |
1514 | * source value that we get to blend with. |
Line -... | Line 1515... | ||
- | 1515 | */ |
|
- | 1516 | if (gen5_blend_op[op].src_alpha && |
|
1036 | tmp->mask.height = mask->drawable.height; |
1517 | (gen5_blend_op[op].src_blend != GEN5_BLENDFACTOR_ZERO)) { |
1037 | 1518 | if (op != PictOpOver) { |
|
- | 1519 | DBG(("%s: unhandled CA blend op %d\n", __FUNCTION__, op)); |
|
- | 1520 | goto cleanup_src; |
|
- | 1521 | } |
|
- | 1522 | ||
- | 1523 | tmp->need_magic_ca_pass = true; |
|
- | 1524 | tmp->op = PictOpOutReverse; |
|
- | 1525 | } |
|
- | 1526 | } |
|
- | 1527 | ||
- | 1528 | if (!reuse_source(sna, |
|
- | 1529 | src, &tmp->src, src_x, src_y, |
|
- | 1530 | mask, &tmp->mask, msk_x, msk_y)) { |
|
- | 1531 | DBG(("%s: preparing mask\n", __FUNCTION__)); |
|
- | 1532 | switch (gen5_composite_picture(sna, mask, &tmp->mask, |
|
- | 1533 | msk_x, msk_y, |
|
- | 1534 | width, height, |
|
- | 1535 | dst_x, dst_y, |
|
Line -... | Line 1536... | ||
- | 1536 | dst->polyMode == PolyModePrecise)) { |
|
- | 1537 | case -1: |
|
Line 1038... | Line 1538... | ||
1038 | if( scale ) |
1538 | DBG(("%s: failed to prepare mask picture\n", __FUNCTION__)); |
1039 | { |
1539 | goto cleanup_src; |
1040 | tmp->src.scale[0] = 1.f/width; |
1540 | case 0: |
1041 | tmp->src.scale[1] = 1.f/height; |
1541 | if (!gen4_channel_init_solid(sna, &tmp->mask, 0)) |
1042 | } |
1542 | goto cleanup_src; |
1043 | else |
1543 | /* fall through to fixup */ |
Line 1044... | Line 1544... | ||
1044 | { |
1544 | case 1: |
1045 | tmp->src.scale[0] = 1.f/src->drawable.width; |
1545 | gen5_composite_channel_convert(&tmp->mask); |
- | 1546 | break; |
|
- | 1547 | } |
|
- | 1548 | } |
|
- | 1549 | ||
- | 1550 | tmp->is_affine &= tmp->mask.is_affine; |
|
1046 | tmp->src.scale[1] = 1.f/src->drawable.height; |
1551 | } |
Line 1047... | Line 1552... | ||
1047 | } |
1552 | |
1048 | 1553 | tmp->u.gen5.wm_kernel = |
|
1049 | tmp->mask.scale[0] = 1.f/mask->drawable.width; |
1554 | gen5_choose_composite_kernel(tmp->op, |
- | 1555 | tmp->mask.bo != NULL, |
|
- | 1556 | tmp->has_component_alpha, |
|
- | 1557 | tmp->is_affine); |
|
1050 | tmp->mask.scale[1] = 1.f/mask->drawable.height; |
1558 | tmp->u.gen5.ve_id = gen4_choose_composite_emitter(sna, tmp); |
Line 1051... | Line 1559... | ||
1051 | 1559 | ||
1052 | 1560 | tmp->blt = gen5_render_composite_blt; |
|
1053 | tmp->u.gen5.wm_kernel = |
1561 | tmp->box = gen5_render_composite_box; |
Line -... | Line 1562... | ||
- | 1562 | tmp->boxes = gen5_render_composite_boxes__blt; |
|
- | 1563 | if (tmp->emit_boxes) { |
|
- | 1564 | tmp->boxes = gen5_render_composite_boxes; |
|
- | 1565 | tmp->thread_boxes = gen5_render_composite_boxes__thread; |
|
- | 1566 | } |
|
- | 1567 | tmp->done = gen5_render_composite_done; |
|
- | 1568 | ||
- | 1569 | if (!kgem_check_bo(&sna->kgem, |
|
- | 1570 | tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) { |
|
- | 1571 | kgem_submit(&sna->kgem); |
|
1054 | gen5_choose_composite_kernel(tmp->op, |
1572 | if (!kgem_check_bo(&sna->kgem, |
Line -... | Line 1573... | ||
- | 1573 | tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) |
|
- | 1574 | goto cleanup_mask; |
|
- | 1575 | } |
|
- | 1576 | ||
- | 1577 | gen5_bind_surfaces(sna, tmp); |
|
- | 1578 | gen5_align_vertex(sna, tmp); |
|
- | 1579 | return true; |
|
- | 1580 | ||
- | 1581 | cleanup_mask: |
|
- | 1582 | if (tmp->mask.bo) |
|
- | 1583 | kgem_bo_destroy(&sna->kgem, tmp->mask.bo); |
|
- | 1584 | cleanup_src: |
|
- | 1585 | if (tmp->src.bo) |
|
- | 1586 | kgem_bo_destroy(&sna->kgem, tmp->src.bo); |
|
Line -... | Line 1587... | ||
- | 1587 | cleanup_dst: |
|
- | 1588 | if (tmp->redirect.real_bo) |
|
- | 1589 | kgem_bo_destroy(&sna->kgem, tmp->dst.bo); |
|
- | 1590 | return false; |
|
- | 1591 | } |
|
- | 1592 | ||
- | 1593 | #if !NO_COMPOSITE_SPANS |
|
- | 1594 | fastcall static void |
|
- | 1595 | gen5_render_composite_spans_box(struct sna *sna, |
|
- | 1596 | const struct sna_composite_spans_op *op, |
|
- | 1597 | const BoxRec *box, float opacity) |
|
- | 1598 | { |
|
- | 1599 | DBG(("%s: src=+(%d, %d), opacity=%f, dst=+(%d, %d), box=(%d, %d) x (%d, %d)\n", |
|
- | 1600 | __FUNCTION__, |
|
- | 1601 | op->base.src.offset[0], op->base.src.offset[1], |
|
- | 1602 | opacity, |
|
- | 1603 | op->base.dst.x, op->base.dst.y, |
|
- | 1604 | box->x1, box->y1, |
|
- | 1605 | box->x2 - box->x1, |
|
- | 1606 | box->y2 - box->y1)); |
|
- | 1607 | ||
- | 1608 | gen5_get_rectangles(sna, &op->base, 1, gen5_bind_surfaces); |
|
- | 1609 | op->prim_emit(sna, op, box, opacity); |
|
- | 1610 | } |
|
- | 1611 | ||
- | 1612 | static void |
|
- | 1613 | gen5_render_composite_spans_boxes(struct sna *sna, |
|
- | 1614 | const struct sna_composite_spans_op *op, |
|
- | 1615 | const BoxRec *box, int nbox, |
|
- | 1616 | float opacity) |
|
- | 1617 | { |
|
- | 1618 | DBG(("%s: nbox=%d, src=+(%d, %d), opacity=%f, dst=+(%d, %d)\n", |
|
- | 1619 | __FUNCTION__, nbox, |
|
- | 1620 | op->base.src.offset[0], op->base.src.offset[1], |
|
- | 1621 | opacity, |
|
- | 1622 | op->base.dst.x, op->base.dst.y)); |
|
- | 1623 | ||
- | 1624 | do { |
|
- | 1625 | int nbox_this_time; |
|
- | 1626 | ||
- | 1627 | nbox_this_time = gen5_get_rectangles(sna, &op->base, nbox, |
|
- | 1628 | gen5_bind_surfaces); |
|
- | 1629 | nbox -= nbox_this_time; |
|
- | 1630 | ||
- | 1631 | do { |
|
- | 1632 | DBG((" %s: (%d, %d) x (%d, %d)\n", __FUNCTION__, |
|
- | 1633 | box->x1, box->y1, |
|
- | 1634 | box->x2 - box->x1, |
|
- | 1635 | box->y2 - box->y1)); |
|
- | 1636 | ||
- | 1637 | op->prim_emit(sna, op, box++, opacity); |
|
- | 1638 | } while (--nbox_this_time); |
|
- | 1639 | } while (nbox); |
|
- | 1640 | } |
|
- | 1641 | ||
- | 1642 | fastcall static void |
|
- | 1643 | gen5_render_composite_spans_boxes__thread(struct sna *sna, |
|
- | 1644 | const struct sna_composite_spans_op *op, |
|
- | 1645 | const struct sna_opacity_box *box, |
|
- | 1646 | int nbox) |
|
- | 1647 | { |
|
- | 1648 | DBG(("%s: nbox=%d, src=+(%d, %d), dst=+(%d, %d)\n", |
|
- | 1649 | __FUNCTION__, nbox, |
|
- | 1650 | op->base.src.offset[0], op->base.src.offset[1], |
|
- | 1651 | op->base.dst.x, op->base.dst.y)); |
|
- | 1652 | ||
- | 1653 | sna_vertex_lock(&sna->render); |
|
- | 1654 | do { |
|
- | 1655 | int nbox_this_time; |
|
- | 1656 | float *v; |
|
- | 1657 | ||
- | 1658 | nbox_this_time = gen5_get_rectangles(sna, &op->base, nbox, |
|
- | 1659 | gen5_bind_surfaces); |
|
- | 1660 | assert(nbox_this_time); |
|
- | 1661 | nbox -= nbox_this_time; |
|
- | 1662 | ||
- | 1663 | v = sna->render.vertices + sna->render.vertex_used; |
|
- | 1664 | sna->render.vertex_used += nbox_this_time * op->base.floats_per_rect; |
|
- | 1665 | ||
- | 1666 | sna_vertex_acquire__locked(&sna->render); |
|
- | 1667 | sna_vertex_unlock(&sna->render); |
|
- | 1668 | ||
- | 1669 | op->emit_boxes(op, box, nbox_this_time, v); |
|
- | 1670 | box += nbox_this_time; |
|
- | 1671 | ||
- | 1672 | sna_vertex_lock(&sna->render); |
|
- | 1673 | sna_vertex_release__locked(&sna->render); |
|
- | 1674 | } while (nbox); |
|
- | 1675 | sna_vertex_unlock(&sna->render); |
|
- | 1676 | } |
|
- | 1677 | ||
- | 1678 | fastcall static void |
|
- | 1679 | gen5_render_composite_spans_done(struct sna *sna, |
|
- | 1680 | const struct sna_composite_spans_op *op) |
|
- | 1681 | { |
|
- | 1682 | if (sna->render.vertex_offset) |
|
- | 1683 | gen4_vertex_flush(sna); |
|
- | 1684 | ||
- | 1685 | DBG(("%s()\n", __FUNCTION__)); |
|
- | 1686 | ||
- | 1687 | kgem_bo_destroy(&sna->kgem, op->base.src.bo); |
|
- | 1688 | sna_render_composite_redirect_done(sna, &op->base); |
|
- | 1689 | } |
|
- | 1690 | ||
- | 1691 | static bool |
|
- | 1692 | gen5_check_composite_spans(struct sna *sna, |
|
- | 1693 | uint8_t op, PicturePtr src, PicturePtr dst, |
|
- | 1694 | int16_t width, int16_t height, |
|
- | 1695 | unsigned flags) |
|
- | 1696 | { |
|
- | 1697 | DBG(("%s: op=%d, width=%d, height=%d, flags=%x\n", |
|
- | 1698 | __FUNCTION__, op, width, height, flags)); |
|
- | 1699 | ||
- | 1700 | if (op >= ARRAY_SIZE(gen5_blend_op)) |
|
- | 1701 | return false; |
|
- | 1702 | ||
- | 1703 | if (gen5_composite_fallback(sna, src, NULL, dst)) { |
|
- | 1704 | DBG(("%s: operation would fallback\n", __FUNCTION__)); |
|
- | 1705 | return false; |
|
- | 1706 | } |
|
- | 1707 | ||
- | 1708 | if (need_tiling(sna, width, height) && |
|
- | 1709 | !is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { |
|
- | 1710 | DBG(("%s: fallback, tiled operation not on GPU\n", |
|
- | 1711 | __FUNCTION__)); |
|
- | 1712 | return false; |
|
- | 1713 | } |
|
- | 1714 | ||
- | 1715 | if ((flags & COMPOSITE_SPANS_RECTILINEAR) == 0) { |
|
- | 1716 | struct sna_pixmap *priv = sna_pixmap_from_drawable(dst->pDrawable); |
|
- | 1717 | assert(priv); |
|
- | 1718 | ||
- | 1719 | if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) |
|
- | 1720 | return true; |
|
- | 1721 | ||
- | 1722 | if (flags & COMPOSITE_SPANS_INPLACE_HINT) |
|
- | 1723 | return false; |
|
- | 1724 | ||
- | 1725 | if ((sna->render.prefer_gpu & PREFER_GPU_SPANS) == 0 && |
|
- | 1726 | dst->format == PICT_a8) |
|
- | 1727 | return false; |
|
- | 1728 | ||
- | 1729 | return priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo); |
|
- | 1730 | } |
|
- | 1731 | ||
- | 1732 | return true; |
|
- | 1733 | } |
|
- | 1734 | ||
- | 1735 | static bool |
|
- | 1736 | gen5_render_composite_spans(struct sna *sna, |
|
- | 1737 | uint8_t op, |
|
- | 1738 | PicturePtr src, |
|
- | 1739 | PicturePtr dst, |
|
- | 1740 | int16_t src_x, int16_t src_y, |
|
- | 1741 | int16_t dst_x, int16_t dst_y, |
|
- | 1742 | int16_t width, int16_t height, |
|
- | 1743 | unsigned flags, |
|
- | 1744 | struct sna_composite_spans_op *tmp) |
|
- | 1745 | { |
|
- | 1746 | DBG(("%s: %dx%d with flags=%x, current mode=%d\n", __FUNCTION__, |
|
- | 1747 | width, height, flags, sna->kgem.ring)); |
|
- | 1748 | ||
- | 1749 | assert(gen5_check_composite_spans(sna, op, src, dst, width, height, flags)); |
|
- | 1750 | ||
- | 1751 | if (need_tiling(sna, width, height)) { |
|
- | 1752 | DBG(("%s: tiling, operation (%dx%d) too wide for pipeline\n", |
|
- | 1753 | __FUNCTION__, width, height)); |
|
- | 1754 | return sna_tiling_composite_spans(op, src, dst, |
|
- | 1755 | src_x, src_y, dst_x, dst_y, |
|
- | 1756 | width, height, flags, tmp); |
|
- | 1757 | } |
|
- | 1758 | ||
- | 1759 | tmp->base.op = op; |
|
- | 1760 | if (!gen5_composite_set_target(sna, &tmp->base, dst, |
|
- | 1761 | dst_x, dst_y, width, height, |
|
- | 1762 | true)) |
|
- | 1763 | return false; |
|
- | 1764 | ||
- | 1765 | switch (gen5_composite_picture(sna, src, &tmp->base.src, |
|
- | 1766 | src_x, src_y, |
|
- | 1767 | width, height, |
|
- | 1768 | dst_x, dst_y, |
|
- | 1769 | dst->polyMode == PolyModePrecise)) { |
|
- | 1770 | case -1: |
|
- | 1771 | goto cleanup_dst; |
|
- | 1772 | case 0: |
|
- | 1773 | if (!gen4_channel_init_solid(sna, &tmp->base.src, 0)) |
|
- | 1774 | goto cleanup_dst; |
|
- | 1775 | /* fall through to fixup */ |
|
- | 1776 | case 1: |
|
- | 1777 | gen5_composite_channel_convert(&tmp->base.src); |
|
- | 1778 | break; |
|
- | 1779 | } |
|
- | 1780 | ||
- | 1781 | tmp->base.mask.bo = NULL; |
|
- | 1782 | ||
- | 1783 | tmp->base.is_affine = tmp->base.src.is_affine; |
|
- | 1784 | tmp->base.has_component_alpha = false; |
|
- | 1785 | tmp->base.need_magic_ca_pass = false; |
|
- | 1786 | ||
- | 1787 | tmp->base.u.gen5.ve_id = gen4_choose_spans_emitter(sna, tmp); |
|
- | 1788 | tmp->base.u.gen5.wm_kernel = WM_KERNEL_OPACITY | !tmp->base.is_affine; |
|
- | 1789 | ||
- | 1790 | tmp->box = gen5_render_composite_spans_box; |
|
- | 1791 | tmp->boxes = gen5_render_composite_spans_boxes; |
|
- | 1792 | if (tmp->emit_boxes) |
|
- | 1793 | tmp->thread_boxes = gen5_render_composite_spans_boxes__thread; |
|
- | 1794 | tmp->done = gen5_render_composite_spans_done; |
|
- | 1795 | ||
- | 1796 | if (!kgem_check_bo(&sna->kgem, |
|
- | 1797 | tmp->base.dst.bo, tmp->base.src.bo, |
|
- | 1798 | NULL)) { |
|
- | 1799 | kgem_submit(&sna->kgem); |
|
- | 1800 | if (!kgem_check_bo(&sna->kgem, |
|
- | 1801 | tmp->base.dst.bo, tmp->base.src.bo, |
|
- | 1802 | NULL)) |
|
- | 1803 | goto cleanup_src; |
|
- | 1804 | } |
|
- | 1805 | ||
- | 1806 | gen5_bind_surfaces(sna, &tmp->base); |
|
- | 1807 | gen5_align_vertex(sna, &tmp->base); |
|
- | 1808 | return true; |
|
- | 1809 | ||
- | 1810 | cleanup_src: |
|
- | 1811 | if (tmp->base.src.bo) |
|
- | 1812 | kgem_bo_destroy(&sna->kgem, tmp->base.src.bo); |
|
- | 1813 | cleanup_dst: |
|
- | 1814 | if (tmp->base.redirect.real_bo) |
|
- | 1815 | kgem_bo_destroy(&sna->kgem, tmp->base.dst.bo); |
|
- | 1816 | return false; |
|
- | 1817 | } |
|
- | 1818 | #endif |
|
- | 1819 | ||
- | 1820 | ||
- | 1821 | ||
- | 1822 | static bool |
|
- | 1823 | gen5_render_copy_boxes(struct sna *sna, uint8_t alu, |
|
- | 1824 | PixmapPtr src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, |
|
- | 1825 | PixmapPtr dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, |
|
- | 1826 | const BoxRec *box, int n, unsigned flags) |
|
- | 1827 | { |
|
- | 1828 | struct sna_composite_op tmp; |
|
- | 1829 | ||
- | 1830 | DBG(("%s alu=%d, src=%ld:handle=%d, dst=%ld:handle=%d boxes=%d x [((%d, %d), (%d, %d))...], flags=%x\n", |
|
- | 1831 | __FUNCTION__, alu, |
|
- | 1832 | src->drawable.serialNumber, src_bo->handle, |
|
- | 1833 | dst->drawable.serialNumber, dst_bo->handle, |
|
- | 1834 | n, box->x1, box->y1, box->x2, box->y2, |
|
- | 1835 | flags)); |
|
- | 1836 | ||
- | 1837 | if (sna_blt_compare_depth(&src->drawable, &dst->drawable) && |
|
- | 1838 | sna_blt_copy_boxes(sna, alu, |
|
- | 1839 | src_bo, src_dx, src_dy, |
|
- | 1840 | dst_bo, dst_dx, dst_dy, |
|
- | 1841 | dst->drawable.bitsPerPixel, |
|
- | 1842 | box, n)) |
|
- | 1843 | return true; |
|
- | 1844 | ||
- | 1845 | if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo) { |
|
- | 1846 | fallback_blt: |
|
- | 1847 | if (!sna_blt_compare_depth(&src->drawable, &dst->drawable)) |
|
- | 1848 | return false; |
|
- | 1849 | ||
- | 1850 | return sna_blt_copy_boxes_fallback(sna, alu, |
|
- | 1851 | src, src_bo, src_dx, src_dy, |
|
- | 1852 | dst, dst_bo, dst_dx, dst_dy, |
|
- | 1853 | box, n); |
|
- | 1854 | } |
|
- | 1855 | ||
- | 1856 | memset(&tmp, 0, sizeof(tmp)); |
|
- | 1857 | ||
- | 1858 | if (dst->drawable.depth == src->drawable.depth) { |
|
- | 1859 | tmp.dst.format = sna_render_format_for_depth(dst->drawable.depth); |
|
- | 1860 | tmp.src.pict_format = tmp.dst.format; |
|
- | 1861 | } else { |
|
- | 1862 | tmp.dst.format = sna_format_for_depth(dst->drawable.depth); |
|
- | 1863 | tmp.src.pict_format = sna_format_for_depth(src->drawable.depth); |
|
- | 1864 | } |
|
- | 1865 | if (!gen5_check_format(tmp.src.pict_format)) { |
|
- | 1866 | DBG(("%s: unsupported source format, %x, use BLT\n", |
|
- | 1867 | __FUNCTION__, tmp.src.pict_format)); |
|
- | 1868 | goto fallback_blt; |
|
- | 1869 | } |
|
- | 1870 | ||
- | 1871 | DBG(("%s (%d, %d)->(%d, %d) x %d\n", |
|
- | 1872 | __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n)); |
|
- | 1873 | ||
- | 1874 | tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear; |
|
- | 1875 | ||
- | 1876 | tmp.dst.pixmap = dst; |
|
- | 1877 | tmp.dst.width = dst->drawable.width; |
|
- | 1878 | tmp.dst.height = dst->drawable.height; |
|
- | 1879 | tmp.dst.x = tmp.dst.y = 0; |
|
- | 1880 | tmp.dst.bo = dst_bo; |
|
- | 1881 | tmp.damage = NULL; |
|
- | 1882 | ||
- | 1883 | sna_render_composite_redirect_init(&tmp); |
|
- | 1884 | if (too_large(tmp.dst.width, tmp.dst.height)) { |
|
- | 1885 | BoxRec extents = box[0]; |
|
- | 1886 | int i; |
|
- | 1887 | ||
- | 1888 | for (i = 1; i < n; i++) { |
|
- | 1889 | if (box[i].x1 < extents.x1) |
|
- | 1890 | extents.x1 = box[i].x1; |
|
- | 1891 | if (box[i].y1 < extents.y1) |
|
- | 1892 | extents.y1 = box[i].y1; |
|
- | 1893 | ||
- | 1894 | if (box[i].x2 > extents.x2) |
|
- | 1895 | extents.x2 = box[i].x2; |
|
- | 1896 | if (box[i].y2 > extents.y2) |
|
- | 1897 | extents.y2 = box[i].y2; |
|
- | 1898 | } |
|
- | 1899 | if (!sna_render_composite_redirect(sna, &tmp, |
|
- | 1900 | extents.x1 + dst_dx, |
|
- | 1901 | extents.y1 + dst_dy, |
|
- | 1902 | extents.x2 - extents.x1, |
|
- | 1903 | extents.y2 - extents.y1, |
|
- | 1904 | n > 1)) |
|
- | 1905 | goto fallback_tiled; |
|
- | 1906 | } |
|
- | 1907 | ||
- | 1908 | tmp.src.filter = SAMPLER_FILTER_NEAREST; |
|
- | 1909 | tmp.src.repeat = SAMPLER_EXTEND_NONE; |
|
- | 1910 | tmp.src.card_format = gen5_get_card_format(tmp.src.pict_format); |
|
- | 1911 | if (too_large(src->drawable.width, src->drawable.height)) { |
|
- | 1912 | BoxRec extents = box[0]; |
|
- | 1913 | int i; |
|
- | 1914 | ||
- | 1915 | for (i = 1; i < n; i++) { |
|
- | 1916 | if (box[i].x1 < extents.x1) |
|
- | 1917 | extents.x1 = box[i].x1; |
|
- | 1918 | if (box[i].y1 < extents.y1) |
|
- | 1919 | extents.y1 = box[i].y1; |
|
- | 1920 | ||
- | 1921 | if (box[i].x2 > extents.x2) |
|
- | 1922 | extents.x2 = box[i].x2; |
|
- | 1923 | if (box[i].y2 > extents.y2) |
|
- | 1924 | extents.y2 = box[i].y2; |
|
- | 1925 | } |
|
- | 1926 | ||
- | 1927 | if (!sna_render_pixmap_partial(sna, src, src_bo, &tmp.src, |
|
- | 1928 | extents.x1 + src_dx, |
|
- | 1929 | extents.y1 + src_dy, |
|
- | 1930 | extents.x2 - extents.x1, |
|
- | 1931 | extents.y2 - extents.y1)) |
|
- | 1932 | goto fallback_tiled_dst; |
|
- | 1933 | } else { |
|
- | 1934 | tmp.src.bo = kgem_bo_reference(src_bo); |
|
- | 1935 | tmp.src.width = src->drawable.width; |
|
- | 1936 | tmp.src.height = src->drawable.height; |
|
- | 1937 | tmp.src.offset[0] = tmp.src.offset[1] = 0; |
|
- | 1938 | tmp.src.scale[0] = 1.f/src->drawable.width; |
|
- | 1939 | tmp.src.scale[1] = 1.f/src->drawable.height; |
|
- | 1940 | } |
|
- | 1941 | ||
- | 1942 | tmp.is_affine = true; |
|
- | 1943 | tmp.floats_per_vertex = 3; |
|
- | 1944 | tmp.floats_per_rect = 9; |
|
- | 1945 | tmp.u.gen5.wm_kernel = WM_KERNEL; |
|
- | 1946 | tmp.u.gen5.ve_id = 2; |
|
- | 1947 | ||
- | 1948 | if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { |
|
- | 1949 | kgem_submit(&sna->kgem); |
|
- | 1950 | if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { |
|
- | 1951 | DBG(("%s: aperture check failed\n", __FUNCTION__)); |
|
- | 1952 | goto fallback_tiled_src; |
|
- | 1953 | } |
|
- | 1954 | } |
|
- | 1955 | ||
- | 1956 | dst_dx += tmp.dst.x; |
|
- | 1957 | dst_dy += tmp.dst.y; |
|
- | 1958 | tmp.dst.x = tmp.dst.y = 0; |
|
- | 1959 | ||
- | 1960 | src_dx += tmp.src.offset[0]; |
|
- | 1961 | src_dy += tmp.src.offset[1]; |
|
- | 1962 | ||
- | 1963 | gen5_copy_bind_surfaces(sna, &tmp); |
|
- | 1964 | gen5_align_vertex(sna, &tmp); |
|
- | 1965 | ||
- | 1966 | do { |
|
- | 1967 | int n_this_time; |
|
- | 1968 | ||
- | 1969 | n_this_time = gen5_get_rectangles(sna, &tmp, n, |
|
- | 1970 | gen5_copy_bind_surfaces); |
|
- | 1971 | n -= n_this_time; |
|
- | 1972 | ||
- | 1973 | do { |
|
- | 1974 | DBG((" (%d, %d) -> (%d, %d) + (%d, %d)\n", |
|
- | 1975 | box->x1 + src_dx, box->y1 + src_dy, |
|
- | 1976 | box->x1 + dst_dx, box->y1 + dst_dy, |
|
- | 1977 | box->x2 - box->x1, box->y2 - box->y1)); |
|
- | 1978 | OUT_VERTEX(box->x2 + dst_dx, box->y2 + dst_dy); |
|
- | 1979 | OUT_VERTEX_F((box->x2 + src_dx) * tmp.src.scale[0]); |
|
- | 1980 | OUT_VERTEX_F((box->y2 + src_dy) * tmp.src.scale[1]); |
|
- | 1981 | ||
- | 1982 | OUT_VERTEX(box->x1 + dst_dx, box->y2 + dst_dy); |
|
- | 1983 | OUT_VERTEX_F((box->x1 + src_dx) * tmp.src.scale[0]); |
|
- | 1984 | OUT_VERTEX_F((box->y2 + src_dy) * tmp.src.scale[1]); |
|
- | 1985 | ||
- | 1986 | OUT_VERTEX(box->x1 + dst_dx, box->y1 + dst_dy); |
|
- | 1987 | OUT_VERTEX_F((box->x1 + src_dx) * tmp.src.scale[0]); |
|
- | 1988 | OUT_VERTEX_F((box->y1 + src_dy) * tmp.src.scale[1]); |
|
- | 1989 | ||
- | 1990 | box++; |
|
- | 1991 | } while (--n_this_time); |
|
- | 1992 | } while (n); |
|
- | 1993 | ||
- | 1994 | gen4_vertex_flush(sna); |
|
- | 1995 | sna_render_composite_redirect_done(sna, &tmp); |
|
- | 1996 | kgem_bo_destroy(&sna->kgem, tmp.src.bo); |
|
- | 1997 | return true; |
|
- | 1998 | ||
- | 1999 | fallback_tiled_src: |
|
Line 1055... | Line 2000... | ||
1055 | tmp->mask.bo != NULL, |
2000 | kgem_bo_destroy(&sna->kgem, tmp.src.bo); |
1056 | tmp->has_component_alpha, |
2001 | fallback_tiled_dst: |
1057 | tmp->is_affine); |
2002 | if (tmp.redirect.real_bo) |
1058 | tmp->u.gen5.ve_id = gen4_choose_composite_emitter(tmp); |
2003 | kgem_bo_destroy(&sna->kgem, tmp.dst.bo); |
Line 1395... | Line 2340... | ||
1395 | 2340 | ||
1396 | state->general_bo = sna_static_stream_fini(sna, &general); |
2341 | state->general_bo = sna_static_stream_fini(sna, &general); |
1397 | return state->general_bo != NULL; |
2342 | return state->general_bo != NULL; |
Line 1398... | Line 2343... | ||
1398 | } |
2343 | } |
1399 | 2344 | ||
1400 | bool gen5_render_init(struct sna *sna) |
2345 | const char *gen5_render_init(struct sna *sna, const char *backend) |
1401 | { |
2346 | { |
Line 1402... | Line 2347... | ||
1402 | if (!gen5_render_setup(sna)) |
2347 | if (!gen5_render_setup(sna)) |
1403 | return false; |
2348 | return backend; |
1404 | 2349 | ||
Line -... | Line 2350... | ||
- | 2350 | sna->kgem.context_switch = gen5_render_context_switch; |
|
- | 2351 | sna->kgem.retire = gen5_render_retire; |
|
- | 2352 | sna->kgem.expire = gen5_render_expire; |
|
- | 2353 | ||
- | 2354 | #if 0 |
|
- | 2355 | #if !NO_COMPOSITE |
|
- | 2356 | sna->render.composite = gen5_render_composite; |
|
- | 2357 | sna->render.prefer_gpu |= PREFER_GPU_RENDER; |
|
- | 2358 | #endif |
|
- | 2359 | #if !NO_COMPOSITE_SPANS |
|
- | 2360 | sna->render.check_composite_spans = gen5_check_composite_spans; |
|
- | 2361 | sna->render.composite_spans = gen5_render_composite_spans; |
|
- | 2362 | if (sna->PciInfo->device_id == 0x0044) |
|
- | 2363 | sna->render.prefer_gpu |= PREFER_GPU_SPANS; |
|
- | 2364 | #endif |
|
- | 2365 | sna->render.video = gen5_render_video; |
|
- | 2366 | ||
- | 2367 | sna->render.copy_boxes = gen5_render_copy_boxes; |
|
- | 2368 | sna->render.copy = gen5_render_copy; |
|
- | 2369 | ||
- | 2370 | sna->render.fill_boxes = gen5_render_fill_boxes; |
|
1405 | sna->kgem.context_switch = gen5_render_context_switch; |
2371 | sna->render.fill = gen5_render_fill; |
- | 2372 | sna->render.fill_one = gen5_render_fill_one; |
|
Line 1406... | Line 2373... | ||
1406 | sna->kgem.retire = gen5_render_retire; |
2373 | #endif |
1407 | sna->kgem.expire = gen5_render_expire; |
2374 | |
1408 | 2375 | sna->render.blit_tex = gen5_blit_tex; |
|
Line 1409... | Line 2376... | ||
1409 | sna->render.blit_tex = gen5_blit_tex; |
2376 | sna->render.caps = HW_BIT_BLIT | HW_TEX_BLIT; |
1410 | 2377 | ||
- | 2378 | sna->render.flush = gen5_render_flush; |
|
- | 2379 | sna->render.reset = gen5_render_reset; |
|
- | 2380 | sna->render.fini = gen5_render_fini; |
|
- | 2381 | ||
- | 2382 | sna->render.max_3d_size = MAX_3D_SIZE; |
|
- | 2383 | sna->render.max_3d_pitch = 1 << 18; |
|
- | 2384 | return "Ironlake (gen5)"; |
|
- | 2385 | }; |
|
- | 2386 | ||
- | 2387 | static bool |
|
- | 2388 | gen5_blit_tex(struct sna *sna, |
|
- | 2389 | uint8_t op, bool scale, |
|
- | 2390 | PixmapPtr src, struct kgem_bo *src_bo, |
|
- | 2391 | PixmapPtr mask,struct kgem_bo *mask_bo, |
|
- | 2392 | PixmapPtr dst, struct kgem_bo *dst_bo, |
|
- | 2393 | int32_t src_x, int32_t src_y, |
|
- | 2394 | int32_t msk_x, int32_t msk_y, |
|
- | 2395 | int32_t dst_x, int32_t dst_y, |
|
- | 2396 | int32_t width, int32_t height, |
|
- | 2397 | struct sna_composite_op *tmp) |
|
- | 2398 | { |
|
- | 2399 | DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__, |
|
- | 2400 | width, height, sna->kgem.mode)); |
|
- | 2401 | ||
1411 | sna->render.flush = gen5_render_flush; |
2402 | tmp->op = PictOpSrc; |
- | 2403 | ||
- | 2404 | tmp->dst.pixmap = dst; |
|
- | 2405 | tmp->dst.bo = dst_bo; |
|
- | 2406 | tmp->dst.width = dst->drawable.width; |
|
- | 2407 | tmp->dst.height = dst->drawable.height; |
|
- | 2408 | tmp->dst.format = PICT_x8r8g8b8; |
|
- | 2409 | ||
- | 2410 | ||
- | 2411 | tmp->src.repeat = RepeatNone; |
|
- | 2412 | tmp->src.filter = PictFilterNearest; |
|
- | 2413 | tmp->src.is_affine = true; |
|
- | 2414 | ||
- | 2415 | tmp->src.bo = src_bo; |
|
- | 2416 | tmp->src.pict_format = PICT_x8r8g8b8; |
|
- | 2417 | tmp->src.card_format = gen5_get_card_format(tmp->src.pict_format); |
|
- | 2418 | tmp->src.width = src->drawable.width; |
|
- | 2419 | tmp->src.height = src->drawable.height; |
|
- | 2420 | ||
- | 2421 | ||
- | 2422 | tmp->is_affine = tmp->src.is_affine; |
|
- | 2423 | tmp->has_component_alpha = false; |
|
- | 2424 | tmp->need_magic_ca_pass = false; |
|
- | 2425 | ||
- | 2426 | tmp->mask.is_affine = true; |
|
- | 2427 | tmp->mask.repeat = SAMPLER_EXTEND_NONE; |
|
Line -... | Line 2428... | ||
- | 2428 | tmp->mask.filter = SAMPLER_FILTER_NEAREST; |
|
- | 2429 | tmp->mask.bo = mask_bo; |
|
- | 2430 | tmp->mask.pict_format = PIXMAN_a8; |
|
- | 2431 | tmp->mask.card_format = gen5_get_card_format(tmp->mask.pict_format); |
|
- | 2432 | tmp->mask.width = mask->drawable.width; |
|
- | 2433 | tmp->mask.height = mask->drawable.height; |
|
- | 2434 | ||
- | 2435 | if( scale ) |
|
- | 2436 | { |
|
- | 2437 | tmp->src.scale[0] = 1.f/width; |
|
- | 2438 | tmp->src.scale[1] = 1.f/height; |
|
- | 2439 | } |
|
- | 2440 | else |
|
- | 2441 | { |
|
- | 2442 | tmp->src.scale[0] = 1.f/src->drawable.width; |
|
- | 2443 | tmp->src.scale[1] = 1.f/src->drawable.height; |
|
- | 2444 | } |
|
- | 2445 | ||
- | 2446 | tmp->mask.scale[0] = 1.f/mask->drawable.width; |
|
- | 2447 | tmp->mask.scale[1] = 1.f/mask->drawable.height; |
|
- | 2448 | ||
- | 2449 | ||
- | 2450 | tmp->u.gen5.wm_kernel = |
|
- | 2451 | gen5_choose_composite_kernel(tmp->op, |
|
- | 2452 | tmp->mask.bo != NULL, |
|
- | 2453 | tmp->has_component_alpha, |
|
- | 2454 | tmp->is_affine); |
|
- | 2455 | tmp->u.gen5.ve_id = gen4_choose_composite_emitter(sna, tmp); |
|
- | 2456 | ||
- | 2457 | tmp->blt = gen5_render_composite_blt; |
|
- | 2458 | tmp->done = gen5_render_composite_done; |
|
- | 2459 | ||
1412 | sna->render.reset = gen5_render_reset; |
2460 | if (!kgem_check_bo(&sna->kgem, |
- | 2461 | tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) { |
|
1413 | sna->render.fini = gen5_render_fini; |
2462 | kgem_submit(&sna->kgem); |