summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristian Høgsberg Kristensen <[email protected]>2016-01-12 10:54:26 -0800
committerKristian Høgsberg Kristensen <[email protected]>2016-01-12 10:54:26 -0800
commitaf422fe9b36e98397d914be9eabae937634bef31 (patch)
treebae52236907092b6b3f6a7e0c63e341ddd6b88d5
parent7df20f0c1456738aa598ba8d4ce88679765ca13e (diff)
parent56fc2986d554b93d16fa1151765a9987bc42e4da (diff)
Merge ../mesa into vulkan
Merge master again to get the brw_device_info with the correct slice counts for KBL.
-rw-r--r--configure.ac2
-rwxr-xr-xscons/gallium.py2
-rw-r--r--src/gallium/auxiliary/Makefile.sources1
-rw-r--r--src/gallium/auxiliary/util/u_init.h52
-rw-r--r--src/gallium/auxiliary/vl/vl_deint_filter.c77
-rw-r--r--src/gallium/auxiliary/vl/vl_deint_filter.h2
-rw-r--r--src/gallium/auxiliary/vl/vl_video_buffer.c10
-rw-r--r--src/gallium/auxiliary/vl/vl_video_buffer.h18
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.cpp4
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h2
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_compute.c12
-rw-r--r--src/gallium/state_trackers/omx/vid_enc.c3
-rw-r--r--src/gallium/state_trackers/va/buffer.c70
-rw-r--r--src/gallium/state_trackers/va/context.c6
-rw-r--r--src/gallium/state_trackers/va/image.c81
-rw-r--r--src/gallium/state_trackers/va/picture.c29
-rw-r--r--src/gallium/state_trackers/va/postproc.c207
-rw-r--r--src/gallium/state_trackers/va/subpicture.c68
-rw-r--r--src/gallium/state_trackers/va/surface.c36
-rw-r--r--src/gallium/state_trackers/va/va_private.h2
-rw-r--r--src/gallium/state_trackers/vdpau/surface.c13
-rw-r--r--src/glsl/ir.h7
-rw-r--r--src/glsl/link_uniforms.cpp9
-rw-r--r--src/glsl/link_varyings.cpp9
-rw-r--r--src/glsl/linker.cpp75
-rw-r--r--src/mesa/drivers/common/meta.c46
-rw-r--r--src/mesa/drivers/common/meta.h10
-rw-r--r--src/mesa/drivers/common/meta_blit.c53
-rw-r--r--src/mesa/drivers/common/meta_generate_mipmap.c53
-rw-r--r--src/mesa/drivers/dri/i965/brw_binding_tables.c7
-rw-r--r--src/mesa/drivers/dri/i965/brw_device_info.c5
-rw-r--r--src/mesa/drivers/dri/i965/brw_meta_stencil_blit.c4
-rw-r--r--src/mesa/main/fbobject.c25
-rw-r--r--src/mesa/main/imports.h7
-rw-r--r--src/mesa/main/mtypes.h61
-rw-r--r--src/mesa/main/samplerobj.c65
-rw-r--r--src/mesa/main/samplerobj.h17
-rw-r--r--src/mesa/main/shader_query.cpp38
-rw-r--r--src/mesa/main/stencil.c18
-rw-r--r--src/mesa/main/uniform_query.cpp2
-rw-r--r--src/mesa/math/m_matrix.c2
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,