Announcement

Collapse
No announcement yet.

AMD Sends In Their Initial AMDGPU Driver Updates For Linux 5.2

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #21
    Originally posted by pixo View Post

    Adaptive-sync is not supported by modesetting DDX but that is all i am aware of.
    There's also TearFree, just for one more example. The amdgpu driver is generally more polished and robust.

    Patched xserver using modesetting DDX can use DRM leases for multiseat with hw acceleration for every seat via 1 GPU.
    That does not work for amdgpu DDX and I could not make it work.
    That requires porting at least the DRM_IOCTL_CRTC_QUEUE_SEQUENCE related changes from modesetting as well, maybe more.

    Comment


    • #22
      Originally posted by Kraut View Post
      This is not about bandwidth. This is about the constant time it takes for the power mode (at last for vram) to switch. If your monitors vblank period is shorter then that you can get flickering each time the power mode changes.
      I don't understand how [the constant time it takes for the power mode (at last for vram) to switch] is preventing you to manually select the lowest mclk+sclk for non-demanding desktop work with a mid-range or high-end AMD GPU.

      Comment


      • #23
        Originally posted by atomsymbol View Post

        I don't understand how [the constant time it takes for the power mode (at last for vram) to switch] is preventing you to manually select the lowest mclk+sclk for non-demanding desktop work with a mid-range or high-end AMD GPU.
        Sure, if you manually overwrite the auto power management and stick to lower power mode it should work fine. (If not that is a driver bug or developer oversight)
        It's just the default auto power management setting that force high power mode when switching could cause flickering on your connected screens.

        Comment


        • #24
          Originally posted by Kraut View Post

          Sure, if you manually overwrite the auto power management and stick to lower power mode it should work fine. (If not that is a driver bug or developer oversight)
          It's just the default auto power management setting that force high power mode when switching could cause flickering on your connected screens.
          My apologies for the long post; I'm not yet smart enough to handle attachments or links.

          I have an RX 580 with 2 monitors, primary @ 75Hz & secondary @ 60Hz. I have ppfeaturemask set to allow undervolting which is very beneficial for the RX 580. For me, the flickering from automatic memory p-state switching is unbearable; the manual workaround is essential.

          Leaning heavily on the thought process behind grmat's amdgpu-fancontrol I've written a similar script to manage the memory p-states. This switches between memory p-states based upon gpu_busy_percent, but only does so very reluctantly. It works well for my situation.

          By the way, I'm a long-time lurker; Phoronix is a great resource.

          Code:
          #!/bin/bash
          
          # Copyright George Scorer, March 2019.
          # You may copy and/or modify and/or use this script as you see fit. There is no warranty of any kind.
          
          # Each memory p-state switch causes a screen flicker. Tweak these variables to match
          # your personal 'flicker aversion' vs 'efficiency and silence desire' trade-off.
          # These variables are integers.
          GPU_BUSY_UP=80                 # The gpu_busy_percent at and above which we consider the gpu is busy
          GPU_BUSY_DOWN=10               # The gpu_busy_percent at and below which we consider the gpu is idle
          LOW_MEM_STATE=0                # Choose between 0 & 1
          STANDARD_SLEEP_INTERVAL=1      # in seconds. How frequently we should poll the core p-state.
          DOWN_DELAY=10                  # in seconds. How long the gpu should appear to be idle before we drop down.
          # These variables are floating point.
          CONCENTRATE_SLEEP_INTERVAL=0.1 # in seconds. How frequently we should poll when we're proposing to jump up.
          UP_DELAY=0.5                   # in seconds. How long the gpu should appear to be busy before we jump up.
          
          # Sysfs paths here are hardcoded for one amdgpu card at card0; adjust as needed.
          FILE_PERF_LEVEL=/sys/class/drm/card0/device/power_dpm_force_performance_level
          FILE_MEM_P_STATE=/sys/class/drm/card0/device/pp_dpm_mclk
          FILE_GPU_BUSY_PERCENT=/sys/class/drm/card0/device/gpu_busy_percent
          
          
          # check for root privileges
          if [ $UID -ne 0 ]
          then
            echo "Writing to sysfs requires root privileges; relaunch as root"
            exit 1
          fi
          
          function get_started {
          # Set gpu performance level control to manual
          # echo "Setting performance level control to manual"
            echo "manual" > "$FILE_PERF_LEVEL"
          
          # Read the current gpu busy percentage and set a corresponding initial memory p-state
          
            GPU_BUSY_PERCENT="$(<$FILE_GPU_BUSY_PERCENT)"
          
            if [ "$GPU_BUSY_PERCENT" -ge "$GPU_BUSY_UP" ]; then
              MEM_P_STATE=2
            else
              MEM_P_STATE=$LOW_MEM_STATE
            fi
          
            echo "$MEM_P_STATE" > "$FILE_MEM_P_STATE"
            echo "New gpu memory p-state: $MEM_P_STATE"
            PROPOSED_MEM_P_STATE=$MEM_P_STATE
            SLEEP_INTERVAL=$STANDARD_SLEEP_INTERVAL
          }
          
          
          function check_gpu_busy_percent {
          
            GPU_BUSY_PERCENT="$(<$FILE_GPU_BUSY_PERCENT)"
          
          # Propose what the corresponding memory p-state should be
            OLD_PROPOSED_MEM_P_STATE=$PROPOSED_MEM_P_STATE
            PROPOSED_MEM_P_STATE=$MEM_P_STATE
            if [ "$GPU_BUSY_PERCENT" -ge "$GPU_BUSY_UP" ]; then
              PROPOSED_MEM_P_STATE=2
            elif [ "$GPU_BUSY_PERCENT" -le "$GPU_BUSY_DOWN" ]; then
              PROPOSED_MEM_P_STATE=$LOW_MEM_STATE
            fi
          
            if [ "$PROPOSED_MEM_P_STATE" -eq "$MEM_P_STATE" ]; then
          #   We're happy in this memory state - go back to sleep
              SLEEP_INTERVAL=$STANDARD_SLEEP_INTERVAL
            else
          #   We want to change so determine whether we're already counting down.    
              if [ "$PROPOSED_MEM_P_STATE" -ne "$OLD_PROPOSED_MEM_P_STATE" ]; then
          #     Start a new countdown
                if [ "$PROPOSED_MEM_P_STATE" -eq 2 ]; then
          #       We might be going up; check more frequently to avoid jumping on a spike. (bad)
                  CHANGE_COUNTDOWN=$UP_DELAY
                  SLEEP_INTERVAL=$CONCENTRATE_SLEEP_INTERVAL
                else
                  CHANGE_COUNTDOWN=$DOWN_DELAY
                  SLEEP_INTERVAL=$STANDARD_SLEEP_INTERVAL
                fi
              else
                CHANGE_COUNTDOWN=$( echo "$CHANGE_COUNTDOWN - $SLEEP_INTERVAL" | bc )
              fi
                
              if ((  $( echo "$CHANGE_COUNTDOWN <= 0.0" | bc ) )); then
          #   The countdown has reached 0 so change the memory p-state.
                MEM_P_STATE=$PROPOSED_MEM_P_STATE
          #      echo "manual" > "$FILE_PERF_LEVEL"
                echo "$MEM_P_STATE" > "$FILE_MEM_P_STATE"
                echo "New gpu memory p-state: $MEM_P_STATE"
                
              fi
            fi
          
          #   echo "Old  Prop  Mem  Busy %  Countdown"
          #   echo "  $OLD_PROPOSED_MEM_P_STATE     $PROPOSED_MEM_P_STATE    $MEM_P_STATE       $GPU_BUSY_PERCENT         $CHANGE_COUNTDOWN"
            }
          
          function reset_on_fail {
            echo "Exiting, setting memory p-state to 2"
            echo "manual" > "$FILE_PERF_LEVEL"
            echo "2" > "$FILE_MEM_P_STATE"
            exit 1
          }
          
          # always try to fix memory p-state 2 on failure
          trap "reset_on_fail" SIGINT SIGTERM
          
          function run_daemon {
            while :; do
          #   If mem_p_state in sysfs differs from our calculated MEM_P_STATE then restart.
          #     Causes: external change to power_dpm_force_performance_level, system sleep, a change to display configuration or a commit of a gpu voltage or clock frequency change.
          #     Note: we're only testing once every $SLEEP_INTERVAL seconds so it might take us a long time to spot a momentary change in mem_p_state.
              SYS_MEM_P_STATE="$(grep -F '*' $FILE_MEM_P_STATE)"
              SYS_MEM_P_STATE=${SYS_MEM_P_STATE:0:1}
          
              if [[ $(< $FILE_PERF_LEVEL) != "manual" ]]; then
                echo "Something's changed memory performance level; taking back control."
                get_started
              fi
              if [[ $MEM_P_STATE != $SYS_MEM_P_STATE ]]; then
                echo "Something's meddling with gpu memory p-states; taking back control."
                get_started
              fi
              sleep $SLEEP_INTERVAL
              check_gpu_busy_percent
            done
          }
          
          get_started
          
          # start the loop
          run_daemon

          Comment


          • #25
            Originally posted by Kraut View Post
            Sure, if you manually overwrite the auto power management and stick to lower power mode it should work fine. (If not that is a driver bug or developer oversight)
            The manual sclk/mclk overwrite used to work in some kernel versions, then broke, worked again, broke again, currently it is broken for about the last 4 months or so of amd-staging-drm-next history.
            While it did work, the manually overwritten values were used only until the next mode change, DPMS-off or suspend/resume.
            It's a mess. And there is absolutely no plausible reason to see why these features work-then-break-again every few months. I have really lost all hope that this development process will converge into something stable.

            Comment


            • #26
              Originally posted by dwagner View Post
              While it did work, the manually overwritten values were used only until the next mode change, DPMS-off or suspend/resume.
              A script for suspend/resume:

              Code:
              $ cat $HOME/bin/shared/suspend-computer 
              #!/bin/bash
              
              # suspend 
              sync
              sudo sh -c "echo mem > /sys/power/state"
              
              # resume
              if [ $(hostname) == "desktop" ]; then
                  sleep 1
                  gpu-powersave  # Script which selects lowest mclk+sclk
              fi
              Or gpu clocks can be recovered in a script which is run (e.g: by systemd) when the machine resumes from suspend.

              Comment

              Working...
              X