diff options
author | Kristian Høgsberg Kristensen <[email protected]> | 2016-01-12 10:54:26 -0800 |
---|---|---|
committer | Kristian Høgsberg Kristensen <[email protected]> | 2016-01-12 10:54:26 -0800 |
commit | af422fe9b36e98397d914be9eabae937634bef31 (patch) | |
tree | bae52236907092b6b3f6a7e0c63e341ddd6b88d5 | |
parent | 7df20f0c1456738aa598ba8d4ce88679765ca13e (diff) | |
parent | 56fc2986d554b93d16fa1151765a9987bc42e4da (diff) |
Merge ../mesa into vulkan
Merge master again to get the brw_device_info with the
correct slice counts for KBL.
41 files changed, 852 insertions, 358 deletions
diff --git a/configure.ac b/configure.ac index b13a6c2f21d..44d16c62033 100644 --- a/configure.ac +++ b/configure.ac @@ -245,7 +245,7 @@ _SAVE_LDFLAGS="$LDFLAGS" _SAVE_CPPFLAGS="$CPPFLAGS" dnl Compiler macros -DEFINES="-D__STDC_LIMIT_MACROS" +DEFINES="-D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS" AC_SUBST([DEFINES]) case "$host_os" in linux*|*-gnu*|gnu*) diff --git a/scons/gallium.py b/scons/gallium.py index 46dbf0ebd0e..6dcd95233c3 100755 --- a/scons/gallium.py +++ b/scons/gallium.py @@ -300,7 +300,7 @@ def generate(env): # C preprocessor options cppdefines = [] - cppdefines += ['__STDC_LIMIT_MACROS'] + cppdefines += ['__STDC_LIMIT_MACROS', '__STDC_CONSTANT_MACROS'] if env['build'] in ('debug', 'checked'): cppdefines += ['DEBUG'] else: diff --git a/src/gallium/auxiliary/Makefile.sources b/src/gallium/auxiliary/Makefile.sources index d92da3de77a..5325f974cda 100644 --- a/src/gallium/auxiliary/Makefile.sources +++ b/src/gallium/auxiliary/Makefile.sources @@ -252,7 +252,6 @@ C_SOURCES := \ util/u_helpers.h \ util/u_index_modify.c \ util/u_index_modify.h \ - util/u_init.h \ util/u_inlines.h \ util/u_keymap.c \ util/u_keymap.h \ diff --git a/src/gallium/auxiliary/util/u_init.h b/src/gallium/auxiliary/util/u_init.h deleted file mode 100644 index 7bc356a7916..00000000000 --- a/src/gallium/auxiliary/util/u_init.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2010 Luca Barbieri - * - * 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 (including the - * next paragraph) 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 THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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. - * - **************************************************************************/ - -#ifndef U_INIT_H -#define U_INIT_H - -/* Use UTIL_INIT(f) to have f called at program initialization. - Note that it is only guaranteed to be called if any symbol in the - .c file it is in sis referenced by the program. - - UTIL_INIT functions are called in arbitrary order. -*/ - -#ifdef __cplusplus -/* use a C++ global constructor */ -#define UTIL_INIT(f) struct f##__gctor_t {f##__gctor_t() {x();}} f##__gctor; -#elif defined(_MSC_VER) -/* add a pointer to the section where MSVC stores global constructor pointers */ -/* see http://blogs.msdn.com/vcblog/archive/2006/10/20/crt-initialization.aspx and - http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc */ -#pragma section(".CRT$XCU",read) -#define UTIL_INIT(f) static void __cdecl f##__init(void) {f();}; __declspec(allocate(".CRT$XCU")) void (__cdecl* f##__xcu)(void) = f##__init; -#elif defined(__GNUC__) -#define UTIL_INIT(f) static void f##__init(void) __attribute__((constructor)); static void f##__init(void) {f();} -#else -#error Unsupported compiler: please find out how to implement global initializers in C on it -#endif - -#endif - diff --git a/src/gallium/auxiliary/vl/vl_deint_filter.c b/src/gallium/auxiliary/vl/vl_deint_filter.c index 8fa70e84c66..9e782e531bf 100644 --- a/src/gallium/auxiliary/vl/vl_deint_filter.c +++ b/src/gallium/auxiliary/vl/vl_deint_filter.c @@ -47,6 +47,7 @@ #include "util/u_draw.h" #include "util/u_memory.h" #include "util/u_math.h" +#include "util/u_format.h" #include "vl_types.h" #include "vl_video_buffer.h" @@ -214,8 +215,9 @@ create_deint_frag_shader(struct vl_deint_filter *filter, unsigned field, ureg_imm4f(shader, -0.02353f, 0, 0, 0)); ureg_MUL(shader, ureg_saturate(ureg_writemask(t_diff, TGSI_WRITEMASK_X)), ureg_src(t_diff), ureg_imm4f(shader, 31.8750f, 0, 0, 0)); - ureg_LRP(shader, ureg_writemask(o_fragment, TGSI_WRITEMASK_X), ureg_src(t_diff), + ureg_LRP(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_X), ureg_src(t_diff), ureg_src(t_linear), ureg_src(t_weave)); + ureg_MOV(shader, o_fragment, ureg_scalar(ureg_src(t_tex), TGSI_SWIZZLE_X)); ureg_release_temporary(shader, t_tex); ureg_release_temporary(shader, t_comp_top); @@ -253,7 +255,13 @@ vl_deint_filter_init(struct vl_deint_filter *filter, struct pipe_context *pipe, /* TODO: handle other than 4:2:0 subsampling */ memset(&templ, 0, sizeof(templ)); - templ.buffer_format = PIPE_FORMAT_YV12; + templ.buffer_format = pipe->screen->get_video_param + ( + pipe->screen, + PIPE_VIDEO_PROFILE_UNKNOWN, + PIPE_VIDEO_ENTRYPOINT_UNKNOWN, + PIPE_VIDEO_CAP_PREFERED_FORMAT + ); templ.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420; templ.width = video_width; templ.height = video_height; @@ -271,10 +279,20 @@ vl_deint_filter_init(struct vl_deint_filter *filter, struct pipe_context *pipe, goto error_rs_state; memset(&blend, 0, sizeof blend); - blend.rt[0].colormask = PIPE_MASK_RGBA; - filter->blend = pipe->create_blend_state(pipe, &blend); - if (!filter->blend) - goto error_blend; + blend.rt[0].colormask = PIPE_MASK_R; + filter->blend[0] = pipe->create_blend_state(pipe, &blend); + if (!filter->blend[0]) + goto error_blendR; + + blend.rt[0].colormask = PIPE_MASK_G; + filter->blend[1] = pipe->create_blend_state(pipe, &blend); + if (!filter->blend[1]) + goto error_blendG; + + blend.rt[0].colormask = PIPE_MASK_B; + filter->blend[2] = pipe->create_blend_state(pipe, &blend); + if (!filter->blend[2]) + goto error_blendB; memset(&sampler, 0, sizeof(sampler)); sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; @@ -349,9 +367,15 @@ error_quad: pipe->delete_sampler_state(pipe, filter->sampler); error_sampler: - pipe->delete_blend_state(pipe, filter->blend); + pipe->delete_blend_state(pipe, filter->blend[2]); + +error_blendB: + pipe->delete_blend_state(pipe, filter->blend[1]); + +error_blendG: + pipe->delete_blend_state(pipe, filter->blend[0]); -error_blend: +error_blendR: pipe->delete_rasterizer_state(pipe, filter->rs_state); error_rs_state: @@ -367,7 +391,9 @@ vl_deint_filter_cleanup(struct vl_deint_filter *filter) assert(filter); filter->pipe->delete_sampler_state(filter->pipe, filter->sampler[0]); - filter->pipe->delete_blend_state(filter->pipe, filter->blend); + filter->pipe->delete_blend_state(filter->pipe, filter->blend[0]); + filter->pipe->delete_blend_state(filter->pipe, filter->blend[1]); + filter->pipe->delete_blend_state(filter->pipe, filter->blend[2]); filter->pipe->delete_rasterizer_state(filter->pipe, filter->rs_state); filter->pipe->delete_vertex_elements_state(filter->pipe, filter->ves); pipe_resource_reference(&filter->quad.buffer, NULL); @@ -420,12 +446,14 @@ vl_deint_filter_render(struct vl_deint_filter *filter, struct pipe_sampler_view **next_sv; struct pipe_sampler_view *sampler_views[4]; struct pipe_surface **dst_surfaces; - int j; + const unsigned *plane_order; + int i, j; assert(filter && prevprev && prev && cur && next && field <= 1); /* set up destination and source */ dst_surfaces = filter->video_buffer->get_surfaces(filter->video_buffer); + plane_order = vl_video_buffer_plane_order(filter->video_buffer->buffer_format); cur_sv = cur->get_sampler_view_components(cur); prevprev_sv = prevprev->get_sampler_view_components(prevprev); prev_sv = prev->get_sampler_view_components(prev); @@ -433,7 +461,6 @@ vl_deint_filter_render(struct vl_deint_filter *filter, /* set up pipe state */ filter->pipe->bind_rasterizer_state(filter->pipe, filter->rs_state); - filter->pipe->bind_blend_state(filter->pipe, filter->blend); filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, &filter->quad); filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves); filter->pipe->bind_vs_state(filter->pipe, filter->vs); @@ -449,12 +476,13 @@ vl_deint_filter_render(struct vl_deint_filter *filter, fb_state.nr_cbufs = 1; /* process each plane separately */ - for (j = 0; j < 3; j++) { - /* select correct YV12 surfaces */ - int k = j == 1 ? 2 : - j == 2 ? 1 : 0; - struct pipe_surface *blit_surf = dst_surfaces[2 * k + field]; - struct pipe_surface *dst_surf = dst_surfaces[2 * k + 1 - field]; + for (i = 0, j = 0; i < VL_NUM_COMPONENTS; ++i) { + struct pipe_surface *blit_surf = dst_surfaces[field]; + struct pipe_surface *dst_surf = dst_surfaces[1 - field]; + int k = plane_order[i]; + + /* bind blend state for this component in the plane */ + filter->pipe->bind_blend_state(filter->pipe, filter->blend[j]); /* update render target state */ viewport.scale[0] = blit_surf->texture->width0; @@ -463,10 +491,10 @@ vl_deint_filter_render(struct vl_deint_filter *filter, fb_state.height = blit_surf->texture->height0; /* update sampler view sources */ - sampler_views[0] = prevprev_sv[j]; - sampler_views[1] = prev_sv[j]; - sampler_views[2] = cur_sv[j]; - sampler_views[3] = next_sv[j]; + sampler_views[0] = prevprev_sv[k]; + sampler_views[1] = prev_sv[k]; + sampler_views[2] = cur_sv[k]; + sampler_views[3] = next_sv[k]; filter->pipe->set_sampler_views(filter->pipe, PIPE_SHADER_FRAGMENT, 0, 4, sampler_views); /* blit current field */ @@ -479,11 +507,16 @@ vl_deint_filter_render(struct vl_deint_filter *filter, /* blit or interpolate other field */ fb_state.cbufs[0] = dst_surf; filter->pipe->set_framebuffer_state(filter->pipe, &fb_state); - if (j > 0 && filter->skip_chroma) { + if (i > 0 && filter->skip_chroma) { util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4); } else { filter->pipe->bind_fs_state(filter->pipe, field ? filter->fs_deint_top : filter->fs_deint_bottom); util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4); } + + if (++j >= util_format_get_nr_components(dst_surf->format)) { + dst_surfaces += 2; + j = 0; + } } } diff --git a/src/gallium/auxiliary/vl/vl_deint_filter.h b/src/gallium/auxiliary/vl/vl_deint_filter.h index 3ca378b183d..49cc96c20b9 100644 --- a/src/gallium/auxiliary/vl/vl_deint_filter.h +++ b/src/gallium/auxiliary/vl/vl_deint_filter.h @@ -38,7 +38,7 @@ struct vl_deint_filter struct pipe_vertex_buffer quad; void *rs_state; - void *blend; + void *blend[3]; void *sampler[4]; void *ves; void *vs; diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.c b/src/gallium/auxiliary/vl/vl_video_buffer.c index e8cd24dec81..462fdcb0882 100644 --- a/src/gallium/auxiliary/vl/vl_video_buffer.c +++ b/src/gallium/auxiliary/vl/vl_video_buffer.c @@ -253,14 +253,8 @@ vl_video_buffer_template(struct pipe_resource *templ, templ->bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; templ->usage = usage; - if (plane > 0) { - if (tmpl->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { - templ->width0 /= 2; - templ->height0 /= 2; - } else if (tmpl->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { - templ->width0 /= 2; - } - } + vl_video_buffer_adjust_size(&templ->width0, &templ->height0, plane, + tmpl->chroma_format, false); } static void diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.h b/src/gallium/auxiliary/vl/vl_video_buffer.h index 488c3cc4eac..8a1c0773fc9 100644 --- a/src/gallium/auxiliary/vl/vl_video_buffer.h +++ b/src/gallium/auxiliary/vl/vl_video_buffer.h @@ -48,6 +48,24 @@ struct vl_video_buffer struct pipe_surface *surfaces[VL_MAX_SURFACES]; }; +static inline void +vl_video_buffer_adjust_size(unsigned *width, unsigned *height, unsigned plane, + enum pipe_video_chroma_format chroma_format, + bool interlaced) +{ + if (interlaced) { + *height /= 2; + } + if (plane > 0) { + if (chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { + *width /= 2; + *height /= 2; + } else if (chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { + *width /= 2; + } + } +} + /** * get subformats for each plane */ diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.cpp index dca799dd9b5..1bf7240e131 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.cpp @@ -407,7 +407,7 @@ BuildUtil::loadImm(Value *dst, float f) Value * BuildUtil::loadImm(Value *dst, double d) { - return mkOp1v(OP_MOV, TYPE_F64, dst ? dst : getScratch(), mkImm(d)); + return mkOp1v(OP_MOV, TYPE_F64, dst ? dst : getScratch(8), mkImm(d)); } Value * @@ -499,7 +499,7 @@ BuildUtil::DataArray::acquire(ValueMap &m, int i, int c) return v; } else { - return up->getScratch(); + return up->getScratch(eltSize); } } diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h index 8f3bf77949c..d171f64d9a1 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h @@ -295,7 +295,7 @@ BuildUtil::mkOp3v(operation op, DataType ty, Value *dst, inline LValue * BuildUtil::mkLoadv(DataType ty, Symbol *mem, Value *ptr) { - LValue *dst = getScratch(); + LValue *dst = getScratch(typeSizeof(ty)); mkLoad(ty, dst, mem, ptr); return dst; } diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c index 2e7c790e9ee..71804343138 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c @@ -195,8 +195,10 @@ nvc0_launch_grid(struct pipe_context *pipe, int ret; ret = !nvc0_compute_state_validate(nvc0); - if (ret) - goto out; + if (ret) { + NOUVEAU_ERR("Failed to launch grid !\n"); + return; + } nvc0_compute_upload_input(nvc0, input); @@ -246,15 +248,11 @@ nvc0_launch_grid(struct pipe_context *pipe, /* rebind all the 3D constant buffers * (looks like binding a CB on COMPUTE clobbers 3D state) */ nvc0->dirty |= NVC0_NEW_CONSTBUF; - for (s = 0; s < 6; s++) { + for (s = 0; s < 5; s++) { for (i = 0; i < NVC0_MAX_PIPE_CONSTBUFS; i++) if (nvc0->constbuf[s][i].u.buf) nvc0->constbuf_dirty[s] |= 1 << i; } memset(nvc0->state.uniform_buffer_bound, 0, sizeof(nvc0->state.uniform_buffer_bound)); - -out: - if (ret) - NOUVEAU_ERR("Failed to launch grid !\n"); } diff --git a/src/gallium/state_trackers/omx/vid_enc.c b/src/gallium/state_trackers/omx/vid_enc.c index aa45089ae04..df22a97a42c 100644 --- a/src/gallium/state_trackers/omx/vid_enc.c +++ b/src/gallium/state_trackers/omx/vid_enc.c @@ -869,6 +869,9 @@ static void enc_ReleaseTasks(struct list_head *head) { struct encode_task *i, *next; + if (!head) + return; + LIST_FOR_EACH_ENTRY_SAFE(i, next, head, list) { pipe_resource_reference(&i->bitstream, NULL); i->buf->destroy(i->buf); diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c index 8de79352b7c..c2c24d693f2 100644 --- a/src/gallium/state_trackers/va/buffer.c +++ b/src/gallium/state_trackers/va/buffer.c @@ -40,6 +40,7 @@ vlVaCreateBuffer(VADriverContextP ctx, VAContextID context, VABufferType type, unsigned int size, unsigned int num_elements, void *data, VABufferID *buf_id) { + vlVaDriver *drv; vlVaBuffer *buf; if (!ctx) @@ -62,7 +63,10 @@ vlVaCreateBuffer(VADriverContextP ctx, VAContextID context, VABufferType type, if (data) memcpy(buf->data, data, size * num_elements); - *buf_id = handle_table_add(VL_VA_DRIVER(ctx)->htab, buf); + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + *buf_id = handle_table_add(drv->htab, buf); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -71,12 +75,16 @@ VAStatus vlVaBufferSetNumElements(VADriverContextP ctx, VABufferID buf_id, unsigned int num_elements) { + vlVaDriver *drv; vlVaBuffer *buf; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id); + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + buf = handle_table_get(drv->htab, buf_id); + pipe_mutex_unlock(drv->mutex); if (!buf) return VA_STATUS_ERROR_INVALID_BUFFER; @@ -109,22 +117,24 @@ vlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void **pbuff) if (!pbuff) return VA_STATUS_ERROR_INVALID_PARAMETER; + pipe_mutex_lock(drv->mutex); buf = handle_table_get(drv->htab, buf_id); - if (!buf) - return VA_STATUS_ERROR_INVALID_BUFFER; - - if (buf->export_refcount > 0) + if (!buf || buf->export_refcount > 0) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } if (buf->derived_surface.resource) { *pbuff = pipe_buffer_map(drv->pipe, buf->derived_surface.resource, PIPE_TRANSFER_WRITE, &buf->derived_surface.transfer); + pipe_mutex_unlock(drv->mutex); if (!buf->derived_surface.transfer || !*pbuff) return VA_STATUS_ERROR_INVALID_BUFFER; } else { + pipe_mutex_unlock(drv->mutex); *pbuff = buf->data; } @@ -144,20 +154,23 @@ vlVaUnmapBuffer(VADriverContextP ctx, VABufferID buf_id) if (!drv) return VA_STATUS_ERROR_INVALID_CONTEXT; + pipe_mutex_lock(drv->mutex); buf = handle_table_get(drv->htab, buf_id); - if (!buf) - return VA_STATUS_ERROR_INVALID_BUFFER; - - if (buf->export_refcount > 0) + if (!buf || buf->export_refcount > 0) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } if (buf->derived_surface.resource) { - if (!buf->derived_surface.transfer) + if (!buf->derived_surface.transfer) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } pipe_buffer_unmap(drv->pipe, buf->derived_surface.transfer); buf->derived_surface.transfer = NULL; } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -165,18 +178,25 @@ vlVaUnmapBuffer(VADriverContextP ctx, VABufferID buf_id) VAStatus vlVaDestroyBuffer(VADriverContextP ctx, VABufferID buf_id) { + vlVaDriver *drv; vlVaBuffer *buf; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id); - if (!buf) + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + buf = handle_table_get(drv->htab, buf_id); + if (!buf) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } if (buf->derived_surface.resource) { - if (buf->export_refcount > 0) + if (buf->export_refcount > 0) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } pipe_resource_reference(&buf->derived_surface.resource, NULL); } @@ -184,6 +204,7 @@ vlVaDestroyBuffer(VADriverContextP ctx, VABufferID buf_id) FREE(buf->data); FREE(buf); handle_table_remove(VL_VA_DRIVER(ctx)->htab, buf_id); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -192,12 +213,16 @@ VAStatus vlVaBufferInfo(VADriverContextP ctx, VABufferID buf_id, VABufferType *type, unsigned int *size, unsigned int *num_elements) { + vlVaDriver *drv; vlVaBuffer *buf; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id); + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + buf = handle_table_get(drv->htab, buf_id); + pipe_mutex_unlock(drv->mutex); if (!buf) return VA_STATUS_ERROR_INVALID_BUFFER; @@ -227,7 +252,11 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id, if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + screen = VL_VA_PSCREEN(ctx); + pipe_mutex_lock(drv->mutex); buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id); + pipe_mutex_unlock(drv->mutex); if (!buf) return VA_STATUS_ERROR_INVALID_BUFFER; @@ -256,9 +285,6 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id, if (!buf->derived_surface.resource) return VA_STATUS_ERROR_INVALID_BUFFER; - drv = VL_VA_DRIVER(ctx); - screen = VL_VA_PSCREEN(ctx); - if (buf->export_refcount > 0) { if (buf->export_state.mem_type != mem_type) return VA_STATUS_ERROR_INVALID_PARAMETER; @@ -269,7 +295,9 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id, case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: { struct winsys_handle whandle; + pipe_mutex_lock(drv->mutex); drv->pipe->flush(drv->pipe, NULL, 0); + pipe_mutex_unlock(drv->mutex); memset(&whandle, 0, sizeof(whandle)); whandle.type = DRM_API_HANDLE_TYPE_FD; @@ -299,12 +327,16 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id, VAStatus vlVaReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id) { + vlVaDriver *drv; vlVaBuffer *buf; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id); + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + buf = handle_table_get(drv->htab, buf_id); + pipe_mutex_unlock(drv->mutex); if (!buf) return VA_STATUS_ERROR_INVALID_BUFFER; diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index 192794fefaa..37a011799e2 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -155,6 +155,7 @@ VA_DRIVER_INIT_FUNC(VADriverContextP ctx) vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, true, &drv->csc); vl_compositor_set_csc_matrix(&drv->cstate, (const vl_csc_matrix *)&drv->csc); + pipe_mutex_init(drv->mutex); ctx->pDriverData = (void *)drv; ctx->version_major = 0; @@ -262,7 +263,9 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, } context->desc.base.profile = config_id; + pipe_mutex_lock(drv->mutex); *context_id = handle_table_add(drv->htab, context); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -277,6 +280,7 @@ vlVaDestroyContext(VADriverContextP ctx, VAContextID context_id) return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); context = handle_table_get(drv->htab, context_id); if (context->decoder) { @@ -294,6 +298,7 @@ vlVaDestroyContext(VADriverContextP ctx, VAContextID context_id) } FREE(context); handle_table_remove(drv->htab, context_id); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -312,6 +317,7 @@ vlVaTerminate(VADriverContextP ctx) drv->pipe->destroy(drv->pipe); drv->vscreen->destroy(drv->vscreen); handle_table_destroy(drv->htab); + pipe_mutex_destroy(drv->mutex); FREE(drv); return VA_STATUS_SUCCESS; diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c index ccc263f77a7..2c42a985823 100644 --- a/src/gallium/state_trackers/va/image.c +++ b/src/gallium/state_trackers/va/image.c @@ -34,6 +34,7 @@ #include "util/u_video.h" #include "vl/vl_winsys.h" +#include "vl/vl_video_buffer.h" #include "va_private.h" @@ -61,15 +62,9 @@ vlVaVideoSurfaceSize(vlVaSurface *p_surf, int component, *width = p_surf->templat.width; *height = p_surf->templat.height; - if (component > 0) { - if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { - *width /= 2; - *height /= 2; - } else if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) - *width /= 2; - } - if (p_surf->templat.interlaced) - *height /= 2; + vl_video_buffer_adjust_size(width, height, component, + p_surf->templat.chroma_format, + p_surf->templat.interlaced); } VAStatus @@ -119,7 +114,9 @@ vlVaCreateImage(VADriverContextP ctx, VAImageFormat *format, int width, int heig img = CALLOC(1, sizeof(VAImage)); if (!img) return VA_STATUS_ERROR_ALLOCATION_FAILED; + pipe_mutex_lock(drv->mutex); img->image_id = handle_table_add(drv->htab, img); + pipe_mutex_unlock(drv->mutex); img->format = *format; img->width = width; @@ -261,6 +258,7 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) return VA_STATUS_ERROR_ALLOCATION_FAILED; } + pipe_mutex_lock(drv->mutex); img->image_id = handle_table_add(drv->htab, img); img_buf->type = VAImageBufferType; @@ -270,6 +268,7 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) pipe_resource_reference(&img_buf->derived_surface.resource, surfaces[0]->texture); img->buf = handle_table_add(VL_VA_DRIVER(ctx)->htab, img_buf); + pipe_mutex_unlock(drv->mutex); *image = *img; @@ -279,16 +278,22 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) VAStatus vlVaDestroyImage(VADriverContextP ctx, VAImageID image) { + vlVaDriver *drv; VAImage *vaimage; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - vaimage = handle_table_get(VL_VA_DRIVER(ctx)->htab, image); - if (!vaimage) + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + vaimage = handle_table_get(drv->htab, image); + if (!vaimage) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_IMAGE; + } handle_table_remove(VL_VA_DRIVER(ctx)->htab, image); + pipe_mutex_unlock(drv->mutex); FREE(vaimage); return vlVaDestroyBuffer(ctx, vaimage->buf); } @@ -321,21 +326,30 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y, drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); surf = handle_table_get(drv->htab, surface); - if (!surf || !surf->buffer) + if (!surf || !surf->buffer) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SURFACE; + } vaimage = handle_table_get(drv->htab, image); - if (!vaimage) + if (!vaimage) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_IMAGE; + } img_buf = handle_table_get(drv->htab, vaimage->buf); - if (!img_buf) + if (!img_buf) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } format = VaFourccToPipeFormat(vaimage->format.fourcc); - if (format == PIPE_FORMAT_NONE) + if (format == PIPE_FORMAT_NONE) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_OPERATION_FAILED; + } if (format != surf->buffer->buffer_format) { /* support NV12 to YV12 and IYUV conversion now only */ @@ -344,13 +358,17 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y, (format == PIPE_FORMAT_IYUV && surf->buffer->buffer_format == PIPE_FORMAT_NV12)) convert = true; - else + else { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_OPERATION_FAILED; + } } views = surf->buffer->get_sampler_view_planes(surf->buffer); - if (!views) + if (!views) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_OPERATION_FAILED; + } for (i = 0; i < vaimage->num_planes; i++) { data[i] = img_buf->data + vaimage->offsets[i]; @@ -377,8 +395,10 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y, uint8_t *map; map = drv->pipe->transfer_map(drv->pipe, views[i]->texture, 0, PIPE_TRANSFER_READ, &box, &transfer); - if (!map) + if (!map) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_OPERATION_FAILED; + } if (i == 1 && convert) { u_copy_nv12_to_yv12(data, pitches, i, j, @@ -393,6 +413,7 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y, pipe_transfer_unmap(drv->pipe, transfer); } } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -415,28 +436,38 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); surf = handle_table_get(drv->htab, surface); - if (!surf || !surf->buffer) + if (!surf || !surf->buffer) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SURFACE; + } vaimage = handle_table_get(drv->htab, image); - if (!vaimage) + if (!vaimage) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_IMAGE; + } img_buf = handle_table_get(drv->htab, vaimage->buf); - if (!img_buf) + if (!img_buf) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } if (img_buf->derived_surface.resource) { /* Attempting to transfer derived image to surface */ + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_UNIMPLEMENTED; } format = VaFourccToPipeFormat(vaimage->format.fourcc); - if (format == PIPE_FORMAT_NONE) + if (format == PIPE_FORMAT_NONE) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_OPERATION_FAILED; + } if (format != surf->buffer->buffer_format) { struct pipe_video_buffer *tmp_buf; @@ -447,6 +478,7 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, if (!tmp_buf) { surf->templat.buffer_format = old_surf_format; + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_ALLOCATION_FAILED; } @@ -455,8 +487,10 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, } views = surf->buffer->get_sampler_view_planes(surf->buffer); - if (!views) + if (!views) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_OPERATION_FAILED; + } for (i = 0; i < vaimage->num_planes; i++) { data[i] = img_buf->data + vaimage->offsets[i]; @@ -485,6 +519,7 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, pitches[i] * views[i]->texture->array_size, 0); } } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index da9ca5aa6c9..89ac02458f4 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -50,24 +50,29 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende if (!drv) return VA_STATUS_ERROR_INVALID_CONTEXT; + pipe_mutex_lock(drv->mutex); context = handle_table_get(drv->htab, context_id); - if (!context) + if (!context) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_CONTEXT; + } surf = handle_table_get(drv->htab, render_target); + pipe_mutex_unlock(drv->mutex); if (!surf || !surf->buffer) return VA_STATUS_ERROR_INVALID_SURFACE; context->target = surf->buffer; if (!context->decoder) { + /* VPP */ if (context->templat.profile == PIPE_VIDEO_PROFILE_UNKNOWN && - ((context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM && - context->target->buffer_format != PIPE_FORMAT_R8G8B8A8_UNORM && - context->target->buffer_format != PIPE_FORMAT_B8G8R8X8_UNORM && - context->target->buffer_format != PIPE_FORMAT_R8G8B8X8_UNORM) || - context->target->interlaced)) + context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM && + context->target->buffer_format != PIPE_FORMAT_R8G8B8A8_UNORM && + context->target->buffer_format != PIPE_FORMAT_B8G8R8X8_UNORM && + context->target->buffer_format != PIPE_FORMAT_R8G8B8X8_UNORM && + context->target->buffer_format != PIPE_FORMAT_NV12) return VA_STATUS_ERROR_UNIMPLEMENTED; return VA_STATUS_SUCCESS; @@ -289,14 +294,19 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff if (!drv) return VA_STATUS_ERROR_INVALID_CONTEXT; + pipe_mutex_lock(drv->mutex); context = handle_table_get(drv->htab, context_id); - if (!context) + if (!context) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_CONTEXT; + } for (i = 0; i < num_buffers; ++i) { vlVaBuffer *buf = handle_table_get(drv->htab, buffers[i]); - if (!buf) + if (!buf) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } switch (buf->type) { case VAPictureParameterBufferType: @@ -322,6 +332,7 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff break; } } + pipe_mutex_unlock(drv->mutex); return vaStatus; } @@ -339,7 +350,9 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (!drv) return VA_STATUS_ERROR_INVALID_CONTEXT; + pipe_mutex_lock(drv->mutex); context = handle_table_get(drv->htab, context_id); + pipe_mutex_unlock(drv->mutex); if (!context) return VA_STATUS_ERROR_INVALID_CONTEXT; diff --git a/src/gallium/state_trackers/va/postproc.c b/src/gallium/state_trackers/va/postproc.c index 15053a9ac3e..0cec0c88124 100644 --- a/src/gallium/state_trackers/va/postproc.c +++ b/src/gallium/state_trackers/va/postproc.c @@ -27,6 +27,9 @@ #include "util/u_handle_table.h" +#include "vl/vl_defines.h" +#include "vl/vl_video_buffer.h" + #include "va_private.h" static const VARectangle * @@ -44,43 +47,22 @@ vlVaRegionDefault(const VARectangle *region, struct pipe_video_buffer *buf, return def; } -VAStatus -vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +static VAStatus +vlVaPostProcCompositor(vlVaDriver *drv, vlVaContext *context, + const VARectangle *src_region, + const VARectangle *dst_region, + struct pipe_video_buffer *src, + struct pipe_video_buffer *dst, + enum vl_compositor_deinterlace deinterlace) { - VARectangle def_src_region, def_dst_region; - const VARectangle *src_region, *dst_region; + struct pipe_surface **surfaces; struct u_rect src_rect; struct u_rect dst_rect; - vlVaSurface *src_surface; - VAProcPipelineParameterBuffer *pipeline_param; - struct pipe_surface **surfaces; - struct pipe_surface *psurf; - - if (!drv || !context) - return VA_STATUS_ERROR_INVALID_CONTEXT; - - if (!buf || !buf->data) - return VA_STATUS_ERROR_INVALID_BUFFER; - - if (!context->target) - return VA_STATUS_ERROR_INVALID_SURFACE; - - pipeline_param = (VAProcPipelineParameterBuffer *)buf->data; - - src_surface = handle_table_get(drv->htab, pipeline_param->surface); - if (!src_surface || !src_surface->buffer) - return VA_STATUS_ERROR_INVALID_SURFACE; - - surfaces = context->target->get_surfaces(context->target); + surfaces = dst->get_surfaces(dst); if (!surfaces || !surfaces[0]) return VA_STATUS_ERROR_INVALID_SURFACE; - psurf = surfaces[0]; - - src_region = vlVaRegionDefault(pipeline_param->surface_region, src_surface->buffer, &def_src_region); - dst_region = vlVaRegionDefault(pipeline_param->output_region, context->target, &def_dst_region); - src_rect.x0 = src_region->x; src_rect.y0 = src_region->y; src_rect.x1 = src_region->x + src_region->width; @@ -92,9 +74,99 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex dst_rect.y1 = dst_region->y + dst_region->height; vl_compositor_clear_layers(&drv->cstate); - vl_compositor_set_buffer_layer(&drv->cstate, &drv->compositor, 0, src_surface->buffer, &src_rect, NULL, VL_COMPOSITOR_WEAVE); + vl_compositor_set_buffer_layer(&drv->cstate, &drv->compositor, 0, src, + &src_rect, NULL, deinterlace); vl_compositor_set_layer_dst_area(&drv->cstate, 0, &dst_rect); - vl_compositor_render(&drv->cstate, &drv->compositor, psurf, NULL, false); + vl_compositor_render(&drv->cstate, &drv->compositor, surfaces[0], NULL, false); + + return VA_STATUS_SUCCESS; +} + +static void vlVaGetBox(struct pipe_video_buffer *buf, unsigned idx, + struct pipe_box *box, const VARectangle *region) +{ + unsigned plane = buf->interlaced ? idx / 2: idx; + unsigned x, y, width, height; + + x = abs(region->x); + y = abs(region->y); + width = region->width; + height = region->height; + + vl_video_buffer_adjust_size(&x, &y, plane, buf->chroma_format, + buf->interlaced); + vl_video_buffer_adjust_size(&width, &height, plane, buf->chroma_format, + buf->interlaced); + + box->x = region->x < 0 ? -x : x; + box->y = region->y < 0 ? -y : y; + box->width = width; + box->height = height; +} + +static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context, + const VARectangle *src_region, + const VARectangle *dst_region, + struct pipe_video_buffer *src, + struct pipe_video_buffer *dst, + enum vl_compositor_deinterlace deinterlace) +{ + struct pipe_surface **src_surfaces; + struct pipe_surface **dst_surfaces; + unsigned i; + + if (src->interlaced != dst->interlaced) + return VA_STATUS_ERROR_INVALID_SURFACE; + + src_surfaces = src->get_surfaces(src); + if (!src_surfaces || !src_surfaces[0]) + return VA_STATUS_ERROR_INVALID_SURFACE; + + dst_surfaces = dst->get_surfaces(dst); + if (!dst_surfaces || !dst_surfaces[0]) + return VA_STATUS_ERROR_INVALID_SURFACE; + + for (i = 0; i < VL_MAX_SURFACES; ++i) { + struct pipe_surface *from = src_surfaces[i]; + struct pipe_blit_info blit; + + if (src->interlaced) { + /* Not 100% accurate, but close enough */ + switch (deinterlace) { + case VL_COMPOSITOR_BOB_TOP: + from = src_surfaces[i & ~1]; + break; + case VL_COMPOSITOR_BOB_BOTTOM: + from = src_surfaces[(i & ~1) + 1]; + break; + default: + break; + } + } + + if (!from || !dst_surfaces[i]) + continue; + + memset(&blit, 0, sizeof(blit)); + blit.src.resource = from->texture; + blit.src.format = from->format; + blit.src.level = 0; + blit.src.box.z = from->u.tex.first_layer; + blit.src.box.depth = 1; + vlVaGetBox(src, i, &blit.src.box, src_region); + + blit.dst.resource = dst_surfaces[i]->texture; + blit.dst.format = dst_surfaces[i]->format; + blit.dst.level = 0; + blit.dst.box.z = dst_surfaces[i]->u.tex.first_layer; + blit.dst.box.depth = 1; + vlVaGetBox(dst, i, &blit.dst.box, dst_region); + + blit.mask = PIPE_MASK_RGBA; + blit.filter = PIPE_TEX_MIPFILTER_LINEAR; + + drv->pipe->blit(drv->pipe, &blit); + } // TODO: figure out why this is necessary for DMA-buf sharing drv->pipe->flush(drv->pipe, NULL, 0); @@ -102,4 +174,75 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex return VA_STATUS_SUCCESS; } +VAStatus +vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + enum vl_compositor_deinterlace deinterlace = VL_COMPOSITOR_WEAVE; + VARectangle def_src_region, def_dst_region; + const VARectangle *src_region, *dst_region; + VAProcPipelineParameterBuffer *param; + vlVaSurface *src_surface; + unsigned i; + if (!drv || !context) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + if (!buf || !buf->data) + return VA_STATUS_ERROR_INVALID_BUFFER; + + if (!context->target) + return VA_STATUS_ERROR_INVALID_SURFACE; + + param = buf->data; + + src_surface = handle_table_get(drv->htab, param->surface); + if (!src_surface || !src_surface->buffer) + return VA_STATUS_ERROR_INVALID_SURFACE; + + for (i = 0; i < param->num_filters; i++) { + vlVaBuffer *buf = handle_table_get(drv->htab, param->filters[i]); + VAProcFilterParameterBufferBase *filter; + + if (!buf || buf->type != VAProcFilterParameterBufferType) + return VA_STATUS_ERROR_INVALID_BUFFER; + + filter = buf->data; + switch (filter->type) { + case VAProcFilterDeinterlacing: { + VAProcFilterParameterBufferDeinterlacing *deint = buf->data; + switch (deint->algorithm) { + case VAProcDeinterlacingBob: + if (deint->flags & VA_DEINTERLACING_BOTTOM_FIELD) + deinterlace = VL_COMPOSITOR_BOB_BOTTOM; + else + deinterlace = VL_COMPOSITOR_BOB_TOP; + break; + + case VAProcDeinterlacingWeave: + deinterlace = VL_COMPOSITOR_WEAVE; + break; + + default: + return VA_STATUS_ERROR_UNIMPLEMENTED; + } + + break; + } + + default: + return VA_STATUS_ERROR_UNIMPLEMENTED; + } + } + + src_region = vlVaRegionDefault(param->surface_region, src_surface->buffer, &def_src_region); + dst_region = vlVaRegionDefault(param->output_region, context->target, &def_dst_region); + + if (context->target->buffer_format != PIPE_FORMAT_NV12) + return vlVaPostProcCompositor(drv, context, src_region, dst_region, + src_surface->buffer, context->target, + deinterlace); + else + return vlVaPostProcBlit(drv, context, src_region, dst_region, + src_surface->buffer, context->target, + deinterlace); +} diff --git a/src/gallium/state_trackers/va/subpicture.c b/src/gallium/state_trackers/va/subpicture.c index f1461894699..f546e566242 100644 --- a/src/gallium/state_trackers/va/subpicture.c +++ b/src/gallium/state_trackers/va/subpicture.c @@ -65,22 +65,30 @@ VAStatus vlVaCreateSubpicture(VADriverContextP ctx, VAImageID image, VASubpictureID *subpicture) { + vlVaDriver *drv; vlVaSubpicture *sub; VAImage *img; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - img = handle_table_get(VL_VA_DRIVER(ctx)->htab, image); - if (!img) + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + img = handle_table_get(drv->htab, image); + if (!img) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_IMAGE; + } sub = CALLOC(1, sizeof(*sub)); - if (!sub) + if (!sub) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_ALLOCATION_FAILED; + } sub->image = img; *subpicture = handle_table_add(VL_VA_DRIVER(ctx)->htab, sub); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -88,17 +96,24 @@ vlVaCreateSubpicture(VADriverContextP ctx, VAImageID image, VAStatus vlVaDestroySubpicture(VADriverContextP ctx, VASubpictureID subpicture) { + vlVaDriver *drv; vlVaSubpicture *sub; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - sub = handle_table_get(VL_VA_DRIVER(ctx)->htab, subpicture); - if (!sub) + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + + sub = handle_table_get(drv->htab, subpicture); + if (!sub) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SUBPICTURE; + } FREE(sub); - handle_table_remove(VL_VA_DRIVER(ctx)->htab, subpicture); + handle_table_remove(drv->htab, subpicture); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -106,17 +121,24 @@ vlVaDestroySubpicture(VADriverContextP ctx, VASubpictureID subpicture) VAStatus vlVaSubpictureImage(VADriverContextP ctx, VASubpictureID subpicture, VAImageID image) { + vlVaDriver *drv; vlVaSubpicture *sub; VAImage *img; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - img = handle_table_get(VL_VA_DRIVER(ctx)->htab, image); - if (!img) + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + + img = handle_table_get(drv->htab, image); + if (!img) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_IMAGE; + } - sub = handle_table_get(VL_VA_DRIVER(ctx)->htab, subpicture); + sub = handle_table_get(drv->htab, subpicture); + pipe_mutex_unlock(drv->mutex); if (!sub) return VA_STATUS_ERROR_INVALID_SUBPICTURE; @@ -164,15 +186,20 @@ vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture, if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); sub = handle_table_get(drv->htab, subpicture); - if (!sub) + if (!sub) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SUBPICTURE; + } for (i = 0; i < num_surfaces; i++) { surf = handle_table_get(drv->htab, target_surfaces[i]); - if (!surf) + if (!surf) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SURFACE; + } } sub->src_rect = src_rect; @@ -191,8 +218,10 @@ vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture, tex_temp.flags = 0; if (!drv->pipe->screen->is_format_supported( drv->pipe->screen, tex_temp.format, tex_temp.target, - tex_temp.nr_samples, tex_temp.bind)) + tex_temp.nr_samples, tex_temp.bind)) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_ALLOCATION_FAILED; + } tex = drv->pipe->screen->resource_create(drv->pipe->screen, &tex_temp); @@ -200,13 +229,16 @@ vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture, u_sampler_view_default_template(&sampler_templ, tex, tex->format); sub->sampler = drv->pipe->create_sampler_view(drv->pipe, tex, &sampler_templ); pipe_resource_reference(&tex, NULL); - if (!sub->sampler) + if (!sub->sampler) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_ALLOCATION_FAILED; + } for (i = 0; i < num_surfaces; i++) { surf = handle_table_get(drv->htab, target_surfaces[i]); util_dynarray_append(&surf->subpics, vlVaSubpicture *, sub); } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -224,15 +256,20 @@ vlVaDeassociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture, if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); sub = handle_table_get(drv->htab, subpicture); - if (!sub) + if (!sub) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SUBPICTURE; + } for (i = 0; i < num_surfaces; i++) { surf = handle_table_get(drv->htab, target_surfaces[i]); - if (!surf) + if (!surf) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SURFACE; + } array = surf->subpics.data; if (!array) @@ -246,6 +283,7 @@ vlVaDeassociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture, while (surf->subpics.size && util_dynarray_top(&surf->subpics, vlVaSubpicture *) == NULL) (void)util_dynarray_pop(&surf->subpics, vlVaSubpicture *); } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c index 5ddaf04a8c7..f23a88901f5 100644 --- a/src/gallium/state_trackers/va/surface.c +++ b/src/gallium/state_trackers/va/surface.c @@ -68,6 +68,7 @@ vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_sur return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); for (i = 0; i < num_surfaces; ++i) { vlVaSurface *surf = handle_table_get(drv->htab, surface_list[i]); if (surf->buffer) @@ -76,6 +77,7 @@ vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_sur FREE(surf); handle_table_remove(drv->htab, surface_list[i]); } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -236,16 +238,21 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); surf = handle_table_get(drv->htab, surface_id); - if (!surf) + if (!surf) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SURFACE; + } screen = drv->pipe->screen; vscreen = drv->vscreen; tex = vscreen->texture_from_drawable(vscreen, draw); - if (!tex) + if (!tex) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_DISPLAY; + } dirty_area = vscreen->get_dirty_area(vscreen); @@ -254,6 +261,7 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s surf_draw = drv->pipe->create_surface(drv->pipe, tex, &surf_templ); if (!surf_draw) { pipe_resource_reference(&tex, NULL); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_DISPLAY; } @@ -268,8 +276,10 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s vl_compositor_render(&drv->cstate, &drv->compositor, surf_draw, dirty_area, true); status = vlVaPutSubpictures(surf, drv, surf_draw, dirty_area, &src_rect, &dst_rect); - if (status) + if (status) { + pipe_mutex_unlock(drv->mutex); return status; + } screen->flush_frontbuffer(screen, tex, 0, 0, vscreen->get_private(vscreen), NULL); @@ -278,6 +288,7 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s pipe_resource_reference(&tex, NULL); pipe_surface_reference(&surf_draw, NULL); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -599,6 +610,7 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format, memset(surfaces, VA_INVALID_ID, num_surfaces * sizeof(VASurfaceID)); + pipe_mutex_lock(drv->mutex); for (i = 0; i < num_surfaces; i++) { vlVaSurface *surf = CALLOC(1, sizeof(vlVaSurface)); if (!surf) @@ -627,10 +639,12 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format, assert(0); } } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; no_res: + pipe_mutex_unlock(drv->mutex); if (i) vlVaDestroySurfaces(ctx, surfaces, i); @@ -649,7 +663,7 @@ vlVaQueryVideoProcFilters(VADriverContextP ctx, VAContextID context, if (!num_filters || !filters) return VA_STATUS_ERROR_INVALID_PARAMETER; - filters[num++] = VAProcFilterNone; + filters[num++] = VAProcFilterDeinterlacing; *num_filters = num; @@ -674,8 +688,20 @@ vlVaQueryVideoProcFilterCaps(VADriverContextP ctx, VAContextID context, switch (type) { case VAProcFilterNone: break; + case VAProcFilterDeinterlacing: { + VAProcFilterCapDeinterlacing *deint = filter_caps; + + if (*num_filter_caps < 2) { + *num_filter_caps = 2; + return VA_STATUS_ERROR_MAX_NUM_EXCEEDED; + } + + deint[i++].type = VAProcDeinterlacingBob; + deint[i++].type = VAProcDeinterlacingWeave; + break; + } + case VAProcFilterNoiseReduction: - case VAProcFilterDeinterlacing: case VAProcFilterSharpening: case VAProcFilterColorBalance: case VAProcFilterSkinToneEnhancement: diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index bf9d24b2d34..7afd81a196d 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -44,6 +44,7 @@ #include "vl/vl_csc.h" #include "util/u_dynarray.h" +#include "os/os_thread.h" #define VL_VA_DRIVER(ctx) ((vlVaDriver *)ctx->pDriverData) #define VL_VA_PSCREEN(ctx) (VL_VA_DRIVER(ctx)->vscreen->pscreen) @@ -203,6 +204,7 @@ typedef struct { struct vl_compositor compositor; struct vl_compositor_state cstate; vl_csc_matrix csc; + pipe_mutex mutex; } vlVaDriver; typedef struct { diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c index 55d0d76d16d..ffcedc12de6 100644 --- a/src/gallium/state_trackers/vdpau/surface.c +++ b/src/gallium/state_trackers/vdpau/surface.c @@ -183,16 +183,9 @@ vlVdpVideoSurfaceSize(vlVdpSurface *p_surf, int component, *width = p_surf->templat.width; *height = p_surf->templat.height; - if (component > 0) { - if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { - *width /= 2; - *height /= 2; - } else if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { - *width /= 2; - } - } - if (p_surf->templat.interlaced) - *height /= 2; + vl_video_buffer_adjust_size(width, height, component, + p_surf->templat.chroma_format, + p_surf->templat.interlaced); } /** diff --git a/src/glsl/ir.h b/src/glsl/ir.h index a728c036e6b..93e07343559 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -1726,7 +1726,12 @@ public: operation == ir_binop_dot || operation == ir_binop_vector_extract || operation == ir_triop_vector_insert || - operation == ir_quadop_vector; + operation == ir_quadop_vector || + /* TODO: these can't currently be vectorized */ + operation == ir_quadop_bitfield_insert || + operation == ir_triop_bitfield_extract || + operation == ir_triop_bfi || + operation == ir_binop_bfm; } /** diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp index 47bb7717f84..33b2d4c8646 100644 --- a/src/glsl/link_uniforms.cpp +++ b/src/glsl/link_uniforms.cpp @@ -532,6 +532,8 @@ public: */ if (var->is_interface_instance()) { ubo_byte_offset = 0; + process(var->get_interface_type(), + var->get_interface_type()->name); } else { const struct gl_uniform_block *const block = &prog->BufferInterfaceBlocks[ubo_block_index]; @@ -542,13 +544,8 @@ public: &block->Uniforms[var->data.location]; ubo_byte_offset = ubo_var->Offset; - } - - if (var->is_interface_instance()) - process(var->get_interface_type(), - var->get_interface_type()->name); - else process(var); + } } else { /* Store any explicit location and reset data location so we can * reuse this variable for storing the uniform slot number. diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp index 3853abdb8e6..7cc58800765 100644 --- a/src/glsl/link_varyings.cpp +++ b/src/glsl/link_varyings.cpp @@ -1295,13 +1295,12 @@ public: void process(ir_variable *var) { + /* All named varying interface blocks should be flattened by now */ + assert(!var->is_interface_instance()); + this->toplevel_var = var; this->varying_floats = 0; - if (var->is_interface_instance()) - program_resource_visitor::process(var->get_interface_type(), - var->get_interface_type()->name); - else - program_resource_visitor::process(var); + program_resource_visitor::process(var); } private: diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 418bd09e49e..eb1bdc05932 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -3130,6 +3130,7 @@ check_explicit_uniform_locations(struct gl_context *ctx, return; } + unsigned entries_total = 0; for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_shader *sh = prog->_LinkedShaders[i]; @@ -3138,8 +3139,12 @@ check_explicit_uniform_locations(struct gl_context *ctx, foreach_in_list(ir_instruction, node, sh->ir) { ir_variable *var = node->as_variable(); - if (var && (var->data.mode == ir_var_uniform && - var->data.explicit_location)) { + if (!var || var->data.mode != ir_var_uniform) + continue; + + entries_total += var->type->uniform_locations(); + + if (var->data.explicit_location) { bool ret; if (var->type->is_subroutine()) ret = reserve_subroutine_explicit_locations(prog, sh, var); @@ -3153,6 +3158,14 @@ check_explicit_uniform_locations(struct gl_context *ctx, } } + /* Verify that total amount of entries for explicit and implicit locations + * is less than MAX_UNIFORM_LOCATIONS. + */ + if (entries_total >= ctx->Const.MaxUserAssignableUniformLocations) { + linker_error(prog, "count of uniform locations >= MAX_UNIFORM_LOCATIONS" + "(%u >= %u)", entries_total, + ctx->Const.MaxUserAssignableUniformLocations); + } delete uniform_map; } @@ -3349,6 +3362,30 @@ build_stageref(struct gl_shader_program *shProg, const char *name, return stages; } +/** + * Create gl_shader_variable from ir_variable class. + */ +static gl_shader_variable * +create_shader_variable(struct gl_shader_program *shProg, const ir_variable *in) +{ + gl_shader_variable *out = ralloc(shProg, struct gl_shader_variable); + if (!out) + return NULL; + + out->type = in->type; + out->name = ralloc_strdup(shProg, in->name); + + if (!out->name) + return NULL; + + out->location = in->data.location; + out->index = in->data.index; + out->patch = in->data.patch; + out->mode = in->data.mode; + + return out; +} + static bool add_interface_variables(struct gl_shader_program *shProg, exec_list *ir, GLenum programInterface) @@ -3400,9 +3437,13 @@ add_interface_variables(struct gl_shader_program *shProg, if (strncmp(var->name, "gl_out_FragData", 15) == 0) continue; - if (!add_program_resource(shProg, programInterface, var, - build_stageref(shProg, var->name, - var->data.mode) | mask)) + gl_shader_variable *sha_v = create_shader_variable(shProg, var); + if (!sha_v) + return false; + + if (!add_program_resource(shProg, programInterface, sha_v, + build_stageref(shProg, sha_v->name, + sha_v->mode) | mask)) return false; } return true; @@ -3432,9 +3473,12 @@ add_packed_varyings(struct gl_shader_program *shProg, int stage, GLenum type) } if (type == iface) { - if (!add_program_resource(shProg, iface, var, - build_stageref(shProg, var->name, - var->data.mode))) + gl_shader_variable *sha_v = create_shader_variable(shProg, var); + if (!sha_v) + return false; + if (!add_program_resource(shProg, iface, sha_v, + build_stageref(shProg, sha_v->name, + sha_v->mode))) return false; } } @@ -3454,7 +3498,10 @@ add_fragdata_arrays(struct gl_shader_program *shProg) ir_variable *var = node->as_variable(); if (var) { assert(var->data.mode == ir_var_shader_out); - if (!add_program_resource(shProg, GL_PROGRAM_OUTPUT, var, + gl_shader_variable *sha_v = create_shader_variable(shProg, var); + if (!sha_v) + return false; + if (!add_program_resource(shProg, GL_PROGRAM_OUTPUT, sha_v, 1 << MESA_SHADER_FRAGMENT)) return false; } @@ -3705,8 +3752,14 @@ build_program_resource_list(struct gl_shader_program *shProg) if (shProg->SeparateShader) { if (!add_packed_varyings(shProg, input_stage, GL_PROGRAM_INPUT)) return; - if (!add_packed_varyings(shProg, output_stage, GL_PROGRAM_OUTPUT)) - return; + + /* Only when dealing with multiple stages, otherwise we would have + * duplicate gl_shader_variable entries. + */ + if (input_stage != output_stage) { + if (!add_packed_varyings(shProg, output_stage, GL_PROGRAM_OUTPUT)) + return; + } } if (!add_fragdata_arrays(shProg)) diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index 36bed77b481..1ed0e4d1f59 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -2986,8 +2986,7 @@ meta_decompress_cleanup(struct gl_context *ctx, _mesa_reference_buffer_object(ctx, &decompress->buf_obj, NULL); } - if (decompress->Sampler != 0) - _mesa_DeleteSamplers(1, &decompress->Sampler); + _mesa_reference_sampler_object(ctx, &decompress->samp_obj, NULL); memset(decompress, 0, sizeof(*decompress)); } @@ -3017,7 +3016,7 @@ decompress_texture_image(struct gl_context *ctx, GLenum rbFormat; GLenum faceTarget; struct vertex verts[4]; - GLuint samplerSave; + struct gl_sampler_object *samp_obj_save = NULL; GLenum status; const bool use_glsl_version = ctx->Extensions.ARB_vertex_shader && ctx->Extensions.ARB_fragment_shader; @@ -3067,8 +3066,8 @@ decompress_texture_image(struct gl_context *ctx, _mesa_meta_begin(ctx, MESA_META_ALL & ~(MESA_META_PIXEL_STORE | MESA_META_DRAW_BUFFERS)); - samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? - ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; + _mesa_reference_sampler_object(ctx, &samp_obj_save, + ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler); /* Create/bind FBO/renderbuffer */ if (decompress_fbo->FBO == 0) { @@ -3113,22 +3112,32 @@ decompress_texture_image(struct gl_context *ctx, &decompress->buf_obj, 3); } - if (!decompress->Sampler) { - _mesa_GenSamplers(1, &decompress->Sampler); - _mesa_BindSampler(ctx->Texture.CurrentUnit, decompress->Sampler); - /* nearest filtering */ - _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - /* No sRGB decode or encode.*/ - if (ctx->Extensions.EXT_texture_sRGB_decode) { - _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_SRGB_DECODE_EXT, - GL_SKIP_DECODE_EXT); + if (decompress->samp_obj == NULL) { + decompress->samp_obj = ctx->Driver.NewSamplerObject(ctx, 0xDEADBEEF); + if (decompress->samp_obj == NULL) { + _mesa_meta_end(ctx); + + /* This is a bit lazy. Flag out of memory, and then don't bother to + * clean up. Once out of memory is flagged, the only realistic next + * move is to destroy the context. That will trigger all the right + * clean up. + * + * Returning true prevents other GetTexImage methods from attempting + * anything since they will likely fail too. + */ + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); + return true; } - } else { - _mesa_BindSampler(ctx->Texture.CurrentUnit, decompress->Sampler); + /* nearest filtering */ + _mesa_set_sampler_filters(ctx, decompress->samp_obj, GL_NEAREST, GL_NEAREST); + + /* We don't want to encode or decode sRGB values; treat them as linear. */ + _mesa_set_sampler_srgb_decode(ctx, decompress->samp_obj, GL_SKIP_DECODE_EXT); } + _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, decompress->samp_obj); + /* Silence valgrind warnings about reading uninitialized stack. */ memset(verts, 0, sizeof(verts)); @@ -3218,7 +3227,8 @@ decompress_texture_image(struct gl_context *ctx, if (!use_glsl_version) _mesa_set_enable(ctx, target, GL_FALSE); - _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); + _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, samp_obj_save); + _mesa_reference_sampler_object(ctx, &samp_obj_save, NULL); _mesa_meta_end(ctx); diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h index 5b04755a63e..d7d8fd38d89 100644 --- a/src/mesa/drivers/common/meta.h +++ b/src/mesa/drivers/common/meta.h @@ -309,7 +309,9 @@ struct blit_state struct fb_tex_blit_state { GLint baseLevelSave, maxLevelSave; - GLuint sampler, samplerSave, stencilSamplingSave; + struct gl_sampler_object *samp_obj; + struct gl_sampler_object *samp_obj_save; + GLuint stencilSamplingSave; GLuint tempTex; }; @@ -367,7 +369,7 @@ struct gen_mipmap_state GLuint VAO; struct gl_buffer_object *buf_obj; GLuint FBO; - GLuint Sampler; + struct gl_sampler_object *samp_obj; struct blit_shader_table shaders; }; @@ -390,7 +392,7 @@ struct decompress_state GLuint VAO; struct decompress_fbo_state byteFBO, floatFBO; struct gl_buffer_object *buf_obj; - GLuint Sampler; + struct gl_sampler_object *samp_obj; struct blit_shader_table shaders; }; @@ -465,7 +467,7 @@ _mesa_meta_bind_rb_as_tex_image(struct gl_context *ctx, struct gl_texture_object **texObj, GLenum *target); -GLuint +struct gl_sampler_object * _mesa_meta_setup_sampler(struct gl_context *ctx, const struct gl_texture_object *texObj, GLenum target, GLenum filter, GLuint srcLevel); diff --git a/src/mesa/drivers/common/meta_blit.c b/src/mesa/drivers/common/meta_blit.c index 4dbf0a76308..78434cfdcfe 100644 --- a/src/mesa/drivers/common/meta_blit.c +++ b/src/mesa/drivers/common/meta_blit.c @@ -703,8 +703,8 @@ blitframebuffer_texture(struct gl_context *ctx, printf(" srcTex %p dstText %p\n", texObj, drawAtt->Texture); */ - fb_tex_blit.sampler = _mesa_meta_setup_sampler(ctx, texObj, target, filter, - srcLevel); + fb_tex_blit.samp_obj = _mesa_meta_setup_sampler(ctx, texObj, target, filter, + srcLevel); /* Always do our blits with no net sRGB decode or encode. * @@ -725,13 +725,12 @@ blitframebuffer_texture(struct gl_context *ctx, if (ctx->Extensions.EXT_texture_sRGB_decode) { if (_mesa_get_format_color_encoding(rb->Format) == GL_SRGB && drawFb->Visual.sRGBCapable) { - _mesa_SamplerParameteri(fb_tex_blit.sampler, - GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT); + _mesa_set_sampler_srgb_decode(ctx, fb_tex_blit.samp_obj, + GL_DECODE_EXT); _mesa_set_framebuffer_srgb(ctx, GL_TRUE); } else { - _mesa_SamplerParameteri(fb_tex_blit.sampler, - GL_TEXTURE_SRGB_DECODE_EXT, - GL_SKIP_DECODE_EXT); + _mesa_set_sampler_srgb_decode(ctx, fb_tex_blit.samp_obj, + GL_SKIP_DECODE_EXT); /* set_framebuffer_srgb was set by _mesa_meta_begin(). */ } } @@ -811,9 +810,17 @@ void _mesa_meta_fb_tex_blit_begin(const struct gl_context *ctx, struct fb_tex_blit_state *blit) { - blit->samplerSave = - ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? - ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; + /* None of the existing callers preinitialize fb_tex_blit_state to zeros, + * and both use stack variables. If samp_obj_save is not NULL, + * _mesa_reference_sampler_object will try to dereference it. Leaving + * random garbage in samp_obj_save can only lead to crashes. + * + * Since the state isn't persistent across calls, we won't catch ref + * counting problems. + */ + blit->samp_obj_save = NULL; + _mesa_reference_sampler_object(ctx, &blit->samp_obj_save, + ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler); blit->tempTex = 0; } @@ -839,8 +846,10 @@ _mesa_meta_fb_tex_blit_end(struct gl_context *ctx, GLenum target, } } - _mesa_BindSampler(ctx->Texture.CurrentUnit, blit->samplerSave); - _mesa_DeleteSamplers(1, &blit->sampler); + _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, blit->samp_obj_save); + _mesa_reference_sampler_object(ctx, &blit->samp_obj_save, NULL); + _mesa_reference_sampler_object(ctx, &blit->samp_obj, NULL); + if (blit->tempTex) _mesa_DeleteTextures(1, &blit->tempTex); } @@ -884,31 +893,33 @@ _mesa_meta_bind_rb_as_tex_image(struct gl_context *ctx, return true; } -GLuint +struct gl_sampler_object * _mesa_meta_setup_sampler(struct gl_context *ctx, const struct gl_texture_object *texObj, GLenum target, GLenum filter, GLuint srcLevel) { - GLuint sampler; + struct gl_sampler_object *samp_obj; GLenum tex_filter = (filter == GL_SCALED_RESOLVE_FASTEST_EXT || filter == GL_SCALED_RESOLVE_NICEST_EXT) ? GL_NEAREST : filter; - _mesa_GenSamplers(1, &sampler); - _mesa_BindSampler(ctx->Texture.CurrentUnit, sampler); + samp_obj = ctx->Driver.NewSamplerObject(ctx, 0xDEADBEEF); + if (samp_obj == NULL) + return NULL; + + _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, samp_obj); + _mesa_set_sampler_filters(ctx, samp_obj, tex_filter, tex_filter); + _mesa_set_sampler_wrap(ctx, samp_obj, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, + samp_obj->WrapR); /* Prepare src texture state */ _mesa_BindTexture(target, texObj->Name); - _mesa_SamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, tex_filter); - _mesa_SamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, tex_filter); if (target != GL_TEXTURE_RECTANGLE_ARB) { _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel); _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel); } - _mesa_SamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - _mesa_SamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - return sampler; + return samp_obj; } /** diff --git a/src/mesa/drivers/common/meta_generate_mipmap.c b/src/mesa/drivers/common/meta_generate_mipmap.c index 2b942d6fd71..f20fcac68d6 100644 --- a/src/mesa/drivers/common/meta_generate_mipmap.c +++ b/src/mesa/drivers/common/meta_generate_mipmap.c @@ -137,8 +137,7 @@ _mesa_meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx, _mesa_DeleteVertexArrays(1, &mipmap->VAO); mipmap->VAO = 0; _mesa_reference_buffer_object(ctx, &mipmap->buf_obj, NULL); - _mesa_DeleteSamplers(1, &mipmap->Sampler); - mipmap->Sampler = 0; + _mesa_reference_sampler_object(ctx, &mipmap->samp_obj, NULL); if (mipmap->FBO != 0) { _mesa_DeleteFramebuffers(1, &mipmap->FBO); @@ -182,7 +181,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, ctx->Extensions.ARB_fragment_shader; GLenum faceTarget; GLuint dstLevel; - GLuint samplerSave; + struct gl_sampler_object *samp_obj_save = NULL; GLint swizzle[4]; GLboolean swizzleSaved = GL_FALSE; @@ -213,8 +212,8 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, _mesa_set_enable(ctx, target, GL_TRUE); } - samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? - ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; + _mesa_reference_sampler_object(ctx, &samp_obj_save, + ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler); /* We may have been called from glGenerateTextureMipmap with CurrentUnit * still set to 0, so we don't know when we can skip binding the texture. @@ -223,30 +222,29 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, */ _mesa_BindTexture(target, texObj->Name); - if (!mipmap->Sampler) { - _mesa_GenSamplers(1, &mipmap->Sampler); - _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); - - _mesa_SamplerParameteri(mipmap->Sampler, - GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - /* We don't want to encode or decode sRGB values; treat them as linear. - * This is not technically correct for GLES3 but we don't get any API - * error at the moment. - */ - if (ctx->Extensions.EXT_texture_sRGB_decode) { - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_SRGB_DECODE_EXT, - GL_SKIP_DECODE_EXT); + if (mipmap->samp_obj == NULL) { + mipmap->samp_obj = ctx->Driver.NewSamplerObject(ctx, 0xDEADBEEF); + if (mipmap->samp_obj == NULL) { + /* This is a bit lazy. Flag out of memory, and then don't bother to + * clean up. Once out of memory is flagged, the only realistic next + * move is to destroy the context. That will trigger all the right + * clean up. + */ + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenerateMipmap"); + return; } - } else { - _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); + + _mesa_set_sampler_filters(ctx, mipmap->samp_obj, GL_LINEAR_MIPMAP_LINEAR, + GL_LINEAR); + _mesa_set_sampler_wrap(ctx, mipmap->samp_obj, GL_CLAMP_TO_EDGE, + GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); + + /* We don't want to encode or decode sRGB values; treat them as linear. */ + _mesa_set_sampler_srgb_decode(ctx, mipmap->samp_obj, GL_SKIP_DECODE_EXT); } + _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, mipmap->samp_obj); + assert(mipmap->FBO != 0); _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, mipmap->FBO); @@ -370,7 +368,8 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, _mesa_lock_texture(ctx, texObj); /* relock */ - _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); + _mesa_bind_sampler(ctx, ctx->Texture.CurrentUnit, samp_obj_save); + _mesa_reference_sampler_object(ctx, &samp_obj_save, NULL); _mesa_meta_end(ctx); diff --git a/src/mesa/drivers/dri/i965/brw_binding_tables.c b/src/mesa/drivers/dri/i965/brw_binding_tables.c index 80935cf0aae..7fa5d602b96 100644 --- a/src/mesa/drivers/dri/i965/brw_binding_tables.c +++ b/src/mesa/drivers/dri/i965/brw_binding_tables.c @@ -196,12 +196,12 @@ const struct brw_tracked_state brw_wm_binding_table = { .emit = brw_upload_wm_binding_table, }; -/** Upload the TCS binding table (if TCS is active). */ +/** Upload the TCS binding table (if tessellation stages are active). */ static void brw_tcs_upload_binding_table(struct brw_context *brw) { - /* If there's no TCS, skip changing anything. */ - if (brw->tess_ctrl_program == NULL) + /* Skip if the tessellation stages are disabled. */ + if (brw->tess_eval_program == NULL) return; /* BRW_NEW_TCS_PROG_DATA */ @@ -216,6 +216,7 @@ const struct brw_tracked_state brw_tcs_binding_table = { .dirty = { .mesa = 0, .brw = BRW_NEW_BATCH | + BRW_NEW_DEFAULT_TESS_LEVELS | BRW_NEW_SURFACES | BRW_NEW_TCS_CONSTBUF | BRW_NEW_TCS_PROG_DATA, diff --git a/src/mesa/drivers/dri/i965/brw_device_info.c b/src/mesa/drivers/dri/i965/brw_device_info.c index 4eeca5cab95..e8af70cc571 100644 --- a/src/mesa/drivers/dri/i965/brw_device_info.c +++ b/src/mesa/drivers/dri/i965/brw_device_info.c @@ -420,6 +420,7 @@ static const struct brw_device_info brw_device_info_kbl_gt1 = { .max_cs_threads = 7 * 6, .max_wm_threads = KBL_MAX_THREADS_PER_PSD * 2, .urb.size = 192, + .num_slices = 1, }; static const struct brw_device_info brw_device_info_kbl_gt1_5 = { @@ -428,6 +429,7 @@ static const struct brw_device_info brw_device_info_kbl_gt1_5 = { .max_cs_threads = 7 * 6, .max_wm_threads = KBL_MAX_THREADS_PER_PSD * 3, + .num_slices = 1, }; static const struct brw_device_info brw_device_info_kbl_gt2 = { @@ -435,6 +437,7 @@ static const struct brw_device_info brw_device_info_kbl_gt2 = { .gt = 2, .max_wm_threads = KBL_MAX_THREADS_PER_PSD * 3, + .num_slices = 1, }; static const struct brw_device_info brw_device_info_kbl_gt3 = { @@ -442,6 +445,7 @@ static const struct brw_device_info brw_device_info_kbl_gt3 = { .gt = 3, .max_wm_threads = KBL_MAX_THREADS_PER_PSD * 6, + .num_slices = 2, }; static const struct brw_device_info brw_device_info_kbl_gt4 = { @@ -460,6 +464,7 @@ static const struct brw_device_info brw_device_info_kbl_gt4 = { * will be used." */ .urb.size = 1008 / 3, + .num_slices = 3, }; const struct brw_device_info * diff --git a/src/mesa/drivers/dri/i965/brw_meta_stencil_blit.c b/src/mesa/drivers/dri/i965/brw_meta_stencil_blit.c index ed471723fcf..c5f6c4f8fc8 100644 --- a/src/mesa/drivers/dri/i965/brw_meta_stencil_blit.c +++ b/src/mesa/drivers/dri/i965/brw_meta_stencil_blit.c @@ -409,8 +409,8 @@ set_read_rb_tex_image(struct gl_context *ctx, struct fb_tex_blit_state *blit, blit->baseLevelSave = tex_obj->BaseLevel; blit->maxLevelSave = tex_obj->MaxLevel; blit->stencilSamplingSave = tex_obj->StencilSampling; - blit->sampler = _mesa_meta_setup_sampler(ctx, tex_obj, *target, - GL_NEAREST, level); + blit->samp_obj = _mesa_meta_setup_sampler(ctx, tex_obj, *target, + GL_NEAREST, level); return true; } diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index fe6bdc2b4d1..3be216da234 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -1253,23 +1253,22 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, ctx->Driver.ValidateFramebuffer(ctx, fb); if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { fbo_incomplete(ctx, "driver marked FBO as incomplete", -1); + return; } } - if (fb->_Status == GL_FRAMEBUFFER_COMPLETE_EXT) { - /* - * Note that if ARB_framebuffer_object is supported and the attached - * renderbuffers/textures are different sizes, the framebuffer - * width/height will be set to the smallest width/height. - */ - if (numImages != 0) { - fb->Width = minWidth; - fb->Height = minHeight; - } - - /* finally, update the visual info for the framebuffer */ - _mesa_update_framebuffer_visual(ctx, fb); + /* + * Note that if ARB_framebuffer_object is supported and the attached + * renderbuffers/textures are different sizes, the framebuffer + * width/height will be set to the smallest width/height. + */ + if (numImages != 0) { + fb->Width = minWidth; + fb->Height = minHeight; } + + /* finally, update the visual info for the framebuffer */ + _mesa_update_framebuffer_visual(ctx, fb); } diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h index 042147fd8bb..ad7af5c1d8c 100644 --- a/src/mesa/main/imports.h +++ b/src/mesa/main/imports.h @@ -151,6 +151,13 @@ static inline int IROUND(float f) return (int) ((f >= 0.0F) ? (f + 0.5F) : (f - 0.5F)); } +/** + * Convert double to int by rounding to nearest integer, away from zero. + */ +static inline int IROUNDD(double d) +{ + return (int) ((d >= 0.0) ? (d + 0.5) : (d - 0.5)); +} /** * Convert float to int64 by rounding to nearest integer. diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 39e3cfdc047..1c717feabc2 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2530,6 +2530,67 @@ struct gl_active_atomic_buffer }; /** + * Data container for shader queries. This holds only the minimal + * amount of required information for resource queries to work. + */ +struct gl_shader_variable +{ + /** + * Declared type of the variable + */ + const struct glsl_type *type; + + /** + * Declared name of the variable + */ + char *name; + + /** + * Storage location of the base of this variable + * + * The precise meaning of this field depends on the nature of the variable. + * + * - Vertex shader input: one of the values from \c gl_vert_attrib. + * - Vertex shader output: one of the values from \c gl_varying_slot. + * - Geometry shader input: one of the values from \c gl_varying_slot. + * - Geometry shader output: one of the values from \c gl_varying_slot. + * - Fragment shader input: one of the values from \c gl_varying_slot. + * - Fragment shader output: one of the values from \c gl_frag_result. + * - Uniforms: Per-stage uniform slot number for default uniform block. + * - Uniforms: Index within the uniform block definition for UBO members. + * - Non-UBO Uniforms: explicit location until linking then reused to + * store uniform slot number. + * - Other: This field is not currently used. + * + * If the variable is a uniform, shader input, or shader output, and the + * slot has not been assigned, the value will be -1. + */ + int location; + + /** + * Output index for dual source blending. + * + * \note + * The GLSL spec only allows the values 0 or 1 for the index in \b dual + * source blending. + */ + unsigned index:1; + + /** + * Specifies whether a shader input/output is per-patch in tessellation + * shader stages. + */ + unsigned patch:1; + + /** + * Storage class of the variable. + * + * \sa (n)ir_variable_mode + */ + unsigned mode:4; +}; + +/** * Active resource in a gl_shader_program */ struct gl_program_resource diff --git a/src/mesa/main/samplerobj.c b/src/mesa/main/samplerobj.c index 676dd367b3f..fe15508696e 100644 --- a/src/mesa/main/samplerobj.c +++ b/src/mesa/main/samplerobj.c @@ -270,6 +270,17 @@ _mesa_IsSampler(GLuint sampler) return sampObj != NULL; } +void +_mesa_bind_sampler(struct gl_context *ctx, GLuint unit, + struct gl_sampler_object *sampObj) +{ + if (ctx->Texture.Unit[unit].Sampler != sampObj) { + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + } + + _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[unit].Sampler, + sampObj); +} void GLAPIENTRY _mesa_BindSampler(GLuint unit, GLuint sampler) @@ -297,13 +308,8 @@ _mesa_BindSampler(GLuint unit, GLuint sampler) } } - if (ctx->Texture.Unit[unit].Sampler != sampObj) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - } - /* bind new sampler */ - _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[unit].Sampler, - sampObj); + _mesa_bind_sampler(ctx, unit, sampObj); } @@ -444,6 +450,22 @@ flush(struct gl_context *ctx) FLUSH_VERTICES(ctx, _NEW_TEXTURE); } +void +_mesa_set_sampler_wrap(struct gl_context *ctx, struct gl_sampler_object *samp, + GLenum s, GLenum t, GLenum r) +{ + assert(validate_texture_wrap_mode(ctx, s)); + assert(validate_texture_wrap_mode(ctx, t)); + assert(validate_texture_wrap_mode(ctx, r)); + + if (samp->WrapS == s && samp->WrapT == t && samp->WrapR == r) + return; + + flush(ctx); + samp->WrapS = s; + samp->WrapT = t; + samp->WrapR = r; +} #define INVALID_PARAM 0x100 #define INVALID_PNAME 0x101 @@ -493,6 +515,27 @@ set_sampler_wrap_r(struct gl_context *ctx, struct gl_sampler_object *samp, return INVALID_PARAM; } +void +_mesa_set_sampler_filters(struct gl_context *ctx, + struct gl_sampler_object *samp, + GLenum min_filter, GLenum mag_filter) +{ + assert(min_filter == GL_NEAREST || + min_filter == GL_LINEAR || + min_filter == GL_NEAREST_MIPMAP_NEAREST || + min_filter == GL_LINEAR_MIPMAP_NEAREST || + min_filter == GL_NEAREST_MIPMAP_LINEAR || + min_filter == GL_LINEAR_MIPMAP_LINEAR); + assert(mag_filter == GL_NEAREST || + mag_filter == GL_LINEAR); + + if (samp->MinFilter == min_filter && samp->MagFilter == mag_filter) + return; + + flush(ctx); + samp->MinFilter = min_filter; + samp->MagFilter = mag_filter; +} static GLuint set_sampler_min_filter(struct gl_context *ctx, struct gl_sampler_object *samp, @@ -713,6 +756,16 @@ set_sampler_cube_map_seamless(struct gl_context *ctx, return GL_TRUE; } +void +_mesa_set_sampler_srgb_decode(struct gl_context *ctx, + struct gl_sampler_object *samp, GLenum param) +{ + assert(param == GL_DECODE_EXT || param == GL_SKIP_DECODE_EXT); + + flush(ctx); + samp->sRGBDecode = param; +} + static GLuint set_sampler_srgb_decode(struct gl_context *ctx, struct gl_sampler_object *samp, GLenum param) diff --git a/src/mesa/main/samplerobj.h b/src/mesa/main/samplerobj.h index 7bea9111480..abc6e019046 100644 --- a/src/mesa/main/samplerobj.h +++ b/src/mesa/main/samplerobj.h @@ -80,6 +80,23 @@ _mesa_new_sampler_object(struct gl_context *ctx, GLuint name); extern void _mesa_init_sampler_object_functions(struct dd_function_table *driver); +extern void +_mesa_set_sampler_wrap(struct gl_context *ctx, struct gl_sampler_object *samp, + GLenum s, GLenum t, GLenum r); + +extern void +_mesa_set_sampler_filters(struct gl_context *ctx, + struct gl_sampler_object *samp, + GLenum min_filter, GLenum mag_filter); + +extern void +_mesa_set_sampler_srgb_decode(struct gl_context *ctx, + struct gl_sampler_object *samp, GLenum param); + +extern void +_mesa_bind_sampler(struct gl_context *ctx, GLuint unit, + struct gl_sampler_object *sampObj); + void GLAPIENTRY _mesa_GenSamplers(GLsizei count, GLuint *samplers); void GLAPIENTRY diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index b25732a2e3b..014977b28ca 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -56,7 +56,7 @@ const type * RESOURCE_ ## name (gl_program_resource *res) { \ return (type *) res->Data; \ } -DECL_RESOURCE_FUNC(VAR, ir_variable); +DECL_RESOURCE_FUNC(VAR, gl_shader_variable); DECL_RESOURCE_FUNC(UBO, gl_uniform_block); DECL_RESOURCE_FUNC(UNI, gl_uniform_storage); DECL_RESOURCE_FUNC(ATC, gl_active_atomic_buffer); @@ -101,14 +101,14 @@ _mesa_BindAttribLocation(GLhandleARB program, GLuint index, } static bool -is_active_attrib(const ir_variable *var) +is_active_attrib(const gl_shader_variable *var) { if (!var) return false; - switch (var->data.mode) { + switch (var->mode) { case ir_var_shader_in: - return var->data.location != -1; + return var->location != -1; case ir_var_system_value: /* From GL 4.3 core spec, section 11.1.1 (Vertex Attributes): @@ -116,9 +116,9 @@ is_active_attrib(const ir_variable *var) * are enumerated, including the special built-in inputs gl_VertexID * and gl_InstanceID." */ - return var->data.location == SYSTEM_VALUE_VERTEX_ID || - var->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE || - var->data.location == SYSTEM_VALUE_INSTANCE_ID; + return var->location == SYSTEM_VALUE_VERTEX_ID || + var->location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE || + var->location == SYSTEM_VALUE_INSTANCE_ID; default: return false; @@ -163,7 +163,7 @@ _mesa_GetActiveAttrib(GLhandleARB program, GLuint desired_index, return; } - const ir_variable *const var = RESOURCE_VAR(res); + const gl_shader_variable *const var = RESOURCE_VAR(res); if (!is_active_attrib(var)) return; @@ -174,8 +174,8 @@ _mesa_GetActiveAttrib(GLhandleARB program, GLuint desired_index, * consider gl_VertexIDMESA as gl_VertexID for purposes of checking * active attributes. */ - if (var->data.mode == ir_var_system_value && - var->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) { + if (var->mode == ir_var_system_value && + var->location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) { var_name = "gl_VertexID"; } @@ -427,7 +427,7 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name) const char* _mesa_program_resource_name(struct gl_program_resource *res) { - const ir_variable *var; + const gl_shader_variable *var; switch (res->Type) { case GL_UNIFORM_BLOCK: case GL_SHADER_STORAGE_BLOCK: @@ -437,8 +437,8 @@ _mesa_program_resource_name(struct gl_program_resource *res) case GL_PROGRAM_INPUT: var = RESOURCE_VAR(res); /* Special case gl_VertexIDMESA -> gl_VertexID. */ - if (var->data.mode == ir_var_system_value && - var->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) { + if (var->mode == ir_var_system_value && + var->location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) { return "gl_VertexID"; } /* fallthrough */ @@ -857,14 +857,14 @@ program_resource_location(struct gl_shader_program *shProg, */ switch (res->Type) { case GL_PROGRAM_INPUT: { - const ir_variable *var = RESOURCE_VAR(res); + const gl_shader_variable *var = RESOURCE_VAR(res); /* If the input is an array, fail if the index is out of bounds. */ if (array_index > 0 && array_index >= var->type->length) { return -1; } - return (var->data.location + + return (var->location + (array_index * var->type->without_array()->matrix_columns) - VERT_ATTRIB_GENERIC0); } @@ -874,7 +874,7 @@ program_resource_location(struct gl_shader_program *shProg, && array_index >= RESOURCE_VAR(res)->type->length) { return -1; } - return RESOURCE_VAR(res)->data.location + array_index - FRAG_RESULT_DATA0; + return RESOURCE_VAR(res)->location + array_index - FRAG_RESULT_DATA0; case GL_UNIFORM: /* If the uniform is built-in, fail. */ if (RESOURCE_UNI(res)->builtin) @@ -954,7 +954,7 @@ _mesa_program_resource_location_index(struct gl_shader_program *shProg, if (!res || !(res->StageReferences & (1 << MESA_SHADER_FRAGMENT))) return -1; - return RESOURCE_VAR(res)->data.index; + return RESOURCE_VAR(res)->index; } static uint8_t @@ -1252,7 +1252,7 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg, case GL_LOCATION_INDEX: if (res->Type != GL_PROGRAM_OUTPUT) goto invalid_operation; - *val = RESOURCE_VAR(res)->data.index; + *val = RESOURCE_VAR(res)->index; return 1; case GL_NUM_COMPATIBLE_SUBROUTINES: @@ -1309,7 +1309,7 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg, switch (res->Type) { case GL_PROGRAM_INPUT: case GL_PROGRAM_OUTPUT: - *val = RESOURCE_VAR(res)->data.patch; + *val = RESOURCE_VAR(res)->patch; return 1; default: goto invalid_operation; diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c index 2a19a17b884..409b2f0d58c 100644 --- a/src/mesa/main/stencil.c +++ b/src/mesa/main/stencil.c @@ -124,8 +124,8 @@ _mesa_ClearStencil( GLint s ) * \sa glStencilFunc(). * * Verifies the parameters and updates the respective values in - * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies the - * driver via the dd_function_table::StencilFunc callback. + * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies + * the driver via the dd_function_table::StencilFunc callback. */ void GLAPIENTRY _mesa_StencilFuncSeparateATI( GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask ) @@ -178,8 +178,8 @@ _mesa_StencilFuncSeparateATI( GLenum frontfunc, GLenum backfunc, GLint ref, GLui * \sa glStencilFunc(). * * Verifies the parameters and updates the respective values in - * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies the - * driver via the dd_function_table::StencilFunc callback. + * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies + * the driver via the dd_function_table::StencilFunc callback. */ void GLAPIENTRY _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ) @@ -298,8 +298,8 @@ _mesa_StencilMask( GLuint mask ) * \sa glStencilOp(). * * Verifies the parameters and updates the respective fields in - * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies the - * driver via the dd_function_table::StencilOp callback. + * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies + * the driver via the dd_function_table::StencilOp callback. */ void GLAPIENTRY _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) @@ -389,12 +389,6 @@ _mesa_ActiveStencilFaceEXT(GLenum face) -/** - * OpenGL 2.0 function. - * \todo Make StencilOp() call this function. And eventually remove the - * ctx->Driver.StencilOp function and use ctx->Driver.StencilOpSeparate - * instead. - */ void GLAPIENTRY _mesa_StencilOpSeparate(GLenum face, GLenum sfail, GLenum zfail, GLenum zpass) { diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp index b2ac65fd68f..766a465cb11 100644 --- a/src/mesa/main/uniform_query.cpp +++ b/src/mesa/main/uniform_query.cpp @@ -437,7 +437,7 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, dst[didx].i = src[sidx].i ? 1 : 0; break; case GLSL_TYPE_DOUBLE: - dst[didx].i = *(double *)&src[sidx].f; + dst[didx].i = IROUNDD(*(double *)&src[sidx].f); break; default: assert(!"Should not get here."); diff --git a/src/mesa/math/m_matrix.c b/src/mesa/math/m_matrix.c index b3cfcd26a14..493d0e5cb27 100644 --- a/src/mesa/math/m_matrix.c +++ b/src/mesa/math/m_matrix.c @@ -131,7 +131,7 @@ static const char *types[] = { /** * Identity matrix. */ -static GLfloat Identity[16] = { +static const GLfloat Identity[16] = { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, |