diff options
Diffstat (limited to 'meta-xilinx-core/dynamic-layers')
22 files changed, 1457 insertions, 99 deletions
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/device-tree.bbappend b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/device-tree.bbappend index 7dcee565..7d374291 100644 --- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/device-tree.bbappend +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/device-tree.bbappend | |||
@@ -3,19 +3,19 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/files:" | |||
3 | # openamp.dtsi is in the WORKDIR | 3 | # openamp.dtsi is in the WORKDIR |
4 | DT_INCLUDE:append = " ${WORKDIR}" | 4 | DT_INCLUDE:append = " ${WORKDIR}" |
5 | 5 | ||
6 | do_configure[vardeps] += "ENABLE_OPENAMP_DTSI OPENAMP_EXTRA_OVERLAYS" | 6 | do_configure[vardeps] += "ENABLE_OPENAMP_DTSI OPENAMP_EXTRA_DT_INCLUDE_FILES" |
7 | 7 | ||
8 | OPENAMP_EXTRA_OVERLAYS:zynq = "zynq-openamp.dtsi" | 8 | OPENAMP_EXTRA_DT_INCLUDE_FILES ?= "" |
9 | OPENAMP_EXTRA_OVERLAYS:zynqmp = "zynqmp-openamp.dtsi" | 9 | OPENAMP_EXTRA_DT_INCLUDE_FILES:zynqmp = "zynqmp-openamp.dtsi" |
10 | OPENAMP_EXTRA_OVERLAYS:versal = "versal-openamp.dtsi" | 10 | OPENAMP_EXTRA_DT_INCLUDE_FILES:versal = "versal-openamp.dtsi" |
11 | OPENAMP_EXTRA_OVERLAYS:versal-net = "versal-net-openamp.dtsi" | 11 | OPENAMP_EXTRA_DT_INCLUDE_FILES:versal-net = "versal-net-openamp.dtsi" |
12 | 12 | ||
13 | def set_openamp_extra_overlays(d): | 13 | def set_openamp_extra_dt_include_files(d): |
14 | distro_features = d.getVar('DISTRO_FEATURES', True) | 14 | distro_features = d.getVar('DISTRO_FEATURES', True) |
15 | enable_openamp_dtsi = d.getVar('ENABLE_OPENAMP_DTSI') | 15 | enable_openamp_dtsi = d.getVar('ENABLE_OPENAMP_DTSI') |
16 | if 'openamp' in distro_features and enable_openamp_dtsi == '1': | 16 | if 'openamp' in distro_features and enable_openamp_dtsi == '1': |
17 | return ' ${OPENAMP_EXTRA_OVERLAYS}' | 17 | return ' ${OPENAMP_EXTRA_DT_INCLUDE_FILES}' |
18 | else: | 18 | else: |
19 | return '' | 19 | return '' |
20 | 20 | ||
21 | EXTRA_OVERLAYS:append = "${@set_openamp_extra_overlays(d)}" | 21 | EXTRA_DT_INCLUDE_FILES:append = "${@set_openamp_extra_dt_include_files(d)}" |
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-net-openamp.dtsi b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-net-openamp.dtsi index a918faf2..a1c939eb 100644 --- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-net-openamp.dtsi +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-net-openamp.dtsi | |||
@@ -53,7 +53,7 @@ | |||
53 | reg = <0x0 0xeba00000 0x0 0x10000>; | 53 | reg = <0x0 0xeba00000 0x0 0x10000>; |
54 | status = "okay"; | 54 | status = "okay"; |
55 | compatible = "mmio-sram"; | 55 | compatible = "mmio-sram"; |
56 | power-domain = <&versal_net_firmware 0x183180cb>; | 56 | power-domains = <&versal_net_firmware 0x183180cb>; |
57 | }; | 57 | }; |
58 | 58 | ||
59 | tcm_0b: tcm_0b@eba10000 { | 59 | tcm_0b: tcm_0b@eba10000 { |
@@ -61,7 +61,7 @@ | |||
61 | reg = <0x0 0xeba10000 0x0 0x8000>; | 61 | reg = <0x0 0xeba10000 0x0 0x8000>; |
62 | status = "okay"; | 62 | status = "okay"; |
63 | compatible = "mmio-sram"; | 63 | compatible = "mmio-sram"; |
64 | power-domain = <&versal_net_firmware 0x183180cc>; | 64 | power-domains = <&versal_net_firmware 0x183180cc>; |
65 | }; | 65 | }; |
66 | 66 | ||
67 | tcm_0c: tcm_0b@eba20000 { | 67 | tcm_0c: tcm_0b@eba20000 { |
@@ -69,7 +69,7 @@ | |||
69 | reg = <0x0 0xeba20000 0x0 0x8000>; | 69 | reg = <0x0 0xeba20000 0x0 0x8000>; |
70 | status = "okay"; | 70 | status = "okay"; |
71 | compatible = "mmio-sram"; | 71 | compatible = "mmio-sram"; |
72 | power-domain = <&versal_net_firmware 0x183180cd>; | 72 | power-domains = <&versal_net_firmware 0x183180cd>; |
73 | }; | 73 | }; |
74 | 74 | ||
75 | tcm_1a: tcm_0a@eba40000 { | 75 | tcm_1a: tcm_0a@eba40000 { |
@@ -77,7 +77,7 @@ | |||
77 | reg = <0x0 0xeba40000 0x0 0x10000>; | 77 | reg = <0x0 0xeba40000 0x0 0x10000>; |
78 | status = "okay"; | 78 | status = "okay"; |
79 | compatible = "mmio-sram"; | 79 | compatible = "mmio-sram"; |
80 | power-domain = <&versal_net_firmware 0x183180ce>; | 80 | power-domains = <&versal_net_firmware 0x183180ce>; |
81 | }; | 81 | }; |
82 | 82 | ||
83 | tcm_1b: tcm_0b@eba50000 { | 83 | tcm_1b: tcm_0b@eba50000 { |
@@ -85,7 +85,7 @@ | |||
85 | reg = <0x0 0xeba50000 0x0 0x8000>; | 85 | reg = <0x0 0xeba50000 0x0 0x8000>; |
86 | status = "okay"; | 86 | status = "okay"; |
87 | compatible = "mmio-sram"; | 87 | compatible = "mmio-sram"; |
88 | power-domain = <&versal_net_firmware 0x183180cf>; | 88 | power-domains = <&versal_net_firmware 0x183180cf>; |
89 | }; | 89 | }; |
90 | 90 | ||
91 | tcm_1c: tcm_0b@eba60000 { | 91 | tcm_1c: tcm_0b@eba60000 { |
@@ -93,7 +93,7 @@ | |||
93 | reg = <0x0 0xeba60000 0x0 0x8000>; | 93 | reg = <0x0 0xeba60000 0x0 0x8000>; |
94 | status = "okay"; | 94 | status = "okay"; |
95 | compatible = "mmio-sram"; | 95 | compatible = "mmio-sram"; |
96 | power-domain = <&versal_net_firmware 0x183180d0>; | 96 | power-domains = <&versal_net_firmware 0x183180d0>; |
97 | }; | 97 | }; |
98 | 98 | ||
99 | r52ss { | 99 | r52ss { |
@@ -110,7 +110,7 @@ | |||
110 | ranges; | 110 | ranges; |
111 | sram = <&tcm_0a>, <&tcm_0b>, <&tcm_0c>; | 111 | sram = <&tcm_0a>, <&tcm_0b>, <&tcm_0c>; |
112 | memory-region = <&rproc_0_reserved>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; | 112 | memory-region = <&rproc_0_reserved>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; |
113 | power-domain = <&versal_net_firmware 0x181100BF>; | 113 | power-domains = <&versal_net_firmware 0x181100BF>; |
114 | mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; | 114 | mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; |
115 | mbox-names = "tx", "rx"; | 115 | mbox-names = "tx", "rx"; |
116 | }; | 116 | }; |
@@ -121,7 +121,7 @@ | |||
121 | ranges; | 121 | ranges; |
122 | sram = <&tcm_1a>, <&tcm_1b>, <&tcm_1c>; | 122 | sram = <&tcm_1a>, <&tcm_1b>, <&tcm_1c>; |
123 | memory-region = <&rproc_1_reserved>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>; | 123 | memory-region = <&rproc_1_reserved>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>; |
124 | power-domain = <&versal_net_firmware 0x181100C0>; | 124 | power-domains = <&versal_net_firmware 0x181100C0>; |
125 | mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>; | 125 | mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>; |
126 | mbox-names = "tx", "rx"; | 126 | mbox-names = "tx", "rx"; |
127 | }; | 127 | }; |
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-openamp.dtsi b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-openamp.dtsi index 01e337c7..b21b4096 100644 --- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-openamp.dtsi +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/versal-openamp.dtsi | |||
@@ -52,7 +52,7 @@ | |||
52 | reg = <0x0 0xffe00000 0x0 0x10000>; | 52 | reg = <0x0 0xffe00000 0x0 0x10000>; |
53 | status = "okay"; | 53 | status = "okay"; |
54 | compatible = "mmio-sram"; | 54 | compatible = "mmio-sram"; |
55 | power-domain = <&versal_firmware 0x1831800b>; | 55 | power-domains = <&versal_firmware 0x1831800b>; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | tcm_0b: tcm_0b@ffe20000 { | 58 | tcm_0b: tcm_0b@ffe20000 { |
@@ -60,7 +60,7 @@ | |||
60 | reg = <0x0 0xffe20000 0x0 0x10000>; | 60 | reg = <0x0 0xffe20000 0x0 0x10000>; |
61 | status = "okay"; | 61 | status = "okay"; |
62 | compatible = "mmio-sram"; | 62 | compatible = "mmio-sram"; |
63 | power-domain = <&versal_firmware 0x1831800c>; | 63 | power-domains = <&versal_firmware 0x1831800c>; |
64 | }; | 64 | }; |
65 | 65 | ||
66 | tcm_1a: tcm_1a@ffe90000 { | 66 | tcm_1a: tcm_1a@ffe90000 { |
@@ -68,7 +68,7 @@ | |||
68 | reg = <0x0 0xffe90000 0x0 0x10000>; | 68 | reg = <0x0 0xffe90000 0x0 0x10000>; |
69 | status = "okay"; | 69 | status = "okay"; |
70 | compatible = "mmio-sram"; | 70 | compatible = "mmio-sram"; |
71 | power-domain = <&versal_firmware 0x1831800d>; | 71 | power-domains = <&versal_firmware 0x1831800d>; |
72 | }; | 72 | }; |
73 | 73 | ||
74 | tcm_1b: tcm_1b@ffeb0000 { | 74 | tcm_1b: tcm_1b@ffeb0000 { |
@@ -76,7 +76,7 @@ | |||
76 | reg = <0x0 0xffeb0000 0x0 0x10000>; | 76 | reg = <0x0 0xffeb0000 0x0 0x10000>; |
77 | status = "okay"; | 77 | status = "okay"; |
78 | compatible = "mmio-sram"; | 78 | compatible = "mmio-sram"; |
79 | power-domain = <&versal_firmware 0x1831800e>; | 79 | power-domains = <&versal_firmware 0x1831800e>; |
80 | }; | 80 | }; |
81 | 81 | ||
82 | rf5ss@ff9a0000 { | 82 | rf5ss@ff9a0000 { |
@@ -94,7 +94,7 @@ | |||
94 | ranges; | 94 | ranges; |
95 | sram = <&tcm_0a>, <&tcm_0b>; | 95 | sram = <&tcm_0a>, <&tcm_0b>; |
96 | memory-region = <&rproc_0_reserved>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; | 96 | memory-region = <&rproc_0_reserved>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; |
97 | power-domain = <&versal_firmware 0x18110005>; | 97 | power-domains = <&versal_firmware 0x18110005>; |
98 | mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; | 98 | mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; |
99 | mbox-names = "tx", "rx"; | 99 | mbox-names = "tx", "rx"; |
100 | }; | 100 | }; |
@@ -105,7 +105,7 @@ | |||
105 | ranges; | 105 | ranges; |
106 | sram = <&tcm_1a>, <&tcm_1b>; | 106 | sram = <&tcm_1a>, <&tcm_1b>; |
107 | memory-region = <&rproc_1_reserved>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>; | 107 | memory-region = <&rproc_1_reserved>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>; |
108 | power-domain = <&versal_firmware 0x18110006>; | 108 | power-domains = <&versal_firmware 0x18110006>; |
109 | mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>; | 109 | mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>; |
110 | mbox-names = "tx", "rx"; | 110 | mbox-names = "tx", "rx"; |
111 | }; | 111 | }; |
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynq-openamp-overlay.dts b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynq-openamp-overlay.dts deleted file mode 100644 index b5d238ff..00000000 --- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynq-openamp-overlay.dts +++ /dev/null | |||
@@ -1,13 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-License-Identifier: MIT | ||
3 | * | ||
4 | * dts overlay file for Zynq OpenAMP | ||
5 | * | ||
6 | * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | /dts-v1/; | ||
11 | /plugin/; | ||
12 | |||
13 | #include "zynq-openamp.dtsi" | ||
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynq-openamp.dtsi b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynq-openamp.dtsi deleted file mode 100644 index 0e822202..00000000 --- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynq-openamp.dtsi +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-License-Identifier: MIT | ||
3 | * | ||
4 | * dts file for Zynq OpenAMP | ||
5 | * | ||
6 | * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | &{/} { | ||
11 | reserved-memory { | ||
12 | #address-cells = <1>; | ||
13 | #size-cells = <1>; | ||
14 | ranges; | ||
15 | vdev0vring0: vdev0vring0@3e800000 { | ||
16 | no-map; | ||
17 | compatible = "shared-dma-pool"; | ||
18 | reg = <0x3e800000 0x4000>; | ||
19 | }; | ||
20 | vdev0vring1: vdev0vring1@3e804000 { | ||
21 | no-map; | ||
22 | compatible = "shared-dma-pool"; | ||
23 | reg = <0x3e804000 0x4000>; | ||
24 | }; | ||
25 | vdev0buffer: vdev0buffer@3e808000 { | ||
26 | no-map; | ||
27 | compatible = "shared-dma-pool"; | ||
28 | reg = <0x3e808000 0x100000>; | ||
29 | }; | ||
30 | rproc_0_reserved: rproc@3e000000 { | ||
31 | no-map; | ||
32 | compatible = "shared-dma-pool"; | ||
33 | reg = <0x3e000000 0x800000>; | ||
34 | }; | ||
35 | }; | ||
36 | |||
37 | remoteproc0: remoteproc@0 { | ||
38 | compatible = "xlnx,zynq_remoteproc"; | ||
39 | firmware = "firmware"; | ||
40 | memory-region = <&rproc_0_reserved>, <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>; | ||
41 | interrupt-parent = <&intc>; | ||
42 | }; | ||
43 | }; | ||
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynqmp-openamp.dtsi b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynqmp-openamp.dtsi index 8ef72656..1ad51fef 100644 --- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynqmp-openamp.dtsi +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/files/zynqmp-openamp.dtsi | |||
@@ -52,7 +52,7 @@ | |||
52 | reg = <0x0 0xffe00000 0x0 0x10000>; | 52 | reg = <0x0 0xffe00000 0x0 0x10000>; |
53 | status = "okay"; | 53 | status = "okay"; |
54 | compatible = "mmio-sram"; | 54 | compatible = "mmio-sram"; |
55 | power-domain = <&zynqmp_firmware 15>; | 55 | power-domains = <&zynqmp_firmware 15>; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | tcm_0b: tcm_0b@ffe20000 { | 58 | tcm_0b: tcm_0b@ffe20000 { |
@@ -60,14 +60,14 @@ | |||
60 | reg = <0x0 0xffe20000 0x0 0x10000>; | 60 | reg = <0x0 0xffe20000 0x0 0x10000>; |
61 | status = "okay"; | 61 | status = "okay"; |
62 | compatible = "mmio-sram"; | 62 | compatible = "mmio-sram"; |
63 | power-domain = <&zynqmp_firmware 16>; | 63 | power-domains = <&zynqmp_firmware 16>; |
64 | }; | 64 | }; |
65 | tcm_1a: tcm_0a@ffe90000 { | 65 | tcm_1a: tcm_0a@ffe90000 { |
66 | no-map; | 66 | no-map; |
67 | reg = <0x0 0xffe90000 0x0 0x10000>; | 67 | reg = <0x0 0xffe90000 0x0 0x10000>; |
68 | status = "okay"; | 68 | status = "okay"; |
69 | compatible = "mmio-sram"; | 69 | compatible = "mmio-sram"; |
70 | power-domain = <&zynqmp_firmware 17>; | 70 | power-domains = <&zynqmp_firmware 17>; |
71 | }; | 71 | }; |
72 | 72 | ||
73 | tcm_1b: tcm_0b@ffeb0000 { | 73 | tcm_1b: tcm_0b@ffeb0000 { |
@@ -75,7 +75,7 @@ | |||
75 | reg = <0x0 0xffeb0000 0x0 0x10000>; | 75 | reg = <0x0 0xffeb0000 0x0 0x10000>; |
76 | status = "okay"; | 76 | status = "okay"; |
77 | compatible = "mmio-sram"; | 77 | compatible = "mmio-sram"; |
78 | power-domain = <&zynqmp_firmware 18>; | 78 | power-domains = <&zynqmp_firmware 18>; |
79 | }; | 79 | }; |
80 | rf5ss@ff9a0000 { | 80 | rf5ss@ff9a0000 { |
81 | compatible = "xlnx,zynqmp-r5-remoteproc"; | 81 | compatible = "xlnx,zynqmp-r5-remoteproc"; |
@@ -92,7 +92,7 @@ | |||
92 | ranges; | 92 | ranges; |
93 | sram = <&tcm_0a>, <&tcm_0b>; | 93 | sram = <&tcm_0a>, <&tcm_0b>; |
94 | memory-region = <&rproc_0_reserved>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; | 94 | memory-region = <&rproc_0_reserved>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; |
95 | power-domain = <&zynqmp_firmware 7>; | 95 | power-domains = <&zynqmp_firmware 7>; |
96 | mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; | 96 | mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; |
97 | mbox-names = "tx", "rx"; | 97 | mbox-names = "tx", "rx"; |
98 | }; | 98 | }; |
@@ -103,7 +103,7 @@ | |||
103 | ranges; | 103 | ranges; |
104 | sram = <&tcm_1a>, <&tcm_1b>; | 104 | sram = <&tcm_1a>, <&tcm_1b>; |
105 | memory-region = <&rproc_1_reserved>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>; | 105 | memory-region = <&rproc_1_reserved>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>; |
106 | power-domain = <&zynqmp_firmware 8>; | 106 | power-domains = <&zynqmp_firmware 8>; |
107 | mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>; | 107 | mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>; |
108 | mbox-names = "tx", "rx"; | 108 | mbox-names = "tx", "rx"; |
109 | }; | 109 | }; |
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/open-amp-device-tree.bb b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/open-amp-device-tree.bb index 9f481fec..7b626ee3 100644 --- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/open-amp-device-tree.bb +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-bsp/device-tree/open-amp-device-tree.bb | |||
@@ -5,8 +5,6 @@ LICENSE = "MIT" | |||
5 | LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" | 5 | LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" |
6 | 6 | ||
7 | SRC_URI = " \ | 7 | SRC_URI = " \ |
8 | file://zynq-openamp.dtsi \ | ||
9 | file://zynq-openamp-overlay.dts \ | ||
10 | file://zynqmp-openamp.dtsi \ | 8 | file://zynqmp-openamp.dtsi \ |
11 | file://zynqmp-openamp-overlay.dts \ | 9 | file://zynqmp-openamp-overlay.dts \ |
12 | file://versal-openamp.dtsi \ | 10 | file://versal-openamp.dtsi \ |
@@ -18,7 +16,6 @@ SRC_URI = " \ | |||
18 | # We don't have anything to include from the kernel | 16 | # We don't have anything to include from the kernel |
19 | KERNEL_INCLUDE = "" | 17 | KERNEL_INCLUDE = "" |
20 | 18 | ||
21 | COMPATIBLE_MACHINE:zynq = "${MACHINE}" | ||
22 | COMPATIBLE_MACHINE:zynqmp = "${MACHINE}" | 19 | COMPATIBLE_MACHINE:zynqmp = "${MACHINE}" |
23 | COMPATIBLE_MACHINE:versal = "${MACHINE}" | 20 | COMPATIBLE_MACHINE:versal = "${MACHINE}" |
24 | COMPATIBLE_MACHINE:versal-net = "${MACHINE}" | 21 | COMPATIBLE_MACHINE:versal-net = "${MACHINE}" |
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-core/packagegroups/packagegroup-openamp.bb b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-core/packagegroups/packagegroup-openamp.bb new file mode 100644 index 00000000..13992ebc --- /dev/null +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-core/packagegroups/packagegroup-openamp.bb | |||
@@ -0,0 +1,38 @@ | |||
1 | DESCRIPTION = "OpenAMP supported packages" | ||
2 | |||
3 | PACKAGE_ARCH = "${MACHINE_ARCH}" | ||
4 | |||
5 | # We don't support Zynq | ||
6 | COMPATIBLE_MACHINE:zynq = "$^" | ||
7 | |||
8 | inherit packagegroup features_check | ||
9 | |||
10 | REQUIRED_DISTRO_FEATURES = "openamp" | ||
11 | |||
12 | PACKAGES = "\ | ||
13 | packagegroup-openamp-echo-test \ | ||
14 | packagegroup-openamp-matrix-mul \ | ||
15 | packagegroup-openamp-rpc-demo \ | ||
16 | packagegroup-openamp \ | ||
17 | " | ||
18 | |||
19 | RDEPENDS:${PN}-echo-test = "rpmsg-echo-test" | ||
20 | RDEPENDS:${PN}-echo-test:append:zcu102-zynqmp = " openamp-fw-echo-testd" | ||
21 | |||
22 | RDEPENDS:${PN}-matrix-mul = "rpmsg-mat-mul" | ||
23 | RDEPENDS:${PN}-matrix-mul:append:zcu102-zynqmp = " openamp-fw-mat-muld" | ||
24 | |||
25 | RDEPENDS:${PN}-rpc-demo = "rpmsg-proxy-app" | ||
26 | RDEPENDS:${PN}-rpc-demo:append:zcu102-zynqmp = " openamp-fw-rpc-demo" | ||
27 | |||
28 | RDEPENDS:${PN}:append = " ${@'open-amp-device-tree' if d.getVar('ENABLE_OPENAMP_DTSI') != '1' else ''}" | ||
29 | |||
30 | RDEPENDS:${PN}:append = " \ | ||
31 | libmetal \ | ||
32 | libmetal-demos \ | ||
33 | open-amp \ | ||
34 | open-amp-demos \ | ||
35 | packagegroup-openamp-echo-test \ | ||
36 | packagegroup-openamp-matrix-mul \ | ||
37 | packagegroup-openamp-rpc-demo \ | ||
38 | " | ||
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.1.bb b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.1.bb index a03912d7..9ca9cbc1 100644 --- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.1.bb +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.1.bb | |||
@@ -1,8 +1,8 @@ | |||
1 | SRCBRANCH ?= "2024" | 1 | SRCBRANCH ?= "2024" |
2 | SRCREV = "e2fdb4fecbebe41b4cd1c0b4fbfa3496bcded485" | 2 | SRCREV = "9e9997221ddd335c31cf881edf7026c762024a58" |
3 | BRANCH = "xlnx_rel_v2024.1" | 3 | BRANCH = "xlnx_rel_v2024.1" |
4 | LIC_FILES_CHKSUM ?= "file://LICENSE.md;md5=f4d5df0f12dcea1b1a0124219c0dbab4" | 4 | LIC_FILES_CHKSUM ?= "file://LICENSE.md;md5=f4d5df0f12dcea1b1a0124219c0dbab4" |
5 | PV = "${SRCBRANCH}+git" | 5 | PV .= "+git" |
6 | 6 | ||
7 | REPO = "git://github.com/Xilinx/libmetal.git;protocol=https" | 7 | REPO = "git://github.com/Xilinx/libmetal.git;protocol=https" |
8 | 8 | ||
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.2.bb b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.2.bb new file mode 100644 index 00000000..bcde904d --- /dev/null +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/libmetal/libmetal-xlnx_v2024.2.bb | |||
@@ -0,0 +1,16 @@ | |||
1 | SRCBRANCH ?= "2024" | ||
2 | SRCREV = "e2fdb4fecbebe41b4cd1c0b4fbfa3496bcded485" | ||
3 | BRANCH = "xlnx_rel_v2024.2" | ||
4 | LIC_FILES_CHKSUM ?= "file://LICENSE.md;md5=f4d5df0f12dcea1b1a0124219c0dbab4" | ||
5 | PV .= "+git" | ||
6 | |||
7 | REPO = "git://github.com/Xilinx/libmetal.git;protocol=https" | ||
8 | |||
9 | include ${LAYER_PATH_openamp-layer}/recipes-openamp/libmetal/libmetal.inc | ||
10 | include ${LAYER_PATH_openamp-layer}/vendor/xilinx/recipes-openamp/libmetal/libmetal-xlnx.inc | ||
11 | |||
12 | RPROVIDES:${PN}-dbg += "libmetal-dbg" | ||
13 | RPROVIDES:${PN}-dev += "libmetal-dev" | ||
14 | RPROVIDES:${PN}-lic += "libmetal-lic" | ||
15 | RPROVIDES:${PN}-src += "libmetal-src" | ||
16 | RPROVIDES:${PN}-staticdev += "libmetal-staticdev" | ||
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.1.bb b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.1.bb index 94535abc..29d4bc4f 100644 --- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.1.bb +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.1.bb | |||
@@ -1,8 +1,8 @@ | |||
1 | SRCBRANCH ?= "2024" | 1 | SRCBRANCH ?= "2024" |
2 | SRCREV = "dbf0857389190f4c4cedfb77bd1f9bdd7ab404f3" | 2 | SRCREV = "699ad2c5b9236d61aae1b89e2857361db1bfeb95" |
3 | BRANCH = "xlnx_rel_v2024.1" | 3 | BRANCH = "xlnx_rel_v2024.1" |
4 | LIC_FILES_CHKSUM ?= "file://LICENSE.md;md5=ab88daf995c0bd0071c2e1e55f3d3505" | 4 | LIC_FILES_CHKSUM ?= "file://LICENSE.md;md5=ab88daf995c0bd0071c2e1e55f3d3505" |
5 | PV = "${SRCBRANCH}+git" | 5 | PV .= "+git" |
6 | REPO = "git://github.com/Xilinx/open-amp.git;protocol=https" | 6 | REPO = "git://github.com/Xilinx/open-amp.git;protocol=https" |
7 | 7 | ||
8 | include ${LAYER_PATH_openamp-layer}/recipes-openamp/open-amp/open-amp.inc | 8 | include ${LAYER_PATH_openamp-layer}/recipes-openamp/open-amp/open-amp.inc |
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.2.bb b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.2.bb new file mode 100644 index 00000000..06c2ecbc --- /dev/null +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-openamp/open-amp/open-amp-xlnx_v2024.2.bb | |||
@@ -0,0 +1,16 @@ | |||
1 | SRCBRANCH ?= "2024" | ||
2 | SRCREV = "47caef116ccbf5d5a9778082a98fe8f3710b549c" | ||
3 | BRANCH = "xlnx_rel_v2024.2" | ||
4 | LIC_FILES_CHKSUM ?= "file://LICENSE.md;md5=ab88daf995c0bd0071c2e1e55f3d3505" | ||
5 | PV .= "+git" | ||
6 | REPO = "git://github.com/Xilinx/open-amp.git;protocol=https" | ||
7 | |||
8 | include ${LAYER_PATH_openamp-layer}/recipes-openamp/open-amp/open-amp.inc | ||
9 | require ${LAYER_PATH_openamp-layer}/vendor/xilinx/recipes-openamp/open-amp/open-amp-xlnx.inc | ||
10 | |||
11 | RPROVIDES:${PN}-dbg += "open-amp-dbg" | ||
12 | RPROVIDES:${PN}-dev += "open-amp-dev" | ||
13 | RPROVIDES:${PN}-lic += "open-amp-lic" | ||
14 | RPROVIDES:${PN}-src += "open-amp-src" | ||
15 | RPROVIDES:${PN}-staticdev += "open-amp-staticdev" | ||
16 | |||
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_%.bbappend b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202210.2.13.479.bbappend index 0e7f3693..0e7f3693 100644 --- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_%.bbappend +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202210.2.13.479.bbappend | |||
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202220.2.14.0.bbappend b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202220.2.14.0.bbappend new file mode 100644 index 00000000..0e7f3693 --- /dev/null +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202220.2.14.0.bbappend | |||
@@ -0,0 +1,8 @@ | |||
1 | # Use libmetal for systems with AIE | ||
2 | # For versal devices with the ai-engine | ||
3 | PACKAGE_ARCH_orig := "${PACKAGE_ARCH}" | ||
4 | PACKAGE_ARCH = "${@bb.utils.contains('MACHINE_FEATURES', 'aie', '${MACHINE_ARCH}', '${PACKAGE_ARCH_orig}', d)}" | ||
5 | EXTRA_OECMAKE .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_AIE_BUILD=true', '', d)}" | ||
6 | TARGET_CXXFLAGS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_ENABLE_AIE -DFAL_LINUX=on', '', d)}" | ||
7 | DEPENDS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal', '', d)}" | ||
8 | RDEPENDS:${PN} += "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal', '', d)}" | ||
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202310.2.15.0.bbappend b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202310.2.15.0.bbappend index 362dc45a..a7ab6bb8 100644 --- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202310.2.15.0.bbappend +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202310.2.15.0.bbappend | |||
@@ -1,2 +1,9 @@ | |||
1 | # Older xrt requires a manual dependency on libmetal | 1 | # Use libmetal for systems with AIE |
2 | DEPENDS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libmetal', '', d)}" | 2 | # For versal devices with the ai-engine |
3 | PACKAGE_ARCH_orig := "${PACKAGE_ARCH}" | ||
4 | PACKAGE_ARCH = "${@bb.utils.contains('MACHINE_FEATURES', 'aie', '${MACHINE_ARCH}', '${PACKAGE_ARCH_orig}', d)}" | ||
5 | EXTRA_OECMAKE .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_AIE_BUILD=true', '', d)}" | ||
6 | TARGET_CXXFLAGS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_ENABLE_AIE -DFAL_LINUX=on', '', d)}" | ||
7 | DEPENDS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal libmetal', '', d)}" | ||
8 | RDEPENDS:${PN} += "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal', '', d)}" | ||
9 | |||
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202320.2.16.0.bbappend b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202320.2.16.0.bbappend index 362dc45a..a7ab6bb8 100644 --- a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202320.2.16.0.bbappend +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202320.2.16.0.bbappend | |||
@@ -1,2 +1,9 @@ | |||
1 | # Older xrt requires a manual dependency on libmetal | 1 | # Use libmetal for systems with AIE |
2 | DEPENDS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libmetal', '', d)}" | 2 | # For versal devices with the ai-engine |
3 | PACKAGE_ARCH_orig := "${PACKAGE_ARCH}" | ||
4 | PACKAGE_ARCH = "${@bb.utils.contains('MACHINE_FEATURES', 'aie', '${MACHINE_ARCH}', '${PACKAGE_ARCH_orig}', d)}" | ||
5 | EXTRA_OECMAKE .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_AIE_BUILD=true', '', d)}" | ||
6 | TARGET_CXXFLAGS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_ENABLE_AIE -DFAL_LINUX=on', '', d)}" | ||
7 | DEPENDS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal libmetal', '', d)}" | ||
8 | RDEPENDS:${PN} += "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal', '', d)}" | ||
9 | |||
diff --git a/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202410.2.17.319.bbappend b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202410.2.17.319.bbappend new file mode 100644 index 00000000..0e7f3693 --- /dev/null +++ b/meta-xilinx-core/dynamic-layers/openamp-layer/recipes-xrt/xrt/xrt_202410.2.17.319.bbappend | |||
@@ -0,0 +1,8 @@ | |||
1 | # Use libmetal for systems with AIE | ||
2 | # For versal devices with the ai-engine | ||
3 | PACKAGE_ARCH_orig := "${PACKAGE_ARCH}" | ||
4 | PACKAGE_ARCH = "${@bb.utils.contains('MACHINE_FEATURES', 'aie', '${MACHINE_ARCH}', '${PACKAGE_ARCH_orig}', d)}" | ||
5 | EXTRA_OECMAKE .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_AIE_BUILD=true', '', d)}" | ||
6 | TARGET_CXXFLAGS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' -DXRT_ENABLE_AIE -DFAL_LINUX=on', '', d)}" | ||
7 | DEPENDS .= "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal', '', d)}" | ||
8 | RDEPENDS:${PN} += "${@bb.utils.contains('MACHINE_FEATURES', 'aie', ' libxaiengine aiefal', '', d)}" | ||
diff --git a/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armosc-Accelerate-picture-composition.patch b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armosc-Accelerate-picture-composition.patch new file mode 100644 index 00000000..3fa4d6ec --- /dev/null +++ b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armosc-Accelerate-picture-composition.patch | |||
@@ -0,0 +1,1058 @@ | |||
1 | From 015f8a54f7e5a754e1cefba1aa7b1f6992a8aa9b Mon Sep 17 00:00:00 2001 | ||
2 | From: Anatoliy Klymenko <anatoliy.klymenko@amd.com> | ||
3 | Date: Tue, 16 Jul 2024 19:48:47 +0000 | ||
4 | Subject: [PATCH] xf86-video-armosc: Accelerate picture composition | ||
5 | |||
6 | Introduce Repulsion - simplistic GPU accelerated compositor to back RandR | ||
7 | display manipulation features. This library is inspired by Glamor extension | ||
8 | https://www.freedesktop.org/wiki/Software/Glamor/. Unfortunately Glamor | ||
9 | doesn't work as is on ARM Mali-400 MP due to the lack of required features | ||
10 | and several bugs in Mali EGL/GLES implementation. | ||
11 | |||
12 | Install and manage picture compositor hooks. | ||
13 | |||
14 | Provide access to dma-buf fd from ARSOC buffer object. | ||
15 | |||
16 | Attach shadow buffer object to corresponding pixmap. | ||
17 | |||
18 | Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com> | ||
19 | --- | ||
20 | src/Makefile.am | 3 +- | ||
21 | src/armsoc_driver.c | 145 ++++++++++ | ||
22 | src/armsoc_driver.h | 7 + | ||
23 | src/armsoc_dumb.c | 8 + | ||
24 | src/armsoc_dumb.h | 1 + | ||
25 | src/armsoc_exa.c | 18 +- | ||
26 | src/armsoc_repulsion.c | 624 +++++++++++++++++++++++++++++++++++++++++ | ||
27 | src/armsoc_repulsion.h | 67 +++++ | ||
28 | 8 files changed, 867 insertions(+), 6 deletions(-) | ||
29 | create mode 100644 src/armsoc_repulsion.c | ||
30 | create mode 100644 src/armsoc_repulsion.h | ||
31 | |||
32 | diff --git a/src/Makefile.am b/src/Makefile.am | ||
33 | index db5f110..cd4f795 100644 | ||
34 | --- a/src/Makefile.am | ||
35 | +++ b/src/Makefile.am | ||
36 | @@ -38,7 +38,7 @@ ERROR_CFLAGS = -Werror -Wall -Wdeclaration-after-statement -Wvla \ | ||
37 | AM_CFLAGS = @XORG_CFLAGS@ $(ERROR_CFLAGS) | ||
38 | armsoc_drv_la_LTLIBRARIES = armsoc_drv.la | ||
39 | armsoc_drv_la_LDFLAGS = -module -avoid-version -no-undefined | ||
40 | -armsoc_drv_la_LIBADD = @XORG_LIBS@ | ||
41 | +armsoc_drv_la_LIBADD = -lMali @XORG_LIBS@ | ||
42 | armsoc_drv_ladir = @moduledir@/drivers | ||
43 | DRMMODE_SRCS = drmmode_exynos/drmmode_exynos.c \ | ||
44 | drmmode_pl111/drmmode_pl111.c \ | ||
45 | @@ -54,4 +54,5 @@ armsoc_drv_la_SOURCES = \ | ||
46 | armsoc_dri2.c \ | ||
47 | armsoc_driver.c \ | ||
48 | armsoc_dumb.c \ | ||
49 | + armsoc_repulsion.c \ | ||
50 | $(DRMMODE_SRCS) | ||
51 | diff --git a/src/armsoc_driver.c b/src/armsoc_driver.c | ||
52 | index a4a1ba3..f5b8f21 100644 | ||
53 | --- a/src/armsoc_driver.c | ||
54 | +++ b/src/armsoc_driver.c | ||
55 | @@ -42,6 +42,7 @@ | ||
56 | #include <pixman.h> | ||
57 | |||
58 | #include "armsoc_driver.h" | ||
59 | +#include "armsoc_repulsion.h" | ||
60 | |||
61 | #include "micmap.h" | ||
62 | |||
63 | @@ -971,6 +972,138 @@ ARMSOCAccelInit(ScreenPtr pScreen) | ||
64 | pARMSOC->dri = FALSE; | ||
65 | } | ||
66 | |||
67 | +#define ARMSOC_ACCEL_MIN_DIMS 200 | ||
68 | + | ||
69 | +/** | ||
70 | + * Classify compositor input to figure out if we can accelerate composition | ||
71 | + */ | ||
72 | +static Bool | ||
73 | +ARMSOCCanAccelerateComposition(CARD8 op, | ||
74 | + PicturePtr src, | ||
75 | + PicturePtr mask, | ||
76 | + PicturePtr dest, | ||
77 | + CARD16 width, | ||
78 | + CARD16 height) | ||
79 | +{ | ||
80 | + /* We only support source to destination pixmap copy */ | ||
81 | + if (op != PictOpSrc) | ||
82 | + return FALSE; | ||
83 | + | ||
84 | + /* | ||
85 | + * Don't accelerate small picture compositions, e.g. toolbars, cursor, | ||
86 | + * icons, etc. | ||
87 | + */ | ||
88 | + if (width < ARMSOC_ACCEL_MIN_DIMS || height < ARMSOC_ACCEL_MIN_DIMS) | ||
89 | + return FALSE; | ||
90 | + | ||
91 | + /* Check source picture */ | ||
92 | + if (!src || !src->pDrawable) | ||
93 | + return FALSE; | ||
94 | + | ||
95 | + /* Check destination picture constraints */ | ||
96 | + if (!dest || !dest->pDrawable || dest->pDrawable->type != DRAWABLE_PIXMAP) | ||
97 | + return FALSE; | ||
98 | + | ||
99 | + /* We don't support masking */ | ||
100 | + if (mask) | ||
101 | + return FALSE; | ||
102 | + | ||
103 | + /* | ||
104 | + * We expect source transform to be assigned, otherwise there is not much | ||
105 | + * to accelerate | ||
106 | + */ | ||
107 | + if (!src->transform) | ||
108 | + return FALSE; | ||
109 | + | ||
110 | + /* We expect buffer object to be assigned to source */ | ||
111 | + if (!draw2pix(src->pDrawable)) | ||
112 | + return FALSE; | ||
113 | + | ||
114 | + /* We expect buffer object to be assigned to destination */ | ||
115 | + if (!draw2pix(dest->pDrawable)) | ||
116 | + return FALSE; | ||
117 | + | ||
118 | + return TRUE; | ||
119 | +} | ||
120 | + | ||
121 | +/** | ||
122 | + * This callback will be invoked every time xserver needs to combine 2 | ||
123 | + * pictures. Our special interest is the case when we need to blit draw buffer | ||
124 | + * into shadow buffer while performing rotation or reflection. Without | ||
125 | + * acceleration such composition will end up in tons of matrix multiplications | ||
126 | + * for every pixel, which is obviously very slow. Here we need to detect such | ||
127 | + * cases and accelerate the composition on the GPU. | ||
128 | + */ | ||
129 | +static void | ||
130 | +ARMSOCComposite(CARD8 op, | ||
131 | + PicturePtr src, | ||
132 | + PicturePtr mask, | ||
133 | + PicturePtr dest, | ||
134 | + INT16 x_src, | ||
135 | + INT16 y_src, | ||
136 | + INT16 x_mask, | ||
137 | + INT16 y_mask, | ||
138 | + INT16 x_dest, | ||
139 | + INT16 y_dest, | ||
140 | + CARD16 width, | ||
141 | + CARD16 height) | ||
142 | +{ | ||
143 | + ScreenPtr pScreen = dest->pDrawable->pScreen; | ||
144 | + PictureScreenPtr ps = GetPictureScreen(pScreen); | ||
145 | + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); | ||
146 | + struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn); | ||
147 | + struct armsoc_bo *src_bo = NULL, *dest_bo = NULL; | ||
148 | + float xform_matrix[3][3] = {}; | ||
149 | + | ||
150 | + Bool can_accelerate = | ||
151 | + ARMSOCCanAccelerateComposition(op, src, mask, dest, width, height); | ||
152 | + | ||
153 | + | ||
154 | + if (can_accelerate) { | ||
155 | + /* Transpose, scale & adjust transformation matrix */ | ||
156 | + int x, y; | ||
157 | + for (y = 0; y < 3; ++y) | ||
158 | + for (x = 0; x < 3; ++x) | ||
159 | + xform_matrix[x][y] = | ||
160 | + (float)src->transform->matrix[y][x] / 65536.f; | ||
161 | + /* | ||
162 | + * TODO: Figure out coordinate system where these sins make sence, | ||
163 | + * insted of just reversing them | ||
164 | + */ | ||
165 | + xform_matrix[0][1] = -xform_matrix[0][1]; | ||
166 | + xform_matrix[1][0] = -xform_matrix[1][0]; | ||
167 | + } | ||
168 | + | ||
169 | + /* Extract source buffer object */ | ||
170 | + if (can_accelerate) { | ||
171 | + PixmapPtr pm = draw2pix(src->pDrawable); | ||
172 | + src_bo = ARMSOCPixmapBo(pm); | ||
173 | + } | ||
174 | + | ||
175 | + /* Extract destination buffer object */ | ||
176 | + if (can_accelerate) { | ||
177 | + PixmapPtr pm = draw2pix(dest->pDrawable); | ||
178 | + dest_bo = ARMSOCPixmapBo(pm); | ||
179 | + } | ||
180 | + | ||
181 | + if (can_accelerate && | ||
182 | + armsoc_repulsion_composite(pARMSOC->repulsion, | ||
183 | + src_bo, | ||
184 | + dest_bo, | ||
185 | + xform_matrix)) { | ||
186 | + } else { | ||
187 | + /* Fallback to saved compositor if accelerated composition fails */ | ||
188 | + pARMSOC->composite_proc(op, src, mask, dest, | ||
189 | + x_src, y_src, x_mask, y_mask, | ||
190 | + x_dest, y_dest, width, height); | ||
191 | + } | ||
192 | + | ||
193 | + if (ps->Composite != ARMSOCComposite) { | ||
194 | + pARMSOC->composite_proc = ps->Composite; | ||
195 | + ps->Composite = ARMSOCComposite; | ||
196 | + } | ||
197 | +} | ||
198 | + | ||
199 | /** | ||
200 | * The driver's ScreenInit() function, called at the start of each server | ||
201 | * generation. Fill in pScreen, map the frame buffer, save state, | ||
202 | @@ -986,6 +1119,7 @@ ARMSOCScreenInit(SCREEN_INIT_ARGS_DECL) | ||
203 | struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn); | ||
204 | VisualPtr visual; | ||
205 | xf86CrtcConfigPtr xf86_config; | ||
206 | + PictureScreenPtr ps; | ||
207 | int j; | ||
208 | const char *fbdev; | ||
209 | int depth; | ||
210 | @@ -1174,6 +1308,13 @@ ARMSOCScreenInit(SCREEN_INIT_ARGS_DECL) | ||
211 | pARMSOC->lockFD = -1; | ||
212 | } | ||
213 | |||
214 | + pARMSOC->repulsion = armsoc_repulsion_init(); | ||
215 | + | ||
216 | + ps = GetPictureScreen(pScreen); | ||
217 | + pARMSOC->composite_proc = ps->Composite; | ||
218 | + | ||
219 | + ps->Composite = ARMSOCComposite; | ||
220 | + | ||
221 | TRACE_EXIT(); | ||
222 | return TRUE; | ||
223 | |||
224 | @@ -1250,6 +1391,8 @@ ARMSOCCloseScreen(CLOSE_SCREEN_ARGS_DECL) | ||
225 | |||
226 | TRACE_ENTER(); | ||
227 | |||
228 | + armsoc_repulsion_release(pARMSOC->repulsion); | ||
229 | + | ||
230 | drmmode_screen_fini(pScrn); | ||
231 | drmmode_cursor_fini(pScreen); | ||
232 | |||
233 | @@ -1294,6 +1437,8 @@ ARMSOCCloseScreen(CLOSE_SCREEN_ARGS_DECL) | ||
234 | pARMSOC->lockFD = -1; | ||
235 | } | ||
236 | |||
237 | + armsoc_repulsion_release(pARMSOC->repulsion); | ||
238 | + | ||
239 | TRACE_EXIT(); | ||
240 | |||
241 | return ret; | ||
242 | diff --git a/src/armsoc_driver.h b/src/armsoc_driver.h | ||
243 | index eae76ca..20b0f80 100644 | ||
244 | --- a/src/armsoc_driver.h | ||
245 | +++ b/src/armsoc_driver.h | ||
246 | @@ -38,6 +38,7 @@ | ||
247 | #include "xf86drm.h" | ||
248 | #include <errno.h> | ||
249 | #include "armsoc_exa.h" | ||
250 | +#include "armsoc_repulsion.h" | ||
251 | |||
252 | /* Apparently not used by X server */ | ||
253 | #define ARMSOC_VERSION 1000 | ||
254 | @@ -183,6 +184,12 @@ struct ARMSOCRec { | ||
255 | /* Size of the swap chain. Set to 1 if DRI2SwapLimit unsupported, | ||
256 | * driNumBufs if early display enabled, otherwise driNumBufs-1 */ | ||
257 | unsigned int swap_chain_size; | ||
258 | + | ||
259 | + /* GPU accelerated picture compositor, AKA Repulsion */ | ||
260 | + struct ARMSOCRepulsion *repulsion; | ||
261 | + | ||
262 | + /* SW (pixman based) picture compositor fallback */ | ||
263 | + CompositeProcPtr composite_proc; | ||
264 | }; | ||
265 | |||
266 | /* | ||
267 | diff --git a/src/armsoc_dumb.c b/src/armsoc_dumb.c | ||
268 | index 7e6dbd9..3c16ed2 100644 | ||
269 | --- a/src/armsoc_dumb.c | ||
270 | +++ b/src/armsoc_dumb.c | ||
271 | @@ -130,6 +130,14 @@ int armsoc_bo_has_dmabuf(struct armsoc_bo *bo) | ||
272 | return bo->dmabuf >= 0; | ||
273 | } | ||
274 | |||
275 | +int armsoc_bo_get_dmabuf(struct armsoc_bo *bo) | ||
276 | +{ | ||
277 | + if (!armsoc_bo_has_dmabuf(bo)) | ||
278 | + armsoc_bo_set_dmabuf(bo); | ||
279 | + | ||
280 | + return bo->dmabuf; | ||
281 | +} | ||
282 | + | ||
283 | struct armsoc_bo *armsoc_bo_new_with_dim(struct armsoc_device *dev, | ||
284 | uint32_t width, uint32_t height, uint8_t depth, | ||
285 | uint8_t bpp, enum armsoc_buf_type buf_type) | ||
286 | diff --git a/src/armsoc_dumb.h b/src/armsoc_dumb.h | ||
287 | index a299ccf..3b687c7 100644 | ||
288 | --- a/src/armsoc_dumb.h | ||
289 | +++ b/src/armsoc_dumb.h | ||
290 | @@ -89,6 +89,7 @@ void armsoc_bo_unreference(struct armsoc_bo *bo); | ||
291 | int armsoc_bo_set_dmabuf(struct armsoc_bo *bo); | ||
292 | void armsoc_bo_clear_dmabuf(struct armsoc_bo *bo); | ||
293 | int armsoc_bo_has_dmabuf(struct armsoc_bo *bo); | ||
294 | +int armsoc_bo_get_dmabuf(struct armsoc_bo *bo); | ||
295 | int armsoc_bo_clear(struct armsoc_bo *bo); | ||
296 | int armsoc_bo_rm_fb(struct armsoc_bo *bo); | ||
297 | int armsoc_bo_resize(struct armsoc_bo *bo, uint32_t new_width, | ||
298 | diff --git a/src/armsoc_exa.c b/src/armsoc_exa.c | ||
299 | index a310727..7edf0ac 100644 | ||
300 | --- a/src/armsoc_exa.c | ||
301 | +++ b/src/armsoc_exa.c | ||
302 | @@ -161,10 +161,16 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, | ||
303 | ScrnInfoPtr pScrn = pix2scrn(pPixmap); | ||
304 | struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn); | ||
305 | enum armsoc_buf_type buf_type = ARMSOC_BO_NON_SCANOUT; | ||
306 | + struct armsoc_bo *fb_bo = NULL; | ||
307 | |||
308 | /* Only modify specified fields, keeping all others intact. */ | ||
309 | - if (pPixData) | ||
310 | + if (pPixData) { | ||
311 | pPixmap->devPrivate.ptr = pPixData; | ||
312 | + if (pARMSOC->shadow && pPixData == armsoc_bo_map(pARMSOC->shadow)) | ||
313 | + fb_bo = pARMSOC->shadow; | ||
314 | + else if (pPixData == armsoc_bo_map(pARMSOC->scanout)) | ||
315 | + fb_bo = pARMSOC->scanout; | ||
316 | + } | ||
317 | |||
318 | if (devKind > 0) | ||
319 | pPixmap->devKind = devKind; | ||
320 | @@ -173,7 +179,7 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, | ||
321 | * We can't accelerate this pixmap, and don't ever want to | ||
322 | * see it again.. | ||
323 | */ | ||
324 | - if (pPixData && pPixData != armsoc_bo_map(pARMSOC->scanout)) { | ||
325 | + if (pPixData && fb_bo && pPixData != armsoc_bo_map(fb_bo)) { | ||
326 | /* scratch-pixmap (see GetScratchPixmapHeader()) gets recycled, | ||
327 | * so could have a previous bo! | ||
328 | * Pixmap drops ref on its old bo */ | ||
329 | @@ -185,10 +191,10 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, | ||
330 | } | ||
331 | |||
332 | /* Replacing the pixmap's current bo with the scanout bo */ | ||
333 | - if (pPixData == armsoc_bo_map(pARMSOC->scanout) && priv->bo != pARMSOC->scanout) { | ||
334 | + if (fb_bo && pPixData == armsoc_bo_map(fb_bo) && priv->bo != fb_bo) { | ||
335 | struct armsoc_bo *old_bo = priv->bo; | ||
336 | |||
337 | - priv->bo = pARMSOC->scanout; | ||
338 | + priv->bo = fb_bo; | ||
339 | /* pixmap takes a ref on its new bo */ | ||
340 | armsoc_bo_reference(priv->bo); | ||
341 | |||
342 | @@ -225,7 +231,9 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, | ||
343 | if (!pPixmap->drawable.width || !pPixmap->drawable.height) | ||
344 | return TRUE; | ||
345 | |||
346 | - assert(priv->bo); | ||
347 | + if(!priv->bo) | ||
348 | + return FALSE; | ||
349 | + | ||
350 | if (armsoc_bo_width(priv->bo) != pPixmap->drawable.width || | ||
351 | armsoc_bo_height(priv->bo) != pPixmap->drawable.height || | ||
352 | armsoc_bo_bpp(priv->bo) != pPixmap->drawable.bitsPerPixel) { | ||
353 | diff --git a/src/armsoc_repulsion.c b/src/armsoc_repulsion.c | ||
354 | new file mode 100644 | ||
355 | index 0000000..1a7c0cd | ||
356 | --- /dev/null | ||
357 | +++ b/src/armsoc_repulsion.c | ||
358 | @@ -0,0 +1,624 @@ | ||
359 | +/* | ||
360 | + * Copyright (C) 2024 AMD, Inc. | ||
361 | + * | ||
362 | + * Permission is hereby granted, free of charge, to any person obtaining a | ||
363 | + * copy of this software and associated documentation files (the "Software"), | ||
364 | + * to deal in the Software without restriction, including without limitation | ||
365 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
366 | + * and/or sell copies of the Software, and to permit persons to whom the | ||
367 | + * Software is furnished to do so, subject to the following conditions: | ||
368 | + * | ||
369 | + * The above copyright notice and this permission notice (including the next | ||
370 | + * paragraph) shall be included in all copies or substantial portions of the | ||
371 | + * Software. | ||
372 | + * | ||
373 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
374 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
375 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
376 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
377 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
378 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
379 | + * SOFTWARE. | ||
380 | + * | ||
381 | + * Author: Anatoliy Klymenko <anatoliy.klymenko@amd.com> | ||
382 | + * | ||
383 | + */ | ||
384 | + | ||
385 | +#include "armsoc_repulsion.h" | ||
386 | + | ||
387 | +#include <stdlib.h> | ||
388 | +#include <drm_fourcc.h> | ||
389 | + | ||
390 | +#define EGL_GL_PROTOTYPES 1 | ||
391 | +#include <EGL/egl.h> | ||
392 | +#define EGL_EGLEXT_PROTOTYPES 1 | ||
393 | +#include <EGL/eglext.h> | ||
394 | +#include <GLES2/gl2.h> | ||
395 | +#define GL_GLEXT_PROTOTYPES 1 | ||
396 | +#include <GLES2/gl2ext.h> | ||
397 | + | ||
398 | +#include <xf86.h> | ||
399 | + | ||
400 | +/* ----------------------------------------------------------------------------- | ||
401 | + * Utilities | ||
402 | + */ | ||
403 | + | ||
404 | +#define INFO_LOG(fmt, ...) \ | ||
405 | +do { xf86DrvMsg(0, X_INFO, fmt "\n", ##__VA_ARGS__); } while (0) | ||
406 | + | ||
407 | +#define WARN_LOG(fmt, ...) \ | ||
408 | +do { xf86DrvMsg(0, X_WARNING, "WARNING: " fmt "\n", ##__VA_ARGS__); } while (0) | ||
409 | + | ||
410 | +#define ERROR_LOG(fmt, ...) \ | ||
411 | +do { xf86DrvMsg(0, X_ERROR, "ERROR: " fmt "\n", ##__VA_ARGS__); } while (0) | ||
412 | + | ||
413 | +/** | ||
414 | + * struct RepulsiveVertex - vertex data used for rendering | ||
415 | + * @pos: vertex position in the screen coordinate space | ||
416 | + * @uv: texture coordinate bound to this vertex | ||
417 | + */ | ||
418 | +struct RepulsiveVertex { | ||
419 | + GLfloat pos[3]; | ||
420 | + GLfloat uv[2]; | ||
421 | +}; | ||
422 | + | ||
423 | +/** | ||
424 | + * struct ARMSOCRepulsion - GPU acceleration data | ||
425 | + * @egl: EGL specific bits | ||
426 | + * @egl.display: EGL display connection | ||
427 | + * @egl.context: EGL context | ||
428 | + * @egl.surface: primary EGL surface | ||
429 | + * @gles: OpenGL ES related bits | ||
430 | + * @gles.vbo: Vertex buffer object | ||
431 | + * @gles.ibo: Index buffer object | ||
432 | + * @gles.texture: External texture object | ||
433 | + * @gles.proj_location: Shader location for projection matrix | ||
434 | + * @gles.xform_location: Shader location for transformation matrix | ||
435 | + * @gles.vertices: Array of vertices used in rendering | ||
436 | + */ | ||
437 | +struct ARMSOCRepulsion { | ||
438 | + struct { | ||
439 | + EGLDisplay display; | ||
440 | + EGLContext context; | ||
441 | + EGLSurface surface; | ||
442 | + } egl; | ||
443 | + struct { | ||
444 | + GLuint vbo; | ||
445 | + GLuint ibo; | ||
446 | + GLuint texture; | ||
447 | + GLuint program; | ||
448 | + GLint proj_location; | ||
449 | + GLint xform_location; | ||
450 | + struct RepulsiveVertex vertices[4]; | ||
451 | + } gles; | ||
452 | +}; | ||
453 | + | ||
454 | +/* ----------------------------------------------------------------------------- | ||
455 | + * GLES2 Functions | ||
456 | + */ | ||
457 | + | ||
458 | +static const char *vertex_shader = " \ | ||
459 | +precision highp float; \ | ||
460 | + \ | ||
461 | +uniform mat3 u_projection; \ | ||
462 | +uniform mat3 u_transform; \ | ||
463 | +attribute vec3 a_position; \ | ||
464 | +attribute vec2 a_texcoord; \ | ||
465 | + \ | ||
466 | +varying vec2 v_texcoord; \ | ||
467 | + \ | ||
468 | +void main() \ | ||
469 | +{ \ | ||
470 | + gl_Position.xyz = u_transform * u_projection * a_position; \ | ||
471 | + gl_Position.w = 1.0; \ | ||
472 | + v_texcoord = a_texcoord; \ | ||
473 | +} \ | ||
474 | +"; | ||
475 | + | ||
476 | +static const char *fragment_shader = " \ | ||
477 | +#extension GL_OES_EGL_image_external : require\n \ | ||
478 | +precision highp float; \ | ||
479 | + \ | ||
480 | +uniform samplerExternalOES texture; \ | ||
481 | +varying vec2 v_texcoord; \ | ||
482 | + \ | ||
483 | +void main() \ | ||
484 | +{ \ | ||
485 | + gl_FragColor = texture2D(texture, v_texcoord); \ | ||
486 | +} \ | ||
487 | +"; | ||
488 | + | ||
489 | +#define SHADER_POSITION_ATTR_SLOT 0 | ||
490 | +#define SHADER_TEX_COOR_ATTR_SLOT 1 | ||
491 | + | ||
492 | +static void armsoc_repulsion_gles_log(GLenum source, GLenum type, GLuint id, | ||
493 | + GLenum severity, GLsizei length, | ||
494 | + const GLchar *message, const void *data) | ||
495 | +{ | ||
496 | + switch (severity) { | ||
497 | + case GL_DEBUG_SEVERITY_HIGH_KHR: | ||
498 | + ERROR_LOG("GLES2: %s", message); | ||
499 | + break; | ||
500 | + case GL_DEBUG_SEVERITY_MEDIUM_KHR: | ||
501 | + WARN_LOG("GLES2: %s", message); | ||
502 | + break; | ||
503 | + default: | ||
504 | + INFO_LOG("GLES2: %s", message); | ||
505 | + }; | ||
506 | +} | ||
507 | + | ||
508 | +static const char* gles_error_str(GLenum err) | ||
509 | +{ | ||
510 | + switch (err) { | ||
511 | + case GL_NO_ERROR: return "no error"; | ||
512 | + case GL_INVALID_ENUM: return "invalid enum"; | ||
513 | + case GL_INVALID_VALUE: return "invalid value"; | ||
514 | + case GL_INVALID_OPERATION: return "invalid operation"; | ||
515 | + case GL_OUT_OF_MEMORY: return "out of memory"; | ||
516 | + case GL_INVALID_FRAMEBUFFER_OPERATION: return "invalid fb operation"; | ||
517 | + default: return "unknowm error"; | ||
518 | + } | ||
519 | +}; | ||
520 | + | ||
521 | +static int armsoc_repulsion_compile_shader(struct ARMSOCRepulsion *repulsion) | ||
522 | +{ | ||
523 | + GLuint vs, fs; | ||
524 | + GLint status, texture; | ||
525 | + GLenum err; | ||
526 | + | ||
527 | + vs = glCreateShader(GL_VERTEX_SHADER); | ||
528 | + if (!vs) { | ||
529 | + err = glGetError(); | ||
530 | + return err == GL_NO_ERROR ? -1 : err; | ||
531 | + } | ||
532 | + glShaderSource(vs, 1, &vertex_shader, NULL); | ||
533 | + glCompileShader(vs); | ||
534 | + glGetShaderiv(vs, GL_COMPILE_STATUS, &status); | ||
535 | + if (status == GL_FALSE) { | ||
536 | + GLint max_len = 1024; | ||
537 | + GLchar err_log[1024]; | ||
538 | + glGetShaderInfoLog(vs, max_len, &max_len, &err_log[0]); | ||
539 | + ERROR_LOG("VS: %s", err_log); | ||
540 | + err = glGetError(); | ||
541 | + return err == GL_NO_ERROR ? -1 : err; | ||
542 | + } | ||
543 | + | ||
544 | + fs = glCreateShader(GL_FRAGMENT_SHADER); | ||
545 | + if (!fs) { | ||
546 | + err = glGetError(); | ||
547 | + return err == GL_NO_ERROR ? -1 : err; | ||
548 | + } | ||
549 | + glShaderSource(fs, 1, &fragment_shader, NULL); | ||
550 | + glCompileShader(fs); | ||
551 | + glGetShaderiv(fs, GL_COMPILE_STATUS, &status); | ||
552 | + if (status == GL_FALSE) { | ||
553 | + err = glGetError(); | ||
554 | + return err == GL_NO_ERROR ? -1 : err; | ||
555 | + } | ||
556 | + | ||
557 | + repulsion->gles.program = glCreateProgram(); | ||
558 | + if (!repulsion->gles.program) { | ||
559 | + err = glGetError(); | ||
560 | + return err == GL_NO_ERROR ? -1 : err; | ||
561 | + } | ||
562 | + glAttachShader(repulsion->gles.program, vs); | ||
563 | + glAttachShader(repulsion->gles.program, fs); | ||
564 | + glBindAttribLocation(repulsion->gles.program, SHADER_POSITION_ATTR_SLOT, | ||
565 | + "a_position"); | ||
566 | + glBindAttribLocation(repulsion->gles.program, SHADER_TEX_COOR_ATTR_SLOT, | ||
567 | + "a_texcoord"); | ||
568 | + glLinkProgram(repulsion->gles.program); | ||
569 | + glDetachShader(repulsion->gles.program, vs); | ||
570 | + glDetachShader(repulsion->gles.program, fs); | ||
571 | + glGetProgramiv(repulsion->gles.program, GL_LINK_STATUS, &status); | ||
572 | + if (status == GL_FALSE) { | ||
573 | + err = glGetError(); | ||
574 | + return err == GL_NO_ERROR ? -1 : err; | ||
575 | + } | ||
576 | + glUseProgram(repulsion->gles.program); | ||
577 | + glEnableVertexAttribArray(SHADER_POSITION_ATTR_SLOT); | ||
578 | + glEnableVertexAttribArray(SHADER_TEX_COOR_ATTR_SLOT); | ||
579 | + | ||
580 | + repulsion->gles.proj_location = | ||
581 | + glGetUniformLocation(repulsion->gles.program, "u_projection"); | ||
582 | + repulsion->gles.xform_location = | ||
583 | + glGetUniformLocation(repulsion->gles.program, "u_transform"); | ||
584 | + | ||
585 | + texture = glGetUniformLocation(repulsion->gles.program, "texture"); | ||
586 | + glUniform1i(texture, 0); | ||
587 | + glActiveTexture(GL_TEXTURE0); | ||
588 | + | ||
589 | + return GL_NO_ERROR; | ||
590 | +} | ||
591 | + | ||
592 | +static int armsoc_repulsion_create_vbo(struct ARMSOCRepulsion *repulsion) | ||
593 | +{ | ||
594 | + glGenBuffers(1, &repulsion->gles.vbo); | ||
595 | + glBindBuffer(GL_ARRAY_BUFFER, repulsion->gles.vbo); | ||
596 | + | ||
597 | + return GL_NO_ERROR; | ||
598 | +} | ||
599 | + | ||
600 | +static int armsoc_repulsion_create_ibo(struct ARMSOCRepulsion *repulsion) | ||
601 | +{ | ||
602 | + static const GLushort indices[] = {0, 1, 2, 0, 2, 3}; | ||
603 | + | ||
604 | + glGenBuffers(1, &repulsion->gles.ibo); | ||
605 | + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, repulsion->gles.ibo); | ||
606 | + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, | ||
607 | + GL_STATIC_DRAW); | ||
608 | + | ||
609 | + return GL_NO_ERROR; | ||
610 | +} | ||
611 | + | ||
612 | +static int armsoc_repulsion_create_texture(struct ARMSOCRepulsion *repulsion) | ||
613 | +{ | ||
614 | + glGenTextures(1, &repulsion->gles.texture); | ||
615 | + glBindTexture(GL_TEXTURE_EXTERNAL_OES, repulsion->gles.texture); | ||
616 | + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
617 | + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
618 | + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, | ||
619 | + GL_CLAMP_TO_EDGE); | ||
620 | + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, | ||
621 | + GL_CLAMP_TO_EDGE); | ||
622 | + | ||
623 | + return GL_NO_ERROR; | ||
624 | +} | ||
625 | + | ||
626 | +static int armsoc_repulsion_init_gles(struct ARMSOCRepulsion *repulsion) | ||
627 | +{ | ||
628 | + int rc; | ||
629 | + | ||
630 | + glEnable(GL_DEBUG_OUTPUT_KHR); | ||
631 | + glDebugMessageCallbackKHR(armsoc_repulsion_gles_log, repulsion); | ||
632 | + | ||
633 | + rc = armsoc_repulsion_compile_shader(repulsion); | ||
634 | + if (rc != GL_NO_ERROR) { | ||
635 | + ERROR_LOG("Failed to compile shader: 0x%04x (%s)", | ||
636 | + rc, gles_error_str(rc)); | ||
637 | + return rc; | ||
638 | + } | ||
639 | + | ||
640 | + rc = armsoc_repulsion_create_vbo(repulsion); | ||
641 | + if (rc != GL_NO_ERROR) { | ||
642 | + ERROR_LOG("Failed to create vertex buffer: 0x%04x (%s)", | ||
643 | + rc, gles_error_str(rc)); | ||
644 | + return rc; | ||
645 | + } | ||
646 | + | ||
647 | + rc = armsoc_repulsion_create_ibo(repulsion); | ||
648 | + if (rc != GL_NO_ERROR) { | ||
649 | + ERROR_LOG("Failed to create index buffer: 0x%04x (%s)", | ||
650 | + rc, gles_error_str(rc)); | ||
651 | + return rc; | ||
652 | + } | ||
653 | + | ||
654 | + rc = armsoc_repulsion_create_texture(repulsion); | ||
655 | + if (rc != GL_NO_ERROR) { | ||
656 | + ERROR_LOG("Failed to create texture: 0x%04x (%s)", | ||
657 | + rc, gles_error_str(rc)); | ||
658 | + return rc; | ||
659 | + } | ||
660 | + | ||
661 | + return GL_NO_ERROR; | ||
662 | +} | ||
663 | + | ||
664 | +static void armsoc_repulsion_release_texture(struct ARMSOCRepulsion *repulsion) | ||
665 | +{ | ||
666 | + glDeleteTextures(1, &repulsion->gles.texture); | ||
667 | +} | ||
668 | + | ||
669 | +static void armsoc_repulsion_release_ibo(struct ARMSOCRepulsion *repulsion) | ||
670 | +{ | ||
671 | + glDeleteBuffers(1, &repulsion->gles.ibo); | ||
672 | +} | ||
673 | + | ||
674 | +static void armsoc_repulsion_release_vbo(struct ARMSOCRepulsion *repulsion) | ||
675 | +{ | ||
676 | + glDeleteBuffers(1, &repulsion->gles.vbo); | ||
677 | +} | ||
678 | + | ||
679 | +static void armsoc_repulsion_release_shader(struct ARMSOCRepulsion *repulsion) | ||
680 | +{ | ||
681 | + glDeleteProgram(repulsion->gles.program); | ||
682 | +} | ||
683 | + | ||
684 | +static void armsoc_repulsion_release_gles(struct ARMSOCRepulsion *repulsion) | ||
685 | +{ | ||
686 | + armsoc_repulsion_release_texture(repulsion); | ||
687 | + armsoc_repulsion_release_ibo(repulsion); | ||
688 | + armsoc_repulsion_release_vbo(repulsion); | ||
689 | + armsoc_repulsion_release_shader(repulsion); | ||
690 | +} | ||
691 | + | ||
692 | +/* ----------------------------------------------------------------------------- | ||
693 | + * EGL Functions | ||
694 | + */ | ||
695 | + | ||
696 | +static const char* egl_error_str(EGLint err) | ||
697 | +{ | ||
698 | + switch (err) { | ||
699 | + case EGL_SUCCESS: return "no error"; | ||
700 | + case EGL_NOT_INITIALIZED: return "not initialized"; | ||
701 | + case EGL_BAD_ACCESS: return "bad access"; | ||
702 | + case EGL_BAD_ALLOC: return "bad alloc"; | ||
703 | + case EGL_BAD_CONFIG: return "bad config"; | ||
704 | + case EGL_BAD_CONTEXT: return "bad context"; | ||
705 | + case EGL_BAD_CURRENT_SURFACE: return "bad current surface"; | ||
706 | + case EGL_BAD_DISPLAY: return "bad display"; | ||
707 | + case EGL_BAD_MATCH: return "bad match"; | ||
708 | + case EGL_BAD_NATIVE_PIXMAP: return "bad native pixmap"; | ||
709 | + case EGL_BAD_NATIVE_WINDOW: return "bad native window"; | ||
710 | + case EGL_BAD_PARAMETER: return "bad parameter"; | ||
711 | + case EGL_BAD_SURFACE: return "bad surface"; | ||
712 | + case EGL_CONTEXT_LOST: return "context lost"; | ||
713 | + default: return "unknowm error"; | ||
714 | + } | ||
715 | +}; | ||
716 | + | ||
717 | +static int armsoc_repulsion_init_egl(struct ARMSOCRepulsion *repulsion) | ||
718 | +{ | ||
719 | + static const EGLint config_attrs[] = { | ||
720 | + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, | ||
721 | + EGL_CONFORMANT, EGL_OPENGL_ES2_BIT, | ||
722 | + EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, | ||
723 | + EGL_DEPTH_SIZE, 8, | ||
724 | + EGL_RED_SIZE, 8, | ||
725 | + EGL_GREEN_SIZE, 8, | ||
726 | + EGL_BLUE_SIZE, 8, | ||
727 | + EGL_ALPHA_SIZE, 8, | ||
728 | + EGL_NONE | ||
729 | + }; | ||
730 | + static const EGLint context_attrs[] = { | ||
731 | + EGL_CONTEXT_CLIENT_VERSION, 2, | ||
732 | + EGL_NONE | ||
733 | + }; | ||
734 | + EGLint count; | ||
735 | + EGLConfig config; | ||
736 | + | ||
737 | + repulsion->egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | ||
738 | + if (repulsion->egl.display == EGL_NO_DISPLAY) | ||
739 | + return eglGetError(); | ||
740 | + | ||
741 | + if(!eglInitialize(repulsion->egl.display, NULL, NULL)) | ||
742 | + return eglGetError(); | ||
743 | + | ||
744 | + if (!eglChooseConfig(repulsion->egl.display, config_attrs, &config, 1, | ||
745 | + &count)) | ||
746 | + return eglGetError(); | ||
747 | + | ||
748 | + if (!eglBindAPI(EGL_OPENGL_ES_API)) | ||
749 | + return eglGetError(); | ||
750 | + | ||
751 | + repulsion->egl.context = eglCreateContext(repulsion->egl.display, config, | ||
752 | + EGL_NO_CONTEXT, context_attrs); | ||
753 | + if (repulsion->egl.context == EGL_NO_CONTEXT) | ||
754 | + return eglGetError(); | ||
755 | + | ||
756 | + repulsion->egl.surface = eglCreatePbufferSurface(repulsion->egl.display, | ||
757 | + config, NULL); | ||
758 | + if (repulsion->egl.surface == EGL_NO_SURFACE) | ||
759 | + return eglGetError(); | ||
760 | + | ||
761 | + if (!eglMakeCurrent(repulsion->egl.display, repulsion->egl.surface, | ||
762 | + repulsion->egl.surface, repulsion->egl.context)) | ||
763 | + return eglGetError(); | ||
764 | + | ||
765 | + if (!eglSwapInterval(repulsion->egl.display, 0)) | ||
766 | + return eglGetError(); | ||
767 | + | ||
768 | + return EGL_SUCCESS; | ||
769 | +} | ||
770 | + | ||
771 | +static void armsoc_repulsion_release_egl(struct ARMSOCRepulsion *repulsion) | ||
772 | +{ | ||
773 | + if (repulsion->egl.surface != EGL_NO_SURFACE) | ||
774 | + eglDestroySurface(repulsion->egl.display, repulsion->egl.surface); | ||
775 | + | ||
776 | + if (repulsion->egl.context) | ||
777 | + eglDestroyContext(repulsion->egl.display, repulsion->egl.context); | ||
778 | + | ||
779 | + if (repulsion->egl.display) | ||
780 | + eglTerminate(repulsion->egl.display); | ||
781 | + | ||
782 | + repulsion->egl.display = EGL_NO_DISPLAY; | ||
783 | +} | ||
784 | + | ||
785 | +static EGLint armsoc_repulsion_guess_bo_format(struct armsoc_bo *bo) | ||
786 | +{ | ||
787 | + switch(armsoc_bo_bpp(bo)) { | ||
788 | + case 16: | ||
789 | + return DRM_FORMAT_RGB565; | ||
790 | + case 32: | ||
791 | + return DRM_FORMAT_ARGB8888; | ||
792 | + default: | ||
793 | + return 0; | ||
794 | + } | ||
795 | +} | ||
796 | + | ||
797 | +static EGLImageKHR | ||
798 | +armsoc_repulsion_create_egl_image(struct ARMSOCRepulsion *repulsion, | ||
799 | + struct armsoc_bo *bo) | ||
800 | +{ | ||
801 | + const EGLint attributes[] = { | ||
802 | + EGL_WIDTH, armsoc_bo_width(bo), | ||
803 | + EGL_HEIGHT, armsoc_bo_height(bo), | ||
804 | + EGL_LINUX_DRM_FOURCC_EXT, armsoc_repulsion_guess_bo_format(bo), | ||
805 | + EGL_DMA_BUF_PLANE0_FD_EXT, armsoc_bo_get_dmabuf(bo), | ||
806 | + EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, | ||
807 | + EGL_DMA_BUF_PLANE0_PITCH_EXT, armsoc_bo_pitch(bo), | ||
808 | + EGL_NONE | ||
809 | + }; | ||
810 | + | ||
811 | + return eglCreateImageKHR(repulsion->egl.display, EGL_NO_CONTEXT, | ||
812 | + EGL_LINUX_DMA_BUF_EXT, NULL, attributes); | ||
813 | +} | ||
814 | + | ||
815 | +static void | ||
816 | +armsoc_repulsion_destroy_egl_image(struct ARMSOCRepulsion *repulsion, | ||
817 | + EGLImageKHR img) | ||
818 | +{ | ||
819 | + eglDestroyImageKHR(repulsion->egl.display, img); | ||
820 | +} | ||
821 | + | ||
822 | +/* ----------------------------------------------------------------------------- | ||
823 | + * Repulsion API | ||
824 | + */ | ||
825 | + | ||
826 | +bool armsoc_repulsion_composite(struct ARMSOCRepulsion *repulsion, | ||
827 | + struct armsoc_bo *src, | ||
828 | + struct armsoc_bo *dest, | ||
829 | + float xform_matrix[3][3]) | ||
830 | +{ | ||
831 | + GLuint tex, fbo; | ||
832 | + GLenum status; | ||
833 | + EGLImageKHR dest_img, src_img; | ||
834 | + GLsizei width, height; | ||
835 | + static GLfloat proj_matrix[3][3] = { | ||
836 | + { 2.f, 0.f, 0.f }, | ||
837 | + { 0.f, 2.f, 0.f }, | ||
838 | + { -1.f, -1.f, 0.f }, | ||
839 | + }; | ||
840 | + | ||
841 | + if (!repulsion || !src || !dest) | ||
842 | + return false; | ||
843 | + | ||
844 | + dest_img = armsoc_repulsion_create_egl_image(repulsion, dest); | ||
845 | + if (dest_img == EGL_NO_IMAGE_KHR) { | ||
846 | + EGLint err = eglGetError(); | ||
847 | + ERROR_LOG("Failed to create dest EGL image: 0x%04x (%s)", | ||
848 | + err, egl_error_str(err)); | ||
849 | + return false; | ||
850 | + } | ||
851 | + src_img = armsoc_repulsion_create_egl_image(repulsion, src); | ||
852 | + if (src_img == EGL_NO_IMAGE_KHR) { | ||
853 | + EGLint err = eglGetError(); | ||
854 | + ERROR_LOG("Failed to create src EGL image: 0x%04x (%s)", | ||
855 | + err, egl_error_str(err)); | ||
856 | + armsoc_repulsion_destroy_egl_image(repulsion, dest_img); | ||
857 | + return false; | ||
858 | + } | ||
859 | + | ||
860 | + glGenTextures(1, &tex); | ||
861 | + glBindTexture(GL_TEXTURE_2D, tex); | ||
862 | + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, dest_img); | ||
863 | + | ||
864 | + glGenFramebuffers(1, &fbo); | ||
865 | + glBindFramebuffer(GL_FRAMEBUFFER, fbo); | ||
866 | + | ||
867 | + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | ||
868 | + GL_TEXTURE_2D, tex, 0); | ||
869 | + | ||
870 | + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); | ||
871 | + if (status != GL_FRAMEBUFFER_COMPLETE) { | ||
872 | + ERROR_LOG("Failed to complete framebuffer"); | ||
873 | + glDeleteFramebuffers(1, &fbo); | ||
874 | + glDeleteTextures(1, &tex); | ||
875 | + armsoc_repulsion_destroy_egl_image(repulsion, dest_img); | ||
876 | + armsoc_repulsion_destroy_egl_image(repulsion, src_img); | ||
877 | + return false; | ||
878 | + } | ||
879 | + | ||
880 | + width = armsoc_bo_width(dest); | ||
881 | + height = armsoc_bo_height(dest); | ||
882 | + proj_matrix[0][0] = 2.f / width; | ||
883 | + proj_matrix[1][1] = 2.f / height; | ||
884 | + | ||
885 | + glUniformMatrix3fv(repulsion->gles.proj_location, 1, false, | ||
886 | + &proj_matrix[0][0]); | ||
887 | + | ||
888 | + glUniformMatrix3fv(repulsion->gles.xform_location, 1, false, | ||
889 | + &xform_matrix[0][0]); | ||
890 | + | ||
891 | + glViewport(0, 0, width, height); | ||
892 | + | ||
893 | + glClearColor(0.f, 0.f, 1.f, 1.f); | ||
894 | + glClear(GL_COLOR_BUFFER_BIT); | ||
895 | + | ||
896 | + glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, src_img); | ||
897 | + | ||
898 | + repulsion->gles.vertices[0].pos[0] = 0.f; | ||
899 | + repulsion->gles.vertices[0].pos[1] = height; | ||
900 | + repulsion->gles.vertices[0].pos[2] = 1.f; | ||
901 | + repulsion->gles.vertices[0].uv[0] = 0.f; | ||
902 | + repulsion->gles.vertices[0].uv[1] = 1.f; | ||
903 | + | ||
904 | + repulsion->gles.vertices[1].pos[0] = 0.f; | ||
905 | + repulsion->gles.vertices[1].pos[1] = 0.f; | ||
906 | + repulsion->gles.vertices[1].pos[2] = 1.f; | ||
907 | + repulsion->gles.vertices[1].uv[0] = 0.f; | ||
908 | + repulsion->gles.vertices[1].uv[1] = 0.f; | ||
909 | + | ||
910 | + repulsion->gles.vertices[2].pos[0] = width; | ||
911 | + repulsion->gles.vertices[2].pos[1] = 0.f; | ||
912 | + repulsion->gles.vertices[2].pos[2] = 1.f; | ||
913 | + repulsion->gles.vertices[2].uv[0] = 1.f; | ||
914 | + repulsion->gles.vertices[2].uv[1] = 0.f; | ||
915 | + | ||
916 | + repulsion->gles.vertices[3].pos[0] = width; | ||
917 | + repulsion->gles.vertices[3].pos[1] = height; | ||
918 | + repulsion->gles.vertices[3].pos[2] = 1.f; | ||
919 | + repulsion->gles.vertices[3].uv[0] = 1.f; | ||
920 | + repulsion->gles.vertices[3].uv[1] = 1.f; | ||
921 | + | ||
922 | + glBufferData(GL_ARRAY_BUFFER, sizeof(repulsion->gles.vertices), | ||
923 | + repulsion->gles.vertices, GL_STATIC_DRAW); | ||
924 | + | ||
925 | + glVertexAttribPointer(SHADER_POSITION_ATTR_SLOT, 3, GL_FLOAT, GL_FALSE, | ||
926 | + sizeof(*repulsion->gles.vertices), (const void *)(0)); | ||
927 | + glVertexAttribPointer(SHADER_TEX_COOR_ATTR_SLOT, 2, GL_FLOAT, GL_FALSE, | ||
928 | + sizeof(*repulsion->gles.vertices), | ||
929 | + (const void *)(sizeof(repulsion->gles.vertices->pos))); | ||
930 | + | ||
931 | + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); | ||
932 | + | ||
933 | + glFinish(); | ||
934 | + | ||
935 | + glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||
936 | + glDeleteFramebuffers(1, &fbo); | ||
937 | + glDeleteTextures(1, &tex); | ||
938 | + | ||
939 | + armsoc_repulsion_destroy_egl_image(repulsion, src_img); | ||
940 | + armsoc_repulsion_destroy_egl_image(repulsion, dest_img); | ||
941 | + | ||
942 | + return true; | ||
943 | +} | ||
944 | + | ||
945 | +struct ARMSOCRepulsion *armsoc_repulsion_init(void) | ||
946 | +{ | ||
947 | + int rc; | ||
948 | + struct ARMSOCRepulsion *repulsion = calloc(1, sizeof(*repulsion)); | ||
949 | + if (!repulsion) { | ||
950 | + ERROR_LOG("Out of memory"); | ||
951 | + return NULL; | ||
952 | + } | ||
953 | + | ||
954 | + rc = armsoc_repulsion_init_egl(repulsion); | ||
955 | + if (rc != EGL_SUCCESS) { | ||
956 | + ERROR_LOG("Failed to initialize EGL: 0x%04x (%s)", | ||
957 | + rc, egl_error_str(rc)); | ||
958 | + armsoc_repulsion_release(repulsion); | ||
959 | + return NULL; | ||
960 | + } | ||
961 | + | ||
962 | + rc = armsoc_repulsion_init_gles(repulsion); | ||
963 | + if (rc != GL_NO_ERROR) { | ||
964 | + ERROR_LOG("Failed to initialize GLES: 0x%04x (%s)", | ||
965 | + rc, gles_error_str(rc)); | ||
966 | + armsoc_repulsion_release(repulsion); | ||
967 | + return NULL; | ||
968 | + } | ||
969 | + | ||
970 | + INFO_LOG("Repulsion initialized"); | ||
971 | + | ||
972 | + return repulsion; | ||
973 | +} | ||
974 | + | ||
975 | +void armsoc_repulsion_release(struct ARMSOCRepulsion *repulsion) | ||
976 | +{ | ||
977 | + if (!repulsion) | ||
978 | + return; | ||
979 | + armsoc_repulsion_release_gles(repulsion); | ||
980 | + armsoc_repulsion_release_egl(repulsion); | ||
981 | + free(repulsion); | ||
982 | +} | ||
983 | diff --git a/src/armsoc_repulsion.h b/src/armsoc_repulsion.h | ||
984 | new file mode 100644 | ||
985 | index 0000000..b5e57df | ||
986 | --- /dev/null | ||
987 | +++ b/src/armsoc_repulsion.h | ||
988 | @@ -0,0 +1,67 @@ | ||
989 | +/* | ||
990 | + * Copyright (C) 2024 AMD, Inc. | ||
991 | + * | ||
992 | + * Permission is hereby granted, free of charge, to any person obtaining a | ||
993 | + * copy of this software and associated documentation files (the "Software"), | ||
994 | + * to deal in the Software without restriction, including without limitation | ||
995 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
996 | + * and/or sell copies of the Software, and to permit persons to whom the | ||
997 | + * Software is furnished to do so, subject to the following conditions: | ||
998 | + * | ||
999 | + * The above copyright notice and this permission notice (including the next | ||
1000 | + * paragraph) shall be included in all copies or substantial portions of the | ||
1001 | + * Software. | ||
1002 | + * | ||
1003 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
1004 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
1005 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
1006 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
1007 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
1008 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
1009 | + * SOFTWARE. | ||
1010 | + * | ||
1011 | + * Author: Anatoliy Klymenko <anatoliy.klymenko@amd.com> | ||
1012 | + * | ||
1013 | + */ | ||
1014 | + | ||
1015 | +#ifndef ARMSOC_REPULSION_H_ | ||
1016 | +#define ARMSOC_REPULSION_H_ | ||
1017 | + | ||
1018 | +#include <stdbool.h> | ||
1019 | +#include "armsoc_dumb.h" | ||
1020 | + | ||
1021 | +struct ARMSOCRepulsion; | ||
1022 | + | ||
1023 | +/** | ||
1024 | + * Initialize armsoc repulsion compositor. | ||
1025 | + * | ||
1026 | + * Return: pointer to new ARMSOCRepulsion object on success, NULL otherwise. | ||
1027 | + */ | ||
1028 | +struct ARMSOCRepulsion *armsoc_repulsion_init(void); | ||
1029 | + | ||
1030 | +/** | ||
1031 | + * Release armsoc repulsion compositor and free all resources. | ||
1032 | + * @repulsion: pointer to previously allocated ARMSOCRepulsion object. | ||
1033 | + */ | ||
1034 | +void armsoc_repulsion_release(struct ARMSOCRepulsion *repulsion); | ||
1035 | + | ||
1036 | +/** | ||
1037 | + * Perform 2 image composition. | ||
1038 | + * @repulsion: pointer to ARMSOCRepulsion object. | ||
1039 | + * @src: source buffer object. | ||
1040 | + * @dest: destination buffer object. | ||
1041 | + * @xform_matrix: transformation matrix to apply to source image before copying | ||
1042 | + * it into destination. | ||
1043 | + * | ||
1044 | + * This function performs GPU accelerated copy of @src buffer into @dest buffer | ||
1045 | + * while applying linear transformation. | ||
1046 | + * | ||
1047 | + * Return: pointer to new ARMSOCRepulsion object on success, NULL otherwise. | ||
1048 | + */ | ||
1049 | +bool armsoc_repulsion_composite(struct ARMSOCRepulsion *repulsion, | ||
1050 | + struct armsoc_bo *src, | ||
1051 | + struct armsoc_bo *dest, | ||
1052 | + float xform_matrix[3][3]); | ||
1053 | + | ||
1054 | + | ||
1055 | +#endif // ARMSOC_REPULSION_H_ | ||
1056 | -- | ||
1057 | 2.25.1 | ||
1058 | |||
diff --git a/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armosc-Option-to-control-acceleration.patch b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armosc-Option-to-control-acceleration.patch new file mode 100644 index 00000000..9cc186de --- /dev/null +++ b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armosc-Option-to-control-acceleration.patch | |||
@@ -0,0 +1,110 @@ | |||
1 | From 83047c38b0a9e8cc535eba580ca28497f1bee544 Mon Sep 17 00:00:00 2001 | ||
2 | From: Anatoliy Klymenko <anatoliy.klymenko@amd.com> | ||
3 | Date: Fri, 19 Jul 2024 14:10:22 -0700 | ||
4 | Subject: [PATCH] xf86-video-armosc: Option to control acceleration | ||
5 | |||
6 | Add xorg config option to enable / disable GPU accelerated picture | ||
7 | composition. Enable acceleration by default. | ||
8 | |||
9 | Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com> | ||
10 | --- | ||
11 | man/armsoc.man | 6 ++++++ | ||
12 | src/armsoc_driver.c | 20 +++++++++++++++----- | ||
13 | src/armsoc_driver.h | 3 +++ | ||
14 | 3 files changed, 24 insertions(+), 5 deletions(-) | ||
15 | |||
16 | diff --git a/man/armsoc.man b/man/armsoc.man | ||
17 | index d85c2fa..cdeb19e 100644 | ||
18 | --- a/man/armsoc.man | ||
19 | +++ b/man/armsoc.man | ||
20 | @@ -69,6 +69,12 @@ Default: NULL | ||
21 | Use the umplock module for cross-process access synchronization. It should be only enabled for Mali400 | ||
22 | .IP | ||
23 | Default: Umplock is Disabled | ||
24 | +.TP | ||
25 | +.BI "Option \*qAccelerateComposition\*q \*q" boolean \*q | ||
26 | +Accelerate picture composition on GPU. | ||
27 | +.IP | ||
28 | +Default: Accelerated composition is Enabled | ||
29 | + | ||
30 | |||
31 | .SH DRM DEVICE SELECTION | ||
32 | |||
33 | diff --git a/src/armsoc_driver.c b/src/armsoc_driver.c | ||
34 | index f5b8f21..15cc620 100644 | ||
35 | --- a/src/armsoc_driver.c | ||
36 | +++ b/src/armsoc_driver.c | ||
37 | @@ -110,6 +110,7 @@ enum { | ||
38 | OPTION_DRI_NUM_BUF, | ||
39 | OPTION_INIT_FROM_FBDEV, | ||
40 | OPTION_UMP_LOCK, | ||
41 | + OPTION_ACCELERATE_COMPOSITION, | ||
42 | }; | ||
43 | |||
44 | /** Supported options. */ | ||
45 | @@ -122,6 +123,8 @@ static const OptionInfoRec ARMSOCOptions[] = { | ||
46 | { OPTION_DRI_NUM_BUF, "DRI2MaxBuffers", OPTV_INTEGER, {-1}, FALSE }, | ||
47 | { OPTION_INIT_FROM_FBDEV, "InitFromFBDev", OPTV_STRING, {0}, FALSE }, | ||
48 | { OPTION_UMP_LOCK, "UMP_LOCK", OPTV_BOOLEAN, {0}, FALSE }, | ||
49 | + { OPTION_ACCELERATE_COMPOSITION, "AccelerateComposition", OPTV_BOOLEAN, | ||
50 | + {0}, FALSE }, | ||
51 | { -1, NULL, OPTV_NONE, {0}, FALSE } | ||
52 | }; | ||
53 | |||
54 | @@ -871,6 +874,10 @@ ARMSOCPreInit(ScrnInfoPtr pScrn, int flags) | ||
55 | armsocDebug = xf86ReturnOptValBool(pARMSOC->pOptionInfo, | ||
56 | OPTION_DEBUG, FALSE); | ||
57 | |||
58 | + /* Should we enable GPU accelerated picture composition? */ | ||
59 | + pARMSOC->enable_repulsion = xf86ReturnOptValBool(pARMSOC->pOptionInfo, | ||
60 | + OPTION_ACCELERATE_COMPOSITION, TRUE); | ||
61 | + | ||
62 | if (!xf86GetOptValInteger(pARMSOC->pOptionInfo, OPTION_DRI_NUM_BUF, | ||
63 | &driNumBufs)) { | ||
64 | /* Default to double buffering */ | ||
65 | @@ -1119,7 +1126,6 @@ ARMSOCScreenInit(SCREEN_INIT_ARGS_DECL) | ||
66 | struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn); | ||
67 | VisualPtr visual; | ||
68 | xf86CrtcConfigPtr xf86_config; | ||
69 | - PictureScreenPtr ps; | ||
70 | int j; | ||
71 | const char *fbdev; | ||
72 | int depth; | ||
73 | @@ -1308,12 +1314,16 @@ ARMSOCScreenInit(SCREEN_INIT_ARGS_DECL) | ||
74 | pARMSOC->lockFD = -1; | ||
75 | } | ||
76 | |||
77 | - pARMSOC->repulsion = armsoc_repulsion_init(); | ||
78 | + if (pARMSOC->enable_repulsion) { | ||
79 | + PictureScreenPtr ps; | ||
80 | + | ||
81 | + pARMSOC->repulsion = armsoc_repulsion_init(); | ||
82 | |||
83 | - ps = GetPictureScreen(pScreen); | ||
84 | - pARMSOC->composite_proc = ps->Composite; | ||
85 | + ps = GetPictureScreen(pScreen); | ||
86 | + pARMSOC->composite_proc = ps->Composite; | ||
87 | |||
88 | - ps->Composite = ARMSOCComposite; | ||
89 | + ps->Composite = ARMSOCComposite; | ||
90 | + } | ||
91 | |||
92 | TRACE_EXIT(); | ||
93 | return TRUE; | ||
94 | diff --git a/src/armsoc_driver.h b/src/armsoc_driver.h | ||
95 | index 20b0f80..27e978e 100644 | ||
96 | --- a/src/armsoc_driver.h | ||
97 | +++ b/src/armsoc_driver.h | ||
98 | @@ -185,6 +185,9 @@ struct ARMSOCRec { | ||
99 | * driNumBufs if early display enabled, otherwise driNumBufs-1 */ | ||
100 | unsigned int swap_chain_size; | ||
101 | |||
102 | + /* Enable GPU accelerated picture compositor? */ | ||
103 | + Bool enable_repulsion; | ||
104 | + | ||
105 | /* GPU accelerated picture compositor, AKA Repulsion */ | ||
106 | struct ARMSOCRepulsion *repulsion; | ||
107 | |||
108 | -- | ||
109 | 2.25.1 | ||
110 | |||
diff --git a/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armsoc-Add-shadow-buffer-hooks.patch b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armsoc-Add-shadow-buffer-hooks.patch new file mode 100644 index 00000000..8a1a8ca7 --- /dev/null +++ b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc/0001-xf86-video-armsoc-Add-shadow-buffer-hooks.patch | |||
@@ -0,0 +1,141 @@ | |||
1 | From 8c62932a848c3c9eef8b663a24d90026687d5b02 Mon Sep 17 00:00:00 2001 | ||
2 | From: Anatoliy Klymenko <anatoliy.klymenko@amd.com> | ||
3 | Date: Thu, 13 Jun 2024 17:37:46 -0700 | ||
4 | Subject: [PATCH] xf86-video-armsoc: Add shadow buffer hooks | ||
5 | |||
6 | Add shadow buffer management callbacks. These callbacks are required for | ||
7 | RandR extension to operate. Implement the shadow buffer as a dumb DRM | ||
8 | framebuffer. Use the shadow buffer as page flip souce. Fix armsoc_dri2.c | ||
9 | file mode (drop exec bits). | ||
10 | |||
11 | Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com> | ||
12 | --- | ||
13 | src/armsoc_dri2.c | 3 ++ | ||
14 | src/armsoc_driver.h | 3 ++ | ||
15 | src/drmmode_display.c | 65 +++++++++++++++++++++++++++++++++++++++++++ | ||
16 | 3 files changed, 71 insertions(+) | ||
17 | mode change 100755 => 100644 src/armsoc_dri2.c | ||
18 | |||
19 | diff --git a/src/armsoc_dri2.c b/src/armsoc_dri2.c | ||
20 | old mode 100755 | ||
21 | new mode 100644 | ||
22 | index dc502e4..af5d074 | ||
23 | --- a/src/armsoc_dri2.c | ||
24 | +++ b/src/armsoc_dri2.c | ||
25 | @@ -853,6 +853,9 @@ ARMSOCDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw, | ||
26 | (armsoc_bo_height(src_bo) == armsoc_bo_height(dst_bo)); | ||
27 | |||
28 | if (do_flip) { | ||
29 | + if (pARMSOC->shadow) | ||
30 | + src_fb_id = armsoc_bo_get_fb(pARMSOC->shadow); | ||
31 | + | ||
32 | DEBUG_MSG("FLIPPING: FB%d -> FB%d", src_fb_id, dst_fb_id); | ||
33 | cmd->type = DRI2_FLIP_COMPLETE; | ||
34 | |||
35 | diff --git a/src/armsoc_driver.h b/src/armsoc_driver.h | ||
36 | index ef2836f..eae76ca 100644 | ||
37 | --- a/src/armsoc_driver.h | ||
38 | +++ b/src/armsoc_driver.h | ||
39 | @@ -149,6 +149,9 @@ struct ARMSOCRec { | ||
40 | /** Scan-out buffer. */ | ||
41 | struct armsoc_bo *scanout; | ||
42 | |||
43 | + /** Rotation shadow buffer */ | ||
44 | + struct armsoc_bo *shadow; | ||
45 | + | ||
46 | /** Pointer to the options for this screen. */ | ||
47 | OptionInfoPtr pOptionInfo; | ||
48 | |||
49 | diff --git a/src/drmmode_display.c b/src/drmmode_display.c | ||
50 | index 39fa75c..f054b3a 100644 | ||
51 | --- a/src/drmmode_display.c | ||
52 | +++ b/src/drmmode_display.c | ||
53 | @@ -333,6 +333,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, | ||
54 | goto cleanup; | ||
55 | } | ||
56 | |||
57 | + if (pARMSOC->shadow) | ||
58 | + fb_id = armsoc_bo_get_fb(pARMSOC->shadow); | ||
59 | + | ||
60 | if (crtc->funcs->gamma_set) | ||
61 | crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, | ||
62 | crtc->gamma_blue, crtc->gamma_size); | ||
63 | @@ -860,6 +863,65 @@ drmmode_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, | ||
64 | } | ||
65 | #endif | ||
66 | |||
67 | +static void* | ||
68 | +drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height) | ||
69 | +{ | ||
70 | + ScrnInfoPtr pScrn = crtc->scrn; | ||
71 | + struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn); | ||
72 | + struct armsoc_bo *bo; | ||
73 | + int ret; | ||
74 | + | ||
75 | + bo = armsoc_bo_new_with_dim(pARMSOC->dev, width, height, | ||
76 | + pScrn->bitsPerPixel, pScrn->bitsPerPixel, ARMSOC_BO_SCANOUT); | ||
77 | + if (!bo) | ||
78 | + return NULL; | ||
79 | + | ||
80 | + /* We will use this bo as a scanout, so add it as a framebuffer */ | ||
81 | + ret = armsoc_bo_add_fb(bo); | ||
82 | + if (ret) { | ||
83 | + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, | ||
84 | + "failed to add framebuffer: %s\n", strerror(-ret)); | ||
85 | + armsoc_bo_unreference(bo); | ||
86 | + return NULL; | ||
87 | + } | ||
88 | + | ||
89 | + pARMSOC->shadow = bo; | ||
90 | + | ||
91 | + return bo; | ||
92 | +} | ||
93 | + | ||
94 | +static PixmapPtr | ||
95 | +drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) | ||
96 | +{ | ||
97 | + ScrnInfoPtr pScrn = crtc->scrn; | ||
98 | + ScreenPtr pScreen = pScrn->pScreen; | ||
99 | + struct armsoc_bo *bo = data; | ||
100 | + PixmapPtr pixmap; | ||
101 | + | ||
102 | + pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, armsoc_bo_depth(bo), 0); | ||
103 | + if (!pixmap) { | ||
104 | + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "failed to create pixmap.\n"); | ||
105 | + return NULL; | ||
106 | + } | ||
107 | + (*pScreen->ModifyPixmapHeader)(pixmap, armsoc_bo_width(bo), | ||
108 | + armsoc_bo_height(bo), armsoc_bo_depth(bo), armsoc_bo_bpp(bo), | ||
109 | + armsoc_bo_pitch(bo), armsoc_bo_map(bo)); | ||
110 | + | ||
111 | + return pixmap; | ||
112 | +} | ||
113 | + | ||
114 | +static void | ||
115 | +drmmode_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) | ||
116 | +{ | ||
117 | + ScrnInfoPtr pScrn = crtc->scrn; | ||
118 | + struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn); | ||
119 | + struct armsoc_bo *bo = data; | ||
120 | + | ||
121 | + armsoc_bo_unreference(bo); | ||
122 | + | ||
123 | + pARMSOC->shadow = NULL; | ||
124 | +} | ||
125 | + | ||
126 | static const xf86CrtcFuncsRec drmmode_crtc_funcs = { | ||
127 | .dpms = drmmode_crtc_dpms, | ||
128 | .set_mode_major = drmmode_set_mode_major, | ||
129 | @@ -870,6 +932,9 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = { | ||
130 | #if 1 == ARMSOC_SUPPORT_GAMMA | ||
131 | .gamma_set = drmmode_gamma_set, | ||
132 | #endif | ||
133 | + .shadow_allocate = drmmode_shadow_allocate, | ||
134 | + .shadow_create = drmmode_shadow_create, | ||
135 | + .shadow_destroy = drmmode_shadow_destroy, | ||
136 | }; | ||
137 | |||
138 | |||
139 | -- | ||
140 | 2.25.1 | ||
141 | |||
diff --git a/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc_%.bbappend b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc_%.bbappend index f7b52f58..9f8af267 100644 --- a/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc_%.bbappend +++ b/meta-xilinx-core/dynamic-layers/openembedded-layer/recipes-graphics/xorg-driver/xf86-video-armsoc_%.bbappend | |||
@@ -2,4 +2,12 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/xf86-video-armsoc:" | |||
2 | 2 | ||
3 | SRC_URI:append = " file://0001-src-drmmode_xilinx-Add-the-dumb-gem-support-for-Xili.patch \ | 3 | SRC_URI:append = " file://0001-src-drmmode_xilinx-Add-the-dumb-gem-support-for-Xili.patch \ |
4 | file://0001-armsoc_driver.c-Bypass-the-exa-layer-to-free-the-roo.patch \ | 4 | file://0001-armsoc_driver.c-Bypass-the-exa-layer-to-free-the-roo.patch \ |
5 | " | 5 | file://0001-xf86-video-armsoc-Add-shadow-buffer-hooks.patch \ |
6 | " | ||
7 | EXTRA_MALI400_SRC = " file://0001-xf86-video-armosc-Accelerate-picture-composition.patch \ | ||
8 | file://0001-xf86-video-armosc-Option-to-control-acceleration.patch \ | ||
9 | " | ||
10 | SRC_URI:append = "${@bb.utils.contains('MACHINE_FEATURES', 'mali400', '${EXTRA_MALI400_SRC}', '', d)}" | ||
11 | |||
12 | DEPENDS:append = "${@bb.utils.contains('MACHINE_FEATURES', 'mali400', ' libmali-xlnx', '', d)}" | ||
13 | |||
diff --git a/meta-xilinx-core/dynamic-layers/virtualization-layer/recipes-kernel/lopper/lopper_git.bbappend b/meta-xilinx-core/dynamic-layers/virtualization-layer/recipes-kernel/lopper/lopper_git.bbappend index 8a2b7a46..6de745a5 100644 --- a/meta-xilinx-core/dynamic-layers/virtualization-layer/recipes-kernel/lopper/lopper_git.bbappend +++ b/meta-xilinx-core/dynamic-layers/virtualization-layer/recipes-kernel/lopper/lopper_git.bbappend | |||
@@ -1,9 +1,9 @@ | |||
1 | SRC_URI = "git://github.com/devicetree-org/lopper.git;branch=v0.2024.x;protocol=https" | 1 | SRC_URI = "git://github.com/devicetree-org/lopper.git;branch=master;protocol=https" |
2 | SRCREV = "4fb08575157d7712e0cd50e9e9c07620bc9f8b4b" | 2 | SRCREV = "c0facd087263a24a83f7fad917884348db03175d" |
3 | 3 | ||
4 | FILESEXTRAPATHS:prepend := "${THISDIR}/lopper:" | 4 | FILESEXTRAPATHS:prepend := "${THISDIR}/lopper:" |
5 | 5 | ||
6 | BASEVERSION = "1.1.0" | 6 | BASEVERSION = "1.2.0" |
7 | 7 | ||
8 | RDEPENDS:${PN} += " \ | 8 | RDEPENDS:${PN} += " \ |
9 | python3-ruamel-yaml \ | 9 | python3-ruamel-yaml \ |