[Bug 39421] Majesty Gold HD runs very slowly

wine-bugs at winehq.org wine-bugs at winehq.org
Sat Oct 17 07:10:23 CDT 2015


https://bugs.winehq.org/show_bug.cgi?id=39421

--- Comment #8 from Jonas Maebe <jonas.bugzilla at gmail.com> ---
(In reply to Jonas Maebe from comment #7)
> I guess it would boil down to implementing double buffering ourselves:
> always keep a copy of the previous image in VRAM, and then composite that
> one (on the card) with textures created from the the new partial blits
> (which come from system memory and which only cover part of the screen).

As may be clear from the above, until now I know/knew very little about either
DirectDraw and OpenGL (other than high level concepts). I've been reading up a
bit on both, and disregarding the adagio that"a little knowledge is worse than
none", here's what I understood from it:

1) a ddraw surface can be updated in two ways: either you lock the surface
manually and directly manipulate the pixel data, or you use the ddraw blit
functions. In the former case, ddraw has no clue what exactly changed, in the
latter case it knows exactly what changed.

2) you could have an OpenGL FBO, three texture images and a single render
buffer image. Initially, you make texture image 1 all black. You assign texture
image 2 via a texture object to one of the color attachments of the FBO, and
the render buffer to to the depth attachment. Then you use the following logic
after every blit:

  previous_frame_tex = texture_image_1;
  blit_data_tex = texture_image_2;
  new_frame_tex = texture_image_3;

  /* render the new frame into a texture ... */
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
new_frame_tex);
  /* ... and into a frame to display */
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_FRAMEBUFFER, render_buffer);
  /* set up textures with data from previous frame and new frame */
  glGenTextures(2, &textures);
  glBindTexture(textures[0], previous_frame_tex);
  glBindTextture(textures[1],new_drawing_tex);
  ...
  /* render */
  ...
  /* flip FBO to frontbuffer */
  ...
  /* flush */
  glFlush();

  /* set newly rendered frame as "previous frame" for the next invocation */
  texture_image_1 = new_frame_tex;
  /* switch the texture ID for the next new frame */
  texture_image_3 = previous_frame_tex;

Now,
a) I don't know what the conditions are under which you can be confident that
the frontbuffer will never be changed by anything else but ddraw (so that you
can in fact use the rendering outcome of the previous frame as basis for a new
one). In the case of this game, we always take the wined3d_surface_blt() path
in ddraw_surface_update_frontbuffer(), whose comment says "Nothing to do, we
control the frontbuffer, or at least the parts we care about.", so that
suggests to me that it may be okay (along with the fact that it runs quickly on
native, and that it presumably does something similar there)
b) I don't know in what way the wined3d internals can conflict with this
approach
c) I don't know what wined3d does exactly currently that makes it so slow. Is
it just blitting a complete new screen after every (small) blit, or is it in
addition also getting the data from the frontbuffer for every frame? I think
it's the former, but I'm not sure.
d) probably other things I haven't thought of

I'll also attach the profiling data for the drawing thread. Some notes about
this data. Note that it's sampling based, but the percentages *include* time
spent blocked for kernel operations to complete. That's why the thread is
recorded as using 8.5% of the total sampled time, as there are 12 "full time"
threads in the program (I guess it's rounded up) and e.g. even threads that do
almost nothing but spend time waiting for a select call to finish, are counted
just as much as a thread that is constantly calculating.

The reason I'm attaching this data, is that it nicely illustrates how the game
is indeed constantly waiting for glFlush() to finish in the main drawing/game
logic thread. It also shows which paths it takes through ddraw and wined3d.

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list