VirtualBox

Changeset 74779 in vbox for trunk


Ignore:
Timestamp:
Oct 12, 2018 8:05:16 AM (6 years ago)
Author:
vboxsync
Message:

Additions/linux/vboxvideo: only set the views once, at initialisation time.
bugref: 9253: Enabling 2nd virtual screen results in an assert.
Views in vboxvideo/HGSMI are a concept used to tell the graphics card about
the virtual frame-buffer in use for each virtual screen. Up until now we have
set these prior to each mode-set operation. The assertion reported in this
bug was due to a mismatch when enabling and disabling screens using a mode-set
for DPMS.
In fact though, there is no good reason for the graphics hardware to need to
know about the frame-buffers at all. It is enough for it to know the offset
in the video memory where scan-out starts, along with size and stride. So
this change switches to just setting the views once, at driver initialisation
time, and setting them to cover the whole range of potentially usable video
memory for each screen at that point. Thus whatever framebuffer is created
for a mode-set will always be a subset of the view.

Location:
trunk/src/VBox/Additions/linux/drm
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/linux/drm/vbox_main.c

    r74773 r74779  
    4040#include <VBoxVideoVBE.h>
    4141
     42#include "hgsmi_channels.h"
     43
    4244static void vbox_user_framebuffer_destroy(struct drm_framebuffer *fb)
    4345{
     
    232234#endif
    233235
     236/**
     237 * Tell the host about the views.  This design originally targeted the
     238 * Windows XP driver architecture and assumed that each screen would
     239 * have a dedicated frame buffer with the command buffer following it,
     240 * the whole being a "view".  The host works out which screen a command
     241 * buffer belongs to by checking whether it is in the first view, then
     242 * whether it is in the second and so on.  The first match wins.  We
     243 * cheat around this by making the first view be the managed memory
     244 * plus the first command buffer, the second the same plus the second
     245 * buffer and so on.
     246 */
     247static int vbox_set_views(struct vbox_private *vbox)
     248{
     249        VBVAINFOVIEW *p;
     250        int i;
     251
     252        p = VBoxHGSMIBufferAlloc(vbox->guest_pool, sizeof(*p),
     253                               HGSMI_CH_VBVA, VBVA_INFO_VIEW);
     254        if (!p)
     255                return -ENOMEM;
     256
     257        for (i = 0; i < vbox->num_crtcs; ++i) {
     258                p->u32ViewIndex = i;
     259                p->u32ViewOffset = 0;
     260                p->u32ViewSize = vbox->available_vram_size +
     261                        i * VBVA_MIN_BUFFER_SIZE;
     262                p->u32MaxScreenSize = vbox->available_vram_size;
     263
     264                VBoxHGSMIBufferSubmit(vbox->guest_pool, p);
     265        }
     266
     267        VBoxHGSMIBufferFree(vbox->guest_pool, p);
     268
     269        return 0;
     270}
     271
    234272static int vbox_accel_init(struct vbox_private *vbox)
    235273{
    236         unsigned int i;
     274        unsigned int i, ret;
    237275
    238276        vbox->vbva_info = devm_kcalloc(vbox->dev->dev, vbox->num_crtcs,
     
    258296
    259297        vbox_enable_accel(vbox);
    260 
    261         return 0;
     298        ret = vbox_set_views(vbox);
     299        if (ret)
     300                goto err_pci_iounmap;
     301
     302        return 0;
     303
     304err_pci_iounmap:
     305        pci_iounmap(vbox->dev->pdev, vbox->vbva_buffers);
     306        return ret;
    262307}
    263308
  • trunk/src/VBox/Additions/linux/drm/vbox_mode.c

    r74773 r74779  
    4545
    4646#include "VBoxVideo.h"
    47 #include "hgsmi_channels.h"
    4847
    4948static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
     
    108107        flags |= vbox_crtc->disconnected ? VBVA_SCREEN_F_DISABLED : 0;
    109108        VBoxHGSMIProcessDisplayInfo(vbox->guest_pool, vbox_crtc->crtc_id,
    110                                    x_offset, y_offset,
     109                                   x_offset, y_offset, vbox_crtc->fb_offset +
    111110                                   crtc->x * bpp / 8 + crtc->y * pitch,
    112111                                   pitch, width, height,
    113112                                   vbox_crtc->blanked ? 0 : bpp, flags);
    114 }
    115 
    116 static int vbox_set_view(struct drm_crtc *crtc)
    117 {
    118         struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
    119         struct vbox_private *vbox = crtc->dev->dev_private;
    120         VBVAINFOVIEW *p;
    121 
    122         /*
    123          * Tell the host about the view.  This design originally targeted the
    124          * Windows XP driver architecture and assumed that each screen would
    125          * have a dedicated frame buffer with the command buffer following it,
    126          * the whole being a "view".  The host works out which screen a command
    127          * buffer belongs to by checking whether it is in the first view, then
    128          * whether it is in the second and so on.  The first match wins.  We
    129          * cheat around this by making the first view be the managed memory
    130          * plus the first command buffer, the second the same plus the second
    131          * buffer and so on.
    132          */
    133         p = VBoxHGSMIBufferAlloc(vbox->guest_pool, sizeof(*p),
    134                                HGSMI_CH_VBVA, VBVA_INFO_VIEW);
    135         if (!p)
    136                 return -ENOMEM;
    137 
    138         p->u32ViewIndex = vbox_crtc->crtc_id;
    139         p->u32ViewOffset = vbox_crtc->fb_offset;
    140         p->u32ViewSize = vbox->available_vram_size - vbox_crtc->fb_offset +
    141                        vbox_crtc->crtc_id * VBVA_MIN_BUFFER_SIZE;
    142         p->u32MaxScreenSize = vbox->available_vram_size - vbox_crtc->fb_offset;
    143 
    144         VBoxHGSMIBufferSubmit(vbox->guest_pool, p);
    145         VBoxHGSMIBufferFree(vbox->guest_pool, p);
    146 
    147         return 0;
    148113}
    149114
     
    287252                list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
    288253                                    head) {
    289                         vbox_set_view(crtc);
    290254                        vbox_do_modeset(crtci, &crtci->mode);
    291255                }
     
    305269                return ret;
    306270        mutex_lock(&vbox->hw_mutex);
    307         ret = vbox_set_view(crtc);
    308271        if (!ret)
    309272                vbox_do_modeset(crtc, mode);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette