User Tools

Site Tools


digic6:registers

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
digic6:registers [2025/05/05 19:06] – [LV peaking (Highlights / zebra)] kitordigic6:registers [2025/05/06 10:12] (current) – [Setting palette for Indexed RGB layers] kitor
Line 3: Line 3:
 ===== Display layers and effects (HDMI, LCD, peaking/zebras control) ===== ===== Display layers and effects (HDMI, LCD, peaking/zebras control) =====
  
-Digic 6 and 7 allow to define up to 8 hardware display layers. Each of layers has independent source, resolution, visible area and even can support multiple variants of YUV and also Indexed RGB buffers. Layers can also do some hardware effects like over/under exposure highlights (known as zebras) and probably more.+Digic 6 and 7 allow to define up to 8 hardware display layers. Each layer has independent data source, resolution, visible area and even can support either one of YUV variants or Indexed RGB input. Layers can also do some hardware effects like over/under exposure highlights (known as zebras) and probably more.
  
 === Note on directly writing the display registers === === Note on directly writing the display registers ===
Line 9: Line 9:
 Depending on generation and model, Canon code will overwrite some (but not all) of the register values based on data structures stored in RAM. This applies also to layers code doesn't use. Depending on generation and model, Canon code will overwrite some (but not all) of the register values based on data structures stored in RAM. This applies also to layers code doesn't use.
  
-Output has to be active when MMIO is being written, otherwise changes will be ignored.+Output has to be active when corresponding MMIO is being written, otherwise changes will be ignored. 
  
 ==== Hardware compositor / layers ==== ==== Hardware compositor / layers ====
  
-There should be 3rd set of registers used for analog output similar to ones below.+Please note that Digic 6 and up have two separate concepts of layers and image compositing. One is GPU accelerated software solution known as Ximr/XCM - used by Canon code to draw OSD (GUI).
  
