diff options
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r-- | src/mesa/state_tracker/st_cb_eglimage.c | 160 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_eglimage.h | 48 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.c | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw.c | 23 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_extensions.c | 4 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_manager.c | 28 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_manager.h | 4 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_mesa_to_tgsi.c | 116 |
8 files changed, 331 insertions, 55 deletions
diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c new file mode 100644 index 0000000000..935b29a324 --- /dev/null +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -0,0 +1,160 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Chia-I Wu <olv@lunarg.com> + */ + +#include "main/texobj.h" +#include "main/texfetch.h" +#include "main/teximage.h" +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "st_cb_eglimage.h" +#include "st_cb_fbo.h" +#include "st_texture.h" +#include "st_format.h" +#include "st_manager.h" + +#if FEATURE_OES_EGL_image + +/** + * Return the base format just like _mesa_base_fbo_format does. + */ +static GLenum +st_pipe_format_to_base_format(enum pipe_format format) +{ + GLenum base_format; + + if (util_format_is_depth_or_stencil(format)) { + if (util_format_is_depth_and_stencil(format)) { + base_format = GL_DEPTH_STENCIL; + } + else { + if (format == PIPE_FORMAT_S8_USCALED) + base_format = GL_STENCIL_INDEX; + else + base_format = GL_DEPTH_COMPONENT; + } + } + else { + /* is this enough? */ + if (util_format_has_alpha(format)) + base_format = GL_RGBA; + else + base_format = GL_RGB; + } + + return base_format; +} + +static void +st_egl_image_target_renderbuffer_storage(GLcontext *ctx, + struct gl_renderbuffer *rb, + GLeglImageOES image_handle) +{ + struct st_context *st = ctx->st; + struct st_renderbuffer *strb = st_renderbuffer(rb); + struct pipe_surface *ps; + unsigned usage; + + usage = PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE; + ps = st_manager_get_egl_image_surface(st, (void *) image_handle, usage); + if (ps) { + strb->Base.Width = ps->width; + strb->Base.Height = ps->height; + strb->Base.Format = st_pipe_format_to_mesa_format(ps->format); + strb->Base.DataType = st_format_datatype(ps->format); + strb->Base._BaseFormat = st_pipe_format_to_base_format(ps->format); + strb->Base.InternalFormat = strb->Base._BaseFormat; + + pipe_surface_reference(&strb->surface, ps); + pipe_texture_reference(&strb->texture, ps->texture); + + pipe_surface_reference(&ps, NULL); + } +} + +static void +st_bind_surface(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + struct pipe_surface *ps) +{ + struct st_texture_object *stObj; + struct st_texture_image *stImage; + GLenum internalFormat; + + /* map pipe format to base format */ + if (util_format_get_component_bits(ps->format, UTIL_FORMAT_COLORSPACE_RGB, 3) > 0) + internalFormat = GL_RGBA; + else + internalFormat = GL_RGB; + + stObj = st_texture_object(texObj); + stImage = st_texture_image(texImage); + + /* switch to surface based */ + if (!stObj->surface_based) { + _mesa_clear_texture_object(ctx, texObj); + stObj->surface_based = GL_TRUE; + } + + _mesa_init_teximage_fields(ctx, target, texImage, + ps->width, ps->height, 1, 0, internalFormat); + texImage->TexFormat = st_pipe_format_to_mesa_format(ps->format); + _mesa_set_fetch_functions(texImage, 2); + + stObj->pipe = ctx->st->pipe; + /* FIXME create a non-default sampler view from the pipe_surface? */ + pipe_texture_reference(&stImage->pt, ps->texture); + + _mesa_dirty_texobj(ctx, texObj, GL_TRUE); +} + +static void +st_egl_image_target_texture_2d(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLeglImageOES image_handle) +{ + struct st_context *st = ctx->st; + struct pipe_surface *ps; + unsigned usage; + + usage = PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE; + ps = st_manager_get_egl_image_surface(st, (void *) image_handle, usage); + if (ps) { + st_bind_surface(ctx, target, texObj, texImage, ps); + pipe_surface_reference(&ps, NULL); + } +} + +void +st_init_eglimage_functions(struct dd_function_table *functions) +{ + functions->EGLImageTargetTexture2D = st_egl_image_target_texture_2d; + functions->EGLImageTargetRenderbufferStorage = st_egl_image_target_renderbuffer_storage; +} + +#endif /* FEATURE_OES_EGL_image */ diff --git a/src/mesa/state_tracker/st_cb_eglimage.h b/src/mesa/state_tracker/st_cb_eglimage.h new file mode 100644 index 0000000000..77e668d919 --- /dev/null +++ b/src/mesa/state_tracker/st_cb_eglimage.h @@ -0,0 +1,48 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Chia-I Wu <olv@lunarg.com> + */ + +#ifndef ST_CB_EGLIMAGE_H +#define ST_CB_EGLIMAGE_H + +#include "main/mtypes.h" +#include "main/dd.h" + +#if FEATURE_OES_EGL_image + +extern void +st_init_eglimage_functions(struct dd_function_table *functions); + +#else + +static INLINE void +st_init_eglimage_functions(struct dd_function_table *functions) +{ +} + +#endif + +#endif /* ST_CB_EGLIMAGE_H */ diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 72f5a9c1e0..83580591fc 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -46,6 +46,7 @@ #if FEATURE_OES_draw_texture #include "st_cb_drawtex.h" #endif +#include "st_cb_eglimage.h" #include "st_cb_fbo.h" #if FEATURE_feedback #include "st_cb_feedback.h" @@ -359,6 +360,8 @@ void st_init_driver_functions(struct dd_function_table *functions) st_init_drawtex_functions(functions); #endif + st_init_eglimage_functions(functions); + st_init_fbo_functions(functions); #if FEATURE_feedback st_init_feedback_functions(functions); diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 7f45e3f548..e0bb1a0af5 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -669,9 +669,17 @@ st_draw_vbo(GLcontext *ctx, for (i = 0; i < nr_prims; i++) { prim = translate_prim( ctx, prims[i].mode ); - pipe->draw_elements(pipe, indexBuf, indexSize, - prim, - prims[i].start + indexOffset, prims[i].count); + if (prims[i].num_instances == 1) { + pipe->draw_elements(pipe, indexBuf, indexSize, prim, + prims[i].start + indexOffset, + prims[i].count); + } + else { + pipe->draw_elements_instanced(pipe, indexBuf, indexSize, prim, + prims[i].start + indexOffset, + prims[i].count, + 0, prims[i].num_instances); + } } } @@ -685,7 +693,14 @@ st_draw_vbo(GLcontext *ctx, for (i = 0; i < nr_prims; i++) { prim = translate_prim( ctx, prims[i].mode ); - pipe->draw_arrays(pipe, prim, prims[i].start, prims[i].count); + if (prims[i].num_instances == 1) { + pipe->draw_arrays(pipe, prim, prims[i].start, prims[i].count); + } + else { + pipe->draw_arrays_instanced(pipe, prim, prims[i].start, + prims[i].count, + 0, prims[i].num_instances); + } } } diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 0118c600f0..affb054866 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -183,6 +183,7 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.EXT_framebuffer_object = GL_TRUE; ctx->Extensions.EXT_framebuffer_multisample = GL_TRUE; ctx->Extensions.EXT_fog_coord = GL_TRUE; + ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE; ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE; ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE; ctx->Extensions.EXT_point_parameters = GL_TRUE; @@ -209,6 +210,9 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.NV_vertex_program1_1 = GL_TRUE; #endif +#if FEATURE_OES_EGL_image + ctx->Extensions.OES_EGL_image = GL_TRUE; +#endif #if FEATURE_OES_draw_texture ctx->Extensions.OES_draw_texture = GL_TRUE; #endif diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c index cac62e4a14..696d8aa792 100644 --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -721,6 +721,34 @@ st_manager_flush_frontbuffer(struct st_context *st) } /** + * Return the surface of an EGLImage. + */ +struct pipe_surface * +st_manager_get_egl_image_surface(struct st_context *st, + void *eglimg, unsigned usage) +{ + struct st_manager *smapi = + (struct st_manager *) st->iface.st_context_private; + struct st_egl_image stimg; + struct pipe_surface *ps; + + if (!smapi || !smapi->get_egl_image) + return NULL; + + memset(&stimg, 0, sizeof(stimg)); + stimg.stctxi = &st->iface; + stimg.egl_image = eglimg; + if (!smapi->get_egl_image(smapi, &stimg)) + return NULL; + + ps = smapi->screen->get_tex_surface(smapi->screen, + stimg.texture, stimg.face, stimg.level, stimg.zslice, usage); + pipe_texture_reference(&stimg.texture, NULL); + + return ps; +} + +/** * Re-validate the framebuffers. */ void diff --git a/src/mesa/state_tracker/st_manager.h b/src/mesa/state_tracker/st_manager.h index a3f5199223..0d3f8f7de4 100644 --- a/src/mesa/state_tracker/st_manager.h +++ b/src/mesa/state_tracker/st_manager.h @@ -31,6 +31,10 @@ #include "state_tracker/st_api.h" #include "st_context.h" +struct pipe_surface * +st_manager_get_egl_image_surface(struct st_context *st, + void *eglimg, unsigned usage); + void st_manager_flush_frontbuffer(struct st_context *st); diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index 807d21a719..ad7a2b87ea 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -739,6 +739,65 @@ emit_inverted_wpos( struct st_translate *t, /** + * Emit fragment position/ooordinate code. + */ +static void +emit_wpos(struct st_context *st, + struct st_translate *t, + const struct gl_program *program, + struct ureg_program *ureg) +{ + const struct gl_fragment_program *fp = + (const struct gl_fragment_program *) program; + struct pipe_screen *pscreen = st->pipe->screen; + boolean invert = FALSE; + + if (fp->OriginUpperLeft) { + if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) { + } + else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) { + ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); + invert = TRUE; + } + else + assert(0); + } + else { + if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) + ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); + else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) + invert = TRUE; + else + assert(0); + } + + if (fp->PixelCenterInteger) { + if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) + ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); + else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) + emit_adjusted_wpos(t, program, invert ? 0.5f : -0.5f); + else + assert(0); + } + else { + if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { + } + else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { + ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); + emit_adjusted_wpos(t, program, invert ? -0.5f : 0.5f); + } + else + assert(0); + } + + /* we invert after adjustment so that we avoid the MOV to temporary, + * and reuse the adjustment ADD instead */ + if (invert) + emit_inverted_wpos(t, program); +} + + +/** * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back. * TGSI uses +1 for front, -1 for back. * This function converts the TGSI value to the GL value. Simply clamping/ @@ -831,7 +890,6 @@ st_translate_mesa_program( * Declare input attributes. */ if (procType == TGSI_PROCESSOR_FRAGMENT) { - struct gl_fragment_program* fp = (struct gl_fragment_program*)program; for (i = 0; i < numInputs; i++) { if (program->InputFlags[0] & PROG_PARAM_BIT_CYL_WRAP) { t->inputs[i] = ureg_DECL_fs_input_cyl(ureg, @@ -852,51 +910,7 @@ st_translate_mesa_program( /* Must do this after setting up t->inputs, and before * emitting constant references, below: */ - struct pipe_screen* pscreen = st_context(ctx)->pipe->screen; - boolean invert = FALSE; - - if (fp->OriginUpperLeft) { - if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) { - } - else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) { - ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); - invert = TRUE; - } - else - assert(0); - } - else { - if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) - ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); - else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) - invert = TRUE; - else - assert(0); - } - - if (fp->PixelCenterInteger) { - if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) - ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); - else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) - emit_adjusted_wpos(t, program, invert ? 0.5f : -0.5f); - else - assert(0); - } - else { - if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { - } - else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { - ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); - emit_adjusted_wpos(t, program, invert ? -0.5f : 0.5f); - } - else - assert(0); - } - - /* we invert after adjustment so that we avoid the MOV to temporary, - * and reuse the adjustment ADD instead */ - if (invert) - emit_inverted_wpos(t, program); + emit_wpos(st_context(ctx), t, program, ureg); } if (program->InputsRead & FRAG_BIT_FACE) { @@ -943,8 +957,9 @@ st_translate_mesa_program( * do this before emitting the constant decls below, or this * will be missed: */ - unsigned pointSizeClampConst = _mesa_add_state_reference(program->Parameters, - pointSizeClampState); + unsigned pointSizeClampConst = + _mesa_add_state_reference(program->Parameters, + pointSizeClampState); struct ureg_dst psizregtemp = ureg_DECL_temporary( ureg ); t->pointSizeConst = ureg_DECL_constant( ureg, pointSizeClampConst ); t->psizregreal = t->outputs[i]; @@ -963,12 +978,10 @@ st_translate_mesa_program( t->address[0] = ureg_DECL_address( ureg ); } - /* Emit constants and immediates. Mesa uses a single index space * for these, so we put all the translated regs in t->constants. */ if (program->Parameters) { - t->constants = CALLOC( program->Parameters->NumParameters, sizeof t->constants[0] ); if (t->constants == NULL) { @@ -1023,7 +1036,8 @@ st_translate_mesa_program( possible early return */ if (t->prevInstWrotePsiz && program->Id) { set_insn_start( t, ureg_get_instruction_number( ureg )); - ureg_MAX( t->ureg, ureg_writemask(t->outputs[t->psizoutindex], WRITEMASK_X), + ureg_MAX( t->ureg, + ureg_writemask(t->outputs[t->psizoutindex], WRITEMASK_X), ureg_src(t->outputs[t->psizoutindex]), ureg_swizzle(t->pointSizeConst, 1,1,1,1)); ureg_MIN( t->ureg, ureg_writemask(t->psizregreal, WRITEMASK_X), |