[PATCHv4 2/3] wined3d: Use an rbtree for storing shaders for texture format conversion/blitting
Stefan Dösinger
stefandoesinger at gmail.com
Thu Feb 13 07:13:45 CST 2014
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Looks good to me.
Am 2014-02-13 13:05, schrieb Martin Storsjo:
> --- Fixed the final style issues and added comments about who
> activates the GL context. --- dlls/wined3d/arb_program_shader.c |
> 204 +++++++++++++++++++++++++------------- 1 file changed, 134
> insertions(+), 70 deletions(-)
>
> diff --git a/dlls/wined3d/arb_program_shader.c
> b/dlls/wined3d/arb_program_shader.c index 93a6e31..a273eac 100644
> --- a/dlls/wined3d/arb_program_shader.c +++
> b/dlls/wined3d/arb_program_shader.c @@ -6768,22 +6768,74 @@ const
> struct fragment_pipeline arbfp_fragment_pipeline = {
> arbfp_fragmentstate_template, };
>
> -struct arbfp_blit_priv { - GLenum yuy2_rect_shader,
> yuy2_2d_shader; - GLenum uyvy_rect_shader, uyvy_2d_shader; -
> GLenum yv12_rect_shader, yv12_2d_shader; - GLenum
> nv12_rect_shader, nv12_2d_shader; - GLenum p8_rect_shader,
> p8_2d_shader; +struct arbfp_blit_type +{ + enum complex_fixup
> fixup; + GLenum textype; +}; + +struct arbfp_blit_desc +{ +
> GLenum shader; + struct arbfp_blit_type type; + struct
> wine_rb_entry entry; +}; + +struct arbfp_blit_priv +{ + struct
> wine_rb_tree shaders; GLuint palette_texture; };
>
> +static int arbfp_blit_type_compare(const void *key, const struct
> wine_rb_entry *entry) +{ + const struct arbfp_blit_type *ka =
> key; + const struct arbfp_blit_type *kb =
> &WINE_RB_ENTRY_VALUE(entry, const struct arbfp_blit_desc,
> entry)->type; + + if (ka->fixup != kb->fixup) + return
> ka->fixup < kb->fixup ? -1 : 1; + if (ka->textype !=
> kb->textype) + return ka->textype < kb->textype ? -1 : 1; +
> return 0; +} + +/* Context activation is done by the caller. */
> +static void arbfp_free_blit_shader(struct wine_rb_entry *entry,
> void *context) +{ + const struct wined3d_gl_info *gl_info =
> context; + struct arbfp_blit_desc *entry_arb =
> WINE_RB_ENTRY_VALUE(entry, struct arbfp_blit_desc, entry); + +
> GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader)); +
> checkGLcall("glDeleteProgramsARB(1, &entry_arb->shader)"); +
> HeapFree(GetProcessHeap(), 0, entry_arb); +} + +const struct
> wine_rb_functions wined3d_arbfp_blit_rb_functions = +{ +
> wined3d_rb_alloc, + wined3d_rb_realloc, + wined3d_rb_free, +
> arbfp_blit_type_compare, +}; + static HRESULT
> arbfp_blit_alloc(struct wined3d_device *device) { + struct
> arbfp_blit_priv *priv; device->blit_priv =
> HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct
> arbfp_blit_priv)); if(!device->blit_priv) { ERR("Out of
> memory\n"); return E_OUTOFMEMORY; } + priv = device->blit_priv;
> + + if (wine_rb_init(&priv->shaders,
> &wined3d_arbfp_blit_rb_functions) == -1) + { +
> ERR("Failed to initialize rbtree.\n"); +
> HeapFree(GetProcessHeap(), 0, device->blit_priv); +
> device->blit_priv = NULL; + return E_OUTOFMEMORY; + } +
> return WINED3D_OK; }
>
> @@ -6793,17 +6845,8 @@ static void arbfp_blit_free(struct
> wined3d_device *device) const struct wined3d_gl_info *gl_info =
> &device->adapter->gl_info; struct arbfp_blit_priv *priv =
> device->blit_priv;
>
> - GL_EXTCALL(glDeleteProgramsARB(1, &priv->yuy2_rect_shader)); -
> GL_EXTCALL(glDeleteProgramsARB(1, &priv->yuy2_2d_shader)); -
> GL_EXTCALL(glDeleteProgramsARB(1, &priv->uyvy_rect_shader)); -
> GL_EXTCALL(glDeleteProgramsARB(1, &priv->uyvy_2d_shader)); -
> GL_EXTCALL(glDeleteProgramsARB(1, &priv->yv12_rect_shader)); -
> GL_EXTCALL(glDeleteProgramsARB(1, &priv->yv12_2d_shader)); -
> GL_EXTCALL(glDeleteProgramsARB(1, &priv->nv12_rect_shader)); -
> GL_EXTCALL(glDeleteProgramsARB(1, &priv->nv12_2d_shader)); -
> GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_rect_shader)); -
> GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_2d_shader)); -
> checkGLcall("Delete yuv and p8 programs"); +
> wine_rb_destroy(&priv->shaders, arbfp_free_blit_shader,
> &device->adapter->gl_info); + checkGLcall("Delete blit
> programs");
>
> if (priv->palette_texture) gl_info->gl_ops.gl.p_glDeleteTextures(1,
> &priv->palette_texture); @@ -7196,12 +7239,14 @@ static BOOL
> gen_nv12_read(struct wined3d_shader_buffer *buffer, GLenum
> textype, return TRUE; }
>
> +/* Context activation is done by the caller. */ static GLuint
> gen_p8_shader(struct arbfp_blit_priv *priv, const struct
> wined3d_gl_info *gl_info, GLenum textype) { GLenum shader; struct
> wined3d_shader_buffer buffer; GLint pos; + struct
> arbfp_blit_desc *desc;
>
> /* Shader header */ if (!shader_buffer_init(&buffer)) @@ -7249,14
> +7294,34 @@ static GLuint gen_p8_shader(struct arbfp_blit_priv
> *priv, shader_arb_dump_program_source(buffer.buffer); }
>
> - if (textype == GL_TEXTURE_RECTANGLE_ARB) -
> priv->p8_rect_shader = shader; - else -
> priv->p8_2d_shader = shader; - shader_buffer_free(&buffer);
>
> + desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*desc)); + if
> (!desc) + { + ERR("Out of memory\n"); + goto
> err_out; + } + + desc->type.textype = textype; +
> desc->type.fixup = COMPLEX_FIXUP_P8; + desc->shader = shader; +
> if (wine_rb_put(&priv->shaders, &desc->type, &desc->entry) == -1) +
> { + ERR("Out of memory\n"); + goto err_out; + } +
> return shader; + +err_out: + GL_EXTCALL(glDeleteProgramsARB(1,
> &shader)); + checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1,
> &shader))"); +
> GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0)); +
> checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0)"); +
> if (desc) + HeapFree(GetProcessHeap(), 0, desc); + return
> 0; }
>
> /* Context activation is done by the caller. */ @@ -7298,6 +7363,7
> @@ static GLuint gen_yuv_shader(struct arbfp_blit_priv *priv, const
> struct wined3d_ struct wined3d_shader_buffer buffer; char
> luminance_component; GLint pos; + struct arbfp_blit_desc *desc;
>
> /* Shader header */ if (!shader_buffer_init(&buffer)) @@ -7428,34
> +7494,32 @@ static GLuint gen_yuv_shader(struct arbfp_blit_priv
> *priv, const struct wined3d_
>
> shader_buffer_free(&buffer);
>
> - switch (yuv_fixup) + desc = HeapAlloc(GetProcessHeap(), 0,
> sizeof(*desc)); + if (!desc) { - case
> COMPLEX_FIXUP_YUY2: - if (textype ==
> GL_TEXTURE_RECTANGLE_ARB) priv->yuy2_rect_shader = shader; -
> else priv->yuy2_2d_shader = shader; - break; - -
> case COMPLEX_FIXUP_UYVY: - if (textype ==
> GL_TEXTURE_RECTANGLE_ARB) priv->uyvy_rect_shader = shader; -
> else priv->uyvy_2d_shader = shader; - break; - -
> case COMPLEX_FIXUP_YV12: - if (textype ==
> GL_TEXTURE_RECTANGLE_ARB) priv->yv12_rect_shader = shader; -
> else priv->yv12_2d_shader = shader; - break; +
> ERR("Out of memory\n"); + goto err_out; + }
>
> - case COMPLEX_FIXUP_NV12: - if (textype ==
> GL_TEXTURE_RECTANGLE_ARB) - priv->nv12_rect_shader =
> shader; - else - priv->nv12_2d_shader =
> shader; - break; - default: -
> ERR("Unsupported complex fixup: %d\n", yuv_fixup); +
> desc->type.textype = textype; + desc->type.fixup = yuv_fixup; +
> desc->shader = shader; + if (wine_rb_put(&priv->shaders,
> &desc->type, &desc->entry) == -1) + { + ERR("Out of
> memory\n"); + goto err_out; }
>
> return shader; + +err_out: + GL_EXTCALL(glDeleteProgramsARB(1,
> &shader)); + checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1,
> &shader))"); +
> GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0)); +
> checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0)"); +
> if (desc) + HeapFree(GetProcessHeap(), 0, desc); + return
> 0; }
>
> /* Context activation is done by the caller. */ @@ -7467,6 +7531,8
> @@ static HRESULT arbfp_blit_set(void *blit_priv, struct
> wined3d_context *context, enum complex_fixup fixup; const struct
> wined3d_gl_info *gl_info = context->gl_info; GLenum textype =
> surface->container->target; + struct wine_rb_entry *entry; +
> struct arbfp_blit_type type;
>
> if (surface->flags & SFLAG_CONVERTED) { @@ -7487,39 +7553,37 @@
> static HRESULT arbfp_blit_set(void *blit_priv, struct
> wined3d_context *context,
>
> fixup = get_complex_fixup(surface->resource.format->color_fixup);
>
> - switch(fixup) + type.fixup = fixup; + type.textype =
> textype; + entry = wine_rb_get(&priv->shaders, &type); + if
> (entry) { - case COMPLEX_FIXUP_YUY2: - shader =
> textype == GL_TEXTURE_RECTANGLE_ARB ? priv->yuy2_rect_shader :
> priv->yuy2_2d_shader; - break; - - case
> COMPLEX_FIXUP_UYVY: - shader = textype ==
> GL_TEXTURE_RECTANGLE_ARB ? priv->uyvy_rect_shader :
> priv->uyvy_2d_shader; - break; - - case
> COMPLEX_FIXUP_YV12: - shader = textype ==
> GL_TEXTURE_RECTANGLE_ARB ? priv->yv12_rect_shader :
> priv->yv12_2d_shader; - break; - - case
> COMPLEX_FIXUP_NV12: - shader = textype ==
> GL_TEXTURE_RECTANGLE_ARB ? priv->nv12_rect_shader :
> priv->nv12_2d_shader; - break; - - case
> COMPLEX_FIXUP_P8: - shader = textype ==
> GL_TEXTURE_RECTANGLE_ARB ? priv->p8_rect_shader :
> priv->p8_2d_shader; - if (!shader) shader =
> gen_p8_shader(priv, gl_info, textype); + struct
> arbfp_blit_desc *desc = WINE_RB_ENTRY_VALUE(entry, struct
> arbfp_blit_desc, entry); + shader = desc->shader; + } +
> else + { + switch (fixup) + { + case
> COMPLEX_FIXUP_P8: + shader = gen_p8_shader(priv,
> gl_info, textype); + break;
>
> - upload_palette(surface, context); - break;
> + default: + shader =
> gen_yuv_shader(priv, gl_info, fixup, textype); +
> break; + }
>
> - default: + if (!shader) + {
> FIXME("Unsupported complex fixup %#x, not setting a shader\n",
> fixup); gl_info->gl_ops.gl.p_glEnable(textype);
> checkGLcall("glEnable(textype)"); return E_NOTIMPL; + } } -
> - if (!shader) shader = gen_yuv_shader(priv, gl_info, fixup,
> textype); + if (fixup == COMPLEX_FIXUP_P8) +
> upload_palette(surface, context);
>
> gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB);
> checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB)");
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
iQIcBAEBAgAGBQJS/MUJAAoJEN0/YqbEcdMwJDEQAIEBkWRt2YIly+I+2jO2Y2al
MxewjsCeQRf2uFnn4QIVNSfBOrjx6tq5d4aaj0pMlW2O98nXpVJWrHH5suqdX3IP
F57tC6bLkucvwuutKFn+h5JohkHw7mjiPjDMYV2H2Lml3Yy0CXDfpSUJsREfTXgl
YefKfzxIjckRV/u64kCTOxXCjkeI1LakEWIs8zL8QKXHSUIQtUHfN5uNynbhSnNq
SU7+d3B/p/ZFvdOpT6HyhXHyGmx584CcmDTIz9tj6JG0oWmHE6dLZoIrgR/f32iH
M0SYfxFEpRhv26a3NFEx98VAHTarZKkMTrcu6QQIgZ0RiC1jpSOvidk98sIK7dbr
T+ynOho0GaZt5ZC0pvc1w6GPw7sf040Oz2JcSqIxDX+S5JjqG7PsMvJSYcziY8xJ
eBrYgpO/Db5DVyOHfEuFbcS6fyLcO9P9hi2VvhQx2TR9q2XQEMklMamo+OTGng5t
cx61mfvCLUF/BsQBteW/SAIHaUGfKgUOgmPIJpucssVbULVXnxI1op1PcczvT6JP
xqaG+GiXzuDMulcQR+gnYz7oWnMWj2AA+bPVrTKUhZTbEupUgG9j8CsxeJ678tlk
bBKK1p/3UBz1+oc7Qo+Yu6mBVSjPSxwczxmErWe+L7K1kP2L8vtqYg06CSTPH8t7
Y6kf6yuWGIbyapYMcuAO
=jA/i
-----END PGP SIGNATURE-----
More information about the wine-devel
mailing list