-^ Base address   ^ Output  +For more details on Ximr/XCM and GUI, see this forum post: 
-| ''0xD2010510'' | HDMI    |  +[[https://www.magiclantern.fm/forum/index.php?topic=26024.0|Compositorslayerscontexts in RGB and YUV - How Digic 7(6?)+ draw GUI]]
-| ''0xD2013810'' | LCD     | +
-| ''??''         | Video   |  +
- +
-Each address consists of **8** sets (layers), each consisting of eight 32 bit values representing each hardware layerMMIO order starts from bottom layer (0) to topmost (7) in Z axis. +
- +
-^ Offset ^ Summary          ^ Description     +
-+0     | Flags            | Configures data typetransformations (flipupscale), zebras, etc | +
-| +0x4   | Vram index ?     | Assignment to a peviously registered Vram buffer ID +
-| +0x8   | Input offsets    | Source buffer offsets (skips). ''x_off | (y_off << 16)'' +
-| +0xC   | Vram resolution  | Source buffer size in pixels. ''width | (height << 16)'' +
-+0x10  | Output offsets   | Destination offsets. ''x_off | (y_off << 16)'' +
-| +0x14  | scaling flag ?   | In HDMI mode it has to be set to 1 so vertical doubling works. +
-| +0x18  | ?                |           +
-| +0x1C  | ?                | +
- +
-=== Vram index ===+
  
-Wildly enough, MMIO doesn't take source buffer address, but rather a number associated to VRAM, which is registered via different MMIO. See TBD. +This section describes hardware layer compositor supported on Digic 6 and 7 models. Canon uses it to mix OSD (GUIwith image preview (LiveViewplayback, etc). Similar hardware exists in later models (Digic 8 and up) but it has different capabilities, thus it is covered in dedicated section[[digic8:registersDigic 8 Registers]]
- +
-Vram index register seems to also take two 16 bit values instead of one, possibly for layers that use separate image and alpha buffers (eg UYVY+AA, unconfirmed). +
- +
-=== Resolution, offsets === +
- +
-  * Vram resolution is the resolution of entire buffer, in pixels. +
-  * Input offsets will "crop" source image by skipping everything up to X,Y (eg. to cut black borders) +
-  * Output offsets will move rendered image on screen by X,Y pixels. +
- +
-=== Flags === +
- +
-So far we observed following flags by doing some empirical tests: +
- +
-<code> +
-#define HWLAYER_ENABLE           0x1 +
-#define HWLAYER_ALWAYS_SET     0x300 // At least on indexed, black (index 0?) becomes transparent with this not set +
-#define HWLAYER_FLIP_H        0x2000 +
-#define HWLAYER_FLIP_V        0x4000 +
-#define HWLAYER_DOUBLE_H     0x20000 +
-#define HWLAYER_DOUBLE_V     0x40000 +
-#define HWLAYER_ZEBRAS    0x10000000 +
- +
-// Going through lowest byte (except LSB which is ENABLE bit) +
-// reveals multiple combinations that work for some YUV and indexed formats. +
-#define HWLAYER_TYPE_OSD     0x40 +
-#define HWLAYER_TYPE_LV      0x04 +
-#define HWLAYER_TYPE_INDEXED 0x48 +
- +
-// No idea, Canon uses HWLAYER_UNK on LCD, HWLAYER_ZEBRAS on HDMI +
-// Seems to have no effect at leat on indexed RGB +
-#define HWLAYER_UNK       0x40000000 +
-</code> +
- +
-Combining those flags is required to get desired effects. For example, `0x10000341` is YUV/no transparency  buffer and zebras enabled on that layer. `0x660349` will result in indexed RGB source, upscaled 2x and mirrored in both axes. +
- +
-Please note than for unknown reasons HWLAYER_DOUBLE_V doesn't seem to work on HDMI unless scaling flag (+0x14is set to 1.  +
- +
-Canon code will also forcefully overwrite some of the flags (zebrasupscaling registerfrom RAM data structures so values may need to be updated there instead of MMIO directly. +
- +
-=== How original firmware utilizes HW layers? === +
- +
-In default configuration, bootloader uses Indexed RGB on layer 0 to draw things on screen. +
-EOS codebase seems to use layer 0 to display active preview (LV, photo) image and layer 5 for GUI (referred as internally as OSD). Other layers are inactive. +
- +
-The notes below are from 80D, but 77D (DIGIC 7) has the same setup: +
- +
-<code> +
-    //     Flags    Kind    | Output | TypeOutput  | Output layer ID (80D) +
-    //   0x40000305 | OSD     | LCD    | YUV+Alpha.  | 5 +
-    //   0x10060305 | OSD     | HDMI   | YUV+Alpha   | 5 +
-    //   0x40000341 | LV      | LCD    | YUV         | 0 +
-    //   0x10000341 | LV      | HDMI   | YUV         | 0 +
-    //   0x00000349 | BootLdr | LCD    | Indexed RGB | 0 +
-    //   0x00000300 | N/A     | Any    | Inactive    | Layers not used by Canon +
-</code>+
  
 ==== VRAM registration ==== ==== VRAM registration ====
  
-Before VRAM can be used by a hardware layer, it has to be registered and assigned an ID.+Before VRAM buffer can be used by a hardware layer, it has to be registered and assigned an ID.
  
  
-^ Base address   ^ Generation  +^ Base address   ^ Generation ^ 
-| ''0xD2030100'' | DIGIC 6 +| ''0xD2030100'' | DIGIC 6 | 
-| ''0xD2060040'' | DIGIC 7+| ''0xD2060040'' | DIGIC 7 |
  
 MMIO structure is as below: MMIO structure is as below:
  
-^ Offset ^ Summary     ^ Description +^ Offset ^ Summary     ^ Description ^ 
-| +0x0   | index       | Numerical ID, 8 bits - used for assignment in HW layer registers. +| +0x0   | index       | Numerical ID, 8 bits - used for assignment in HW layer registers. | 
-| +0x4   | pitch ?     | Derivative of image width. Computed as ''(( width << 16) >> 20) - 1 | 0x20000'' +| +0x4   | pitch ?     | Derivative of image width. Computed as ''(( width \<\< 16) >> 20) - 1 | 0x20000'' | 
-| +0x8   | pointer-ish | Vram address bit shifted 8 to the right. Possibly to enforce alignment.+| +0x8   | pointer-ish | Vram address bit shifted 8 to the right. Possibly to enforce alignment. |
  
-MMIO as to be written in order, be aware of any compiler optimizations (best to set data structures as volatile).+MMIO has to be written in order, be aware of any compiler optimizations (best to set data structures as volatile).
  
 Example code: Example code:
Line 133: Line 63:
 ==== Setting palette for Indexed RGB layers ==== ==== Setting palette for Indexed RGB layers ====
  
-This works differently than Digic 5 and below. There's a MMIO structure (per output), which takes a pointer to palette of 256 uint32_t entries stored in RAM.+This works differently than Digic 5 and below. There's a MMIO structure (per output), which takes a pointer to palette of 256 uint32_t entries stored in RAM. Palette is assigned to output, not layer - so all layers on given output will be rendered using the same palette.
  
-^ Address        ^ Output  +Address didn't change between Digic 6 and 7. 
-| ''0xD2010680'' | HDMI + 
-| ''0xD20139A0'' | LCD +^ Address        ^ Output ^ 
-| ''?''          | Video+| ''0xD2010680'' | HDMI | 
 +| ''0xD20139A0'' | LCD | 
 +| ''?''          | Video |
  
 MMIO structure is as below: MMIO structure is as below:
  
-^ Offset ^ Summary     ^ Description +^ Offset ^ Summary     ^ Description ^ 
-| +0x0   | apply       | Write 0x1 to apply selected palette +| +0x0   | apply       | Write 0x1 to apply selected palette | 
-| +0x4   | flag maybe  | Unknown, Canon BL writes 0xFF +| +0x4   | flag maybe  | Unknown, Canon BL writes 0xFF | 
-| +0x8   | pointer-ish | Palette address, bit shifted 4 to the right. Possibly to enforce alignment.+| +0x8   | pointer-ish | Palette address, bit shifted 4 to the right. Possibly to enforce alignment. |
  
-Please note that fields has to be written in order: flag, pointer, apply.+Please note that fields have to be written in order: 'flag''pointer''apply'.
  
 Example code: Example code:
Line 166: Line 98:
 } }
 </code> </code>
 +
 +==== Layers setup ====
 +
 +There should be 3rd set of registers used for analog output similar to ones below. Address didn't change between Digic 6 and 7.
 +
 +^ Base address   ^ Output 
 +| ''0xD2010510'' | HDMI    | 
 +| ''0xD2013810'' | LCD     |
 +| ''??''         | Video   
 +
 +Each layer config consists of eight 32 bit configuration words (registers). There are 8 total layers (8 sets of 8 registers) starting from Base address. MMIO is Z ordered starting from bottom layer (0) to topmost one (7).
 +
 +
 +^ Offset ^ Summary          ^ Description ^
 +| +0     | Flags            | Configures data type, transformations (flip, upscale), zebras, etc |
 +| +0x4   | Vram index ?     | Assignment to a previously registered Vram buffer ID |
 +| +0x8   | Input offsets    | Source buffer offsets (skips). ''%%x_off | (y_off << 16)%%'' |
 +| +0xC   | Vram resolution  | Source buffer size in pixels. ''%%width | (height << 16)%%'' |
 +| +0x10  | Output offsets   | Destination offsets. ''%%x_off | (y_off << 16)%%'' |
 +| +0x14  | scaling flag ?   | In HDMI mode it has to be set to 1 so vertical doubling works. |
 +| +0x18  | ?                | |
 +| +0x1C  | ?                | |
 +
 +=== Vram index ===
 +
 +Strangely enough, MMIO doesn't take source buffer address, but rather a number associated with VRAM, which is registered via different MMIO. See [[registers##vram_registration|Vram registration]].
 +
 +Vram index register seems to also take two 16 bit values instead of one, possibly for layers that use separate image and alpha buffers (eg UYVY+AA, unconfirmed).
 +
 +=== Resolution, offsets ===
 +
 +  * Vram resolution is the resolution of entire buffer, in pixels.
 +  * Input offsets will "crop" source image by skipping everything up to X,Y (eg. to cut black borders)
 +  * Output offsets will move rendered image on screen by X,Y pixels.
 +
 +=== Flags ===
 +
 +So far we observed following flags by doing some empirical tests:
 +
 +<code>
 +#define HWLAYER_ENABLE           0x1
 +#define HWLAYER_ALWAYS_SET     0x300 // At least on indexed, black (index 0?) becomes transparent with this not set
 +#define HWLAYER_FLIP_H        0x2000
 +#define HWLAYER_FLIP_V        0x4000
 +#define HWLAYER_DOUBLE_H     0x20000
 +#define HWLAYER_DOUBLE_V     0x40000
 +#define HWLAYER_ZEBRAS    0x10000000
 +
 +// Going through lowest byte (except LSB which is ENABLE bit)
 +// reveals multiple combinations that work for some YUV and indexed formats.
 +#define HWLAYER_TYPE_UYVY_AA     0x40   // UYVY + separate alpha, eg. OSD
 +#define HWLAYER_TYPE_UYVY        0x04   // UYVY, no alpha - eg. LV
 +#define HWLAYER_TYPE_INDEXED_RGB 0x48   // Indexed RGB - eg. bootloader
 +
 +// No idea, Canon uses HWLAYER_UNK on LCD, HWLAYER_ZEBRAS on HDMI
 +// Seems to have no effect, at least on indexed RGB
 +#define HWLAYER_UNK       0x40000000
 +</code>
 +
 +Combining those flags is required to get desired effects. For example, ''0x10000341'' is YUV/no transparency  buffer and zebras enabled on that layer. ''0x660349'' will result in indexed RGB source, upscaled 2x and mirrored in both axes.
 +
 +Please note than for unknown reasons ''HWLAYER_DOUBLE_V'' doesn't work on HDMI unless scaling flag (''+0x14'') is set to ''1''
 +
 +Canon code will also forcefully overwrite some of the flags (zebras, upscaling register) from RAM data structures so values may need to be updated there instead of MMIO directly.
 +
 +=== How does original firmware utilize HW layers? ===
 +
 +In default configuration, bootloader uses Indexed RGB on layer 0 to draw things on screen.
 +EOS codebase seems to use layer 0 to display active preview (LV, photo) image and layer 5 for GUI (referred as internally as OSD). Other layers are inactive.
 +
 +The notes below are from 80D, but 77D (DIGIC 7) has the same setup:
 +
 +
 +^  Flags        ^ Kind     ^ Output ^ Output type ^ Output layer ID (80D) ^
 +| ''0x40000305'' | OSD     | LCD    | YUV+Alpha.  | 5 |
 +| ''0x10060305'' | OSD     | HDMI   | YUV+Alpha   | 5 |
 +| ''0x40000341'' | LV      | LCD    | YUV         | 0 |
 +| ''0x10000341'' | LV      | HDMI   | YUV         | 0 |
 +| ''0x00000349'' | BootLdr | LCD    | Indexed RGB | 0 |
 +| ''0x00000300'' | N/A     | Any    | Inactive    | Unused layers |
 +
  
 ==== Display effects (zebras, etc) ==== ==== Display effects (zebras, etc) ====
Line 207: Line 220:
 | speed        | 0-1   | lines/dots are moving slower -> faster                  | | speed        | 0-1   | lines/dots are moving slower -> faster                  |
 | style        | 0-3   | 0: light dots, 1: thin lines, 2: thick lines, 3 = 0     | | style        | 0-3   | 0: light dots, 1: thin lines, 2: thick lines, 3 = 0     |
-| opacity      | 0-7   very opaque -> solid color                              |+| opacity      | 0-7   0 for transparent -> 7 for solid color                  |
 | underexpo_th | 0-255 | Threshold on undexexpo register, ignored on overexpo    |  | underexpo_th | 0-255 | Threshold on undexexpo register, ignored on overexpo    | 
 | overexpo_th  | 0-255 | Threshold on overexpo register, ignored on underexpo    | | overexpo_th  | 0-255 | Threshold on overexpo register, ignored on underexpo    |
digic6/registers.1746464770.txt.gz · Last modified: 2025/05/05 19:06 by kitor