summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
authorChristian König <[email protected]>2010-12-11 13:43:44 +0100
committerChristian König <[email protected]>2010-12-11 13:43:44 +0100
commit772b25e1f366edc857e77b8c1ccdc5297d82cc41 (patch)
tree88d38b52e80319dbd4a0c5b5e038d92f1105110a /src/gallium/state_trackers
parentab130400cf91ab471e265e58193c95f04c7aeeda (diff)
parentb3d2ec9942303d1d03e28a25b030eb060415abfb (diff)
Merge remote branch 'origin/master' into pipe-video
Conflicts: src/gallium/drivers/r600/r600_pipe.c src/gallium/drivers/r600/r600_texture.c
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp23
-rw-r--r--src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h95
-rw-r--r--src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h72
-rw-r--r--src/gallium/state_trackers/dri/common/dri_screen.c3
-rw-r--r--src/gallium/state_trackers/dri/common/dri_screen.h3
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.c8
-rw-r--r--src/gallium/state_trackers/dri/sw/drisw.c26
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h3
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.c28
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_image.c11
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.c4
-rw-r--r--src/gallium/state_trackers/egl/common/native_helper.c20
-rw-r--r--src/gallium/state_trackers/egl/drm/native_drm.c2
-rw-r--r--src/gallium/state_trackers/egl/x11/native_dri2.c1
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_st.c34
-rw-r--r--src/gallium/state_trackers/python/p_context.i55
-rw-r--r--src/gallium/state_trackers/python/p_state.i6
-rw-r--r--src/gallium/state_trackers/python/p_texture.i18
-rw-r--r--src/gallium/state_trackers/python/st_device.c3
-rw-r--r--src/gallium/state_trackers/python/st_device.h15
-rw-r--r--src/gallium/state_trackers/python/st_sample.c3
-rw-r--r--src/gallium/state_trackers/vega/.gitignore1
-rw-r--r--src/gallium/state_trackers/vega/Makefile7
-rw-r--r--src/gallium/state_trackers/vega/SConscript12
-rw-r--r--src/gallium/state_trackers/vega/api.c17
-rw-r--r--src/gallium/state_trackers/vega/api.h5
-rw-r--r--src/gallium/state_trackers/vega/api_filters.c236
-rw-r--r--src/gallium/state_trackers/vega/api_images.c26
-rw-r--r--src/gallium/state_trackers/vega/api_masks.c142
-rw-r--r--src/gallium/state_trackers/vega/api_misc.c4
-rw-r--r--src/gallium/state_trackers/vega/api_params.c5
-rw-r--r--src/gallium/state_trackers/vega/api_path.c3
-rw-r--r--src/gallium/state_trackers/vega/api_text.c122
-rw-r--r--src/gallium/state_trackers/vega/asm_fill.h588
-rw-r--r--src/gallium/state_trackers/vega/asm_util.h51
-rw-r--r--src/gallium/state_trackers/vega/image.c160
-rw-r--r--src/gallium/state_trackers/vega/image.h2
-rw-r--r--src/gallium/state_trackers/vega/mask.c387
-rw-r--r--src/gallium/state_trackers/vega/matrix.h2
-rw-r--r--src/gallium/state_trackers/vega/paint.c125
-rw-r--r--src/gallium/state_trackers/vega/paint.h4
-rw-r--r--src/gallium/state_trackers/vega/path.c72
-rw-r--r--src/gallium/state_trackers/vega/path.h4
-rw-r--r--src/gallium/state_trackers/vega/polygon.c300
-rw-r--r--src/gallium/state_trackers/vega/renderer.c1766
-rw-r--r--src/gallium/state_trackers/vega/renderer.h116
-rw-r--r--src/gallium/state_trackers/vega/shader.c211
-rw-r--r--src/gallium/state_trackers/vega/shader.h7
-rw-r--r--src/gallium/state_trackers/vega/shaders_cache.c199
-rw-r--r--src/gallium/state_trackers/vega/shaders_cache.h73
-rw-r--r--src/gallium/state_trackers/vega/st_inlines.h122
-rw-r--r--src/gallium/state_trackers/vega/text.c250
-rw-r--r--src/gallium/state_trackers/vega/text.h71
-rw-r--r--src/gallium/state_trackers/vega/vg_context.c542
-rw-r--r--src/gallium/state_trackers/vega/vg_context.h66
-rw-r--r--src/gallium/state_trackers/vega/vg_manager.c223
-rw-r--r--src/gallium/state_trackers/wgl/SConscript2
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.c109
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.c10
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.h4
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c1
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_pbuffer.c212
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_pixelformat.c18
-rw-r--r--src/gallium/state_trackers/wgl/stw_framebuffer.c14
-rw-r--r--src/gallium/state_trackers/wgl/stw_framebuffer.h4
-rw-r--r--src/gallium/state_trackers/wgl/stw_getprocaddress.c7
-rw-r--r--src/gallium/state_trackers/wgl/stw_pixelformat.c2
-rw-r--r--src/gallium/state_trackers/wgl/stw_st.c66
-rw-r--r--src/gallium/state_trackers/wgl/stw_winsys.h7
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.c4
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c7
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c1
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c66
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c64
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.h2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c16
-rw-r--r--src/gallium/state_trackers/xorg/xorg_tracker.h1
-rw-r--r--src/gallium/state_trackers/xorg/xorg_xv.c21
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/subpicture.c11
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/surface.c12
80 files changed, 3970 insertions, 3045 deletions
diff --git a/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp b/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp
index c246fc5ef76..a54324a04f2 100644
--- a/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp
+++ b/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp
@@ -1159,8 +1159,15 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
unsigned blit_x, blit_y, blit_w, blit_h;
float black[4] = {0, 0, 0, 0};
- if(!formats_compatible || src->width0 != dst_w || src->height0 != dst_h)
- dst_surface = pipe->screen->get_tex_surface(pipe->screen, dst, 0, 0, 0, PIPE_BIND_RENDER_TARGET);
+ if(!formats_compatible || src->width0 != dst_w || src->height0 != dst_h) {
+ struct pipe_surface templat;
+ templat.usage = PIPE_BIND_RENDER_TARGET;
+ templat.format = dst->format;
+ templat.u.tex.level = 0;
+ templat.u.tex.first_layer = 0;
+ templat.u.tex.last_layer = 0;
+ dst_surface = pipe->create_surface(pipe, dst, &templat);
+ }
if(preserve_aspect_ratio)
{
@@ -1199,10 +1206,12 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
if(formats_compatible && blit_w == src->width0 && blit_h == src->height0)
{
- pipe_subresource sr;
- sr.face = 0;
- sr.level = 0;
- pipe->resource_copy_region(pipe, dst, sr, rect.left, rect.top, 0, src, sr, 0, 0, 0, blit_w, blit_h);
+ pipe_box box;
+ box.x = box.y = box.z;
+ box.width = blit_w;
+ box.height = blit_h;
+ box.z = 1;
+ pipe->resource_copy_region(pipe, dst, 0, rect.left, rect.top, 0, src, 0, &box);
}
else
{
@@ -1218,7 +1227,7 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
}
if(dst_surface)
- pipe->screen->tex_surface_destroy(dst_surface);
+ pipe->surface_destroy(pipe, dst_surface);
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, 0);
diff --git a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h
index 36110595c20..e1ba6c184fd 100644
--- a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h
+++ b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h
@@ -1416,23 +1416,33 @@ changed:
*out_predicate_value = render_predicate_value;
}
- static pipe_subresource d3d11_to_pipe_subresource(struct pipe_resource* resource, unsigned subresource)
+ static unsigned d3d11_subresource_to_level(struct pipe_resource* resource, unsigned subresource)
{
- pipe_subresource sr;
if(subresource <= resource->last_level)
{
- sr.level = subresource;
- sr.face = 0;
+ return subresource;
}
else
{
unsigned levels = resource->last_level + 1;
- sr.level = subresource % levels;
- sr.face = subresource / levels;
+ return subresource % levels;
}
- return sr;
}
+ static unsigned d3d11_subresource_to_face(struct pipe_resource* resource, unsigned subresource)
+ {
+ if(subresource <= resource->last_level)
+ {
+ return 0;
+ }
+ else
+ {
+ unsigned levels = resource->last_level + 1;
+ return subresource / levels;
+ }
+ }
+
+
/* TODO: deferred contexts will need a different implementation of this,
* because we can't put the transfer info into the resource itself.
* Also, there are very different restrictions, for obvious reasons.
@@ -1448,8 +1458,10 @@ changed:
GalliumD3D11Resource<>* resource = (GalliumD3D11Resource<>*)iresource;
if(resource->transfers.count(subresource))
return E_FAIL;
- pipe_subresource sr = d3d11_to_pipe_subresource(resource->resource, subresource);
- pipe_box box = d3d11_to_pipe_box(resource->resource, sr.level, 0);
+ unsigned level = d3d11_subresource_to_level(resource->resource, subresource);
+ unsigned face = d3d11_subresource_to_face(resource->resource, subresource);
+ pipe_box box = d3d11_to_pipe_box(resource->resource, level, 0);
+ /* XXX the translation from subresource to level/face(zslice/array layer) isn't quite right */
unsigned usage = 0;
if(map_type == D3D11_MAP_READ)
usage = PIPE_TRANSFER_READ;
@@ -1465,7 +1477,7 @@ changed:
return E_INVALIDARG;
if(map_type & D3D10_MAP_FLAG_DO_NOT_WAIT)
usage |= PIPE_TRANSFER_DONTBLOCK;
- struct pipe_transfer* transfer = pipe->get_transfer(pipe, resource->resource, sr, usage, &box);
+ struct pipe_transfer* transfer = pipe->get_transfer(pipe, resource->resource, level, usage, &box);
if(!transfer) {
if(map_type & D3D10_MAP_FLAG_DO_NOT_WAIT)
return DXGI_ERROR_WAS_STILL_DRAWING;
@@ -1475,7 +1487,7 @@ changed:
resource->transfers[subresource] = transfer;
mapped_resource->pData = pipe->transfer_map(pipe, transfer);
mapped_resource->RowPitch = transfer->stride;
- mapped_resource->DepthPitch = transfer->slice_stride;
+ mapped_resource->DepthPitch = transfer->layer_stride;
return S_OK;
}
@@ -1507,15 +1519,16 @@ changed:
SYNCHRONIZED;
GalliumD3D11Resource<>* dst = (GalliumD3D11Resource<>*)dst_resource;
GalliumD3D11Resource<>* src = (GalliumD3D11Resource<>*)src_resource;
- pipe_subresource subdst = d3d11_to_pipe_subresource(dst->resource, dst_subresource);
- pipe_subresource subsrc = d3d11_to_pipe_subresource(src->resource, src_subresource);
- pipe_box box = d3d11_to_pipe_box(src->resource, subsrc.level, src_box);
- for(unsigned i = 0; i < box.depth; ++i)
+ unsigned dst_level = d3d11_subresource_to_level(dst->resource, dst_subresource);
+ unsigned dst_face = d3d11_subresource_to_face(dst->resource, dst_subresource);
+ unsigned src_level = d3d11_subresource_to_level(src->resource, src_subresource);
+ unsigned src_face = d3d11_subresource_to_face(src->resource, src_subresource);
+ /* XXX the translation from subresource to level/face(zslice/array layer) isn't quite right */
+ pipe_box box = d3d11_to_pipe_box(src->resource, src_level, src_box);
{
pipe->resource_copy_region(pipe,
- dst->resource, subdst, dst_x, dst_y, dst_z + i,
- src->resource, subsrc, box.x, box.y, box.z + i,
- box.width, box.height);
+ dst->resource, dst_level, dst_x, dst_y, dst_z,
+ src->resource, src_level, &box);
}
}
@@ -1526,24 +1539,23 @@ changed:
SYNCHRONIZED;
GalliumD3D11Resource<>* dst = (GalliumD3D11Resource<>*)dst_resource;
GalliumD3D11Resource<>* src = (GalliumD3D11Resource<>*)src_resource;
- pipe_subresource sr;
- unsigned faces = dst->resource->target == PIPE_TEXTURE_CUBE ? 6 : 1;
-
- for(sr.face = 0; sr.face < faces; ++sr.face)
+ unsigned level;
+ for(level = 0; level <= dst->resource->last_level; ++level)
{
- for(sr.level = 0; sr.level <= dst->resource->last_level; ++sr.level)
- {
- unsigned w = u_minify(dst->resource->width0, sr.level);
- unsigned h = u_minify(dst->resource->height0, sr.level);
- unsigned d = u_minify(dst->resource->depth0, sr.level);
- for(unsigned i = 0; i < d; ++i)
- {
- pipe->resource_copy_region(pipe,
- dst->resource, sr, 0, 0, i,
- src->resource, sr, 0, 0, i,
- w, h);
- }
- }
+ unsigned layers = 1;
+ pipe_box box;
+ if (dst->resource->target == PIPE_TEXTURE_CUBE)
+ layers = 6;
+ else if (dst->resource->target == PIPE_TEXTURE_3D)
+ layers = u_minify(dst->resource->depth0, level);
+ /* else layers = dst->resource->array_size; */
+ box.x = box.y = box.z = 0;
+ box.width = u_minify(dst->resource->width0, level);
+ box.height = u_minify(dst->resource->height0, level);
+ box.depth = layers;
+ pipe->resource_copy_region(pipe,
+ dst->resource, level, 0, 0, 0,
+ src->resource, level, &box);
}
}
@@ -1557,9 +1569,10 @@ changed:
{
SYNCHRONIZED;
GalliumD3D11Resource<>* dst = (GalliumD3D11Resource<>*)dst_resource;
- pipe_subresource subdst = d3d11_to_pipe_subresource(dst->resource, dst_subresource);
- pipe_box box = d3d11_to_pipe_box(dst->resource, subdst.level, pDstBox);
- pipe->transfer_inline_write(pipe, dst->resource, subdst, PIPE_TRANSFER_WRITE, &box, pSrcData, src_row_pitch, src_depth_pitch);
+ unsigned dst_level = d3d11_subresource_to_level(dst->resource, dst_subresource);
+ /* XXX the translation from subresource to level/face(zslice/array layer) isn't quite right */
+ pipe_box box = d3d11_to_pipe_box(dst->resource, dst_level, pDstBox);
+ pipe->transfer_inline_write(pipe, dst->resource, dst_level, PIPE_TRANSFER_WRITE, &box, pSrcData, src_row_pitch, src_depth_pitch);
}
#if API >= 11
@@ -1714,9 +1727,9 @@ changed:
SYNCHRONIZED;
GalliumD3D11Resource<>* dst = (GalliumD3D11Resource<>*)dst_resource;
GalliumD3D11Resource<>* src = (GalliumD3D11Resource<>*)src_resource;
- pipe_subresource subdst = d3d11_to_pipe_subresource(dst->resource, dst_subresource);
- pipe_subresource subsrc = d3d11_to_pipe_subresource(src->resource, src_subresource);
- pipe->resource_resolve(pipe, dst->resource, subdst, src->resource, subsrc);
+ unsigned dst_layer = d3d11_subresource_to_face(dst->resource, dst_subresource);
+ unsigned src_layer = d3d11_subresource_to_face(src->resource, src_subresource);
+ pipe->resource_resolve(pipe, dst->resource, dst_layer, src->resource, src_layer);
}
#if API >= 11
diff --git a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h
index 95ea4e00fc1..9cfdc837d8e 100644
--- a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h
+++ b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h
@@ -718,15 +718,13 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen
{
for(unsigned level = 0; level <= templat.last_level; ++level)
{
- struct pipe_subresource sr;
- sr.level = level;
- sr.face = slice;
struct pipe_box box;
- box.x = box.y = box.z = 0;
+ box.x = box.y = 0;
+ box.z = slice;
box.width = u_minify(width, level);
box.height = u_minify(height, level);
- box.depth = u_minify(depth, level);
- immediate_pipe->transfer_inline_write(immediate_pipe, resource, sr, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | PIPE_TRANSFER_UNSYNCHRONIZED, &box, initial_data->pSysMem, initial_data->SysMemPitch, initial_data->SysMemSlicePitch);
+ box.depth = 1;
+ immediate_pipe->transfer_inline_write(immediate_pipe, resource, level, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | PIPE_TRANSFER_UNSYNCHRONIZED, &box, initial_data->pSysMem, initial_data->SysMemPitch, initial_data->SysMemSlicePitch);
++initial_data;
}
}
@@ -978,8 +976,8 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen
case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
/* yes, this works for all of these types (but TODO: texture arrays) */
- templat.first_level = desc->Texture1D.MostDetailedMip;
- templat.last_level = templat.first_level + desc->Texture1D.MipLevels - 1;
+ templat.u.tex.first_level = desc->Texture1D.MostDetailedMip;
+ templat.u.tex.last_level = templat.u.tex.first_level + desc->Texture1D.MipLevels - 1;
break;
case D3D11_SRV_DIMENSION_BUFFER:
case D3D11_SRV_DIMENSION_TEXTURE2DMS:
@@ -1054,30 +1052,34 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen
desc = &def_desc;
}
- unsigned zslice = 0;
- unsigned face = 0;
- unsigned level;
- enum pipe_format format;
+ struct pipe_surface templat;
+ memset(&templat, 0, sizeof(templat));
if(invalid(desc->format >= DXGI_FORMAT_COUNT))
return E_INVALIDARG;
- format = dxgi_to_pipe_format[desc->Format];
- if(!format)
+ templat.format = dxgi_to_pipe_format[desc->Format];
+ if(!templat.format)
return E_NOTIMPL;
+ templat.usage = PIPE_BIND_RENDER_TARGET;
+ templat.texture = ((GalliumD3D11Resource<>*)iresource)->resource;
switch(desc->ViewDimension)
{
case D3D11_RTV_DIMENSION_TEXTURE1D:
case D3D11_RTV_DIMENSION_TEXTURE2D:
- level = desc->Texture1D.MipSlice;
+ templat.u.tex.level = desc->Texture1D.MipSlice;
break;
case D3D11_RTV_DIMENSION_TEXTURE3D:
- level = desc->Texture3D.MipSlice;
- zslice = desc->Texture3D.FirstWSlice;
+ templat.u.tex.level = desc->Texture3D.MipSlice;
+ templat.u.tex.first_layer = desc->Texture3D.FirstWSlice;
+ /* XXX FIXME */
+ templat.u.tex.last_layer = desc->Texture3D.FirstWSlice;
break;
case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
- level = desc->Texture1DArray.MipSlice;
- face = desc->Texture1DArray.FirstArraySlice;
+ templat.u.tex.level = desc->Texture1DArray.MipSlice;
+ templat.u.tex.first_layer = desc->Texture1DArray.FirstArraySlice;
+ /* XXX FIXME */
+ templat.u.tex.last_layer = desc->Texture1DArray.FirstArraySlice;
break;
case D3D11_RTV_DIMENSION_BUFFER:
case D3D11_RTV_DIMENSION_TEXTURE2DMS:
@@ -1090,13 +1092,9 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen
if(!out_rtv)
return S_FALSE;
- struct pipe_surface* surface = screen->get_tex_surface(screen,
- ((GalliumD3D11Resource<>*)iresource)->resource,
- face, level, zslice, PIPE_BIND_RENDER_TARGET);
+ struct pipe_surface* surface = immediate_pipe->create_surface(immediate_pipe, templat.texture, &templat);
if(!surface)
return E_FAIL;
- /* muhahahahaha, let's hope this actually works */
- surface->format = format;
*out_rtv = new GalliumD3D11RenderTargetView(this, (GalliumD3D11Resource<>*)iresource, surface, *desc);
return S_OK;
}
@@ -1134,26 +1132,28 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen
desc = &def_desc;
}
- unsigned zslice = 0;
- unsigned face = 0;
- unsigned level;
- enum pipe_format format;
+ struct pipe_surface templat;
+ memset(&templat, 0, sizeof(templat));
if(invalid(desc->format >= DXGI_FORMAT_COUNT))
return E_INVALIDARG;
- format = dxgi_to_pipe_format[desc->Format];
- if(!format)
+ templat.format = dxgi_to_pipe_format[desc->Format];
+ if(!templat.format)
return E_NOTIMPL;
+ templat.usage = PIPE_BIND_DEPTH_STENCIL;
+ templat.texture = ((GalliumD3D11Resource<>*)iresource)->resource;
switch(desc->ViewDimension)
{
case D3D11_DSV_DIMENSION_TEXTURE1D:
case D3D11_DSV_DIMENSION_TEXTURE2D:
- level = desc->Texture1D.MipSlice;
+ templat.u.tex.level = desc->Texture1D.MipSlice;
break;
case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
- level = desc->Texture1DArray.MipSlice;
- face = desc->Texture1DArray.FirstArraySlice;
+ templat.u.tex.level = desc->Texture1DArray.MipSlice;
+ templat.u.tex.first_layer = desc->Texture1DArray.FirstArraySlice;
+ /* XXX FIXME */
+ templat.u.tex.last_layer = desc->Texture1DArray.FirstArraySlice;
break;
case D3D11_DSV_DIMENSION_TEXTURE2DMS:
case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
@@ -1165,13 +1165,9 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen
if(!out_depth_stencil_view)
return S_FALSE;
- struct pipe_surface* surface = screen->get_tex_surface(screen,
- ((GalliumD3D11Resource<>*)iresource)->resource,
- face, level, zslice, PIPE_BIND_DEPTH_STENCIL);
+ struct pipe_surface* surface = immediate_pipe->create_surface(immediate_pipe, templat.texture, &templat);
if(!surface)
return E_FAIL;
- /* muhahahahaha, let's hope this actually works */
- surface->format = format;
*out_depth_stencil_view = new GalliumD3D11DepthStencilView(this, (GalliumD3D11Resource<>*)iresource, surface, *desc);
return S_OK;
}
diff --git a/src/gallium/state_trackers/dri/common/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c
index 1302e9bc013..f6e22c74b4e 100644
--- a/src/gallium/state_trackers/dri/common/dri_screen.c
+++ b/src/gallium/state_trackers/dri/common/dri_screen.c
@@ -304,9 +304,8 @@ dri_get_egl_image(struct st_manager *smapi,
stimg->texture = NULL;
pipe_resource_reference(&stimg->texture, img->texture);
- stimg->face = img->face;
stimg->level = img->level;
- stimg->zslice = img->zslice;
+ stimg->layer = img->layer;
return TRUE;
}
diff --git a/src/gallium/state_trackers/dri/common/dri_screen.h b/src/gallium/state_trackers/dri/common/dri_screen.h
index 0da9b5510fc..8cb0a102c8d 100644
--- a/src/gallium/state_trackers/dri/common/dri_screen.h
+++ b/src/gallium/state_trackers/dri/common/dri_screen.h
@@ -83,9 +83,8 @@ dri_screen(__DRIscreen * sPriv)
struct __DRIimageRec {
struct pipe_resource *texture;
- unsigned face;
unsigned level;
- unsigned zslice;
+ unsigned layer;
void *loader_private;
};
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index 3c5b0756174..a9d05a80fbd 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -200,6 +200,7 @@ dri2_drawable_process_buffers(struct dri_drawable *drawable,
templ.width0 = dri_drawable->w;
templ.height0 = dri_drawable->h;
templ.depth0 = 1;
+ templ.array_size = 1;
memset(&whandle, 0, sizeof(whandle));
@@ -348,6 +349,7 @@ dri2_create_image_from_name(__DRIscreen *_screen,
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
+ templ.array_size = 1;
memset(&whandle, 0, sizeof(whandle));
whandle.handle = name;
@@ -360,9 +362,8 @@ dri2_create_image_from_name(__DRIscreen *_screen,
return NULL;
}
- img->face = 0;
img->level = 0;
- img->zslice = 0;
+ img->layer = 0;
img->loader_private = loaderPrivate;
return img;
@@ -430,9 +431,8 @@ dri2_create_image(__DRIscreen *_screen,
return NULL;
}
- img->face = 0;
img->level = 0;
- img->zslice = 0;
+ img->layer = 0;
img->loader_private = loaderPrivate;
return img;
diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c
index c48cc440367..30088b09685 100644
--- a/src/gallium/state_trackers/dri/sw/drisw.c
+++ b/src/gallium/state_trackers/dri/sw/drisw.c
@@ -87,40 +87,17 @@ drisw_put_image(struct dri_drawable *drawable,
put_image(dPriv, data, width, height);
}
-static struct pipe_surface *
-drisw_get_pipe_surface(struct dri_drawable *drawable, struct pipe_resource *ptex)
-{
- struct pipe_screen *pipe_screen = dri_screen(drawable->sPriv)->base.screen;
- struct pipe_surface *psurf = drawable->drisw_surface;
-
- if (!psurf || psurf->texture != ptex) {
- pipe_surface_reference(&drawable->drisw_surface, NULL);
-
- drawable->drisw_surface = pipe_screen->get_tex_surface(pipe_screen,
- ptex, 0, 0, 0, 0/* no bind flag???*/);
-
- psurf = drawable->drisw_surface;
- }
-
- return psurf;
-}
-
static INLINE void
drisw_present_texture(__DRIdrawable *dPriv,
struct pipe_resource *ptex)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
struct dri_screen *screen = dri_screen(drawable->sPriv);
- struct pipe_surface *psurf;
if (swrast_no_present)
return;
- psurf = drisw_get_pipe_surface(drawable, ptex);
- if (!psurf)
- return;
-
- screen->base.screen->flush_frontbuffer(screen->base.screen, psurf, drawable);
+ screen->base.screen->flush_frontbuffer(screen->base.screen, ptex, 0, 0, drawable);
}
static INLINE void
@@ -220,6 +197,7 @@ drisw_allocate_textures(struct dri_drawable *drawable,
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
+ templ.array_size = 1;
templ.last_level = 0;
for (i = 0; i < count; i++) {
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index 72c14f0ac49..9873fee6ec2 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -92,9 +92,8 @@ struct egl_g3d_config {
struct egl_g3d_image {
_EGLImage base;
struct pipe_resource *texture;
- unsigned face;
unsigned level;
- unsigned zslice;
+ unsigned layer;
};
/* standard typecasts */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
index fd7dc8f8149..8e53e1dccba 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -30,6 +30,7 @@
#include "pipe/p_screen.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
+#include "util/u_box.h"
#include "egl_g3d.h"
#include "egl_g3d_api.h"
@@ -140,11 +141,22 @@ egl_g3d_choose_config(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attribs,
if (!_eglParseConfigAttribList(&criteria, dpy, attribs))
return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
- tmp_configs = (_EGLConfig **) _eglFilterArray(dpy->Configs, &tmp_size,
+ /* get the number of matched configs */
+ tmp_size = _eglFilterArray(dpy->Configs, NULL, 0,
(_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria);
+ if (!tmp_size) {
+ *num_configs = tmp_size;
+ return EGL_TRUE;
+ }
+
+ tmp_configs = MALLOC(sizeof(tmp_configs[0]) * tmp_size);
if (!tmp_configs)
return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)");
+ /* get the matched configs */
+ _eglFilterArray(dpy->Configs, (void **) tmp_configs, tmp_size,
+ (_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria);
+
/* perform sorting of configs */
if (tmp_configs && tmp_size) {
_eglSortConfigs((const _EGLConfig **) tmp_configs, tmp_size,
@@ -154,7 +166,7 @@ egl_g3d_choose_config(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attribs,
configs[i] = _eglGetConfigHandle(tmp_configs[i]);
}
- free(tmp_configs);
+ FREE(tmp_configs);
*num_configs = size;
@@ -665,15 +677,11 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
ptex = get_pipe_resource(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
if (ptex) {
struct pipe_resource *psrc = gsurf->render_texture;
- struct pipe_subresource subsrc, subdst;
- subsrc.face = 0;
- subsrc.level = 0;
- subdst.face = 0;
- subdst.level = 0;
-
+ struct pipe_box src_box;
+ u_box_origin_2d(ptex->width0, ptex->height0, &src_box);
if (psrc) {
- gdpy->pipe->resource_copy_region(gdpy->pipe, ptex, subdst, 0, 0, 0,
- gsurf->render_texture, subsrc, 0, 0, 0, ptex->width0, ptex->height0);
+ gdpy->pipe->resource_copy_region(gdpy->pipe, ptex, 0, 0, 0, 0,
+ gsurf->render_texture, 0, &src_box);
nsurf->present(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0);
}
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
index 6a1f8cc697b..b2d6b433c5e 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
@@ -173,6 +173,7 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name,
templ.width0 = attrs.Width;
templ.height0 = attrs.Height;
templ.depth0 = 1;
+ templ.array_size = 1;
memset(&wsh, 0, sizeof(wsh));
wsh.handle = (unsigned) name;
@@ -191,7 +192,7 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
{
struct pipe_resource *ptex;
struct egl_g3d_image *gimg;
- unsigned face = 0, level = 0, zslice = 0;
+ unsigned level = 0, layer = 0;
gimg = CALLOC_STRUCT(egl_g3d_image);
if (!gimg) {
@@ -231,7 +232,7 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
FREE(gimg);
return NULL;
}
- if (zslice > ptex->depth0) {
+ if (layer >= (u_minify(ptex->depth0, level) + ptex->array_size - 1)) {
_eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
pipe_resource_reference(&gimg->texture, NULL);
FREE(gimg);
@@ -240,9 +241,8 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
/* transfer the ownership to the image */
gimg->texture = ptex;
- gimg->face = face;
gimg->level = level;
- gimg->zslice = zslice;
+ gimg->layer = layer;
return &gimg->base;
}
@@ -288,9 +288,8 @@ egl_g3d_create_drm_image(_EGLDriver *drv, _EGLDisplay *dpy,
/* transfer the ownership to the image */
gimg->texture = ptex;
- gimg->face = 0;
gimg->level = 0;
- gimg->zslice = 0;
+ gimg->layer = 0;
return &gimg->base;
}
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
index 25e2999590c..2b944b521a4 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
@@ -72,9 +72,8 @@ egl_g3d_st_manager_get_egl_image(struct st_manager *smapi,
out->texture = NULL;
pipe_resource_reference(&out->texture, gimg->texture);
- out->face = gimg->face;
out->level = gimg->level;
- out->zslice = gimg->zslice;
+ out->layer = gimg->layer;
_eglUnlockMutex(&gsmapi->display->Mutex);
@@ -140,6 +139,7 @@ pbuffer_allocate_render_texture(struct egl_g3d_surface *gsurf)
templ.width0 = gsurf->base.Width;
templ.height0 = gsurf->base.Height;
templ.depth0 = 1;
+ templ.array_size = 1;
templ.format = gsurf->stvis.color_format;
templ.bind = PIPE_BIND_RENDER_TARGET;
diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c
index 7832b2b693f..0f2d02032b5 100644
--- a/src/gallium/state_trackers/egl/common/native_helper.c
+++ b/src/gallium/state_trackers/egl/common/native_helper.c
@@ -40,7 +40,6 @@ struct resource_surface {
uint bind;
struct pipe_resource *resources[NUM_NATIVE_ATTACHMENTS];
- struct pipe_surface *present_surfaces[NUM_NATIVE_ATTACHMENTS];
uint resource_mask;
uint width, height;
};
@@ -67,8 +66,6 @@ resource_surface_free_resources(struct resource_surface *rsurf)
int i;
for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
- if (rsurf->present_surfaces[i])
- pipe_surface_reference(&rsurf->present_surfaces[i], NULL);
if (rsurf->resources[i])
pipe_resource_reference(&rsurf->resources[i], NULL);
}
@@ -130,6 +127,7 @@ resource_surface_add_resources(struct resource_surface *rsurf,
templ.width0 = rsurf->width;
templ.height0 = rsurf->height;
templ.depth0 = 1;
+ templ.array_size = 1;
for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
if (resource_mask & (1 <<i)) {
@@ -193,8 +191,6 @@ resource_surface_swap_buffers(struct resource_surface *rsurf,
pointer_swap((const void **) &rsurf->resources[buf1],
(const void **) &rsurf->resources[buf2]);
- pointer_swap((const void **) &rsurf->present_surfaces[buf1],
- (const void **) &rsurf->present_surfaces[buf2]);
/* swap mask bits */
mask = rsurf->resource_mask & ~(buf1_bit | buf2_bit);
@@ -212,24 +208,12 @@ resource_surface_present(struct resource_surface *rsurf,
void *winsys_drawable_handle)
{
struct pipe_resource *pres = rsurf->resources[which];
- struct pipe_surface *psurf = rsurf->present_surfaces[which];
if (!pres)
return TRUE;
- if (!psurf) {
- psurf = rsurf->screen->get_tex_surface(rsurf->screen,
- pres, 0, 0, 0, PIPE_BIND_DISPLAY_TARGET);
- if (!psurf)
- return FALSE;
-
- rsurf->present_surfaces[which] = psurf;
- }
-
- assert(psurf->texture == pres);
-
rsurf->screen->flush_frontbuffer(rsurf->screen,
- psurf, winsys_drawable_handle);
+ pres, 0, 0, winsys_drawable_handle);
return TRUE;
}
diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c
index 3759c2a26dd..2441b43fd8e 100644
--- a/src/gallium/state_trackers/egl/drm/native_drm.c
+++ b/src/gallium/state_trackers/egl/drm/native_drm.c
@@ -34,7 +34,7 @@
/* see get_drm_screen_name */
#include <radeon_drm.h>
-#include "radeon/drm/radeon_drm.h"
+#include "radeon/drm/radeon_drm_public.h"
static boolean
drm_display_is_format_supported(struct native_display *ndpy,
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index 331a7de432a..8108ce45865 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -136,6 +136,7 @@ dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
templ.width0 = dri2surf->width;
templ.height0 = dri2surf->height;
templ.depth0 = 1;
+ templ.array_size = 1;
templ.format = dri2surf->color_format;
templ.bind = PIPE_BIND_RENDER_TARGET;
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c
index e7466bdbee5..6bfe8b0788c 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_st.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.c
@@ -42,7 +42,7 @@ struct xmesa_st_framebuffer {
unsigned texture_width, texture_height, texture_mask;
struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
- struct pipe_surface *display_surface;
+ struct pipe_resource *display_resource;
};
static INLINE struct xmesa_st_framebuffer *
@@ -60,25 +60,19 @@ xmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi,
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
struct pipe_resource *ptex = xstfb->textures[statt];
- struct pipe_surface *psurf;
+ struct pipe_resource *pres;
if (!ptex)
return TRUE;
- psurf = xstfb->display_surface;
+ pres = xstfb->display_resource;
/* (re)allocate the surface for the texture to be displayed */
- if (!psurf || psurf->texture != ptex) {
- pipe_surface_reference(&xstfb->display_surface, NULL);
-
- psurf = xstfb->screen->get_tex_surface(xstfb->screen,
- ptex, 0, 0, 0, PIPE_BIND_DISPLAY_TARGET);
- if (!psurf)
- return FALSE;
-
- xstfb->display_surface = psurf;
+ if (!pres || pres != ptex) {
+ pipe_resource_reference(&xstfb->display_resource, ptex);
+ pres = xstfb->display_resource;
}
- xstfb->screen->flush_frontbuffer(xstfb->screen, psurf, &xstfb->buffer->ws);
+ xstfb->screen->flush_frontbuffer(xstfb->screen, pres, 0, 0, &xstfb->buffer->ws);
return TRUE;
}
@@ -96,7 +90,7 @@ xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi,
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
struct pipe_resource *src_ptex = xstfb->textures[src_statt];
struct pipe_resource *dst_ptex = xstfb->textures[dst_statt];
- struct pipe_subresource subsrc, subdst;
+ struct pipe_box src_box;
struct pipe_context *pipe;
if (!src_ptex || !dst_ptex)
@@ -110,14 +104,11 @@ xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi,
xstfb->display->pipe = pipe;
}
- subsrc.face = 0;
- subsrc.level = 0;
- subdst.face = 0;
- subdst.level = 0;
+ u_box_2d(x, y, width, height, &src_box);
if (src_ptex && dst_ptex)
- pipe->resource_copy_region(pipe, dst_ptex, subdst, x, y, 0,
- src_ptex, subsrc, x, y, 0, width, height);
+ pipe->resource_copy_region(pipe, dst_ptex, 0, x, y, 0,
+ src_ptex, 0, &src_box);
}
/**
@@ -144,6 +135,7 @@ xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
+ templ.array_size = 1;
templ.last_level = 0;
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
@@ -321,7 +313,7 @@ xmesa_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
int i;
- pipe_surface_reference(&xstfb->display_surface, NULL);
+ pipe_resource_reference(&xstfb->display_resource, NULL);
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_resource_reference(&xstfb->textures[i], NULL);
diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i
index 40c4603fb9d..5bdeaa8e4ea 100644
--- a/src/gallium/state_trackers/python/p_context.i
+++ b/src/gallium/state_trackers/python/p_context.i
@@ -132,6 +132,8 @@ struct st_context {
enum pipe_format format = PIPE_FORMAT_NONE,
unsigned first_level = 0,
unsigned last_level = ~0,
+ unsigned first_layer = 0,
+ unsigned last_layer = ~0,
unsigned swizzle_r = 0,
unsigned swizzle_g = 1,
unsigned swizzle_b = 2,
@@ -146,9 +148,10 @@ struct st_context {
} else {
templat.format = format;
}
- templat.last_level = MIN2(last_level, texture->last_level);
- templat.first_level = first_level;
- templat.last_level = last_level;
+ templat.u.tex.last_level = MIN2(last_level, texture->last_level);
+ templat.u.tex.first_level = first_level;
+ templat.u.tex.first_layer = first_layer;
+ templat.u.tex.last_layer = last_layer;
templat.swizzle_r = swizzle_r;
templat.swizzle_g = swizzle_g;
templat.swizzle_b = swizzle_b;
@@ -412,17 +415,15 @@ error1:
*/
void resource_copy_region(struct pipe_resource *dst,
- struct pipe_subresource subdst,
+ unsigned dst_level,
unsigned dstx, unsigned dsty, unsigned dstz,
struct pipe_resource *src,
- struct pipe_subresource subsrc,
- unsigned srcx, unsigned srcy, unsigned srcz,
- unsigned width, unsigned height)
+ unsigned src_level,
+ const struct pipe_box *src_box)
{
$self->pipe->resource_copy_region($self->pipe,
- dst, subdst, dstx, dsty, dstz,
- src, subsrc, srcx, srcy, srcz,
- width, height);
+ dst, dst_level, dstx, dsty, dstz,
+ src, src_level, src_box);
}
@@ -433,7 +434,7 @@ error1:
{
struct pipe_surface *_dst = NULL;
- _dst = st_pipe_surface(dst, PIPE_BIND_RENDER_TARGET);
+ _dst = st_pipe_surface($self->pipe, dst, PIPE_BIND_RENDER_TARGET);
if(!_dst)
SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing");
@@ -452,7 +453,7 @@ error1:
{
struct pipe_surface *_dst = NULL;
- _dst = st_pipe_surface(dst, PIPE_BIND_DEPTH_STENCIL);
+ _dst = st_pipe_surface($self->pipe, dst, PIPE_BIND_DEPTH_STENCIL);
if(!_dst)
SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing");
@@ -482,9 +483,8 @@ error1:
transfer = pipe_get_transfer(pipe,
surface->texture,
- surface->face,
surface->level,
- surface->zslice,
+ surface->layer,
PIPE_TRANSFER_READ,
x, y, w, h);
if(transfer) {
@@ -511,9 +511,8 @@ error1:
transfer = pipe_get_transfer(pipe,
surface->texture,
- surface->face,
surface->level,
- surface->zslice,
+ surface->layer,
PIPE_TRANSFER_WRITE,
x, y, w, h);
if(!transfer)
@@ -535,9 +534,8 @@ error1:
struct pipe_transfer *transfer;
transfer = pipe_get_transfer(pipe,
surface->texture,
- surface->face,
surface->level,
- surface->zslice,
+ surface->layer,
PIPE_TRANSFER_READ,
x, y, w, h);
if(transfer) {
@@ -555,9 +553,8 @@ error1:
struct pipe_transfer *transfer;
transfer = pipe_get_transfer(pipe,
surface->texture,
- surface->face,
surface->level,
- surface->zslice,
+ surface->layer,
PIPE_TRANSFER_WRITE,
x, y, w, h);
if(transfer) {
@@ -597,9 +594,8 @@ error1:
transfer = pipe_get_transfer(pipe,
surface->texture,
- surface->face,
surface->level,
- surface->zslice,
+ surface->layer,
PIPE_TRANSFER_READ,
x, y, w, h);
if(transfer) {
@@ -624,9 +620,8 @@ error1:
struct pipe_transfer *transfer;
transfer = pipe_get_transfer(pipe,
surface->texture,
- surface->face,
surface->level,
- surface->zslice,
+ surface->layer,
PIPE_TRANSFER_READ,
x, y, w, h);
if(transfer) {
@@ -644,9 +639,8 @@ error1:
struct pipe_transfer *transfer;
transfer = pipe_get_transfer(pipe,
surface->texture,
- surface->face,
surface->level,
- surface->zslice,
+ surface->layer,
PIPE_TRANSFER_WRITE,
x, y, w, h);
if(transfer) {
@@ -681,9 +675,8 @@ error1:
transfer = pipe_get_transfer(pipe,
surface->texture,
- surface->face,
surface->level,
- surface->zslice,
+ surface->layer,
PIPE_TRANSFER_READ,
x, y, w, h);
if(!transfer) {
@@ -715,16 +708,16 @@ error1:
%cstring_input_binary(const char *STRING, unsigned LENGTH);
void
transfer_inline_write(struct pipe_resource *resource,
- struct pipe_subresource *sr,
+ unsigned level,
unsigned usage,
const struct pipe_box *box,
const char *STRING, unsigned LENGTH,
unsigned stride,
- unsigned slice_stride)
+ unsigned layer_stride)
{
struct pipe_context *pipe = $self->pipe;
- pipe->transfer_inline_write(pipe, resource, *sr, usage, box, STRING, stride, slice_stride);
+ pipe->transfer_inline_write(pipe, resource, level, usage, box, STRING, stride, layer_stride);
}
%cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1));
diff --git a/src/gallium/state_trackers/python/p_state.i b/src/gallium/state_trackers/python/p_state.i
index c1e6ea1b43c..0537557661d 100644
--- a/src/gallium/state_trackers/python/p_state.i
+++ b/src/gallium/state_trackers/python/p_state.i
@@ -114,7 +114,8 @@
SWIG_exception(SWIG_ValueError, "index out of bounds");
if(surface) {
- _surface = st_pipe_surface(surface, PIPE_BIND_RENDER_TARGET);
+ /* XXX need a context here */
+ _surface = st_pipe_surface(NULL, surface, PIPE_BIND_RENDER_TARGET);
if(!_surface)
SWIG_exception(SWIG_ValueError, "couldn't acquire surface for writing");
}
@@ -131,7 +132,8 @@
struct pipe_surface *_surface = NULL;
if(surface) {
- _surface = st_pipe_surface(surface, PIPE_BIND_DEPTH_STENCIL);
+ /* XXX need a context here */
+ _surface = st_pipe_surface(NULL, surface, PIPE_BIND_DEPTH_STENCIL);
if(!_surface)
SWIG_exception(SWIG_ValueError, "couldn't acquire surface for writing");
}
diff --git a/src/gallium/state_trackers/python/p_texture.i b/src/gallium/state_trackers/python/p_texture.i
index ae506944c45..1f4b4fd596b 100644
--- a/src/gallium/state_trackers/python/p_texture.i
+++ b/src/gallium/state_trackers/python/p_texture.i
@@ -42,9 +42,8 @@
%ignore pipe_resource::screen;
%immutable st_surface::texture;
-%immutable st_surface::face;
%immutable st_surface::level;
-%immutable st_surface::zslice;
+%immutable st_surface::layer;
%newobject pipe_resource::get_surface;
@@ -73,25 +72,23 @@
/** Get a surface which is a "view" into a texture */
struct st_surface *
- get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0)
+ get_surface(unsigned level=0, unsigned layer=0)
{
struct st_surface *surface;
- if(face >= ($self->target == PIPE_TEXTURE_CUBE ? 6U : 1U))
- SWIG_exception(SWIG_ValueError, "face out of bounds");
if(level > $self->last_level)
SWIG_exception(SWIG_ValueError, "level out of bounds");
- if(zslice >= u_minify($self->depth0, level))
- SWIG_exception(SWIG_ValueError, "zslice out of bounds");
+ if(layer >= ($self->target == PIPE_TEXTURE_3D ?
+ u_minify($self->depth0, level) : $self->depth0))
+ SWIG_exception(SWIG_ValueError, "layer out of bounds");
surface = CALLOC_STRUCT(st_surface);
if(!surface)
return NULL;
pipe_resource_reference(&surface->texture, $self);
- surface->face = face;
surface->level = level;
- surface->zslice = zslice;
+ surface->layer = layer;
return surface;
@@ -113,9 +110,8 @@ struct st_surface
%immutable;
struct pipe_resource *texture;
- unsigned face;
unsigned level;
- unsigned zslice;
+ unsigned layer;
};
diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c
index 29813456b5f..d0a4295c7a2 100644
--- a/src/gallium/state_trackers/python/st_device.c
+++ b/src/gallium/state_trackers/python/st_device.c
@@ -240,6 +240,7 @@ st_context_create(struct st_device *st_dev)
templat.width0 = 1;
templat.height0 = 1;
templat.depth0 = 1;
+ templat.array_size = 1;
templat.last_level = 0;
templat.bind = PIPE_BIND_SAMPLER_VIEW;
@@ -252,7 +253,7 @@ st_context_create(struct st_device *st_dev)
pipe->transfer_inline_write(pipe,
st_ctx->default_texture,
- u_subresource(0,0),
+ 0,
PIPE_TRANSFER_WRITE,
&box,
&zero,
diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h
index 2dca7a1974e..53e2556cb0d 100644
--- a/src/gallium/state_trackers/python/st_device.h
+++ b/src/gallium/state_trackers/python/st_device.h
@@ -41,9 +41,8 @@ struct st_winsys;
struct st_surface
{
struct pipe_resource *texture;
- unsigned face;
unsigned level;
- unsigned zslice;
+ unsigned layer;
};
@@ -83,11 +82,17 @@ struct st_device
static INLINE struct pipe_surface *
-st_pipe_surface(struct st_surface *surface, unsigned usage)
+st_pipe_surface(struct pipe_context *pipe, struct st_surface *surface, unsigned usage)
{
struct pipe_resource *texture = surface->texture;
- struct pipe_screen *screen = texture->screen;
- return screen->get_tex_surface(screen, texture, surface->face, surface->level, surface->zslice, usage);
+ struct pipe_surface surf_tmpl;
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ surf_tmpl.format = texture->format;
+ surf_tmpl.usage = usage;
+ surf_tmpl.u.tex.level = surface->level;
+ surf_tmpl.u.tex.first_layer = surface->layer;
+ surf_tmpl.u.tex.last_layer = surface->layer;
+ return pipe->create_surface(pipe, texture, &surf_tmpl);
}
struct st_context *
diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c
index 25bfbf1ab73..cac9a1a6204 100644
--- a/src/gallium/state_trackers/python/st_sample.c
+++ b/src/gallium/state_trackers/python/st_sample.c
@@ -555,9 +555,8 @@ st_sample_surface(struct pipe_context *pipe,
transfer = pipe_get_transfer(pipe,
surface->texture,
- surface->face,
surface->level,
- surface->zslice,
+ surface->layer,
PIPE_TRANSFER_WRITE,
0, 0,
width,
diff --git a/src/gallium/state_trackers/vega/.gitignore b/src/gallium/state_trackers/vega/.gitignore
new file mode 100644
index 00000000000..c452229f7f4
--- /dev/null
+++ b/src/gallium/state_trackers/vega/.gitignore
@@ -0,0 +1 @@
+api_tmp.h
diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile
index 0543fac0946..7342c124c28 100644
--- a/src/gallium/state_trackers/vega/Makefile
+++ b/src/gallium/state_trackers/vega/Makefile
@@ -38,7 +38,14 @@ C_SOURCES = \
renderer.c \
stroker.c \
mask.c \
+ text.c \
shader.c \
shaders_cache.c
+GENERATED_SOURCES := api_tmp.h
+
include ../../Makefile.template
+
+MAPI := $(TOP)/src/mapi
+api_tmp.h: $(MAPI)/mapi/mapi_abi.py $(MAPI)/vgapi/vgapi.csv
+ $(PYTHON2) $< --printer vgapi --mode app $(MAPI)/vgapi/vgapi.csv > $@
diff --git a/src/gallium/state_trackers/vega/SConscript b/src/gallium/state_trackers/vega/SConscript
index a62783ab18e..4900135a1c5 100644
--- a/src/gallium/state_trackers/vega/SConscript
+++ b/src/gallium/state_trackers/vega/SConscript
@@ -3,6 +3,8 @@
Import('*')
+from sys import executable as python_cmd
+
env = env.Clone()
env.Append(CPPPATH = [
@@ -40,10 +42,16 @@ vega_sources = [
'mask.c',
'shader.c',
'shaders_cache.c',
+ 'text.c',
]
-# vgapi_header must be generated first
-env.Depends(vega_sources, vgapi_header)
+api_tmp = env.CodeGenerate(
+ target = '#/src/gallium/state_trackers/vega/api_tmp.h',
+ script = '#src/mapi/mapi/mapi_abi.py',
+ source = '#src/mapi/vgapi/vgapi.csv',
+ command = python_cmd + ' $SCRIPT --printer vgapi --mode app $SOURCE > $TARGET'
+)
+env.Depends(vega_sources, api_tmp)
st_vega = env.ConvenienceLibrary(
target = 'st_vega',
diff --git a/src/gallium/state_trackers/vega/api.c b/src/gallium/state_trackers/vega/api.c
index bf1d37493af..4bf7c71d453 100644
--- a/src/gallium/state_trackers/vega/api.c
+++ b/src/gallium/state_trackers/vega/api.c
@@ -28,23 +28,10 @@
#include "mapi/mapi.h"
+/* define vega_spec and vega_procs for use with mapi */
+#define API_TMP_DEFINE_SPEC
#include "api.h"
-static const char vega_spec[] =
- "1"
-#define MAPI_ABI_ENTRY(ret, name, params) \
- "\0" #name "\0"
-#define MAPI_ALIAS_ENTRY(alias, ret, name, params) \
- #name "\0"
-#include "vgapi/vgapi_tmp.h"
- "\0";
-
-static const mapi_proc vega_procs[] = {
-#define MAPI_ABI_ENTRY(ret, name, params) \
- (mapi_proc) vega ## name,
-#include "vgapi/vgapi_tmp.h"
-};
-
static void api_init(void)
{
static boolean initialized = FALSE;
diff --git a/src/gallium/state_trackers/vega/api.h b/src/gallium/state_trackers/vega/api.h
index 955508dae9a..459dafb4bb0 100644
--- a/src/gallium/state_trackers/vega/api.h
+++ b/src/gallium/state_trackers/vega/api.h
@@ -33,10 +33,7 @@
#include "VG/vgext.h"
#include "vg_manager.h"
-/* declare the prototypes */
-#define MAPI_ABI_ENTRY(ret, name, params) \
- ret VG_API_ENTRY vega ## name params;
-#include "vgapi/vgapi_tmp.h"
+#include "api_tmp.h"
struct mapi_table;
diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c
index fa1e00d1f88..724e38241b5 100644
--- a/src/gallium/state_trackers/vega/api_filters.c
+++ b/src/gallium/state_trackers/vega/api_filters.c
@@ -31,7 +31,6 @@
#include "api.h"
#include "renderer.h"
#include "shaders_cache.h"
-#include "st_inlines.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
@@ -42,7 +41,6 @@
#include "util/u_sampler.h"
#include "util/u_string.h"
-
#include "asm_filters.h"
@@ -73,6 +71,7 @@ static INLINE struct pipe_resource *create_texture_1d(struct vg_context *ctx,
templ.width0 = color_data_len;
templ.height0 = 1;
templ.depth0 = 1;
+ templ.array_size = 1;
templ.bind = PIPE_BIND_SAMPLER_VIEW;
tex = screen->resource_create(screen, &templ);
@@ -80,9 +79,9 @@ static INLINE struct pipe_resource *create_texture_1d(struct vg_context *ctx,
{ /* upload color_data */
struct pipe_transfer *transfer =
pipe_get_transfer(pipe, tex,
- 0, 0, 0,
- PIPE_TRANSFER_READ_WRITE ,
- 0, 0, tex->width0, tex->height0);
+ 0, 0,
+ PIPE_TRANSFER_READ_WRITE ,
+ 0, 0, tex->width0, tex->height0);
void *map = pipe->transfer_map(pipe, transfer);
memcpy(map, color_data, sizeof(VGint)*color_data_len);
pipe->transfer_unmap(pipe, transfer);
@@ -114,153 +113,11 @@ static INLINE struct pipe_sampler_view *create_texture_1d_view(struct vg_context
return view;
}
-static INLINE struct pipe_surface * setup_framebuffer(struct vg_image *dst)
-{
- struct vg_context *ctx = vg_current_context();
- struct pipe_context *pipe = ctx->pipe;
- struct pipe_framebuffer_state fb;
- struct pipe_surface *dst_surf = pipe->screen->get_tex_surface(
- pipe->screen, dst->sampler_view->texture, 0, 0, 0,
- PIPE_BIND_RENDER_TARGET);
-
- /* drawing dest */
- memset(&fb, 0, sizeof(fb));
- fb.width = dst->x + dst_surf->width;
- fb.height = dst->y + dst_surf->height;
- fb.nr_cbufs = 1;
- fb.cbufs[0] = dst_surf;
- {
- VGint i;
- for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
- fb.cbufs[i] = 0;
- }
- cso_set_framebuffer(ctx->cso_context, &fb);
-
- return dst_surf;
-}
-
-static void setup_viewport(struct vg_image *dst)
-{
- struct vg_context *ctx = vg_current_context();
- vg_set_viewport(ctx, VEGA_Y0_TOP);
-}
-
-static void setup_blend()
-{
- struct vg_context *ctx = vg_current_context();
- struct pipe_blend_state blend;
- memset(&blend, 0, sizeof(blend));
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- if (ctx->state.vg.filter_channel_mask & VG_RED)
- blend.rt[0].colormask |= PIPE_MASK_R;
- if (ctx->state.vg.filter_channel_mask & VG_GREEN)
- blend.rt[0].colormask |= PIPE_MASK_G;
- if (ctx->state.vg.filter_channel_mask & VG_BLUE)
- blend.rt[0].colormask |= PIPE_MASK_B;
- if (ctx->state.vg.filter_channel_mask & VG_ALPHA)
- blend.rt[0].colormask |= PIPE_MASK_A;
- blend.rt[0].blend_enable = 0;
- cso_set_blend(ctx->cso_context, &blend);
-}
-
-static void setup_constant_buffer(struct vg_context *ctx, const void *buffer,
- VGint param_bytes)
-{
- struct pipe_context *pipe = ctx->pipe;
- struct pipe_resource **cbuf = &ctx->filter.buffer;
-
- /* We always need to get a new buffer, to keep the drivers simple and
- * avoid gratuitous rendering synchronization. */
- pipe_resource_reference(cbuf, NULL);
-
- *cbuf = pipe_buffer_create(pipe->screen,
- PIPE_BIND_CONSTANT_BUFFER,
- param_bytes);
-
- if (*cbuf) {
- st_no_flush_pipe_buffer_write(ctx, *cbuf,
- 0, param_bytes, buffer);
- }
-
- ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf);
-}
-
-static void setup_samplers(struct vg_context *ctx, struct filter_info *info)
-{
- struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
- struct pipe_sampler_state sampler[3];
- int num_samplers = 0;
- int num_textures = 0;
-
- samplers[0] = NULL;
- samplers[1] = NULL;
- samplers[2] = NULL;
- samplers[3] = NULL;
- sampler_views[0] = NULL;
- sampler_views[1] = NULL;
- sampler_views[2] = NULL;
- sampler_views[3] = NULL;
-
- memset(&sampler[0], 0, sizeof(struct pipe_sampler_state));
- sampler[0].wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler[0].wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler[0].wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler[0].min_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
- sampler[0].mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
- sampler[0].normalized_coords = 1;
-
- switch(info->tiling_mode) {
- case VG_TILE_FILL:
- sampler[0].wrap_s = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
- sampler[0].wrap_t = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
- memcpy(sampler[0].border_color,
- ctx->state.vg.tile_fill_color,
- sizeof(VGfloat) * 4);
- break;
- case VG_TILE_PAD:
- sampler[0].wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler[0].wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- break;
- case VG_TILE_REPEAT:
- sampler[0].wrap_s = PIPE_TEX_WRAP_REPEAT;
- sampler[0].wrap_t = PIPE_TEX_WRAP_REPEAT;
- break;
- case VG_TILE_REFLECT:
- sampler[0].wrap_s = PIPE_TEX_WRAP_MIRROR_REPEAT;
- sampler[0].wrap_t = PIPE_TEX_WRAP_MIRROR_REPEAT;
- break;
- default:
- debug_assert(!"Unknown tiling mode");
- }
-
- samplers[0] = &sampler[0];
- sampler_views[0] = info->src->sampler_view;
- ++num_samplers;
- ++num_textures;
-
- if (info->extra_texture_view) {
- memcpy(&sampler[1], &sampler[0], sizeof(struct pipe_sampler_state));
- samplers[1] = &sampler[1];
- sampler_views[1] = info->extra_texture_view;
- ++num_samplers;
- ++num_textures;
- }
-
-
- cso_set_samplers(ctx->cso_context, num_samplers, (const struct pipe_sampler_state **)samplers);
- cso_set_fragment_sampler_views(ctx->cso_context, num_textures, sampler_views);
-}
-
static struct vg_shader * setup_color_matrix(struct vg_context *ctx, void *user_data)
{
struct vg_shader *shader =
shader_create_from_text(ctx->pipe, color_matrix_asm, 200,
PIPE_SHADER_FRAGMENT);
- cso_set_fragment_shader_handle(ctx->cso_context, shader->driver);
return shader;
}
@@ -275,7 +132,6 @@ static struct vg_shader * setup_convolution(struct vg_context *ctx, void *user_d
shader = shader_create_from_text(ctx->pipe, buffer, 200,
PIPE_SHADER_FRAGMENT);
- cso_set_fragment_shader_handle(ctx->cso_context, shader->driver);
return shader;
}
@@ -285,7 +141,6 @@ static struct vg_shader * setup_lookup(struct vg_context *ctx, void *user_data)
shader_create_from_text(ctx->pipe, lookup_asm,
200, PIPE_SHADER_FRAGMENT);
- cso_set_fragment_shader_handle(ctx->cso_context, shader->driver);
return shader;
}
@@ -316,49 +171,68 @@ static struct vg_shader * setup_lookup_single(struct vg_context *ctx, void *user
shader = shader_create_from_text(ctx->pipe, buffer, 200,
PIPE_SHADER_FRAGMENT);
- cso_set_fragment_shader_handle(ctx->cso_context, shader->driver);
return shader;
}
static void execute_filter(struct vg_context *ctx,
struct filter_info *info)
{
- struct pipe_surface *dst_surf;
struct vg_shader *shader;
+ const struct pipe_sampler_state *samplers[2];
+ struct pipe_sampler_view *views[2];
+ struct pipe_sampler_state sampler;
+ uint tex_wrap;
+
+ memset(&sampler, 0, sizeof(sampler));
+ sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
+ sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
+ sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ sampler.normalized_coords = 1;
+
+ switch (info->tiling_mode) {
+ case VG_TILE_FILL:
+ tex_wrap = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
+ /* copy border color */
+ memcpy(sampler.border_color, ctx->state.vg.tile_fill_color,
+ sizeof(sampler.border_color));
+ break;
+ case VG_TILE_PAD:
+ tex_wrap = PIPE_TEX_WRAP_CLAMP_TO_EDGE;;
+ break;
+ case VG_TILE_REPEAT:
+ tex_wrap = PIPE_TEX_WRAP_REPEAT;;
+ break;
+ case VG_TILE_REFLECT:
+ tex_wrap = PIPE_TEX_WRAP_MIRROR_REPEAT;
+ break;
+ default:
+ debug_assert(!"Unknown tiling mode");
+ tex_wrap = 0;
+ break;
+ }
+
+ sampler.wrap_s = tex_wrap;
+ sampler.wrap_t = tex_wrap;
+ sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+
+ samplers[0] = samplers[1] = &sampler;
+ views[0] = info->src->sampler_view;
+ views[1] = info->extra_texture_view;
- cso_save_framebuffer(ctx->cso_context);
- cso_save_fragment_shader(ctx->cso_context);
- cso_save_viewport(ctx->cso_context);
- cso_save_blend(ctx->cso_context);
- cso_save_samplers(ctx->cso_context);
- cso_save_fragment_sampler_views(ctx->cso_context);
-
- dst_surf = setup_framebuffer(info->dst);
- setup_viewport(info->dst);
- setup_blend();
- setup_constant_buffer(ctx, info->const_buffer, info->const_buffer_len);
shader = info->setup_shader(ctx, info->user_data);
- setup_samplers(ctx, info);
-
- renderer_draw_texture(ctx->renderer,
- info->src->sampler_view->texture,
- info->dst->x, info->dst->y,
- info->dst->x + info->dst->width,
- info->dst->y + info->dst->height,
- info->dst->x, info->dst->y,
- info->dst->x + info->dst->width,
- info->dst->y + info->dst->height);
-
- cso_restore_framebuffer(ctx->cso_context);
- cso_restore_fragment_shader(ctx->cso_context);
- cso_restore_viewport(ctx->cso_context);
- cso_restore_blend(ctx->cso_context);
- cso_restore_samplers(ctx->cso_context);
- cso_restore_fragment_sampler_views(ctx->cso_context);
- vg_shader_destroy(ctx, shader);
+ if (renderer_filter_begin(ctx->renderer,
+ info->dst->sampler_view->texture, VG_TRUE,
+ ctx->state.vg.filter_channel_mask,
+ samplers, views, (info->extra_texture_view) ? 2 : 1,
+ shader->driver, info->const_buffer, info->const_buffer_len)) {
+ renderer_filter(ctx->renderer,
+ info->dst->x, info->dst->y, info->dst->width, info->dst->height,
+ info->src->x, info->src->y, info->src->width, info->src->height);
+ renderer_filter_end(ctx->renderer);
+ }
- pipe_surface_reference(&dst_surf, NULL);
+ vg_shader_destroy(ctx, shader);
}
void vegaColorMatrix(VGImage dst, VGImage src,
diff --git a/src/gallium/state_trackers/vega/api_images.c b/src/gallium/state_trackers/vega/api_images.c
index e9f038c5f92..ad95409cd00 100644
--- a/src/gallium/state_trackers/vega/api_images.c
+++ b/src/gallium/state_trackers/vega/api_images.c
@@ -303,7 +303,8 @@ void vegaDrawImage(VGImage image)
}
vg_validate_state(ctx);
- image_draw((struct vg_image*)image);
+ image_draw((struct vg_image*)image,
+ &ctx->state.vg.image_user_to_surface_matrix);
}
void vegaSetPixels(VGint dx, VGint dy,
@@ -399,7 +400,6 @@ void vegaReadPixels(void * data, VGint dataStride,
struct st_framebuffer *stfb = ctx->draw_buffer;
struct st_renderbuffer *strb = stfb->strb;
- struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
VGfloat *df = (VGfloat*)temp;
@@ -435,21 +435,21 @@ void vegaReadPixels(void * data, VGint dataStride,
sy = 0;
}
- if (sx + width > fb->width || sy + height > fb->height) {
- width = fb->width - sx;
- height = fb->height - sy;
+ if (sx + width > stfb->width || sy + height > stfb->height) {
+ width = stfb->width - sx;
+ height = stfb->height - sy;
/* nothing to read */
if (width <= 0 || height <= 0)
return;
}
{
- VGint y = (fb->height - sy) - 1, yStep = -1;
+ VGint y = (stfb->height - sy) - 1, yStep = -1;
struct pipe_transfer *transfer;
- transfer = pipe_get_transfer(pipe, strb->texture, 0, 0, 0,
- PIPE_TRANSFER_READ,
- 0, 0, sx + width, fb->height - sy);
+ transfer = pipe_get_transfer(pipe, strb->texture, 0, 0,
+ PIPE_TRANSFER_READ,
+ 0, 0, sx + width, stfb->height - sy);
/* Do a row at a time to flip image data vertically */
for (i = 0; i < height; i++) {
@@ -472,8 +472,8 @@ void vegaCopyPixels(VGint dx, VGint dy,
VGint width, VGint height)
{
struct vg_context *ctx = vg_current_context();
- struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
- struct st_renderbuffer *strb = ctx->draw_buffer->strb;
+ struct st_framebuffer *stfb = ctx->draw_buffer;
+ struct st_renderbuffer *strb = stfb->strb;
if (width <= 0 || height <= 0) {
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
@@ -481,8 +481,8 @@ void vegaCopyPixels(VGint dx, VGint dy,
}
/* do nothing if we copy from outside the fb */
- if (dx >= (VGint)fb->width || dy >= (VGint)fb->height ||
- sx >= (VGint)fb->width || sy >= (VGint)fb->height)
+ if (dx >= (VGint)stfb->width || dy >= (VGint)stfb->height ||
+ sx >= (VGint)stfb->width || sy >= (VGint)stfb->height)
return;
vg_validate_state(ctx);
diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c
index 189390ec2d3..beb15c33a59 100644
--- a/src/gallium/state_trackers/vega/api_masks.c
+++ b/src/gallium/state_trackers/vega/api_masks.c
@@ -28,6 +28,7 @@
#include "mask.h"
#include "api.h"
+#include "renderer.h"
#include "vg_context.h"
#include "pipe/p_context.h"
@@ -36,119 +37,6 @@
#include "util/u_pack_color.h"
#include "util/u_draw_quad.h"
-#define DISABLE_1_1_MASKING 1
-
-/**
- * Draw a screen-aligned quadrilateral.
- * Coords are window coords with y=0=bottom. These coords will be transformed
- * by the vertex shader and viewport transform.
- */
-static void
-draw_clear_quad(struct vg_context *st,
- float x0, float y0, float x1, float y1, float z,
- const VGfloat color[4])
-{
- struct pipe_context *pipe = st->pipe;
- struct pipe_resource *buf;
- VGuint i;
-
- /* positions */
- st->clear.vertices[0][0][0] = x0;
- st->clear.vertices[0][0][1] = y0;
-
- st->clear.vertices[1][0][0] = x1;
- st->clear.vertices[1][0][1] = y0;
-
- st->clear.vertices[2][0][0] = x1;
- st->clear.vertices[2][0][1] = y1;
-
- st->clear.vertices[3][0][0] = x0;
- st->clear.vertices[3][0][1] = y1;
-
- /* same for all verts: */
- for (i = 0; i < 4; i++) {
- st->clear.vertices[i][0][2] = z;
- st->clear.vertices[i][0][3] = 1.0;
- st->clear.vertices[i][1][0] = color[0];
- st->clear.vertices[i][1][1] = color[1];
- st->clear.vertices[i][1][2] = color[2];
- st->clear.vertices[i][1][3] = color[3];
- }
-
-
- /* put vertex data into vbuf */
- buf = pipe_user_buffer_create(pipe->screen,
- st->clear.vertices,
- sizeof(st->clear.vertices),
- PIPE_BIND_VERTEX_BUFFER);
-
-
- /* draw */
- if (buf) {
- cso_set_vertex_elements(st->cso_context, 2, st->velems);
-
- util_draw_vertex_buffer(pipe, buf, 0,
- PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */
-
- pipe_resource_reference(&buf, NULL);
- }
-}
-
-/**
- * Do vgClear by drawing a quadrilateral.
- */
-static void
-clear_with_quad(struct vg_context *st, float x0, float y0,
- float width, float height, const VGfloat clear_color[4])
-{
- VGfloat x1, y1;
-
- vg_validate_state(st);
-
- x1 = x0 + width;
- y1 = y0 + height;
-
- /*
- printf("%s %f,%f %f,%f\n", __FUNCTION__,
- x0, y0,
- x1, y1);
- */
-
- cso_save_blend(st->cso_context);
- cso_save_rasterizer(st->cso_context);
- cso_save_fragment_shader(st->cso_context);
- cso_save_vertex_shader(st->cso_context);
-
- /* blend state: RGBA masking */
- {
- struct pipe_blend_state blend;
- memset(&blend, 0, sizeof(blend));
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].colormask = PIPE_MASK_RGBA;
- cso_set_blend(st->cso_context, &blend);
- }
-
- cso_set_rasterizer(st->cso_context, &st->clear.raster);
-
- cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
- cso_set_vertex_shader_handle(st->cso_context, vg_clear_vs(st));
-
- /* draw quad matching scissor rect (XXX verify coord round-off) */
- draw_clear_quad(st, x0, y0, x1, y1, 0, clear_color);
-
- /* Restore pipe state */
- cso_restore_blend(st->cso_context);
- cso_restore_rasterizer(st->cso_context);
- cso_restore_fragment_shader(st->cso_context);
- cso_restore_vertex_shader(st->cso_context);
-}
-
-
void vegaMask(VGHandle mask, VGMaskOperation operation,
VGint x, VGint y,
VGint width, VGint height)
@@ -176,12 +64,8 @@ void vegaMask(VGHandle mask, VGMaskOperation operation,
struct vg_image *image = (struct vg_image *)mask;
mask_using_image(image, operation, x, y, width, height);
} else if (vg_object_is_valid((void*)mask, VG_OBJECT_MASK)) {
-#if DISABLE_1_1_MASKING
- return;
-#else
struct vg_mask_layer *layer = (struct vg_mask_layer *)mask;
mask_using_layer(layer, operation, x, y, width, height);
-#endif
} else {
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
}
@@ -191,7 +75,7 @@ void vegaClear(VGint x, VGint y,
VGint width, VGint height)
{
struct vg_context *ctx = vg_current_context();
- struct pipe_framebuffer_state *fb;
+ struct st_framebuffer *stfb = ctx->draw_buffer;
if (width <= 0 || height <= 0) {
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
@@ -208,14 +92,15 @@ void vegaClear(VGint x, VGint y,
ctx->state.vg.clear_color[3]);
#endif
- fb = &ctx->state.g3d.fb;
/* check for a whole surface clear */
if (!ctx->state.vg.scissoring &&
- (x == 0 && y == 0 && width == fb->width && height == fb->height)) {
+ (x == 0 && y == 0 && width == stfb->width && height == stfb->height)) {
ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL,
ctx->state.vg.clear_color, 1., 0);
- } else {
- clear_with_quad(ctx, x, y, width, height, ctx->state.vg.clear_color);
+ } else if (renderer_clear_begin(ctx->renderer)) {
+ /* XXX verify coord round-off */
+ renderer_clear(ctx->renderer, x, y, width, height, ctx->state.vg.clear_color);
+ renderer_clear_end(ctx->renderer);
}
}
@@ -247,10 +132,6 @@ void vegaRenderToMask(VGPath path,
return;
}
-#if DISABLE_1_1_MASKING
- return;
-#endif
-
vg_validate_state(ctx);
mask_render_to((struct path *)path, paintModes, operation);
@@ -328,9 +209,8 @@ void vegaFillMaskLayer(VGMaskLayer maskLayer,
return;
}
-#if DISABLE_1_1_MASKING
- return;
-#endif
+ vg_validate_state(ctx);
+
mask_layer_fill(mask, x, y, width, height, value);
}
@@ -355,9 +235,7 @@ void vegaCopyMask(VGMaskLayer maskLayer,
return;
}
-#if DISABLE_1_1_MASKING
- return;
-#endif
+ vg_validate_state(ctx);
mask = (struct vg_mask_layer*)maskLayer;
mask_copy(mask, sx, sy, dx, dy, width, height);
diff --git a/src/gallium/state_trackers/vega/api_misc.c b/src/gallium/state_trackers/vega/api_misc.c
index e648549745b..9e2ab03e01a 100644
--- a/src/gallium/state_trackers/vega/api_misc.c
+++ b/src/gallium/state_trackers/vega/api_misc.c
@@ -63,8 +63,8 @@ const VGubyte *vegaGetString(VGStringID name)
{
struct vg_context *ctx = vg_current_context();
static const VGubyte *vendor = (VGubyte *)"Tungsten Graphics, Inc";
- static const VGubyte *renderer = (VGubyte *)"Vega OpenVG 1.0";
- static const VGubyte *version = (VGubyte *)"1.0";
+ static const VGubyte *renderer = (VGubyte *)"Vega OpenVG 1.1";
+ static const VGubyte *version = (VGubyte *)"1.1";
if (!ctx)
return NULL;
diff --git a/src/gallium/state_trackers/vega/api_params.c b/src/gallium/state_trackers/vega/api_params.c
index a10b009e631..a73b6c3effe 100644
--- a/src/gallium/state_trackers/vega/api_params.c
+++ b/src/gallium/state_trackers/vega/api_params.c
@@ -30,6 +30,7 @@
#include "paint.h"
#include "path.h"
#include "image.h"
+#include "text.h"
#include "matrix.h"
#include "api_consts.h"
#include "api.h"
@@ -174,6 +175,7 @@ void vegaSeti (VGParamType type, VGint value)
error = VG_ILLEGAL_ARGUMENT_ERROR;
else
state->image_mode = value;
+ break;
#ifdef OPENVG_VERSION_1_1
case VG_COLOR_TRANSFORM:
state->color_transform = value;
@@ -1500,7 +1502,8 @@ VGint vegaGetParameteri(VGHandle object,
#ifdef OPENVG_VERSION_1_1
case VG_FONT_NUM_GLYPHS: {
- return 1;
+ struct vg_font *font = (struct vg_font*)object;
+ return font_num_glyphs(font);
}
break;
#endif
diff --git a/src/gallium/state_trackers/vega/api_path.c b/src/gallium/state_trackers/vega/api_path.c
index f76adddb584..fe57b7671d9 100644
--- a/src/gallium/state_trackers/vega/api_path.c
+++ b/src/gallium/state_trackers/vega/api_path.c
@@ -479,6 +479,7 @@ void vegaDrawPath(VGPath path, VGbitfield paintModes)
if (path_is_empty((struct path*)path))
return;
- path_render((struct path*)path, paintModes);
+ path_render((struct path*)path, paintModes,
+ &ctx->state.vg.path_user_to_surface_matrix);
}
diff --git a/src/gallium/state_trackers/vega/api_text.c b/src/gallium/state_trackers/vega/api_text.c
index 2a62da0a1de..7c6b4794099 100644
--- a/src/gallium/state_trackers/vega/api_text.c
+++ b/src/gallium/state_trackers/vega/api_text.c
@@ -27,21 +27,15 @@
#include "VG/openvg.h"
#include "vg_context.h"
+#include "text.h"
+#include "api.h"
#include "util/u_memory.h"
#ifdef OPENVG_VERSION_1_1
-struct vg_font {
- struct vg_object base;
-
- VGint glyph_indices[200];
- VGint num_glyphs;
-};
-
VGFont vegaCreateFont(VGint glyphCapacityHint)
{
- struct vg_font *font = 0;
struct vg_context *ctx = vg_current_context();
if (glyphCapacityHint < 0) {
@@ -49,10 +43,7 @@ VGFont vegaCreateFont(VGint glyphCapacityHint)
return VG_INVALID_HANDLE;
}
- font = CALLOC_STRUCT(vg_font);
- vg_init_object(&font->base, ctx, VG_OBJECT_FONT);
- vg_context_add_object(ctx, VG_OBJECT_FONT, font);
- return (VGFont)font;
+ return (VGFont) font_create(glyphCapacityHint);
}
void vegaDestroyFont(VGFont f)
@@ -64,20 +55,23 @@ void vegaDestroyFont(VGFont f)
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
return;
}
+ if (!vg_object_is_valid((void *) font, VG_OBJECT_FONT)) {
+ vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
+ return;
+ }
- vg_context_remove_object(ctx, VG_OBJECT_FONT, font);
- /*free(font);*/
+ font_destroy(font);
}
void vegaSetGlyphToPath(VGFont font,
VGuint glyphIndex,
VGPath path,
VGboolean isHinted,
- VGfloat glyphOrigin [2],
- VGfloat escapement[2])
+ const VGfloat glyphOrigin[2],
+ const VGfloat escapement[2])
{
struct vg_context *ctx = vg_current_context();
- struct vg_object *pathObj;
+ struct path *pathObj;
struct vg_font *f;
if (font == VG_INVALID_HANDLE ||
@@ -95,25 +89,22 @@ void vegaSetGlyphToPath(VGFont font,
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
return;
}
- pathObj = (struct vg_object*)path;
- if (pathObj && pathObj->type != VG_OBJECT_PATH) {
- vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
- return;
- }
- f = (struct vg_font*)font;
- f->glyph_indices[f->num_glyphs] = glyphIndex;
- ++f->num_glyphs;
+ pathObj = (struct path*) path;
+ f = (struct vg_font*) font;
+
+ font_set_glyph_to_path(f, glyphIndex, pathObj,
+ isHinted, glyphOrigin, escapement);
}
void vegaSetGlyphToImage(VGFont font,
VGuint glyphIndex,
VGImage image,
- VGfloat glyphOrigin [2],
- VGfloat escapement[2])
+ const VGfloat glyphOrigin[2],
+ const VGfloat escapement[2])
{
struct vg_context *ctx = vg_current_context();
- struct vg_object *img_obj;
+ struct vg_image *img_obj;
struct vg_font *f;
if (font == VG_INVALID_HANDLE ||
@@ -131,26 +122,11 @@ void vegaSetGlyphToImage(VGFont font,
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
return;
}
- img_obj = (struct vg_object*)image;
- if (img_obj && img_obj->type != VG_OBJECT_IMAGE) {
- vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
- return;
- }
+
+ img_obj = (struct vg_image*)image;
f = (struct vg_font*)font;
- f->glyph_indices[f->num_glyphs] = glyphIndex;
- ++f->num_glyphs;
-}
-static INLINE VGboolean font_contains_glyph(struct vg_font *font,
- VGuint glyph_index)
-{
- VGint i;
- for (i = 0; i < font->num_glyphs; ++i) {
- if (font->glyph_indices[i] == glyph_index) {
- return VG_TRUE;
- }
- }
- return VG_FALSE;
+ font_set_glyph_to_image(f, glyphIndex, img_obj, glyphOrigin, escapement);
}
void vegaClearGlyph(VGFont font,
@@ -158,30 +134,15 @@ void vegaClearGlyph(VGFont font,
{
struct vg_context *ctx = vg_current_context();
struct vg_font *f;
- VGint i;
if (font == VG_INVALID_HANDLE) {
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
return;
}
- if (glyphIndex <= 0) {
- vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
- return;
- }
- f = (struct vg_font*)font;
- if (!font_contains_glyph(f, glyphIndex)) {
- vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
- return;
- }
- for (i = 0; i < f->num_glyphs; ++i) {
- if (f->glyph_indices[i] == glyphIndex) {
- /*FIXME*/
- f->glyph_indices[f->num_glyphs] = 0;
- --f->num_glyphs;
- return;
- }
- }
+ f = (struct vg_font*) font;
+
+ font_clear_glyph(f, glyphIndex);
}
void vegaDrawGlyph(VGFont font,
@@ -196,31 +157,24 @@ void vegaDrawGlyph(VGFont font,
vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
return;
}
- if (glyphIndex <= 0) {
- vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
- return;
- }
if (paintModes & (~(VG_STROKE_PATH|VG_FILL_PATH))) {
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
return;
}
f = (struct vg_font*)font;
- if (!font_contains_glyph(f, glyphIndex)) {
- vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
- return;
- }
+
+ font_draw_glyph(f, glyphIndex, paintModes, allowAutoHinting);
}
void vegaDrawGlyphs(VGFont font,
VGint glyphCount,
- VGuint *glyphIndices,
- VGfloat *adjustments_x,
- VGfloat *adjustments_y,
+ const VGuint *glyphIndices,
+ const VGfloat *adjustments_x,
+ const VGfloat *adjustments_y,
VGbitfield paintModes,
VGboolean allowAutoHinting)
{
struct vg_context *ctx = vg_current_context();
- VGint i;
struct vg_font *f;
if (font == VG_INVALID_HANDLE) {
@@ -235,8 +189,8 @@ void vegaDrawGlyphs(VGFont font,
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
return;
}
- if (!adjustments_x || !is_aligned(adjustments_x) ||
- !adjustments_y || !is_aligned(adjustments_y)) {
+ if ((adjustments_x && !is_aligned(adjustments_x)) ||
+ (adjustments_y && !is_aligned(adjustments_y))) {
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
return;
}
@@ -246,13 +200,9 @@ void vegaDrawGlyphs(VGFont font,
}
f = (struct vg_font*)font;
- for (i = 0; i < glyphCount; ++i) {
- VGuint glyph_index = glyphIndices[i];
- if (!font_contains_glyph(f, glyph_index)) {
- vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
- return;
- }
- }
+
+ font_draw_glyphs(f, glyphCount, glyphIndices,
+ adjustments_x, adjustments_y, paintModes, allowAutoHinting);
}
-#endif
+#endif /* OPENVG_VERSION_1_1 */
diff --git a/src/gallium/state_trackers/vega/asm_fill.h b/src/gallium/state_trackers/vega/asm_fill.h
index 27773467fa8..77e6a14fe99 100644
--- a/src/gallium/state_trackers/vega/asm_fill.h
+++ b/src/gallium/state_trackers/vega/asm_fill.h
@@ -44,9 +44,31 @@ solid_fill( struct ureg_program *ureg,
struct ureg_dst *temp,
struct ureg_src *constant)
{
- ureg_MOV(ureg, *out, constant[0]);
+ ureg_MOV(ureg, *out, constant[2]);
}
+/**
+ * Perform frag-coord-to-paint-coord transform. The transformation is in
+ * CONST[4..6].
+ */
+#define PAINT_TRANSFORM \
+ ureg_MOV(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_XY), in[0]); \
+ ureg_MOV(ureg, \
+ ureg_writemask(temp[0], TGSI_WRITEMASK_Z), \
+ ureg_scalar(constant[3], TGSI_SWIZZLE_Y)); \
+ ureg_DP3(ureg, temp[1], constant[4], ureg_src(temp[0])); \
+ ureg_DP3(ureg, temp[2], constant[5], ureg_src(temp[0])); \
+ ureg_DP3(ureg, temp[3], constant[6], ureg_src(temp[0])); \
+ ureg_RCP(ureg, temp[3], ureg_src(temp[3])); \
+ ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3])); \
+ ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3])); \
+ ureg_MOV(ureg, \
+ ureg_writemask(temp[4], TGSI_WRITEMASK_X), \
+ ureg_src(temp[1])); \
+ ureg_MOV(ureg, \
+ ureg_writemask(temp[4], TGSI_WRITEMASK_Y), \
+ ureg_src(temp[2]));
+
static INLINE void
linear_grad( struct ureg_program *ureg,
struct ureg_dst *out,
@@ -55,30 +77,19 @@ linear_grad( struct ureg_program *ureg,
struct ureg_dst *temp,
struct ureg_src *constant)
{
+ PAINT_TRANSFORM
- ureg_MOV(ureg,
- ureg_writemask(temp[0], TGSI_WRITEMASK_XY),
- in[0]);
- ureg_MOV(ureg,
- ureg_writemask(temp[0], TGSI_WRITEMASK_Z),
- ureg_scalar(constant[1], TGSI_SWIZZLE_Y));
- ureg_DP3(ureg, temp[1], constant[2], ureg_src(temp[0]));
- ureg_DP3(ureg, temp[2], constant[3], ureg_src(temp[0]));
- ureg_DP3(ureg, temp[3], constant[4], ureg_src(temp[0]));
- ureg_RCP(ureg, temp[3], ureg_src(temp[3]));
- ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3]));
- ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3]));
- ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_X), ureg_src(temp[1]));
- ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_Y), ureg_src(temp[2]));
+ /* grad = DP2((x, y), CONST[2].xy) * CONST[2].z */
ureg_MUL(ureg, temp[0],
- ureg_scalar(constant[0], TGSI_SWIZZLE_Y),
+ ureg_scalar(constant[2], TGSI_SWIZZLE_Y),
ureg_scalar(ureg_src(temp[4]), TGSI_SWIZZLE_Y));
ureg_MAD(ureg, temp[1],
- ureg_scalar(constant[0], TGSI_SWIZZLE_X),
+ ureg_scalar(constant[2], TGSI_SWIZZLE_X),
ureg_scalar(ureg_src(temp[4]), TGSI_SWIZZLE_X),
ureg_src(temp[0]));
ureg_MUL(ureg, temp[2], ureg_src(temp[1]),
- ureg_scalar(constant[0], TGSI_SWIZZLE_Z));
+ ureg_scalar(constant[2], TGSI_SWIZZLE_Z));
+
ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[2]), sampler[0]);
}
@@ -90,52 +101,32 @@ radial_grad( struct ureg_program *ureg,
struct ureg_dst *temp,
struct ureg_src *constant)
{
-
- ureg_MOV(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_XY), in[0]);
- ureg_MOV(ureg,
- ureg_writemask(temp[0], TGSI_WRITEMASK_Z),
- ureg_scalar(constant[1], TGSI_SWIZZLE_Y));
- ureg_DP3(ureg, temp[1], constant[2], ureg_src(temp[0]));
- ureg_DP3(ureg, temp[2], constant[3], ureg_src(temp[0]));
- ureg_DP3(ureg, temp[3], constant[4], ureg_src(temp[0]));
+ PAINT_TRANSFORM
+
+ /*
+ * Calculate (sqrt(B^2 + AC) - B) / A, where
+ *
+ * A is CONST[2].z,
+ * B is DP2((x, y), CONST[2].xy), and
+ * C is DP2((x, y), (x, y)).
+ */
+
+ /* B and C */
+ ureg_DP2(ureg, temp[0], ureg_src(temp[4]), constant[2]);
+ ureg_DP2(ureg, temp[1], ureg_src(temp[4]), ureg_src(temp[4]));
+
+ /* the square root */
+ ureg_MUL(ureg, temp[2], ureg_src(temp[0]), ureg_src(temp[0]));
+ ureg_MAD(ureg, temp[3], ureg_src(temp[1]),
+ ureg_scalar(constant[2], TGSI_SWIZZLE_Z), ureg_src(temp[2]));
+ ureg_RSQ(ureg, temp[3], ureg_src(temp[3]));
ureg_RCP(ureg, temp[3], ureg_src(temp[3]));
- ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3]));
- ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3]));
- ureg_MOV(ureg, ureg_writemask(temp[5], TGSI_WRITEMASK_X), ureg_src(temp[1]));
- ureg_MOV(ureg, ureg_writemask(temp[5], TGSI_WRITEMASK_Y), ureg_src(temp[2]));
- ureg_MUL(ureg, temp[0], ureg_scalar(constant[0], TGSI_SWIZZLE_Y),
- ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_Y));
- ureg_MAD(ureg, temp[1],
- ureg_scalar(constant[0], TGSI_SWIZZLE_X),
- ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_X), ureg_src(temp[0]));
- ureg_ADD(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[1]));
- ureg_MUL(ureg, temp[3],
- ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_Y),
- ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_Y));
- ureg_MAD(ureg, temp[4],
- ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_X),
- ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_X),
- ureg_src(temp[3]));
- ureg_MOV(ureg, temp[4], ureg_negate(ureg_src(temp[4])));
- ureg_MUL(ureg, temp[2],
- ureg_scalar(constant[0], TGSI_SWIZZLE_Z),
- ureg_src(temp[4]));
- ureg_MUL(ureg, temp[0],
- ureg_scalar(constant[1], TGSI_SWIZZLE_W),
- ureg_src(temp[2]));
- ureg_MUL(ureg, temp[3], ureg_src(temp[1]), ureg_src(temp[1]));
-
- ureg_SUB(ureg, temp[2], ureg_src(temp[3]), ureg_src(temp[0]));
- ureg_RSQ(ureg, temp[2], ureg_abs(ureg_src(temp[2])));
- ureg_RCP(ureg, temp[2], ureg_src(temp[2]));
- ureg_SUB(ureg, temp[1], ureg_src(temp[2]), ureg_src(temp[1]));
- ureg_ADD(ureg, temp[0],
- ureg_scalar(constant[0], TGSI_SWIZZLE_Z),
- ureg_scalar(constant[0], TGSI_SWIZZLE_Z));
- ureg_RCP(ureg, temp[0], ureg_src(temp[0]));
- ureg_MUL(ureg, temp[2], ureg_src(temp[1]), ureg_src(temp[0]));
- ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[2]), sampler[0]);
+ ureg_SUB(ureg, temp[3], ureg_src(temp[3]), ureg_src(temp[0]));
+ ureg_RCP(ureg, temp[0], ureg_scalar(constant[2], TGSI_SWIZZLE_Z));
+ ureg_MUL(ureg, temp[0], ureg_src(temp[0]), ureg_src(temp[3]));
+
+ ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[0]), sampler[0]);
}
@@ -147,22 +138,11 @@ pattern( struct ureg_program *ureg,
struct ureg_dst *temp,
struct ureg_src *constant)
{
- ureg_MOV(ureg,
- ureg_writemask(temp[0], TGSI_WRITEMASK_XY),
- in[0]);
- ureg_MOV(ureg,
- ureg_writemask(temp[0], TGSI_WRITEMASK_Z),
- ureg_scalar(constant[1], TGSI_SWIZZLE_Y));
- ureg_DP3(ureg, temp[1], constant[2], ureg_src(temp[0]));
- ureg_DP3(ureg, temp[2], constant[3], ureg_src(temp[0]));
- ureg_DP3(ureg, temp[3], constant[4], ureg_src(temp[0]));
- ureg_RCP(ureg, temp[3], ureg_src(temp[3]));
- ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3]));
- ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3]));
- ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_X), ureg_src(temp[1]));
- ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_Y), ureg_src(temp[2]));
+ PAINT_TRANSFORM
+
+ /* (s, t) = (x / tex_width, y / tex_height) */
ureg_RCP(ureg, temp[0],
- ureg_swizzle(constant[1],
+ ureg_swizzle(constant[3],
TGSI_SWIZZLE_Z,
TGSI_SWIZZLE_W,
TGSI_SWIZZLE_Z,
@@ -176,22 +156,21 @@ pattern( struct ureg_program *ureg,
ureg_writemask(temp[1], TGSI_WRITEMASK_Y),
ureg_src(temp[1]),
ureg_src(temp[0]));
+
ureg_TEX(ureg, *out, TGSI_TEXTURE_2D, ureg_src(temp[1]), sampler[0]);
}
static INLINE void
-mask( struct ureg_program *ureg,
- struct ureg_dst *out,
- struct ureg_src *in,
- struct ureg_src *sampler,
- struct ureg_dst *temp,
- struct ureg_src *constant)
+paint_degenerate( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
{
- ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[1]);
- ureg_MUL(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_W),
- ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
- ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
- ureg_MOV(ureg, *out, ureg_src(temp[0]));
+ /* CONST[3].y is 1.0f */
+ ureg_MOV(ureg, temp[1], ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
+ ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[1]), sampler[0]);
}
static INLINE void
@@ -202,7 +181,9 @@ image_normal( struct ureg_program *ureg,
struct ureg_dst *temp,
struct ureg_src *constant)
{
- ureg_TEX(ureg, *out, TGSI_TEXTURE_2D, in[1], sampler[3]);
+ /* store and pass image color in TEMP[1] */
+ ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
+ ureg_MOV(ureg, *out, ureg_src(temp[1]));
}
@@ -214,6 +195,7 @@ image_multiply( struct ureg_program *ureg,
struct ureg_dst *temp,
struct ureg_src *constant)
{
+ /* store and pass image color in TEMP[1] */
ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
ureg_MUL(ureg, *out, ureg_src(temp[0]), ureg_src(temp[1]));
}
@@ -227,43 +209,279 @@ image_stencil( struct ureg_program *ureg,
struct ureg_dst *temp,
struct ureg_src *constant)
{
+ /* store and pass image color in TEMP[1] */
ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
- ureg_MUL(ureg, *out, ureg_src(temp[0]), ureg_src(temp[1]));
+ ureg_MOV(ureg, *out, ureg_src(temp[0]));
+}
+
+static INLINE void
+color_transform( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ /* note that TEMP[1] may already be used for image color */
+
+ ureg_MAD(ureg, temp[2], ureg_src(temp[0]), constant[0], constant[1]);
+ /* clamp to [0.0f, 1.0f] */
+ ureg_CLAMP(ureg, temp[2],
+ ureg_src(temp[2]),
+ ureg_scalar(constant[3], TGSI_SWIZZLE_X),
+ ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
+ ureg_MOV(ureg, *out, ureg_src(temp[2]));
+}
+
+static INLINE void
+alpha_normal( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ /* save per-channel alpha in TEMP[1] */
+ ureg_MOV(ureg, temp[1], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
+
+ ureg_MOV(ureg, *out, ureg_src(temp[0]));
}
-#define EXTENDED_BLENDER_OVER_FUNC \
- ureg_SUB(ureg, temp[3], \
- ureg_scalar(constant[1], TGSI_SWIZZLE_Y), \
- ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); \
- ureg_SUB(ureg, temp[3], \
- ureg_scalar(constant[1], TGSI_SWIZZLE_Y), \
- ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W)); \
- ureg_MUL(ureg, temp[3], ureg_src(temp[0]), ureg_src(temp[3])); \
- ureg_MUL(ureg, temp[4], ureg_src(temp[1]), ureg_src(temp[4])); \
- ureg_ADD(ureg, temp[3], ureg_src(temp[3]), ureg_src(temp[4]));
+static INLINE void
+alpha_per_channel( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ /* save per-channel alpha in TEMP[1] */
+ ureg_MUL(ureg,
+ ureg_writemask(temp[1], TGSI_WRITEMASK_W),
+ ureg_src(temp[0]),
+ ureg_src(temp[1]));
+ ureg_MUL(ureg,
+ ureg_writemask(temp[1], TGSI_WRITEMASK_XYZ),
+ ureg_src(temp[1]),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ /* update alpha */
+ ureg_MOV(ureg,
+ ureg_writemask(temp[0], TGSI_WRITEMASK_W),
+ ureg_src(temp[1]));
+ ureg_MOV(ureg, *out, ureg_src(temp[0]));
+}
+/**
+ * Premultiply src and dst.
+ */
static INLINE void
-blend_multiply( struct ureg_program *ureg,
+blend_premultiply( struct ureg_program *ureg,
+ struct ureg_src src,
+ struct ureg_src src_channel_alpha,
+ struct ureg_src dst)
+{
+ /* premultiply src */
+ ureg_MUL(ureg,
+ ureg_writemask(ureg_dst(src), TGSI_WRITEMASK_XYZ),
+ src,
+ src_channel_alpha);
+ /* premultiply dst */
+ ureg_MUL(ureg,
+ ureg_writemask(ureg_dst(dst), TGSI_WRITEMASK_XYZ),
+ dst,
+ ureg_scalar(dst, TGSI_SWIZZLE_W));
+}
+
+/**
+ * Unpremultiply src.
+ */
+static INLINE void
+blend_unpremultiply( struct ureg_program *ureg,
+ struct ureg_src src,
+ struct ureg_src one,
+ struct ureg_dst temp[1])
+{
+ /* replace 0.0f by 1.0f before calculating reciprocal */
+ ureg_CMP(ureg,
+ temp[0],
+ ureg_negate(ureg_scalar(src, TGSI_SWIZZLE_W)),
+ ureg_scalar(src, TGSI_SWIZZLE_W),
+ one);
+ ureg_RCP(ureg, temp[0], ureg_src(temp[0]));
+
+ ureg_MUL(ureg,
+ ureg_writemask(ureg_dst(src), TGSI_WRITEMASK_XYZ),
+ src,
+ ureg_src(temp[0]));
+}
+
+/**
+ * Emit instructions for the specified blend mode. Colors will be
+ * unpremultiplied. Two temporary registers are required.
+ *
+ * The output is written back to src.
+ */
+static INLINE void
+blend_generic(struct ureg_program *ureg,
+ VGBlendMode mode,
+ struct ureg_src src,
+ struct ureg_src src_channel_alpha,
+ struct ureg_src dst,
+ struct ureg_src one,
+ struct ureg_dst temp[2])
+{
+ struct ureg_dst out;
+
+ blend_premultiply(ureg, src, src_channel_alpha, dst);
+
+ /* blend in-place */
+ out = ureg_dst(src);
+
+ switch (mode) {
+ case VG_BLEND_SRC:
+ ureg_MOV(ureg, out, src);
+ break;
+ case VG_BLEND_SRC_OVER:
+ /* RGBA_out = RGBA_src + (1 - A_src) * RGBA_dst */
+ ureg_SUB(ureg, temp[0], one, src_channel_alpha);
+ ureg_MAD(ureg, out, ureg_src(temp[0]), dst, src);
+ break;
+ case VG_BLEND_DST_OVER:
+ /* RGBA_out = RGBA_dst + (1 - A_dst) * RGBA_src */
+ ureg_SUB(ureg, temp[0], one, ureg_scalar(dst, TGSI_SWIZZLE_W));
+ ureg_MAD(ureg, out, ureg_src(temp[0]), src, dst);
+ break;
+ case VG_BLEND_SRC_IN:
+ ureg_MUL(ureg, out, src, ureg_scalar(dst, TGSI_SWIZZLE_W));
+ break;
+ case VG_BLEND_DST_IN:
+ ureg_MUL(ureg, out, dst, src_channel_alpha);
+ break;
+ case VG_BLEND_MULTIPLY:
+ /*
+ * RGB_out = (1 - A_dst) * RGB_src + (1 - A_src) * RGB_dst +
+ * RGB_src * RGB_dst
+ */
+ ureg_MAD(ureg, temp[0],
+ ureg_scalar(dst, TGSI_SWIZZLE_W), ureg_negate(src), src);
+ ureg_MAD(ureg, temp[1],
+ src_channel_alpha, ureg_negate(dst), dst);
+ ureg_MAD(ureg, temp[0], src, dst, ureg_src(temp[0]));
+ ureg_ADD(ureg, out, ureg_src(temp[0]), ureg_src(temp[1]));
+ /* alpha is src over */
+ ureg_ADD(ureg, ureg_writemask(out, TGSI_WRITEMASK_W),
+ src, ureg_src(temp[1]));
+ break;
+ case VG_BLEND_SCREEN:
+ /* RGBA_out = RGBA_src + (1 - RGBA_src) * RGBA_dst */
+ ureg_SUB(ureg, temp[0], one, src);
+ ureg_MAD(ureg, out, ureg_src(temp[0]), dst, src);
+ break;
+ case VG_BLEND_DARKEN:
+ case VG_BLEND_LIGHTEN:
+ /* src over */
+ ureg_SUB(ureg, temp[0], one, src_channel_alpha);
+ ureg_MAD(ureg, temp[0], ureg_src(temp[0]), dst, src);
+ /* dst over */
+ ureg_SUB(ureg, temp[1], one, ureg_scalar(dst, TGSI_SWIZZLE_W));
+ ureg_MAD(ureg, temp[1], ureg_src(temp[1]), src, dst);
+ /* take min/max for colors */
+ if (mode == VG_BLEND_DARKEN) {
+ ureg_MIN(ureg, ureg_writemask(out, TGSI_WRITEMASK_XYZ),
+ ureg_src(temp[0]), ureg_src(temp[1]));
+ }
+ else {
+ ureg_MAX(ureg, ureg_writemask(out, TGSI_WRITEMASK_XYZ),
+ ureg_src(temp[0]), ureg_src(temp[1]));
+ }
+ break;
+ case VG_BLEND_ADDITIVE:
+ /* RGBA_out = RGBA_src + RGBA_dst */
+ ureg_ADD(ureg, temp[0], src, dst);
+ ureg_MIN(ureg, out, ureg_src(temp[0]), one);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ blend_unpremultiply(ureg, src, one, temp);
+}
+
+#define BLEND_GENERIC(mode) \
+ do { \
+ ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]); \
+ blend_generic(ureg, (mode), ureg_src(temp[0]), ureg_src(temp[1]), \
+ ureg_src(temp[2]), \
+ ureg_scalar(constant[3], TGSI_SWIZZLE_Y), temp + 3); \
+ ureg_MOV(ureg, *out, ureg_src(temp[0])); \
+ } while (0)
+
+static INLINE void
+blend_src( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ BLEND_GENERIC(VG_BLEND_SRC);
+}
+
+static INLINE void
+blend_src_over( struct ureg_program *ureg,
struct ureg_dst *out,
struct ureg_src *in,
struct ureg_src *sampler,
struct ureg_dst *temp,
struct ureg_src *constant)
{
- ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
- EXTENDED_BLENDER_OVER_FUNC
- ureg_MUL(ureg, temp[4], ureg_src(temp[0]), ureg_src(temp[1]));
- ureg_ADD(ureg, temp[1], ureg_src(temp[4]), ureg_src(temp[3]));
+ BLEND_GENERIC(VG_BLEND_SRC_OVER);
+}
- ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
- ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
- ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
- ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
- ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W),
- ureg_src(temp[3]), ureg_src(temp[2]));
+static INLINE void
+blend_dst_over( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ BLEND_GENERIC(VG_BLEND_DST_OVER);
+}
- ureg_MOV(ureg, *out, ureg_src(temp[1]));
+static INLINE void
+blend_src_in( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ BLEND_GENERIC(VG_BLEND_SRC_IN);
+}
+
+static INLINE void
+blend_dst_in( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ BLEND_GENERIC(VG_BLEND_DST_IN);
+}
+
+static INLINE void
+blend_multiply( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ BLEND_GENERIC(VG_BLEND_MULTIPLY);
}
static INLINE void
@@ -274,10 +492,7 @@ blend_screen( struct ureg_program *ureg,
struct ureg_dst *temp,
struct ureg_src *constant)
{
- ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
- ureg_ADD(ureg, temp[3], ureg_src(temp[0]), ureg_src(temp[1]));
- ureg_MUL(ureg, temp[2], ureg_src(temp[0]), ureg_src(temp[1]));
- ureg_SUB(ureg, *out, ureg_src(temp[3]), ureg_src(temp[2]));
+ BLEND_GENERIC(VG_BLEND_SCREEN);
}
static INLINE void
@@ -288,23 +503,7 @@ blend_darken( struct ureg_program *ureg,
struct ureg_dst *temp,
struct ureg_src *constant)
{
- ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
- EXTENDED_BLENDER_OVER_FUNC
- ureg_MUL(ureg, temp[4], ureg_src(temp[0]),
- ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
- ureg_MUL(ureg, temp[5], ureg_src(temp[1]),
- ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
- ureg_MIN(ureg, temp[4], ureg_src(temp[4]), ureg_src(temp[5]));
- ureg_ADD(ureg, temp[1], ureg_src(temp[3]), ureg_src(temp[4]));
-
- ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
- ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
- ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
- ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
- ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W),
- ureg_src(temp[3]), ureg_src(temp[2]));
-
- ureg_MOV(ureg, *out, ureg_src(temp[1]));
+ BLEND_GENERIC(VG_BLEND_DARKEN);
}
static INLINE void
@@ -315,23 +514,33 @@ blend_lighten( struct ureg_program *ureg,
struct ureg_dst *temp,
struct ureg_src *constant)
{
- ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
- EXTENDED_BLENDER_OVER_FUNC
- ureg_MUL(ureg, temp[4], ureg_src(temp[0]),
- ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
- ureg_MUL(ureg, temp[5], ureg_src(temp[1]),
- ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
- ureg_MAX(ureg, temp[4], ureg_src(temp[4]), ureg_src(temp[5]));
- ureg_ADD(ureg, temp[1], ureg_src(temp[3]), ureg_src(temp[4]));
+ BLEND_GENERIC(VG_BLEND_LIGHTEN);
+}
- ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
- ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
- ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
- ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
- ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W),
- ureg_src(temp[3]), ureg_src(temp[2]));
+static INLINE void
+blend_additive( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ BLEND_GENERIC(VG_BLEND_ADDITIVE);
+}
- ureg_MOV(ureg, *out, ureg_src(temp[1]));
+static INLINE void
+mask( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[1]);
+ ureg_MUL(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_W),
+ ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_MOV(ureg, *out, ureg_src(temp[0]));
}
static INLINE void
@@ -369,11 +578,11 @@ color_bw( struct ureg_program *ureg,
struct ureg_src *constant)
{
ureg_ADD(ureg, temp[1],
- ureg_scalar(constant[1], TGSI_SWIZZLE_Y),
- ureg_scalar(constant[1], TGSI_SWIZZLE_Y));
+ ureg_scalar(constant[3], TGSI_SWIZZLE_Y),
+ ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
ureg_RCP(ureg, temp[2], ureg_src(temp[1]));
ureg_ADD(ureg, temp[1],
- ureg_scalar(constant[1], TGSI_SWIZZLE_Y),
+ ureg_scalar(constant[3], TGSI_SWIZZLE_Y),
ureg_src(temp[2]));
ureg_ADD(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_X),
ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_X),
@@ -410,46 +619,75 @@ struct shader_asm_info {
};
-static const struct shader_asm_info shaders_asm[] = {
- /* fills */
+/* paint types */
+static const struct shader_asm_info shaders_paint_asm[] = {
{VEGA_SOLID_FILL_SHADER, solid_fill,
- VG_FALSE, 0, 1, 0, 0, 0, 0},
+ VG_FALSE, 2, 1, 0, 0, 0, 0},
{VEGA_LINEAR_GRADIENT_SHADER, linear_grad,
- VG_TRUE, 0, 5, 0, 1, 0, 5},
+ VG_TRUE, 2, 5, 0, 1, 0, 5},
{VEGA_RADIAL_GRADIENT_SHADER, radial_grad,
- VG_TRUE, 0, 5, 0, 1, 0, 6},
+ VG_TRUE, 2, 5, 0, 1, 0, 5},
{VEGA_PATTERN_SHADER, pattern,
- VG_TRUE, 1, 4, 0, 1, 0, 5},
+ VG_TRUE, 3, 4, 0, 1, 0, 5},
+ {VEGA_PAINT_DEGENERATE_SHADER, paint_degenerate,
+ VG_FALSE, 3, 1, 0, 1, 0, 2}
+};
- /* image draw modes */
+/* image draw modes */
+static const struct shader_asm_info shaders_image_asm[] = {
{VEGA_IMAGE_NORMAL_SHADER, image_normal,
- VG_TRUE, 0, 0, 3, 1, 0, 0},
+ VG_TRUE, 0, 0, 3, 1, 0, 2},
{VEGA_IMAGE_MULTIPLY_SHADER, image_multiply,
VG_TRUE, 0, 0, 3, 1, 0, 2},
{VEGA_IMAGE_STENCIL_SHADER, image_stencil,
- VG_TRUE, 0, 0, 3, 1, 0, 2},
+ VG_TRUE, 0, 0, 3, 1, 0, 2}
+};
+static const struct shader_asm_info shaders_color_transform_asm[] = {
+ {VEGA_COLOR_TRANSFORM_SHADER, color_transform,
+ VG_FALSE, 0, 4, 0, 0, 0, 3}
+};
+
+static const struct shader_asm_info shaders_alpha_asm[] = {
+ {VEGA_ALPHA_NORMAL_SHADER, alpha_normal,
+ VG_FALSE, 0, 0, 0, 0, 0, 2},
+ {VEGA_ALPHA_PER_CHANNEL_SHADER, alpha_per_channel,
+ VG_FALSE, 0, 0, 0, 0, 0, 2}
+};
+
+/* extra blend modes */
+static const struct shader_asm_info shaders_blend_asm[] = {
+#define BLEND_ASM_INFO(id, func) { (id), (func), VG_TRUE, 3, 1, 2, 1, 0, 5 }
+ BLEND_ASM_INFO(VEGA_BLEND_SRC_SHADER, blend_src),
+ BLEND_ASM_INFO(VEGA_BLEND_SRC_OVER_SHADER, blend_src_over),
+ BLEND_ASM_INFO(VEGA_BLEND_DST_OVER_SHADER, blend_dst_over),
+ BLEND_ASM_INFO(VEGA_BLEND_SRC_IN_SHADER, blend_src_in),
+ BLEND_ASM_INFO(VEGA_BLEND_DST_IN_SHADER, blend_dst_in),
+ BLEND_ASM_INFO(VEGA_BLEND_MULTIPLY_SHADER, blend_multiply),
+ BLEND_ASM_INFO(VEGA_BLEND_SCREEN_SHADER, blend_screen),
+ BLEND_ASM_INFO(VEGA_BLEND_DARKEN_SHADER, blend_darken),
+ BLEND_ASM_INFO(VEGA_BLEND_LIGHTEN_SHADER, blend_lighten),
+ BLEND_ASM_INFO(VEGA_BLEND_ADDITIVE_SHADER, blend_additive)
+#undef BLEND_ASM_INFO
+};
+
+static const struct shader_asm_info shaders_mask_asm[] = {
{VEGA_MASK_SHADER, mask,
- VG_TRUE, 0, 0, 1, 1, 0, 2},
-
- /* extra blend modes */
- {VEGA_BLEND_MULTIPLY_SHADER, blend_multiply,
- VG_TRUE, 1, 1, 2, 1, 0, 5},
- {VEGA_BLEND_SCREEN_SHADER, blend_screen,
- VG_TRUE, 0, 0, 2, 1, 0, 4},
- {VEGA_BLEND_DARKEN_SHADER, blend_darken,
- VG_TRUE, 1, 1, 2, 1, 0, 6},
- {VEGA_BLEND_LIGHTEN_SHADER, blend_lighten,
- VG_TRUE, 1, 1, 2, 1, 0, 6},
-
- /* premultiply */
+ VG_TRUE, 0, 0, 1, 1, 0, 2}
+};
+
+/* premultiply */
+static const struct shader_asm_info shaders_premultiply_asm[] = {
{VEGA_PREMULTIPLY_SHADER, premultiply,
VG_FALSE, 0, 0, 0, 0, 0, 1},
{VEGA_UNPREMULTIPLY_SHADER, unpremultiply,
VG_FALSE, 0, 0, 0, 0, 0, 1},
+};
- /* color transform to black and white */
+/* color transform to black and white */
+static const struct shader_asm_info shaders_bw_asm[] = {
{VEGA_BW_SHADER, color_bw,
- VG_FALSE, 1, 1, 0, 0, 0, 3},
+ VG_FALSE, 3, 1, 0, 0, 0, 3},
};
+
#endif
diff --git a/src/gallium/state_trackers/vega/asm_util.h b/src/gallium/state_trackers/vega/asm_util.h
index 903bfc88a4d..ae1842a62cd 100644
--- a/src/gallium/state_trackers/vega/asm_util.h
+++ b/src/gallium/state_trackers/vega/asm_util.h
@@ -27,16 +27,6 @@
#ifndef ASM_UTIL_H
#define ASM_UTIL_H
-
-static const char pass_through_depth_asm[] =
- "FRAG\n"
- "DCL IN[0], POSITION, LINEAR\n"
- "DCL OUT[0].z, POSITION, CONSTANT\n"
- "0: MOV OUT[0].z, IN[0].zzzz\n"
- "1: END\n";
-
-
-
/* μnew = μmask */
static const char set_mask_asm[] =
"FRAG\n"
@@ -92,45 +82,4 @@ static const char subtract_mask_asm[] =
"3: MUL OUT[0], TEMP[2].wwww, TEMP[0].wwww\n"
"4: END\n";
-
-static const char vs_plain_asm[] =
- "VERT\n"
- "DCL IN[0]\n"
- "DCL OUT[0], POSITION\n"
- "DCL TEMP[0]\n"
- "DCL CONST[0..1]\n"
- "0: MUL TEMP[0], IN[0], CONST[0]\n"
- "1: ADD TEMP[0], TEMP[0], CONST[1]\n"
- "2: MOV OUT[0], TEMP[0]\n"
- "3: END\n";
-
-static const char vs_clear_asm[] =
- "VERT\n"
- "DCL IN[0]\n"
- "DCL IN[1]\n"
- "DCL OUT[0], POSITION\n"
- "DCL OUT[1], COLOR\n"
- "DCL TEMP[0]\n"
- "DCL CONST[0..1]\n"
- "0: MUL TEMP[0], IN[0], CONST[0]\n"
- "1: ADD TEMP[0], TEMP[0], CONST[1]\n"
- "2: MOV OUT[0], TEMP[0]\n"
- "3: MOV OUT[1], IN[1]\n"
- "4: END\n";
-
-
-static const char vs_texture_asm[] =
- "VERT\n"
- "DCL IN[0]\n"
- "DCL IN[1]\n"
- "DCL OUT[0], POSITION\n"
- "DCL OUT[1], GENERIC\n"
- "DCL TEMP[0]\n"
- "DCL CONST[0..1]\n"
- "0: MUL TEMP[0], IN[0], CONST[0]\n"
- "1: ADD TEMP[0], TEMP[0], CONST[1]\n"
- "2: MOV OUT[0], TEMP[0]\n"
- "3: MOV OUT[1], IN[1]\n"
- "4: END\n";
-
#endif
diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c
index 28bbe420a21..318ea94bdfb 100644
--- a/src/gallium/state_trackers/vega/image.c
+++ b/src/gallium/state_trackers/vega/image.c
@@ -42,6 +42,7 @@
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_sampler.h"
+#include "util/u_surface.h"
static enum pipe_format vg_format_to_pipe(VGImageFormat format)
{
@@ -77,33 +78,23 @@ static INLINE void vg_sync_size(VGfloat *src_loc, VGfloat *dst_loc)
dst_loc[3] = src_loc[3];
}
-
-static void vg_copy_texture(struct vg_context *ctx,
- struct pipe_resource *dst, VGint dx, VGint dy,
- struct pipe_sampler_view *src, VGint sx, VGint sy,
- VGint width, VGint height)
+static void vg_get_copy_coords(VGfloat *src_loc,
+ VGfloat src_width, VGfloat src_height,
+ VGfloat *dst_loc,
+ VGfloat dst_width, VGfloat dst_height)
{
- VGfloat dst_loc[4], src_loc[4];
VGfloat dst_bounds[4], src_bounds[4];
VGfloat src_shift[4], dst_shift[4], shift[4];
- dst_loc[0] = dx;
- dst_loc[1] = dy;
- dst_loc[2] = width;
- dst_loc[3] = height;
dst_bounds[0] = 0.f;
dst_bounds[1] = 0.f;
- dst_bounds[2] = dst->width0;
- dst_bounds[3] = dst->height0;
+ dst_bounds[2] = dst_width;
+ dst_bounds[3] = dst_height;
- src_loc[0] = sx;
- src_loc[1] = sy;
- src_loc[2] = width;
- src_loc[3] = height;
src_bounds[0] = 0.f;
src_bounds[1] = 0.f;
- src_bounds[2] = src->texture->width0;
- src_bounds[3] = src->texture->height0;
+ src_bounds[2] = src_width;
+ src_bounds[3] = src_height;
vg_bound_rect(src_loc, src_bounds, src_shift);
vg_bound_rect(dst_loc, dst_bounds, dst_shift);
@@ -121,22 +112,44 @@ static void vg_copy_texture(struct vg_context *ctx,
vg_shift_recty(dst_loc, dst_bounds, shift[1]);
vg_sync_size(src_loc, dst_loc);
+}
+
+static void vg_copy_texture(struct vg_context *ctx,
+ struct pipe_resource *dst, VGint dx, VGint dy,
+ struct pipe_sampler_view *src, VGint sx, VGint sy,
+ VGint width, VGint height)
+{
+ VGfloat dst_loc[4], src_loc[4];
+
+ dst_loc[0] = dx;
+ dst_loc[1] = dy;
+ dst_loc[2] = width;
+ dst_loc[3] = height;
+
+ src_loc[0] = sx;
+ src_loc[1] = sy;
+ src_loc[2] = width;
+ src_loc[3] = height;
+
+ vg_get_copy_coords(src_loc, src->texture->width0, src->texture->height0,
+ dst_loc, dst->width0, dst->height0);
if (src_loc[2] >= 0 && src_loc[3] >= 0 &&
dst_loc[2] >= 0 && dst_loc[3] >= 0) {
- renderer_copy_texture(ctx->renderer,
- src,
- src_loc[0],
- src_loc[1] + src_loc[3],
- src_loc[0] + src_loc[2],
- src_loc[1],
- dst,
- dst_loc[0],
- dst_loc[1] + dst_loc[3],
- dst_loc[0] + dst_loc[2],
- dst_loc[1]);
- }
+ struct pipe_surface *surf, surf_tmpl;
+
+ /* get the destination surface */
+ u_surface_default_template(&surf_tmpl, dst, PIPE_BIND_RENDER_TARGET);
+ surf = ctx->pipe->create_surface(ctx->pipe, dst, &surf_tmpl);
+ if (surf && renderer_copy_begin(ctx->renderer, surf, VG_TRUE, src)) {
+ renderer_copy(ctx->renderer,
+ dst_loc[0], dst_loc[1], dst_loc[2], dst_loc[3],
+ src_loc[0], src_loc[1], src_loc[2], src_loc[3]);
+ renderer_copy_end(ctx->renderer);
+ }
+ pipe_surface_reference(&surf, NULL);
+ }
}
void vg_copy_surface(struct vg_context *ctx,
@@ -145,43 +158,19 @@ void vg_copy_surface(struct vg_context *ctx,
VGint width, VGint height)
{
VGfloat dst_loc[4], src_loc[4];
- VGfloat dst_bounds[4], src_bounds[4];
- VGfloat src_shift[4], dst_shift[4], shift[4];
dst_loc[0] = dx;
dst_loc[1] = dy;
dst_loc[2] = width;
dst_loc[3] = height;
- dst_bounds[0] = 0.f;
- dst_bounds[1] = 0.f;
- dst_bounds[2] = dst->width;
- dst_bounds[3] = dst->height;
src_loc[0] = sx;
src_loc[1] = sy;
src_loc[2] = width;
src_loc[3] = height;
- src_bounds[0] = 0.f;
- src_bounds[1] = 0.f;
- src_bounds[2] = src->width;
- src_bounds[3] = src->height;
-
- vg_bound_rect(src_loc, src_bounds, src_shift);
- vg_bound_rect(dst_loc, dst_bounds, dst_shift);
- shift[0] = src_shift[0] - dst_shift[0];
- shift[1] = src_shift[1] - dst_shift[1];
-
- if (shift[0] < 0)
- vg_shift_rectx(src_loc, src_bounds, -shift[0]);
- else
- vg_shift_rectx(dst_loc, dst_bounds, shift[0]);
-
- if (shift[1] < 0)
- vg_shift_recty(src_loc, src_bounds, -shift[1]);
- else
- vg_shift_recty(dst_loc, dst_bounds, shift[1]);
- vg_sync_size(src_loc, dst_loc);
+ vg_get_copy_coords(src_loc, src->width, src->height,
+ dst_loc, dst->width, dst->height);
if (src_loc[2] > 0 && src_loc[3] > 0 &&
dst_loc[2] > 0 && dst_loc[3] > 0) {
@@ -277,6 +266,7 @@ struct vg_image * image_create(VGImageFormat format,
pt.width0 = width;
pt.height0 = height;
pt.depth0 = 1;
+ pt.array_size = 1;
pt.bind = PIPE_BIND_SAMPLER_VIEW;
newtex = screen->resource_create(screen, &pt);
@@ -284,6 +274,13 @@ struct vg_image * image_create(VGImageFormat format,
debug_assert(newtex);
u_sampler_view_default_template(&view_templ, newtex, newtex->format);
+ /* R, G, and B are treated as 1.0 for alpha-only formats in OpenVG */
+ if (newtex->format == PIPE_FORMAT_A8_UNORM) {
+ view_templ.swizzle_r = PIPE_SWIZZLE_ONE;
+ view_templ.swizzle_g = PIPE_SWIZZLE_ONE;
+ view_templ.swizzle_b = PIPE_SWIZZLE_ONE;
+ }
+
view = pipe->create_sampler_view(pipe, newtex, &view_templ);
/* want the texture to go away if the view is freed */
pipe_resource_reference(&newtex, NULL);
@@ -420,7 +417,7 @@ void image_sub_data(struct vg_image *image,
{ /* upload color_data */
struct pipe_transfer *transfer = pipe_get_transfer(
- pipe, texture, 0, 0, 0,
+ pipe, texture, 0, 0,
PIPE_TRANSFER_WRITE, 0, 0, texture->width0, texture->height0);
src += (dataStride * yoffset);
for (i = 0; i < height; i++) {
@@ -451,11 +448,11 @@ void image_get_sub_data(struct vg_image * image,
{
struct pipe_transfer *transfer =
pipe_get_transfer(pipe,
- image->sampler_view->texture, 0, 0, 0,
- PIPE_TRANSFER_READ,
- 0, 0,
- image->x + image->width,
- image->y + image->height);
+ image->sampler_view->texture, 0, 0,
+ PIPE_TRANSFER_READ,
+ 0, 0,
+ image->x + image->width,
+ image->y + image->height);
/* Do a row at a time to flip image data vertically */
for (i = 0; i < height; i++) {
#if 0
@@ -525,14 +522,20 @@ void image_copy(struct vg_image *dst, VGint dx, VGint dy,
src->sampler_view, src->x + sx, src->y + sy, width, height);
}
-void image_draw(struct vg_image *img)
+void image_draw(struct vg_image *img, struct matrix *matrix)
{
struct vg_context *ctx = vg_current_context();
+ struct matrix paint_matrix;
VGfloat x1, y1;
VGfloat x2, y2;
VGfloat x3, y3;
VGfloat x4, y4;
- struct matrix *matrix;
+
+ if (!vg_get_paint_matrix(ctx,
+ &ctx->state.vg.fill_paint_to_user_matrix,
+ matrix,
+ &paint_matrix))
+ return;
x1 = 0;
y1 = 0;
@@ -543,15 +546,10 @@ void image_draw(struct vg_image *img)
x4 = 0;
y4 = img->height;
- matrix = &ctx->state.vg.image_user_to_surface_matrix;
-
- matrix_map_point(matrix, x1, y1, &x1, &y1);
- matrix_map_point(matrix, x2, y2, &x2, &y2);
- matrix_map_point(matrix, x3, y3, &x3, &y3);
- matrix_map_point(matrix, x4, y4, &x4, &y4);
-
+ shader_set_surface_matrix(ctx->shader, matrix);
shader_set_drawing_image(ctx->shader, VG_TRUE);
shader_set_paint(ctx->shader, ctx->state.vg.fill_paint);
+ shader_set_paint_matrix(ctx->shader, &paint_matrix);
shader_set_image(ctx->shader, img);
shader_bind(ctx->shader);
@@ -566,20 +564,21 @@ void image_set_pixels(VGint dx, VGint dy,
{
struct vg_context *ctx = vg_current_context();
struct pipe_context *pipe = ctx->pipe;
- struct pipe_screen *screen = pipe->screen;
- struct pipe_surface *surf;
+ struct pipe_surface *surf, surf_tmpl;
struct st_renderbuffer *strb = ctx->draw_buffer->strb;
/* make sure rendering has completed */
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
- surf = screen->get_tex_surface(screen, image_texture(src), 0, 0, 0,
- 0 /* no bind flags as surf isn't actually used??? */);
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ u_surface_default_template(&surf_tmpl, image_texture(src),
+ 0 /* no bind flag - not a surface*/);
+ surf = pipe->create_surface(pipe, image_texture(src), &surf_tmpl);
vg_copy_surface(ctx, strb->surface, dx, dy,
surf, sx+src->x, sy+src->y, width, height);
- screen->tex_surface_destroy(surf);
+ pipe->surface_destroy(pipe, surf);
}
void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy,
@@ -588,8 +587,7 @@ void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy,
{
struct vg_context *ctx = vg_current_context();
struct pipe_context *pipe = ctx->pipe;
- struct pipe_screen *screen = pipe->screen;
- struct pipe_surface *surf;
+ struct pipe_surface *surf, surf_tmpl;
struct st_renderbuffer *strb = ctx->draw_buffer->strb;
/* flip the y coordinates */
@@ -598,8 +596,10 @@ void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy,
/* make sure rendering has completed */
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
- surf = screen->get_tex_surface(screen, image_texture(dst), 0, 0, 0,
- 0 /* no bind flags as surf isn't actually used??? */);
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ u_surface_default_template(&surf_tmpl, image_texture(dst),
+ PIPE_BIND_RENDER_TARGET);
+ surf = pipe->create_surface(pipe, image_texture(dst), &surf_tmpl);
vg_copy_surface(ctx, surf, dst->x + dx, dst->y + dy,
strb->surface, sx, sy, width, height);
diff --git a/src/gallium/state_trackers/vega/image.h b/src/gallium/state_trackers/vega/image.h
index a990c9c5873..391c0485948 100644
--- a/src/gallium/state_trackers/vega/image.h
+++ b/src/gallium/state_trackers/vega/image.h
@@ -79,7 +79,7 @@ void image_copy(struct vg_image *dst, VGint dx, VGint dy,
VGint width, VGint height,
VGboolean dither);
-void image_draw(struct vg_image *img);
+void image_draw(struct vg_image *img, struct matrix *matrix);
void image_set_pixels(VGint dx, VGint dy,
struct vg_image *src, VGint sx, VGint sy,
diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c
index ef28ebd740c..dfd0600e444 100644
--- a/src/gallium/state_trackers/vega/mask.c
+++ b/src/gallium/state_trackers/vega/mask.c
@@ -31,13 +31,14 @@
#include "shaders_cache.h"
#include "renderer.h"
#include "asm_util.h"
-#include "st_inlines.h"
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
#include "util/u_inlines.h"
#include "util/u_format.h"
#include "util/u_memory.h"
+#include "util/u_surface.h"
+#include "util/u_sampler.h"
struct vg_mask_layer {
struct vg_object base;
@@ -48,17 +49,6 @@ struct vg_mask_layer {
struct pipe_sampler_view *sampler_view;
};
-static INLINE struct pipe_surface *
-alpha_mask_surface(struct vg_context *ctx, int usage)
-{
- struct pipe_screen *screen = ctx->pipe->screen;
- struct st_framebuffer *stfb = ctx->draw_buffer;
- return screen->get_tex_surface(screen,
- stfb->alpha_mask_view->texture,
- 0, 0, 0,
- usage);
-}
-
static INLINE VGboolean
intersect_rectangles(VGint dwidth, VGint dheight,
VGint swidth, VGint sheight,
@@ -110,15 +100,13 @@ static void read_alpha_mask(void * data, VGint dataStride,
{
struct vg_context *ctx = vg_current_context();
struct pipe_context *pipe = ctx->pipe;
- struct pipe_screen *screen = pipe->screen;
struct st_framebuffer *stfb = ctx->draw_buffer;
struct st_renderbuffer *strb = stfb->alpha_mask;
- struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
VGfloat *df = (VGfloat*)temp;
- VGint y = (fb->height - sy) - 1, yStep = -1;
+ VGint y = (stfb->height - sy) - 1, yStep = -1;
VGint i;
VGubyte *dst = (VGubyte *)data;
VGint xoffset = 0, yoffset = 0;
@@ -135,15 +123,15 @@ static void read_alpha_mask(void * data, VGint dataStride,
yoffset = -sy;
height += sy;
sy = 0;
- y = (fb->height - sy) - 1;
+ y = (stfb->height - sy) - 1;
yoffset *= dataStride;
}
{
struct pipe_surface *surf;
- surf = screen->get_tex_surface(screen, strb->texture, 0, 0, 0,
- PIPE_BIND_TRANSFER_READ);
+ surf = pipe->create_surface(pipe, strb->texture, 0, 0, 0,
+ PIPE_BIND_TRANSFER_READ);
/* Do a row at a time to flip image data vertically */
for (i = 0; i < height; i++) {
@@ -164,23 +152,23 @@ static void read_alpha_mask(void * data, VGint dataStride,
void save_alpha_to_file(const char *filename)
{
struct vg_context *ctx = vg_current_context();
- struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
+ struct st_framebuffer *stfb = ctx->draw_buffer;
VGint *data;
int i, j;
- data = malloc(sizeof(int) * fb->width * fb->height);
- read_alpha_mask(data, fb->width * sizeof(int),
+ data = malloc(sizeof(int) * stfb->width * stfb->height);
+ read_alpha_mask(data, stfb->width * sizeof(int),
VG_sRGBA_8888,
- 0, 0, fb->width, fb->height);
+ 0, 0, stfb->width, stfb->height);
fprintf(stderr, "/*---------- start */\n");
fprintf(stderr, "const int image_width = %d;\n",
- fb->width);
+ stfb->width);
fprintf(stderr, "const int image_height = %d;\n",
- fb->height);
+ stfb->height);
fprintf(stderr, "const int image_data = {\n");
- for (i = 0; i < fb->height; ++i) {
- for (j = 0; j < fb->width; ++j) {
- int rgba = data[i * fb->height + j];
+ for (i = 0; i < stfb->height; ++i) {
+ for (j = 0; j < stfb->width; ++j) {
+ int rgba = data[i * stfb->height + j];
int argb = 0;
argb = (rgba >> 8);
argb |= ((rgba & 0xff) << 24);
@@ -193,49 +181,12 @@ void save_alpha_to_file(const char *filename)
}
#endif
-static void setup_mask_framebuffer(struct pipe_surface *surf,
- VGint surf_width, VGint surf_height)
-{
- struct vg_context *ctx = vg_current_context();
- struct pipe_framebuffer_state fb;
-
- memset(&fb, 0, sizeof(fb));
- fb.width = surf_width;
- fb.height = surf_height;
- fb.nr_cbufs = 1;
- fb.cbufs[0] = surf;
- {
- VGint i;
- for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
- fb.cbufs[i] = 0;
- }
- cso_set_framebuffer(ctx->cso_context, &fb);
-}
-
-
-/* setup shader constants */
-static void setup_mask_operation(VGMaskOperation operation)
+/* setup mask shader */
+static void *setup_mask_operation(VGMaskOperation operation)
{
struct vg_context *ctx = vg_current_context();
- struct pipe_resource **cbuf = &ctx->mask.cbuf;
- const VGint param_bytes = 4 * sizeof(VGfloat);
- const VGfloat ones[4] = {1.f, 1.f, 1.f, 1.f};
void *shader = 0;
- /* We always need to get a new buffer, to keep the drivers simple and
- * avoid gratuitous rendering synchronization.
- */
- pipe_resource_reference(cbuf, NULL);
-
- *cbuf = pipe_buffer_create(ctx->pipe->screen,
- PIPE_BIND_CONSTANT_BUFFER,
- param_bytes);
- if (*cbuf) {
- st_no_flush_pipe_buffer_write(ctx, *cbuf,
- 0, param_bytes, ones);
- }
-
- ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf);
switch (operation) {
case VG_UNION_MASK: {
if (!ctx->mask.union_fs) {
@@ -281,94 +232,21 @@ static void setup_mask_operation(VGMaskOperation operation)
assert(0);
break;
}
- cso_set_fragment_shader_handle(ctx->cso_context, shader);
-}
-
-static void setup_mask_samplers(struct pipe_sampler_view *umask)
-{
- struct vg_context *ctx = vg_current_context();
- struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
- struct st_framebuffer *fb_buffers = ctx->draw_buffer;
- struct pipe_sampler_view *uprev = NULL;
- struct pipe_sampler_state sampler;
-
- uprev = fb_buffers->blend_texture_view;
- sampler = ctx->mask.sampler;
- sampler.normalized_coords = 1;
-
- samplers[0] = NULL;
- samplers[1] = NULL;
- sampler_views[0] = NULL;
- sampler_views[1] = NULL;
-
- samplers[0] = &sampler;
- samplers[1] = &ctx->mask.sampler;
-
- sampler_views[0] = umask;
- sampler_views[1] = uprev;
-
- cso_set_samplers(ctx->cso_context, 2,
- (const struct pipe_sampler_state **)samplers);
- cso_set_fragment_sampler_views(ctx->cso_context, 2, sampler_views);
-}
-
-
-/* setup shader constants */
-static void setup_mask_fill(const VGfloat color[4])
-{
- struct vg_context *ctx = vg_current_context();
- struct pipe_resource **cbuf = &ctx->mask.cbuf;
- const VGint param_bytes = 4 * sizeof(VGfloat);
-
- /* We always need to get a new buffer, to keep the drivers simple and
- * avoid gratuitous rendering synchronization.
- */
- pipe_resource_reference(cbuf, NULL);
-
- *cbuf = pipe_buffer_create(ctx->pipe->screen,
- PIPE_BIND_CONSTANT_BUFFER,
- param_bytes);
- if (*cbuf) {
- st_no_flush_pipe_buffer_write(ctx, *cbuf, 0, param_bytes, color);
- }
-
- ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf);
- cso_set_fragment_shader_handle(ctx->cso_context,
- shaders_cache_fill(ctx->sc,
- VEGA_SOLID_FILL_SHADER));
-}
-
-static void setup_mask_viewport()
-{
- struct vg_context *ctx = vg_current_context();
- vg_set_viewport(ctx, VEGA_Y0_TOP);
-}
-
-static void setup_mask_blend()
-{
- struct vg_context *ctx = vg_current_context();
-
- struct pipe_blend_state blend;
- memset(&blend, 0, sizeof(struct pipe_blend_state));
- blend.rt[0].blend_enable = 0;
- blend.rt[0].colormask = PIPE_MASK_RGBA;
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-
- cso_set_blend(ctx->cso_context, &blend);
+ return shader;
}
-
-static void surface_fill(struct pipe_surface *surf,
- int surf_width, int surf_height,
- int x, int y, int width, int height,
- const VGfloat color[4])
+static void mask_resource_fill(struct pipe_resource *dst,
+ int x, int y, int width, int height,
+ VGfloat coverage)
{
struct vg_context *ctx = vg_current_context();
+ VGfloat fs_consts[12] = {
+ 0.0f, 0.0f, 0.0f, 0.0f, /* not used */
+ 0.0f, 0.0f, 0.0f, 0.0f, /* not used */
+ 0.0f, 0.0f, 0.0f, coverage /* color */
+ };
+ void *fs;
if (x < 0) {
width += x;
@@ -379,50 +257,38 @@ static void surface_fill(struct pipe_surface *surf,
y = 0;
}
- cso_save_framebuffer(ctx->cso_context);
- cso_save_blend(ctx->cso_context);
- cso_save_fragment_shader(ctx->cso_context);
- cso_save_viewport(ctx->cso_context);
-
- setup_mask_blend();
- setup_mask_fill(color);
- setup_mask_framebuffer(surf, surf_width, surf_height);
- setup_mask_viewport();
+ fs = shaders_cache_fill(ctx->sc, VEGA_SOLID_FILL_SHADER);
- renderer_draw_quad(ctx->renderer, x, y,
- x + width, y + height, 0.0f/*depth should be disabled*/);
-
-
- /* make sure rendering has completed */
- ctx->pipe->flush(ctx->pipe,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME,
- NULL);
+ if (renderer_filter_begin(ctx->renderer, dst, VG_FALSE, ~0,
+ NULL, NULL, 0, fs, (const void *) fs_consts, sizeof(fs_consts))) {
+ renderer_filter(ctx->renderer, x, y, width, height, 0, 0, 0, 0);
+ renderer_filter_end(ctx->renderer);
+ }
#if DEBUG_MASKS
save_alpha_to_file(0);
#endif
-
- cso_restore_blend(ctx->cso_context);
- cso_restore_framebuffer(ctx->cso_context);
- cso_restore_fragment_shader(ctx->cso_context);
- cso_restore_viewport(ctx->cso_context);
}
static void mask_using_texture(struct pipe_sampler_view *sampler_view,
+ VGboolean is_layer,
VGMaskOperation operation,
VGint x, VGint y,
VGint width, VGint height)
{
struct vg_context *ctx = vg_current_context();
+ struct pipe_sampler_view *dst_view = vg_get_surface_mask(ctx);
+ struct pipe_resource *dst = dst_view->texture;
struct pipe_resource *texture = sampler_view->texture;
- struct pipe_surface *surface =
- alpha_mask_surface(ctx, PIPE_BIND_RENDER_TARGET);
+ const struct pipe_sampler_state *samplers[2];
+ struct pipe_sampler_view *views[2];
+ struct pipe_sampler_state sampler;
VGint offsets[4], loc[4];
+ const VGfloat ones[4] = {1.f, 1.f, 1.f, 1.f};
+ void *fs;
- if (!surface)
- return;
- if (!intersect_rectangles(surface->width, surface->height,
+ if (!intersect_rectangles(dst->width0, dst->height0,
texture->width0, texture->height0,
x, y, width, height,
offsets, loc))
@@ -434,38 +300,30 @@ static void mask_using_texture(struct pipe_sampler_view *sampler_view,
loc[1], loc[2], loc[3]);
#endif
+
+ sampler = ctx->mask.sampler;
+ sampler.normalized_coords = 1;
+ samplers[0] = &sampler;
+ views[0] = sampler_view;
+
/* prepare our blend surface */
- vg_prepare_blend_surface_from_mask(ctx);
-
- cso_save_samplers(ctx->cso_context);
- cso_save_fragment_sampler_views(ctx->cso_context);
- cso_save_framebuffer(ctx->cso_context);
- cso_save_blend(ctx->cso_context);
- cso_save_fragment_shader(ctx->cso_context);
- cso_save_viewport(ctx->cso_context);
-
- setup_mask_samplers(sampler_view);
- setup_mask_blend();
- setup_mask_operation(operation);
- setup_mask_framebuffer(surface, surface->width, surface->height);
- setup_mask_viewport();
-
- /* render the quad to propagate the rendering from stencil */
- renderer_draw_texture(ctx->renderer, texture,
- offsets[0], offsets[1],
- offsets[0] + offsets[2], offsets[1] + offsets[3],
- loc[0], loc[1], loc[0] + loc[2], loc[1] + loc[3]);
+ samplers[1] = &ctx->mask.sampler;
+ views[1] = vg_prepare_blend_surface_from_mask(ctx);
- /* make sure rendering has completed */
- ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
- cso_restore_blend(ctx->cso_context);
- cso_restore_framebuffer(ctx->cso_context);
- cso_restore_fragment_shader(ctx->cso_context);
- cso_restore_samplers(ctx->cso_context);
- cso_restore_fragment_sampler_views(ctx->cso_context);
- cso_restore_viewport(ctx->cso_context);
-
- pipe_surface_reference(&surface, NULL);
+ fs = setup_mask_operation(operation);
+
+ if (renderer_filter_begin(ctx->renderer, dst, VG_FALSE,
+ ~0, samplers, views, 2, fs, (const void *) ones, sizeof(ones))) {
+ /* layer should be flipped when used as a texture */
+ if (is_layer) {
+ offsets[1] += offsets[3];
+ offsets[3] = -offsets[3];
+ }
+ renderer_filter(ctx->renderer,
+ loc[0], loc[1], loc[2], loc[3],
+ offsets[0], offsets[1], offsets[2], offsets[3]);
+ renderer_filter_end(ctx->renderer);
+ }
}
@@ -496,8 +354,8 @@ struct vg_mask_layer * mask_layer_create(VGint width, VGint height)
pt.width0 = width;
pt.height0 = height;
pt.depth0 = 1;
+ pt.array_size = 1;
pt.bind = PIPE_BIND_SAMPLER_VIEW;
- pt.compressed = 0;
texture = screen->resource_create(screen, &pt);
@@ -519,7 +377,7 @@ void mask_layer_destroy(struct vg_mask_layer *layer)
struct vg_context *ctx = vg_current_context();
vg_context_remove_object(ctx, VG_OBJECT_MASK, layer);
- pipe_resource_release(&layer->texture);
+ pipe_sampler_view_reference(&layer->sampler_view, NULL);
FREE(layer);
}
@@ -528,22 +386,12 @@ void mask_layer_fill(struct vg_mask_layer *layer,
VGint width, VGint height,
VGfloat value)
{
- struct vg_context *ctx = vg_current_context();
VGfloat alpha_color[4] = {0, 0, 0, 0};
- struct pipe_surface *surface;
alpha_color[3] = value;
- surface = ctx->pipe->screen->get_tex_surface(
- ctx->pipe->screen, layer->sampler_view->texture,
- 0, 0, 0,
- PIPE_BIND_RENDER_TARGET);
-
- surface_fill(surface,
- layer->width, layer->height,
- x, y, width, height, alpha_color);
-
- ctx->pipe->screen->tex_surface_release(ctx->pipe->screen, &surface);
+ mask_resource_fill(layer->sampler_view->texture,
+ x, y, width, height, value);
}
void mask_copy(struct vg_mask_layer *layer,
@@ -551,16 +399,27 @@ void mask_copy(struct vg_mask_layer *layer,
VGint dx, VGint dy,
VGint width, VGint height)
{
- struct vg_context *ctx = vg_current_context();
- struct st_framebuffer *fb_buffers = ctx->draw_buffer;
-
- renderer_copy_texture(ctx->renderer,
- layer->sampler_view,
- sx, sy,
- sx + width, sy + height,
- fb_buffers->alpha_mask_view->texture,
- dx, dy,
- dx + width, dy + height);
+ struct vg_context *ctx = vg_current_context();
+ struct pipe_sampler_view *src = vg_get_surface_mask(ctx);
+ struct pipe_surface *surf, surf_tmpl;
+
+ /* get the destination surface */
+ u_surface_default_template(&surf_tmpl, layer->sampler_view->texture,
+ PIPE_BIND_RENDER_TARGET);
+ surf = ctx->pipe->create_surface(ctx->pipe, layer->sampler_view->texture,
+ &surf_tmpl);
+ if (surf && renderer_copy_begin(ctx->renderer, surf, VG_FALSE, src)) {
+ /* layer should be flipped when used as a texture */
+ sy += height;
+ height = -height;
+
+ renderer_copy(ctx->renderer,
+ dx, dy, width, height,
+ sx, sy, width, height);
+ renderer_copy_end(ctx->renderer);
+ }
+
+ pipe_surface_reference(&surf, NULL);
}
static void mask_layer_render_to(struct vg_mask_layer *layer,
@@ -568,41 +427,25 @@ static void mask_layer_render_to(struct vg_mask_layer *layer,
VGbitfield paint_modes)
{
struct vg_context *ctx = vg_current_context();
- const VGfloat fill_color[4] = {1.f, 1.f, 1.f, 1.f};
- struct pipe_screen *screen = ctx->pipe->screen;
- struct pipe_surface *surface;
-
- surface = screen->get_tex_surface(screen, layer->sampler_view->texture, 0, 0, 0,
- PIPE_BIND_RENDER_TARGET);
-
- cso_save_framebuffer(ctx->cso_context);
- cso_save_fragment_shader(ctx->cso_context);
- cso_save_viewport(ctx->cso_context);
+ struct pipe_context *pipe = ctx->pipe;
+ struct pipe_sampler_view *view = vg_get_surface_mask(ctx);
+ struct matrix *mat = &ctx->state.vg.path_user_to_surface_matrix;
+ struct pipe_surface *surf, surf_tmpl;
+ u_surface_default_template(&surf_tmpl, view->texture,
+ PIPE_BIND_RENDER_TARGET);
+ surf = pipe->create_surface(pipe, view->texture, &surf_tmpl);
- setup_mask_blend();
- setup_mask_fill(fill_color);
- setup_mask_framebuffer(surface, layer->width, layer->height);
- setup_mask_viewport();
+ renderer_validate_for_mask_rendering(ctx->renderer, surf, mat);
if (paint_modes & VG_FILL_PATH) {
- struct matrix *mat = &ctx->state.vg.path_user_to_surface_matrix;
- path_fill(path, mat);
+ path_fill(path);
}
if (paint_modes & VG_STROKE_PATH){
path_stroke(path);
}
-
- /* make sure rendering has completed */
- ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
-
- cso_restore_framebuffer(ctx->cso_context);
- cso_restore_fragment_shader(ctx->cso_context);
- cso_restore_viewport(ctx->cso_context);
- ctx->state.dirty |= BLEND_DIRTY;
-
- screen->tex_surface_release(ctx->pipe->screen, &surface);
+ pipe_surface_reference(&surf, NULL);
}
void mask_render_to(struct path *path,
@@ -610,19 +453,19 @@ void mask_render_to(struct path *path,
VGMaskOperation operation)
{
struct vg_context *ctx = vg_current_context();
- struct st_framebuffer *fb_buffers = ctx->draw_buffer;
+ struct st_framebuffer *stfb = ctx->draw_buffer;
struct vg_mask_layer *temp_layer;
VGint width, height;
- width = fb_buffers->alpha_mask_view->texture->width0;
- height = fb_buffers->alpha_mask_view->texture->width0;
+ width = stfb->width;
+ height = stfb->height;
temp_layer = mask_layer_create(width, height);
+ mask_layer_fill(temp_layer, 0, 0, width, height, 0.0f);
mask_layer_render_to(temp_layer, path, paint_modes);
- mask_using_layer(temp_layer, 0, 0, width, height,
- operation);
+ mask_using_layer(temp_layer, operation, 0, 0, width, height);
mask_layer_destroy(temp_layer);
}
@@ -632,7 +475,7 @@ void mask_using_layer(struct vg_mask_layer *layer,
VGint x, VGint y,
VGint width, VGint height)
{
- mask_using_texture(layer->sampler_view, operation,
+ mask_using_texture(layer->sampler_view, VG_TRUE, operation,
x, y, width, height);
}
@@ -654,7 +497,7 @@ void mask_using_image(struct vg_image *image,
VGint x, VGint y,
VGint width, VGint height)
{
- mask_using_texture(image->sampler_view, operation,
+ mask_using_texture(image->sampler_view, VG_FALSE, operation,
x, y, width, height);
}
@@ -662,23 +505,15 @@ void mask_fill(VGint x, VGint y, VGint width, VGint height,
VGfloat value)
{
struct vg_context *ctx = vg_current_context();
- VGfloat alpha_color[4] = {.0f, .0f, .0f, value};
- struct pipe_surface *surf = alpha_mask_surface(
- ctx, PIPE_BIND_RENDER_TARGET);
+ struct pipe_sampler_view *view = vg_get_surface_mask(ctx);
#if DEBUG_MASKS
debug_printf("mask_fill(%d, %d, %d, %d) with rgba(%f, %f, %f, %f)\n",
x, y, width, height,
- alpha_color[0], alpha_color[1],
- alpha_color[2], alpha_color[3]);
- debug_printf("XXX %f === %f \n",
- alpha_color[3], value);
+ 0.0f, 0.0f, 0.0f, value);
#endif
- surface_fill(surf, surf->width, surf->height,
- x, y, width, height, alpha_color);
-
- pipe_surface_reference(&surf, NULL);
+ mask_resource_fill(view->texture, x, y, width, height, value);
}
VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
@@ -687,10 +522,8 @@ VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
struct vg_context *ctx = vg_current_context();
if (ctx->state.vg.masking) {
- struct st_framebuffer *fb_buffers = ctx->draw_buffer;
-
samplers[1] = &ctx->mask.sampler;
- sampler_views[1] = fb_buffers->alpha_mask_view;
+ sampler_views[1] = vg_get_surface_mask(ctx);
return 1;
} else
return 0;
diff --git a/src/gallium/state_trackers/vega/matrix.h b/src/gallium/state_trackers/vega/matrix.h
index 4c207f912a8..bed2b3193d0 100644
--- a/src/gallium/state_trackers/vega/matrix.h
+++ b/src/gallium/state_trackers/vega/matrix.h
@@ -129,7 +129,7 @@ static INLINE void matrix_make_affine(struct matrix *matrix)
}
static INLINE void matrix_mult(struct matrix *dst,
- struct matrix *src)
+ const struct matrix *src)
{
VGfloat m11 = dst->m[0]*src->m[0] + dst->m[3]*src->m[1] + dst->m[6]*src->m[2];
VGfloat m12 = dst->m[0]*src->m[3] + dst->m[3]*src->m[4] + dst->m[6]*src->m[5];
diff --git a/src/gallium/state_trackers/vega/paint.c b/src/gallium/state_trackers/vega/paint.c
index c0c8cddabe9..2db8cbcf7c8 100644
--- a/src/gallium/state_trackers/vega/paint.c
+++ b/src/gallium/state_trackers/vega/paint.c
@@ -28,7 +28,6 @@
#include "matrix.h"
#include "image.h"
-#include "st_inlines.h"
#include "pipe/p_compiler.h"
#include "util/u_inlines.h"
@@ -155,14 +154,15 @@ static INLINE struct pipe_resource *create_gradient_texture(struct vg_paint *p)
templ.width0 = 1024;
templ.height0 = 1;
templ.depth0 = 1;
+ templ.array_size = 1;
templ.bind = PIPE_BIND_SAMPLER_VIEW;
tex = screen->resource_create(screen, &templ);
{ /* upload color_data */
struct pipe_transfer *transfer =
- st_no_flush_get_transfer(p->base.ctx, tex, 0, 0, 0,
- PIPE_TRANSFER_WRITE, 0, 0, 1024, 1);
+ pipe_get_transfer(p->base.ctx->pipe, tex, 0, 0,
+ PIPE_TRANSFER_WRITE, 0, 0, 1024, 1);
void *map = pipe->transfer_map(pipe, transfer);
memcpy(map, p->gradient.color_data, sizeof(VGint)*1024);
pipe->transfer_unmap(pipe, transfer);
@@ -261,14 +261,18 @@ static INLINE void paint_color_buffer(struct vg_paint *paint, void *buffer)
map[7] = 4.f;
}
-static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint, void *buffer)
+static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint,
+ const struct matrix *inv,
+ void *buffer)
{
- struct vg_context *ctx = paint->base.ctx;
VGfloat *map = (VGfloat*)buffer;
+ VGfloat dd;
map[0] = paint->gradient.linear.coords[2] - paint->gradient.linear.coords[0];
map[1] = paint->gradient.linear.coords[3] - paint->gradient.linear.coords[1];
- map[2] = 1.f / (map[0] * map[0] + map[1] * map[1]);
+ dd = (map[0] * map[0] + map[1] * map[1]);
+
+ map[2] = (dd > 0.0f) ? 1.f / dd : 0.f;
map[3] = 1.f;
map[4] = 0.f;
@@ -277,15 +281,10 @@ static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint, void *bu
map[7] = 4.f;
{
struct matrix mat;
- struct matrix inv;
matrix_load_identity(&mat);
+ /* VEGA_LINEAR_GRADIENT_SHADER expects the first point to be at (0, 0) */
matrix_translate(&mat, -paint->gradient.linear.coords[0], -paint->gradient.linear.coords[1]);
- memcpy(&inv, &ctx->state.vg.fill_paint_to_user_matrix,
- sizeof(struct matrix));
- matrix_invert(&inv);
- matrix_mult(&inv, &mat);
- memcpy(&mat, &inv,
- sizeof(struct matrix));
+ matrix_mult(&mat, inv);
map[8] = mat.m[0]; map[9] = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
@@ -298,17 +297,37 @@ static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint, void *bu
}
-static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint, void *buffer)
+static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint,
+ const struct matrix *inv,
+ void *buffer)
{
- VGfloat *radialCoords = paint->gradient.radial.vals;
- struct vg_context *ctx = paint->base.ctx;
-
+ const VGfloat *center = &paint->gradient.radial.vals[0];
+ const VGfloat *focal = &paint->gradient.radial.vals[2];
+ VGfloat rr = paint->gradient.radial.vals[4];
VGfloat *map = (VGfloat*)buffer;
+ VGfloat dd, new_focal[2];
+
+ rr *= rr;
+
+ map[0] = center[0] - focal[0];
+ map[1] = center[1] - focal[1];
+ dd = map[0] * map[0] + map[1] * map[1];
+
+ /* focal point must lie inside the circle */
+ if (0.998f * rr < dd) {
+ VGfloat scale;
+
+ scale = (dd > 0.0f) ? sqrt(0.998f * rr / dd) : 0.0f;
+ map[0] *= scale;
+ map[1] *= scale;
- map[0] = radialCoords[0] - radialCoords[2];
- map[1] = radialCoords[1] - radialCoords[3];
- map[2] = -map[0] * map[0] - map[1] * map[1] +
- radialCoords[4] * radialCoords[4];
+ new_focal[0] = center[0] - map[0];
+ new_focal[1] = center[1] - map[1];
+ dd = map[0] * map[0] + map[1] * map[1];
+ focal = new_focal;
+ }
+
+ map[2] = (rr > dd) ? rr - dd : 1.0f;
map[3] = 1.f;
map[4] = 0.f;
@@ -318,15 +337,9 @@ static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint, void *bu
{
struct matrix mat;
- struct matrix inv;
matrix_load_identity(&mat);
- matrix_translate(&mat, -radialCoords[2], -radialCoords[3]);
- memcpy(&inv, &ctx->state.vg.fill_paint_to_user_matrix,
- sizeof(struct matrix));
- matrix_invert(&inv);
- matrix_mult(&inv, &mat);
- memcpy(&mat, &inv,
- sizeof(struct matrix));
+ matrix_translate(&mat, -focal[0], -focal[1]);
+ matrix_mult(&mat, inv);
map[8] = mat.m[0]; map[9] = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
@@ -340,10 +353,10 @@ static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint, void *bu
}
-static INLINE void paint_pattern_buffer(struct vg_paint *paint, void *buffer)
+static INLINE void paint_pattern_buffer(struct vg_paint *paint,
+ const struct matrix *inv,
+ void *buffer)
{
- struct vg_context *ctx = paint->base.ctx;
-
VGfloat *map = (VGfloat *)buffer;
memcpy(map, paint->solid.color, 4 * sizeof(VGfloat));
@@ -353,17 +366,8 @@ static INLINE void paint_pattern_buffer(struct vg_paint *paint, void *buffer)
map[7] = paint->pattern.sampler_view->texture->height0;
{
struct matrix mat;
- memcpy(&mat, &ctx->state.vg.fill_paint_to_user_matrix,
- sizeof(struct matrix));
- matrix_invert(&mat);
- {
- struct matrix pm;
- memcpy(&pm, &ctx->state.vg.path_user_to_surface_matrix,
- sizeof(struct matrix));
- matrix_invert(&pm);
- matrix_mult(&pm, &mat);
- memcpy(&mat, &pm, sizeof(struct matrix));
- }
+
+ memcpy(&mat, inv, sizeof(*inv));
map[8] = mat.m[0]; map[9] = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
@@ -672,6 +676,34 @@ void paint_resolve_type(struct vg_paint *paint)
}
}
+VGboolean paint_is_degenerate(struct vg_paint *paint)
+{
+ VGboolean degen;
+ VGfloat *vals;
+
+
+ switch (paint->type) {
+ case VG_PAINT_TYPE_LINEAR_GRADIENT:
+ vals = paint->gradient.linear.coords;
+ /* two points are coincident */
+ degen = (floatsEqual(vals[0], vals[2]) &&
+ floatsEqual(vals[1], vals[3]));
+ break;
+ case VG_PAINT_TYPE_RADIAL_GRADIENT:
+ vals = paint->gradient.radial.vals;
+ /* radius <= 0 */
+ degen = (vals[4] <= 0.0f);
+ break;
+ case VG_PAINT_TYPE_COLOR:
+ case VG_PAINT_TYPE_PATTERN:
+ default:
+ degen = VG_FALSE;
+ break;
+ }
+
+ return degen;
+}
+
VGint paint_constant_buffer_size(struct vg_paint *paint)
{
switch(paint->type) {
@@ -695,6 +727,7 @@ VGint paint_constant_buffer_size(struct vg_paint *paint)
}
void paint_fill_constant_buffer(struct vg_paint *paint,
+ const struct matrix *mat,
void *buffer)
{
switch(paint->type) {
@@ -702,13 +735,13 @@ void paint_fill_constant_buffer(struct vg_paint *paint,
paint_color_buffer(paint, buffer);
break;
case VG_PAINT_TYPE_LINEAR_GRADIENT:
- paint_linear_gradient_buffer(paint, buffer);
+ paint_linear_gradient_buffer(paint, mat, buffer);
break;
case VG_PAINT_TYPE_RADIAL_GRADIENT:
- paint_radial_gradient_buffer(paint, buffer);
+ paint_radial_gradient_buffer(paint, mat, buffer);
break;
case VG_PAINT_TYPE_PATTERN:
- paint_pattern_buffer(paint, buffer);
+ paint_pattern_buffer(paint, mat, buffer);
break;
default:
diff --git a/src/gallium/state_trackers/vega/paint.h b/src/gallium/state_trackers/vega/paint.h
index 012cd3e5618..3de3bbe12ed 100644
--- a/src/gallium/state_trackers/vega/paint.h
+++ b/src/gallium/state_trackers/vega/paint.h
@@ -110,8 +110,12 @@ VGboolean paint_color_ramp_premultiplied(struct vg_paint *paint);
VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **samplers,
struct pipe_sampler_view **sampler_views);
+VGboolean paint_is_degenerate(struct vg_paint *paint);
+
VGint paint_constant_buffer_size(struct vg_paint *paint);
+
void paint_fill_constant_buffer(struct vg_paint *paint,
+ const struct matrix *mat,
void *buffer);
diff --git a/src/gallium/state_trackers/vega/path.c b/src/gallium/state_trackers/vega/path.c
index 05f8b0d9979..d7253befd03 100644
--- a/src/gallium/state_trackers/vega/path.c
+++ b/src/gallium/state_trackers/vega/path.c
@@ -207,13 +207,29 @@ struct path * path_create(VGPathDatatype dt, VGfloat scale, VGfloat bias,
return path;
}
+static void polygon_array_cleanup(struct polygon_array *polyarray)
+{
+ if (polyarray->array) {
+ VGint i;
+
+ for (i = 0; i < polyarray->array->num_elements; i++) {
+ struct polygon *p = ((struct polygon **) polyarray->array->data)[i];
+ polygon_destroy(p);
+ }
+
+ array_destroy(polyarray->array);
+ polyarray->array = NULL;
+ }
+}
+
void path_destroy(struct path *p)
{
vg_context_remove_object(vg_current_context(), VG_OBJECT_PATH, p);
array_destroy(p->segments);
array_destroy(p->control_points);
- array_destroy(p->fill_polys.polygon_array.array);
+
+ polygon_array_cleanup(&p->fill_polys.polygon_array);
if (p->stroked.path)
path_destroy(p->stroked.path);
@@ -302,7 +318,6 @@ static void convert_path(struct path *p,
}
}
-
static void polygon_array_calculate_bounds( struct polygon_array *polyarray )
{
struct array *polys = polyarray->array;
@@ -312,7 +327,15 @@ static void polygon_array_calculate_bounds( struct polygon_array *polyarray )
unsigned i;
assert(polys);
- assert(polys->num_elements);
+
+ if (!polys->num_elements) {
+ polyarray->min_x = 0.0f;
+ polyarray->min_y = 0.0f;
+ polyarray->max_x = 0.0f;
+ polyarray->max_y = 0.0f;
+ return;
+ }
+
polygon_bounding_rect((((struct polygon**)polys->data)[0]), bounds);
min_x = bounds[0];
min_y = bounds[1];
@@ -353,16 +376,17 @@ static struct polygon_array * path_get_fill_polygons(struct path *p, struct matr
return &p->fill_polys.polygon_array;
}
else {
- array_destroy( p->fill_polys.polygon_array.array );
- p->fill_polys.polygon_array.array = NULL;
+ polygon_array_cleanup(&p->fill_polys.polygon_array);
}
}
- array = array_create(sizeof(struct array*));
+ /* an array of pointers to polygons */
+ array = array_create(sizeof(struct polygon *));
sx = sy = px = py = ox = oy = 0.f;
- current = polygon_create(32);
+ if (p->num_segments)
+ current = polygon_create(32);
for (i = 0; i < p->num_segments; ++i) {
VGubyte segment = ((VGubyte*)(p->segments->data))[i];
@@ -1519,10 +1543,11 @@ struct path * path_create_stroke(struct path *p,
return stroker.base.path;
}
-void path_render(struct path *p, VGbitfield paintModes)
+void path_render(struct path *p, VGbitfield paintModes,
+ struct matrix *mat)
{
struct vg_context *ctx = vg_current_context();
- struct matrix *mat = &ctx->state.vg.path_user_to_surface_matrix;
+ struct matrix paint_matrix;
vg_validate_state(ctx);
@@ -1534,29 +1559,45 @@ void path_render(struct path *p, VGbitfield paintModes)
mat->m[3], mat->m[4], mat->m[5],
mat->m[6], mat->m[7], mat->m[8]);
#endif
- if (paintModes & VG_FILL_PATH) {
+ if ((paintModes & VG_FILL_PATH) &&
+ vg_get_paint_matrix(ctx,
+ &ctx->state.vg.fill_paint_to_user_matrix,
+ mat,
+ &paint_matrix)) {
/* First the fill */
+ shader_set_surface_matrix(ctx->shader, mat);
shader_set_paint(ctx->shader, ctx->state.vg.fill_paint);
+ shader_set_paint_matrix(ctx->shader, &paint_matrix);
shader_bind(ctx->shader);
- path_fill(p, mat);
+ path_fill(p);
}
- if (paintModes & VG_STROKE_PATH){
+ if ((paintModes & VG_STROKE_PATH) &&
+ vg_get_paint_matrix(ctx,
+ &ctx->state.vg.stroke_paint_to_user_matrix,
+ mat,
+ &paint_matrix)) {
/* 8.7.5: "line width less than or equal to 0 prevents stroking from
* taking place."*/
if (ctx->state.vg.stroke.line_width.f <= 0)
return;
+ shader_set_surface_matrix(ctx->shader, mat);
shader_set_paint(ctx->shader, ctx->state.vg.stroke_paint);
+ shader_set_paint_matrix(ctx->shader, &paint_matrix);
shader_bind(ctx->shader);
path_stroke(p);
}
}
-void path_fill(struct path *p, struct matrix *mat)
+void path_fill(struct path *p)
{
struct vg_context *ctx = vg_current_context();
+ struct matrix identity;
+
+ matrix_load_identity(&identity);
+
{
- struct polygon_array *polygon_array = path_get_fill_polygons(p, mat);
+ struct polygon_array *polygon_array = path_get_fill_polygons(p, &identity);
struct array *polys = polygon_array->array;
if (!polygon_array || !polys || !polys->num_elements) {
@@ -1569,7 +1610,6 @@ void path_fill(struct path *p, struct matrix *mat)
void path_stroke(struct path *p)
{
struct vg_context *ctx = vg_current_context();
- struct matrix *mat = &ctx->state.vg.path_user_to_surface_matrix;
VGFillRule old_fill = ctx->state.vg.fill_rule;
struct matrix identity;
struct path *stroke;
@@ -1579,7 +1619,7 @@ void path_stroke(struct path *p)
if (stroke && !path_is_empty(stroke)) {
ctx->state.vg.fill_rule = VG_NON_ZERO;
- path_fill(stroke, mat);
+ path_fill(stroke);
ctx->state.vg.fill_rule = old_fill;
}
diff --git a/src/gallium/state_trackers/vega/path.h b/src/gallium/state_trackers/vega/path.h
index e34538b7368..d84b1f083ce 100644
--- a/src/gallium/state_trackers/vega/path.h
+++ b/src/gallium/state_trackers/vega/path.h
@@ -104,8 +104,8 @@ VGboolean path_interpolate(struct path *dst,
VGfloat amount);
void path_clear(struct path *p, VGbitfield capabilities);
-void path_render(struct path *p, VGbitfield paintModes);
-void path_fill(struct path *p, struct matrix *mat);
+void path_render(struct path *p, VGbitfield paintModes, struct matrix *mat);
+void path_fill(struct path *p);
void path_stroke(struct path *p);
void path_move_to(struct path *p, float x, float y);
diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c
index ca8831064c9..a491de27fa6 100644
--- a/src/gallium/state_trackers/vega/polygon.c
+++ b/src/gallium/state_trackers/vega/polygon.c
@@ -244,24 +244,11 @@ VGboolean polygon_is_closed(struct polygon *p)
return floatsEqual(start[0], end[0]) && floatsEqual(start[1], end[1]);
}
-static void set_blend_for_fill(struct pipe_blend_state *blend)
-{
- memset(blend, 0, sizeof(struct pipe_blend_state));
- blend->rt[0].colormask = 0; /*disable colorwrites*/
-
- blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
- blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
-}
-
-static void draw_polygon(struct vg_context *ctx,
- struct polygon *poly)
+static void polygon_prepare_buffer(struct vg_context *ctx,
+ struct polygon *poly)
{
int vert_size;
struct pipe_context *pipe;
- struct pipe_vertex_buffer vbuffer;
- struct pipe_vertex_element velement;
vert_size = poly->num_verts * COMPONENTS * sizeof(float);
@@ -281,35 +268,15 @@ static void draw_polygon(struct vg_context *ctx,
PIPE_BIND_VERTEX_BUFFER);
poly->dirty = VG_FALSE;
}
-
-
- /* tell pipe about the vertex buffer */
- memset(&vbuffer, 0, sizeof(vbuffer));
- vbuffer.buffer = poly->vbuf;
- vbuffer.stride = COMPONENTS * sizeof(float); /* vertex size */
- vbuffer.buffer_offset = 0;
- vbuffer.max_index = poly->num_verts - 1;
- pipe->set_vertex_buffers(pipe, 1, &vbuffer);
-
- /* tell pipe about the vertex attributes */
- memset(&velement, 0, sizeof(velement));
- velement.src_offset = 0;
- velement.instance_divisor = 0;
- velement.vertex_buffer_index = 0;
- velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
- cso_set_vertex_elements(ctx->cso_context, 1, &velement);
-
- /* draw */
- util_draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, (uint) poly->num_verts);
}
void polygon_fill(struct polygon *poly, struct vg_context *ctx)
{
- struct pipe_depth_stencil_alpha_state dsa;
- struct pipe_stencil_ref sr;
- struct pipe_blend_state blend;
+ struct pipe_vertex_element velement;
+ struct pipe_vertex_buffer vbuffer;
VGfloat bounds[4];
VGfloat min_x, min_y, max_x, max_y;
+
assert(poly);
polygon_bounding_rect(poly, bounds);
min_x = bounds[0];
@@ -322,113 +289,42 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx)
min_x, min_y, max_x, max_y);
#endif
- set_blend_for_fill(&blend);
-
- memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
- memset(&sr, 0, sizeof(struct pipe_stencil_ref));
- /* only need a fixed 0. Rely on default or move it out at least? */
- cso_set_stencil_ref(ctx->cso_context, &sr);
-
- cso_save_blend(ctx->cso_context);
- cso_save_depth_stencil_alpha(ctx->cso_context);
-
- dsa.stencil[0].enabled = 1;
- if (ctx->state.vg.fill_rule == VG_EVEN_ODD) {
- dsa.stencil[0].writemask = 1;
- dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT;
- dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
- dsa.stencil[0].valuemask = ~0;
-
- cso_set_blend(ctx->cso_context, &blend);
- cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
- draw_polygon(ctx, poly);
- } else if (ctx->state.vg.fill_rule == VG_NON_ZERO) {
- struct pipe_screen *screen = ctx->pipe->screen;
-
- if (screen->get_param(screen, PIPE_CAP_TWO_SIDED_STENCIL)) {
- /* front */
- dsa.stencil[0].writemask = ~0;
- dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
- dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
- dsa.stencil[0].valuemask = ~0;
-
- /* back */
- dsa.stencil[1].enabled = 1;
- dsa.stencil[1].writemask = ~0;
- dsa.stencil[1].fail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[1].zfail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
- dsa.stencil[1].func = PIPE_FUNC_ALWAYS;
- dsa.stencil[1].valuemask = ~0;
-
- cso_set_blend(ctx->cso_context, &blend);
- cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
- draw_polygon(ctx, poly);
- } else {
- struct pipe_rasterizer_state raster;
-
- memcpy(&raster, &ctx->state.g3d.rasterizer, sizeof(struct pipe_rasterizer_state));
-
- cso_save_rasterizer(ctx->cso_context);
- dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
- dsa.stencil[0].valuemask = ~0;
-
- raster.cull_face = PIPE_FACE_BACK;
- dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
-
- cso_set_blend(ctx->cso_context, &blend);
- cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
- cso_set_rasterizer(ctx->cso_context, &raster);
- draw_polygon(ctx, poly);
-
- raster.cull_face = PIPE_FACE_FRONT;
- dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
- cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
- cso_set_rasterizer(ctx->cso_context, &raster);
- draw_polygon(ctx, poly);
-
- cso_restore_rasterizer(ctx->cso_context);
- }
- }
+ polygon_prepare_buffer(ctx, poly);
+
+ /* tell renderer about the vertex attributes */
+ memset(&velement, 0, sizeof(velement));
+ velement.src_offset = 0;
+ velement.instance_divisor = 0;
+ velement.vertex_buffer_index = 0;
+ velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* tell renderer about the vertex buffer */
+ memset(&vbuffer, 0, sizeof(vbuffer));
+ vbuffer.buffer = poly->vbuf;
+ vbuffer.stride = COMPONENTS * sizeof(float); /* vertex size */
+ vbuffer.buffer_offset = 0;
+ vbuffer.max_index = poly->num_verts - 1;
+
+ renderer_polygon_stencil_begin(ctx->renderer,
+ &velement, ctx->state.vg.fill_rule, VG_FALSE);
+ renderer_polygon_stencil(ctx->renderer, &vbuffer,
+ PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts);
+ renderer_polygon_stencil_end(ctx->renderer);
- /* restore color writes */
- cso_restore_blend(ctx->cso_context);
- /* setup stencil ops */
- dsa.stencil[0].func = PIPE_FUNC_NOTEQUAL;
- dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
- dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
- dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
- dsa.stencil[0].valuemask = dsa.stencil[0].writemask;
- dsa.stencil[1].enabled = 0;
- memcpy(&dsa.depth, &ctx->state.g3d.dsa.depth,
- sizeof(struct pipe_depth_state));
- cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
-
- /* render the quad to propagate the rendering from stencil */
- renderer_draw_quad(ctx->renderer, min_x, min_y,
- max_x, max_y, 0.0f/*depth should be disabled*/);
-
- cso_restore_depth_stencil_alpha(ctx->cso_context);
+ renderer_polygon_fill_begin(ctx->renderer, VG_FALSE);
+ renderer_polygon_fill(ctx->renderer, min_x, min_y, max_x, max_y);
+ renderer_polygon_fill_end(ctx->renderer);
}
void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx)
{
struct array *polys = polyarray->array;
- struct pipe_depth_stencil_alpha_state dsa;
- struct pipe_stencil_ref sr;
- struct pipe_blend_state blend;
VGfloat min_x = polyarray->min_x;
VGfloat min_y = polyarray->min_y;
VGfloat max_x = polyarray->max_x;
VGfloat max_y = polyarray->max_y;
+ struct pipe_vertex_element velement;
+ struct pipe_vertex_buffer vbuffer;
VGint i;
@@ -438,111 +334,35 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx)
min_x, min_y, max_x, max_y);
#endif
- set_blend_for_fill(&blend);
-
- memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
- memset(&sr, 0, sizeof(struct pipe_stencil_ref));
- /* only need a fixed 0. Rely on default or move it out at least? */
- cso_set_stencil_ref(ctx->cso_context, &sr);
-
- cso_save_blend(ctx->cso_context);
- cso_save_depth_stencil_alpha(ctx->cso_context);
-
- dsa.stencil[0].enabled = 1;
- if (ctx->state.vg.fill_rule == VG_EVEN_ODD) {
- dsa.stencil[0].writemask = 1;
- dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT;
- dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
- dsa.stencil[0].valuemask = ~0;
-
- cso_set_blend(ctx->cso_context, &blend);
- cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
- for (i = 0; i < polys->num_elements; ++i) {
- struct polygon *poly = (((struct polygon**)polys->data)[i]);
- draw_polygon(ctx, poly);
- }
- } else if (ctx->state.vg.fill_rule == VG_NON_ZERO) {
- struct pipe_screen *screen = ctx->pipe->screen;
-
- if (screen->get_param(screen, PIPE_CAP_TWO_SIDED_STENCIL)) {
- /* front */
- dsa.stencil[0].writemask = ~0;
- dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
- dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
- dsa.stencil[0].valuemask = ~0;
-
- /* back */
- dsa.stencil[1].enabled = 1;
- dsa.stencil[1].writemask = ~0;
- dsa.stencil[1].fail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[1].zfail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
- dsa.stencil[1].func = PIPE_FUNC_ALWAYS;
- dsa.stencil[1].valuemask = ~0;
-
- cso_set_blend(ctx->cso_context, &blend);
- cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
- for (i = 0; i < polys->num_elements; ++i) {
- struct polygon *poly = (((struct polygon**)polys->data)[i]);
- draw_polygon(ctx, poly);
- }
- } else {
- struct pipe_rasterizer_state raster;
-
- memcpy(&raster, &ctx->state.g3d.rasterizer, sizeof(struct pipe_rasterizer_state));
-
- cso_save_rasterizer(ctx->cso_context);
- dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
- dsa.stencil[0].valuemask = ~0;
-
- raster.cull_face = PIPE_FACE_BACK;
- dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
-
- cso_set_blend(ctx->cso_context, &blend);
- cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
- cso_set_rasterizer(ctx->cso_context, &raster);
- for (i = 0; i < polys->num_elements; ++i) {
- struct polygon *poly = (((struct polygon**)polys->data)[i]);
- draw_polygon(ctx, poly);
- }
-
- raster.cull_face = PIPE_FACE_FRONT;
- dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
- dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
- cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
- cso_set_rasterizer(ctx->cso_context, &raster);
- for (i = 0; i < polys->num_elements; ++i) {
- struct polygon *poly = (((struct polygon**)polys->data)[i]);
- draw_polygon(ctx, poly);
- }
-
- cso_restore_rasterizer(ctx->cso_context);
- }
+ /* tell renderer about the vertex attributes */
+ memset(&velement, 0, sizeof(velement));
+ velement.src_offset = 0;
+ velement.instance_divisor = 0;
+ velement.vertex_buffer_index = 0;
+ velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* tell renderer about the vertex buffer */
+ memset(&vbuffer, 0, sizeof(vbuffer));
+ vbuffer.stride = COMPONENTS * sizeof(float); /* vertex size */
+ vbuffer.buffer_offset = 0;
+
+ /* prepare the stencil buffer */
+ renderer_polygon_stencil_begin(ctx->renderer,
+ &velement, ctx->state.vg.fill_rule, VG_FALSE);
+ for (i = 0; i < polys->num_elements; ++i) {
+ struct polygon *poly = (((struct polygon**)polys->data)[i]);
+
+ polygon_prepare_buffer(ctx, poly);
+ vbuffer.buffer = poly->vbuf;
+ vbuffer.max_index = poly->num_verts - 1;
+
+ renderer_polygon_stencil(ctx->renderer, &vbuffer,
+ PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts);
}
+ renderer_polygon_stencil_end(ctx->renderer);
- /* restore color writes */
- cso_restore_blend(ctx->cso_context);
- /* setup stencil ops */
- dsa.stencil[0].func = PIPE_FUNC_NOTEQUAL;
- dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
- dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
- dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
- dsa.stencil[0].valuemask = dsa.stencil[0].writemask;
- dsa.stencil[1].enabled = 0;
- memcpy(&dsa.depth, &ctx->state.g3d.dsa.depth,
- sizeof(struct pipe_depth_state));
- cso_set_depth_stencil_alpha(ctx->cso_context, &dsa);
-
- /* render the quad to propagate the rendering from stencil */
- renderer_draw_quad(ctx->renderer, min_x, min_y,
- max_x, max_y, 0.0f/*depth should be disabled*/);
-
- cso_restore_depth_stencil_alpha(ctx->cso_context);
+ /* fill it */
+ renderer_polygon_fill_begin(ctx->renderer, VG_FALSE);
+ renderer_polygon_fill(ctx->renderer, min_x, min_y, max_x, max_y);
+ renderer_polygon_fill_end(ctx->renderer);
}
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index c6f5f7a05b8..7871c516c41 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright 2009 VMware, Inc. All Rights Reserved.
+ * Copyright 2010 LunarG, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
@@ -27,6 +28,7 @@
#include "renderer.h"
#include "vg_context.h"
+#include "image.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
@@ -38,364 +40,1382 @@
#include "util/u_simple_shaders.h"
#include "util/u_memory.h"
#include "util/u_sampler.h"
+#include "util/u_surface.h"
+#include "util/u_math.h"
+#include "util/u_format.h"
#include "cso_cache/cso_context.h"
+#include "tgsi/tgsi_ureg.h"
+
+typedef enum {
+ RENDERER_STATE_INIT,
+ RENDERER_STATE_COPY,
+ RENDERER_STATE_DRAWTEX,
+ RENDERER_STATE_SCISSOR,
+ RENDERER_STATE_CLEAR,
+ RENDERER_STATE_FILTER,
+ RENDERER_STATE_POLYGON_STENCIL,
+ RENDERER_STATE_POLYGON_FILL,
+ NUM_RENDERER_STATES
+} RendererState;
+
+typedef enum {
+ RENDERER_VS_PLAIN,
+ RENDERER_VS_COLOR,
+ RENDERER_VS_TEXTURE,
+ NUM_RENDERER_VS
+} RendererVs;
+
+typedef enum {
+ RENDERER_FS_COLOR,
+ RENDERER_FS_TEXTURE,
+ RENDERER_FS_SCISSOR,
+ RENDERER_FS_WHITE,
+ NUM_RENDERER_FS
+} RendererFs;
struct renderer {
struct pipe_context *pipe;
- struct vg_context *owner;
-
struct cso_context *cso;
- void *fs;
+ VGbitfield dirty;
+ struct {
+ struct pipe_rasterizer_state rasterizer;
+ struct pipe_depth_stencil_alpha_state dsa;
+ struct pipe_framebuffer_state fb;
+ } g3d;
+ struct matrix projection;
+
+ struct matrix mvp;
+ struct pipe_resource *vs_cbuf;
+
+ struct pipe_resource *fs_cbuf;
+ VGfloat fs_cbuf_data[32];
+ VGint fs_cbuf_len;
+ struct pipe_vertex_element velems[2];
VGfloat vertices[4][2][4];
+
+ void *cached_vs[NUM_RENDERER_VS];
+ void *cached_fs[NUM_RENDERER_FS];
+
+ RendererState state;
+
+ /* state data */
+ union {
+ struct {
+ VGint tex_width;
+ VGint tex_height;
+ } copy;
+
+ struct {
+ VGint tex_width;
+ VGint tex_height;
+ } drawtex;
+
+ struct {
+ VGboolean restore_dsa;
+ } scissor;
+
+ struct {
+ VGboolean use_sampler;
+ VGint tex_width, tex_height;
+ } filter;
+
+ struct {
+ struct pipe_depth_stencil_alpha_state dsa;
+ VGboolean manual_two_sides;
+ VGboolean restore_dsa;
+ } polygon_stencil;
+ } u;
};
-static void setup_shaders(struct renderer *ctx)
+/**
+ * Return VG_TRUE if the renderer can use the resource as the asked bindings.
+ */
+static VGboolean renderer_can_support(struct renderer *renderer,
+ struct pipe_resource *res,
+ unsigned bindings)
{
- struct pipe_context *pipe = ctx->pipe;
- /* fragment shader */
- ctx->fs = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
- TGSI_INTERPOLATE_LINEAR);
-}
-
-static struct pipe_resource *
-setup_vertex_data(struct renderer *ctx,
- float x0, float y0, float x1, float y1, float z)
-{
- ctx->vertices[0][0][0] = x0;
- ctx->vertices[0][0][1] = y0;
- ctx->vertices[0][0][2] = z;
- ctx->vertices[0][1][0] = 0.0f; /*s*/
- ctx->vertices[0][1][1] = 0.0f; /*t*/
-
- ctx->vertices[1][0][0] = x1;
- ctx->vertices[1][0][1] = y0;
- ctx->vertices[1][0][2] = z;
- ctx->vertices[1][1][0] = 1.0f; /*s*/
- ctx->vertices[1][1][1] = 0.0f; /*t*/
-
- ctx->vertices[2][0][0] = x1;
- ctx->vertices[2][0][1] = y1;
- ctx->vertices[2][0][2] = z;
- ctx->vertices[2][1][0] = 1.0f;
- ctx->vertices[2][1][1] = 1.0f;
-
- ctx->vertices[3][0][0] = x0;
- ctx->vertices[3][0][1] = y1;
- ctx->vertices[3][0][2] = z;
- ctx->vertices[3][1][0] = 0.0f;
- ctx->vertices[3][1][1] = 1.0f;
-
- return pipe_user_buffer_create( ctx->pipe->screen,
- ctx->vertices,
- sizeof(ctx->vertices),
- PIPE_BIND_VERTEX_BUFFER);
-}
-
-static struct pipe_resource *
-setup_vertex_data_tex(struct renderer *ctx,
- float x0, float y0, float x1, float y1,
- float s0, float t0, float s1, float t1,
- float z)
-{
- ctx->vertices[0][0][0] = x0;
- ctx->vertices[0][0][1] = y0;
- ctx->vertices[0][0][2] = z;
- ctx->vertices[0][1][0] = s0; /*s*/
- ctx->vertices[0][1][1] = t0; /*t*/
-
- ctx->vertices[1][0][0] = x1;
- ctx->vertices[1][0][1] = y0;
- ctx->vertices[1][0][2] = z;
- ctx->vertices[1][1][0] = s1; /*s*/
- ctx->vertices[1][1][1] = t0; /*t*/
-
- ctx->vertices[2][0][0] = x1;
- ctx->vertices[2][0][1] = y1;
- ctx->vertices[2][0][2] = z;
- ctx->vertices[2][1][0] = s1;
- ctx->vertices[2][1][1] = t1;
-
- ctx->vertices[3][0][0] = x0;
- ctx->vertices[3][0][1] = y1;
- ctx->vertices[3][0][2] = z;
- ctx->vertices[3][1][0] = s0;
- ctx->vertices[3][1][1] = t1;
-
- return pipe_user_buffer_create( ctx->pipe->screen,
- ctx->vertices,
- sizeof(ctx->vertices),
- PIPE_BIND_VERTEX_BUFFER);
-}
-
-
-static struct pipe_resource *
-setup_vertex_data_qtex(struct renderer *ctx,
- float x0, float y0, float x1, float y1,
- float x2, float y2, float x3, float y3,
- float s0, float t0, float s1, float t1,
- float z)
-{
- ctx->vertices[0][0][0] = x0;
- ctx->vertices[0][0][1] = y0;
- ctx->vertices[0][0][2] = z;
- ctx->vertices[0][1][0] = s0; /*s*/
- ctx->vertices[0][1][1] = t0; /*t*/
-
- ctx->vertices[1][0][0] = x1;
- ctx->vertices[1][0][1] = y1;
- ctx->vertices[1][0][2] = z;
- ctx->vertices[1][1][0] = s1; /*s*/
- ctx->vertices[1][1][1] = t0; /*t*/
-
- ctx->vertices[2][0][0] = x2;
- ctx->vertices[2][0][1] = y2;
- ctx->vertices[2][0][2] = z;
- ctx->vertices[2][1][0] = s1;
- ctx->vertices[2][1][1] = t1;
-
- ctx->vertices[3][0][0] = x3;
- ctx->vertices[3][0][1] = y3;
- ctx->vertices[3][0][2] = z;
- ctx->vertices[3][1][0] = s0;
- ctx->vertices[3][1][1] = t1;
-
- return pipe_user_buffer_create( ctx->pipe->screen,
- ctx->vertices,
- sizeof(ctx->vertices),
- PIPE_BIND_VERTEX_BUFFER);
+ struct pipe_screen *screen = renderer->pipe->screen;
+
+ return screen->is_format_supported(screen,
+ res->format, res->target, 0, bindings, 0);
}
-struct renderer * renderer_create(struct vg_context *owner)
+/**
+ * Set the model-view-projection matrix used by vertex shaders.
+ */
+static void renderer_set_mvp(struct renderer *renderer,
+ const struct matrix *mvp)
{
+ struct matrix *cur = &renderer->mvp;
+ struct pipe_resource *cbuf;
+ VGfloat consts[3][4];
VGint i;
- struct renderer *renderer = CALLOC_STRUCT(renderer);
- if (!renderer)
+ /* projection only */
+ if (!mvp)
+ mvp = &renderer->projection;
+
+ /* re-upload only if necessary */
+ if (memcmp(cur, mvp, sizeof(*mvp)) == 0)
+ return;
+
+ /* 3x3 matrix to 3 constant vectors (no Z) */
+ for (i = 0; i < 3; i++) {
+ consts[i][0] = mvp->m[i + 0];
+ consts[i][1] = mvp->m[i + 3];
+ consts[i][2] = 0.0f;
+ consts[i][3] = mvp->m[i + 6];
+ }
+
+ cbuf = renderer->vs_cbuf;
+ pipe_resource_reference(&cbuf, NULL);
+ cbuf = pipe_buffer_create(renderer->pipe->screen,
+ PIPE_BIND_CONSTANT_BUFFER,
+ sizeof(consts));
+ if (cbuf) {
+ pipe_buffer_write(renderer->pipe, cbuf,
+ 0, sizeof(consts), consts);
+ }
+ renderer->pipe->set_constant_buffer(renderer->pipe,
+ PIPE_SHADER_VERTEX, 0, cbuf);
+
+ memcpy(cur, mvp, sizeof(*mvp));
+ renderer->vs_cbuf = cbuf;
+}
+
+/**
+ * Create a simple vertex shader that passes through position and the given
+ * attribute.
+ */
+static void *create_passthrough_vs(struct pipe_context *pipe, int semantic_name)
+{
+ struct ureg_program *ureg;
+ struct ureg_src src[2], constants[3];
+ struct ureg_dst dst[2], tmp;
+ int i;
+
+ ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
+ if (!ureg)
return NULL;
- renderer->owner = owner;
- renderer->pipe = owner->pipe;
- renderer->cso = owner->cso_context;
+ /* position is in user coordinates */
+ src[0] = ureg_DECL_vs_input(ureg, 0);
+ dst[0] = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
+ tmp = ureg_DECL_temporary(ureg);
+ for (i = 0; i < Elements(constants); i++)
+ constants[i] = ureg_DECL_constant(ureg, i);
+
+ /* transform to clipped coordinates */
+ ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), src[0], constants[0]);
+ ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Y), src[0], constants[1]);
+ ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Z), src[0]);
+ ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_W), src[0], constants[2]);
+ ureg_MOV(ureg, dst[0], ureg_src(tmp));
+
+ if (semantic_name >= 0) {
+ src[1] = ureg_DECL_vs_input(ureg, 1);
+ dst[1] = ureg_DECL_output(ureg, semantic_name, 0);
+ ureg_MOV(ureg, dst[1], src[1]);
+ }
- setup_shaders(renderer);
+ ureg_END(ureg);
- /* init vertex data that doesn't change */
- for (i = 0; i < 4; i++) {
- renderer->vertices[i][0][3] = 1.0f; /* w */
- renderer->vertices[i][1][2] = 0.0f; /* r */
- renderer->vertices[i][1][3] = 1.0f; /* q */
+ return ureg_create_shader_and_destroy(ureg, pipe);
+}
+
+/**
+ * Set renderer vertex shader.
+ *
+ * This function modifies vertex_shader state.
+ */
+static void renderer_set_vs(struct renderer *r, RendererVs id)
+{
+ /* create as needed */
+ if (!r->cached_vs[id]) {
+ int semantic_name = -1;
+
+ switch (id) {
+ case RENDERER_VS_PLAIN:
+ break;
+ case RENDERER_VS_COLOR:
+ semantic_name = TGSI_SEMANTIC_COLOR;
+ break;
+ case RENDERER_VS_TEXTURE:
+ semantic_name = TGSI_SEMANTIC_GENERIC;
+ break;
+ default:
+ assert(!"Unknown renderer vs id");
+ break;
+ }
+
+ r->cached_vs[id] = create_passthrough_vs(r->pipe, semantic_name);
}
- return renderer;
+ cso_set_vertex_shader_handle(r->cso, r->cached_vs[id]);
}
-void renderer_destroy(struct renderer *ctx)
+/**
+ * Create a simple fragment shader that sets the depth to 0.0f.
+ */
+static void *create_scissor_fs(struct pipe_context *pipe)
+{
+ struct ureg_program *ureg;
+ struct ureg_dst out;
+ struct ureg_src imm;
+
+ ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ out = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
+ imm = ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 0.0f);
+
+ ureg_MOV(ureg, ureg_writemask(out, TGSI_WRITEMASK_Z), imm);
+ ureg_END(ureg);
+
+ return ureg_create_shader_and_destroy(ureg, pipe);
+}
+
+/**
+ * Create a simple fragment shader that sets the color to white.
+ */
+static void *create_white_fs(struct pipe_context *pipe)
+{
+ struct ureg_program *ureg;
+ struct ureg_dst out;
+ struct ureg_src imm;
+
+ ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
+ imm = ureg_imm4f(ureg, 1.0f, 1.0f, 1.0f, 1.0f);
+
+ ureg_MOV(ureg, out, imm);
+ ureg_END(ureg);
+
+ return ureg_create_shader_and_destroy(ureg, pipe);
+}
+
+/**
+ * Set renderer fragment shader.
+ *
+ * This function modifies fragment_shader state.
+ */
+static void renderer_set_fs(struct renderer *r, RendererFs id)
{
-#if 0
- if (ctx->fs) {
- cso_delete_fragment_shader(ctx->cso, ctx->fs);
- ctx->fs = NULL;
+ /* create as needed */
+ if (!r->cached_fs[id]) {
+ void *fs = NULL;
+
+ switch (id) {
+ case RENDERER_FS_COLOR:
+ fs = util_make_fragment_passthrough_shader(r->pipe);
+ break;
+ case RENDERER_FS_TEXTURE:
+ fs = util_make_fragment_tex_shader(r->pipe,
+ TGSI_TEXTURE_2D, TGSI_INTERPOLATE_LINEAR);
+ break;
+ case RENDERER_FS_SCISSOR:
+ fs = create_scissor_fs(r->pipe);
+ break;
+ case RENDERER_FS_WHITE:
+ fs = create_white_fs(r->pipe);
+ break;
+ default:
+ assert(!"Unknown renderer fs id");
+ break;
+ }
+
+ r->cached_fs[id] = fs;
}
-#endif
- FREE(ctx);
+
+ cso_set_fragment_shader_handle(r->cso, r->cached_fs[id]);
}
-void renderer_draw_quad(struct renderer *r,
- VGfloat x1, VGfloat y1,
- VGfloat x2, VGfloat y2,
- VGfloat depth)
+typedef enum {
+ VEGA_Y0_TOP,
+ VEGA_Y0_BOTTOM
+} VegaOrientation;
+
+static void vg_set_viewport(struct renderer *r,
+ VegaOrientation orientation)
{
- struct pipe_resource *buf;
+ const struct pipe_framebuffer_state *fb = &r->g3d.fb;
+ struct pipe_viewport_state viewport;
+ VGfloat y_scale = (orientation == VEGA_Y0_BOTTOM) ? -2.f : 2.f;
+
+ viewport.scale[0] = fb->width / 2.f;
+ viewport.scale[1] = fb->height / y_scale;
+ viewport.scale[2] = 1.0;
+ viewport.scale[3] = 1.0;
+ viewport.translate[0] = fb->width / 2.f;
+ viewport.translate[1] = fb->height / 2.f;
+ viewport.translate[2] = 0.0;
+ viewport.translate[3] = 0.0;
+
+ cso_set_viewport(r->cso, &viewport);
+}
+
+/**
+ * Set renderer target.
+ *
+ * This function modifies framebuffer and viewport states.
+ */
+static void renderer_set_target(struct renderer *r,
+ struct pipe_surface *cbuf,
+ struct pipe_surface *zsbuf,
+ VGboolean y0_top)
+{
+ struct pipe_framebuffer_state fb;
+
+ memset(&fb, 0, sizeof(fb));
+ fb.width = cbuf->width;
+ fb.height = cbuf->height;
+ fb.cbufs[0] = cbuf;
+ fb.nr_cbufs = 1;
+ fb.zsbuf = zsbuf;
+ cso_set_framebuffer(r->cso, &fb);
+
+ vg_set_viewport(r, (y0_top) ? VEGA_Y0_TOP : VEGA_Y0_BOTTOM);
+}
+
+/**
+ * Set renderer blend state. Blending is disabled.
+ *
+ * This function modifies blend state.
+ */
+static void renderer_set_blend(struct renderer *r,
+ VGbitfield channel_mask)
+{
+ struct pipe_blend_state blend;
+
+ memset(&blend, 0, sizeof(blend));
+
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+
+ if (channel_mask & VG_RED)
+ blend.rt[0].colormask |= PIPE_MASK_R;
+ if (channel_mask & VG_GREEN)
+ blend.rt[0].colormask |= PIPE_MASK_G;
+ if (channel_mask & VG_BLUE)
+ blend.rt[0].colormask |= PIPE_MASK_B;
+ if (channel_mask & VG_ALPHA)
+ blend.rt[0].colormask |= PIPE_MASK_A;
+
+ cso_set_blend(r->cso, &blend);
+}
+
+/**
+ * Set renderer sampler and view states.
+ *
+ * This function modifies samplers and fragment_sampler_views states.
+ */
+static void renderer_set_samplers(struct renderer *r,
+ uint num_views,
+ struct pipe_sampler_view **views)
+{
+ struct pipe_sampler_state sampler;
+ unsigned tex_filter = PIPE_TEX_FILTER_NEAREST;
+ unsigned tex_wrap = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ uint i;
+
+ memset(&sampler, 0, sizeof(sampler));
+
+ sampler.min_img_filter = tex_filter;
+ sampler.mag_img_filter = tex_filter;
+ sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+
+ sampler.wrap_s = tex_wrap;
+ sampler.wrap_t = tex_wrap;
+ sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+
+ sampler.normalized_coords = 1;
+
+ /* set samplers */
+ for (i = 0; i < num_views; i++)
+ cso_single_sampler(r->cso, i, &sampler);
+ cso_single_sampler_done(r->cso);
+
+ /* set views */
+ cso_set_fragment_sampler_views(r->cso, num_views, views);
+}
+
+/**
+ * Set custom renderer fragment shader, and optionally set samplers and views
+ * and upload the fragment constant buffer.
+ *
+ * This function modifies fragment_shader, samplers and fragment_sampler_views
+ * states.
+ */
+static void renderer_set_custom_fs(struct renderer *renderer,
+ void *fs,
+ const struct pipe_sampler_state **samplers,
+ struct pipe_sampler_view **views,
+ VGint num_samplers,
+ const void *const_buffer,
+ VGint const_buffer_len)
+{
+ cso_set_fragment_shader_handle(renderer->cso, fs);
+
+ /* set samplers and views */
+ if (num_samplers) {
+ cso_set_samplers(renderer->cso, num_samplers, samplers);
+ cso_set_fragment_sampler_views(renderer->cso, num_samplers, views);
+ }
+
+ /* upload fs constant buffer */
+ if (const_buffer_len) {
+ struct pipe_resource *cbuf = renderer->fs_cbuf;
+
+ if (!cbuf || renderer->fs_cbuf_len != const_buffer_len ||
+ memcmp(renderer->fs_cbuf_data, const_buffer, const_buffer_len)) {
+ pipe_resource_reference(&cbuf, NULL);
+
+ cbuf = pipe_buffer_create(renderer->pipe->screen,
+ PIPE_BIND_CONSTANT_BUFFER, const_buffer_len);
+ pipe_buffer_write(renderer->pipe, cbuf, 0,
+ const_buffer_len, const_buffer);
+ renderer->pipe->set_constant_buffer(renderer->pipe,
+ PIPE_SHADER_FRAGMENT, 0, cbuf);
+
+ renderer->fs_cbuf = cbuf;
+ if (const_buffer_len <= sizeof(renderer->fs_cbuf_data)) {
+ memcpy(renderer->fs_cbuf_data, const_buffer, const_buffer_len);
+ renderer->fs_cbuf_len = const_buffer_len;
+ }
+ else {
+ renderer->fs_cbuf_len = 0;
+ }
+ }
+ }
+}
+
+/**
+ * Setup renderer quad position.
+ */
+static void renderer_quad_pos(struct renderer *r,
+ VGfloat x0, VGfloat y0,
+ VGfloat x1, VGfloat y1,
+ VGboolean scissor)
+{
+ VGfloat z;
+
+ /* the depth test is used for scissoring */
+ z = (scissor) ? 0.0f : 1.0f;
+
+ /* positions */
+ r->vertices[0][0][0] = x0;
+ r->vertices[0][0][1] = y0;
+ r->vertices[0][0][2] = z;
- buf = setup_vertex_data(r, x1, y1, x2, y2, depth);
+ r->vertices[1][0][0] = x1;
+ r->vertices[1][0][1] = y0;
+ r->vertices[1][0][2] = z;
+ r->vertices[2][0][0] = x1;
+ r->vertices[2][0][1] = y1;
+ r->vertices[2][0][2] = z;
+
+ r->vertices[3][0][0] = x0;
+ r->vertices[3][0][1] = y1;
+ r->vertices[3][0][2] = z;
+}
+
+/**
+ * Setup renderer quad texture coordinates.
+ */
+static void renderer_quad_texcoord(struct renderer *r,
+ VGfloat x0, VGfloat y0,
+ VGfloat x1, VGfloat y1,
+ VGint tex_width, VGint tex_height)
+{
+ VGfloat s0, t0, s1, t1, r0, q0;
+ VGint i;
+
+ s0 = x0 / tex_width;
+ s1 = x1 / tex_width;
+ t0 = y0 / tex_height;
+ t1 = y1 / tex_height;
+ r0 = 0.0f;
+ q0 = 1.0f;
+
+ /* texcoords */
+ r->vertices[0][1][0] = s0;
+ r->vertices[0][1][1] = t0;
+
+ r->vertices[1][1][0] = s1;
+ r->vertices[1][1][1] = t0;
+
+ r->vertices[2][1][0] = s1;
+ r->vertices[2][1][1] = t1;
+
+ r->vertices[3][1][0] = s0;
+ r->vertices[3][1][1] = t1;
+
+ for (i = 0; i < 4; i++) {
+ r->vertices[i][1][2] = r0;
+ r->vertices[i][1][3] = q0;
+ }
+}
+
+/**
+ * Draw renderer quad.
+ */
+static void renderer_quad_draw(struct renderer *r)
+{
+ struct pipe_resource *buf;
+
+ buf = pipe_user_buffer_create(r->pipe->screen,
+ r->vertices,
+ sizeof(r->vertices),
+ PIPE_BIND_VERTEX_BUFFER);
if (buf) {
- cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(r->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */
+ Elements(r->vertices), /* verts */
+ Elements(r->vertices[0])); /* attribs/vert */
- pipe_resource_reference( &buf,
- NULL );
+ pipe_resource_reference(&buf, NULL);
}
}
-void renderer_draw_texture(struct renderer *r,
- struct pipe_resource *tex,
- VGfloat x1offset, VGfloat y1offset,
- VGfloat x2offset, VGfloat y2offset,
- VGfloat x1, VGfloat y1,
- VGfloat x2, VGfloat y2)
+/**
+ * Prepare the renderer for copying.
+ */
+VGboolean renderer_copy_begin(struct renderer *renderer,
+ struct pipe_surface *dst,
+ VGboolean y0_top,
+ struct pipe_sampler_view *src)
{
- struct pipe_context *pipe = r->pipe;
- struct pipe_resource *buf;
- VGfloat s0, t0, s1, t1;
+ assert(renderer->state == RENDERER_STATE_INIT);
- assert(tex->width0 != 0);
- assert(tex->height0 != 0);
+ /* sanity check */
+ if (!renderer_can_support(renderer,
+ dst->texture, PIPE_BIND_RENDER_TARGET) ||
+ !renderer_can_support(renderer,
+ src->texture, PIPE_BIND_SAMPLER_VIEW))
+ return VG_FALSE;
- s0 = x1offset / tex->width0;
- s1 = x2offset / tex->width0;
- t0 = y1offset / tex->height0;
- t1 = y2offset / tex->height0;
+ cso_save_framebuffer(renderer->cso);
+ cso_save_viewport(renderer->cso);
+ cso_save_blend(renderer->cso);
+ cso_save_samplers(renderer->cso);
+ cso_save_fragment_sampler_views(renderer->cso);
+ cso_save_fragment_shader(renderer->cso);
+ cso_save_vertex_shader(renderer->cso);
- cso_save_vertex_shader(r->cso);
- /* shaders */
- cso_set_vertex_shader_handle(r->cso, vg_texture_vs(r->owner));
+ renderer_set_target(renderer, dst, NULL, y0_top);
- /* draw quad */
- buf = setup_vertex_data_tex(r, x1, y1, x2, y2,
- s0, t0, s1, t1, 0.0f);
+ renderer_set_blend(renderer, ~0);
+ renderer_set_samplers(renderer, 1, &src);
- if (buf) {
- cso_set_vertex_elements(r->cso, 2, r->owner->velems);
- util_draw_vertex_buffer(pipe, buf, 0,
- PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */
-
- pipe_resource_reference( &buf,
- NULL );
+ renderer_set_fs(renderer, RENDERER_FS_TEXTURE);
+ renderer_set_vs(renderer, RENDERER_VS_TEXTURE);
+
+ renderer_set_mvp(renderer, NULL);
+
+ /* remember the texture size */
+ renderer->u.copy.tex_width = src->texture->width0;
+ renderer->u.copy.tex_height = src->texture->height0;
+ renderer->state = RENDERER_STATE_COPY;
+
+ return VG_TRUE;
+}
+
+/**
+ * Draw into the destination rectangle given by (x, y, w, h). The texture is
+ * sampled from within the rectangle given by (sx, sy, sw, sh).
+ *
+ * The coordinates are in surface coordinates.
+ */
+void renderer_copy(struct renderer *renderer,
+ VGint x, VGint y, VGint w, VGint h,
+ VGint sx, VGint sy, VGint sw, VGint sh)
+{
+ assert(renderer->state == RENDERER_STATE_COPY);
+
+ /* there is no depth buffer for scissoring anyway */
+ renderer_quad_pos(renderer, x, y, x + w, y + h, VG_FALSE);
+ renderer_quad_texcoord(renderer, sx, sy, sx + sw, sy + sh,
+ renderer->u.copy.tex_width,
+ renderer->u.copy.tex_height);
+
+ renderer_quad_draw(renderer);
+}
+
+/**
+ * End copying and restore the states.
+ */
+void renderer_copy_end(struct renderer *renderer)
+{
+ assert(renderer->state == RENDERER_STATE_COPY);
+
+ cso_restore_framebuffer(renderer->cso);
+ cso_restore_viewport(renderer->cso);
+ cso_restore_blend(renderer->cso);
+ cso_restore_samplers(renderer->cso);
+ cso_restore_fragment_sampler_views(renderer->cso);
+ cso_restore_fragment_shader(renderer->cso);
+ cso_restore_vertex_shader(renderer->cso);
+
+ renderer->state = RENDERER_STATE_INIT;
+}
+
+/**
+ * Prepare the renderer for textured drawing.
+ */
+VGboolean renderer_drawtex_begin(struct renderer *renderer,
+ struct pipe_sampler_view *src)
+{
+ assert(renderer->state == RENDERER_STATE_INIT);
+
+ if (!renderer_can_support(renderer, src->texture, PIPE_BIND_SAMPLER_VIEW))
+ return VG_FALSE;
+
+ cso_save_blend(renderer->cso);
+ cso_save_samplers(renderer->cso);
+ cso_save_fragment_sampler_views(renderer->cso);
+ cso_save_fragment_shader(renderer->cso);
+ cso_save_vertex_shader(renderer->cso);
+
+ renderer_set_blend(renderer, ~0);
+
+ renderer_set_samplers(renderer, 1, &src);
+
+ renderer_set_fs(renderer, RENDERER_FS_TEXTURE);
+ renderer_set_vs(renderer, RENDERER_VS_TEXTURE);
+
+ renderer_set_mvp(renderer, NULL);
+
+ /* remember the texture size */
+ renderer->u.drawtex.tex_width = src->texture->width0;
+ renderer->u.drawtex.tex_height = src->texture->height0;
+ renderer->state = RENDERER_STATE_DRAWTEX;
+
+ return VG_TRUE;
+}
+
+/**
+ * Draw into the destination rectangle given by (x, y, w, h). The texture is
+ * sampled from within the rectangle given by (sx, sy, sw, sh).
+ *
+ * The coordinates are in surface coordinates.
+ */
+void renderer_drawtex(struct renderer *renderer,
+ VGint x, VGint y, VGint w, VGint h,
+ VGint sx, VGint sy, VGint sw, VGint sh)
+{
+ assert(renderer->state == RENDERER_STATE_DRAWTEX);
+
+ /* with scissoring */
+ renderer_quad_pos(renderer, x, y, x + w, y + h, VG_TRUE);
+ renderer_quad_texcoord(renderer, sx, sy, sx + sw, sy + sh,
+ renderer->u.drawtex.tex_width,
+ renderer->u.drawtex.tex_height);
+
+ renderer_quad_draw(renderer);
+}
+
+/**
+ * End textured drawing and restore the states.
+ */
+void renderer_drawtex_end(struct renderer *renderer)
+{
+ assert(renderer->state == RENDERER_STATE_DRAWTEX);
+
+ cso_restore_blend(renderer->cso);
+ cso_restore_samplers(renderer->cso);
+ cso_restore_fragment_sampler_views(renderer->cso);
+ cso_restore_fragment_shader(renderer->cso);
+ cso_restore_vertex_shader(renderer->cso);
+
+ renderer->state = RENDERER_STATE_INIT;
+}
+
+/**
+ * Prepare the renderer for scissor update. This will reset the depth buffer
+ * to 1.0f.
+ */
+VGboolean renderer_scissor_begin(struct renderer *renderer,
+ VGboolean restore_dsa)
+{
+ struct pipe_depth_stencil_alpha_state dsa;
+
+ assert(renderer->state == RENDERER_STATE_INIT);
+
+ if (restore_dsa)
+ cso_save_depth_stencil_alpha(renderer->cso);
+ cso_save_blend(renderer->cso);
+ cso_save_fragment_shader(renderer->cso);
+
+ /* enable depth writes */
+ memset(&dsa, 0, sizeof(dsa));
+ dsa.depth.enabled = 1;
+ dsa.depth.writemask = 1;
+ dsa.depth.func = PIPE_FUNC_ALWAYS;
+ cso_set_depth_stencil_alpha(renderer->cso, &dsa);
+
+ /* disable color writes */
+ renderer_set_blend(renderer, 0);
+ renderer_set_fs(renderer, RENDERER_FS_SCISSOR);
+
+ renderer_set_mvp(renderer, NULL);
+
+ renderer->u.scissor.restore_dsa = restore_dsa;
+ renderer->state = RENDERER_STATE_SCISSOR;
+
+ /* clear the depth buffer to 1.0f */
+ renderer->pipe->clear(renderer->pipe,
+ PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0f, 0);
+
+ return VG_TRUE;
+}
+
+/**
+ * Add a scissor rectangle. Depth values inside the rectangle will be set to
+ * 0.0f.
+ */
+void renderer_scissor(struct renderer *renderer,
+ VGint x, VGint y, VGint width, VGint height)
+{
+ assert(renderer->state == RENDERER_STATE_SCISSOR);
+
+ renderer_quad_pos(renderer, x, y, x + width, y + height, VG_FALSE);
+ renderer_quad_draw(renderer);
+}
+
+/**
+ * End scissor update and restore the states.
+ */
+void renderer_scissor_end(struct renderer *renderer)
+{
+ assert(renderer->state == RENDERER_STATE_SCISSOR);
+
+ if (renderer->u.scissor.restore_dsa)
+ cso_restore_depth_stencil_alpha(renderer->cso);
+ cso_restore_blend(renderer->cso);
+ cso_restore_fragment_shader(renderer->cso);
+
+ renderer->state = RENDERER_STATE_INIT;
+}
+
+/**
+ * Prepare the renderer for clearing.
+ */
+VGboolean renderer_clear_begin(struct renderer *renderer)
+{
+ assert(renderer->state == RENDERER_STATE_INIT);
+
+ cso_save_blend(renderer->cso);
+ cso_save_fragment_shader(renderer->cso);
+ cso_save_vertex_shader(renderer->cso);
+
+ renderer_set_blend(renderer, ~0);
+ renderer_set_fs(renderer, RENDERER_FS_COLOR);
+ renderer_set_vs(renderer, RENDERER_VS_COLOR);
+
+ renderer_set_mvp(renderer, NULL);
+
+ renderer->state = RENDERER_STATE_CLEAR;
+
+ return VG_TRUE;
+}
+
+/**
+ * Clear the framebuffer with the specified region and color.
+ *
+ * The coordinates are in surface coordinates.
+ */
+void renderer_clear(struct renderer *renderer,
+ VGint x, VGint y, VGint width, VGint height,
+ const VGfloat color[4])
+{
+ VGuint i;
+
+ assert(renderer->state == RENDERER_STATE_CLEAR);
+
+ renderer_quad_pos(renderer, x, y, x + width, y + height, VG_TRUE);
+ for (i = 0; i < 4; i++)
+ memcpy(renderer->vertices[i][1], color, sizeof(VGfloat) * 4);
+
+ renderer_quad_draw(renderer);
+}
+
+/**
+ * End clearing and retore the states.
+ */
+void renderer_clear_end(struct renderer *renderer)
+{
+ assert(renderer->state == RENDERER_STATE_CLEAR);
+
+ cso_restore_blend(renderer->cso);
+ cso_restore_fragment_shader(renderer->cso);
+ cso_restore_vertex_shader(renderer->cso);
+
+ renderer->state = RENDERER_STATE_INIT;
+}
+
+/**
+ * Prepare the renderer for image filtering.
+ */
+VGboolean renderer_filter_begin(struct renderer *renderer,
+ struct pipe_resource *dst,
+ VGboolean y0_top,
+ VGbitfield channel_mask,
+ const struct pipe_sampler_state **samplers,
+ struct pipe_sampler_view **views,
+ VGint num_samplers,
+ void *fs,
+ const void *const_buffer,
+ VGint const_buffer_len)
+{
+ struct pipe_surface *surf, surf_tmpl;
+
+ assert(renderer->state == RENDERER_STATE_INIT);
+
+ if (!fs)
+ return VG_FALSE;
+ if (!renderer_can_support(renderer, dst, PIPE_BIND_RENDER_TARGET))
+ return VG_FALSE;
+
+ u_surface_default_template(&surf_tmpl, dst,
+ PIPE_BIND_RENDER_TARGET);
+ surf = renderer->pipe->create_surface(renderer->pipe, dst, &surf_tmpl);
+ if (!surf)
+ return VG_FALSE;
+
+ cso_save_framebuffer(renderer->cso);
+ cso_save_viewport(renderer->cso);
+ cso_save_blend(renderer->cso);
+
+ /* set the image as the target */
+ renderer_set_target(renderer, surf, NULL, y0_top);
+ pipe_surface_reference(&surf, NULL);
+
+ renderer_set_blend(renderer, channel_mask);
+
+ if (num_samplers) {
+ struct pipe_resource *tex;
+
+ cso_save_samplers(renderer->cso);
+ cso_save_fragment_sampler_views(renderer->cso);
+ cso_save_fragment_shader(renderer->cso);
+ cso_save_vertex_shader(renderer->cso);
+
+ renderer_set_custom_fs(renderer, fs,
+ samplers, views, num_samplers,
+ const_buffer, const_buffer_len);
+ renderer_set_vs(renderer, RENDERER_VS_TEXTURE);
+
+ tex = views[0]->texture;
+ renderer->u.filter.tex_width = tex->width0;
+ renderer->u.filter.tex_height = tex->height0;
+ renderer->u.filter.use_sampler = VG_TRUE;
}
+ else {
+ cso_save_fragment_shader(renderer->cso);
- cso_restore_vertex_shader(r->cso);
+ renderer_set_custom_fs(renderer, fs, NULL, NULL, 0,
+ const_buffer, const_buffer_len);
+
+ renderer->u.filter.use_sampler = VG_FALSE;
+ }
+
+ renderer_set_mvp(renderer, NULL);
+
+ renderer->state = RENDERER_STATE_FILTER;
+
+ return VG_TRUE;
}
-void renderer_copy_texture(struct renderer *ctx,
- struct pipe_sampler_view *src,
- VGfloat sx1, VGfloat sy1,
- VGfloat sx2, VGfloat sy2,
- struct pipe_resource *dst,
- VGfloat dx1, VGfloat dy1,
- VGfloat dx2, VGfloat dy2)
+/**
+ * Draw into a rectangle of the destination with the specified region of the
+ * texture(s).
+ *
+ * The coordinates are in surface coordinates.
+ */
+void renderer_filter(struct renderer *renderer,
+ VGint x, VGint y, VGint w, VGint h,
+ VGint sx, VGint sy, VGint sw, VGint sh)
{
- struct pipe_context *pipe = ctx->pipe;
- struct pipe_screen *screen = pipe->screen;
- struct pipe_resource *tex = src->texture;
- struct pipe_resource *buf;
- struct pipe_surface *dst_surf = screen->get_tex_surface(
- screen, dst, 0, 0, 0,
- PIPE_BIND_RENDER_TARGET);
- struct pipe_framebuffer_state fb;
- float s0, t0, s1, t1;
+ assert(renderer->state == RENDERER_STATE_FILTER);
- assert(tex->width0 != 0);
- assert(tex->height0 != 0);
- assert(dst->width0 != 0);
- assert(dst->height0 != 0);
-
-#if 0
- debug_printf("copy texture [%f, %f, %f, %f], [%f, %f, %f, %f]\n",
- sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
-#endif
-
-#if 1
- s0 = sx1 / tex->width0;
- s1 = sx2 / tex->width0;
- t0 = sy1 / tex->height0;
- t1 = sy2 / tex->height0;
-#else
- s0 = 0;
- s1 = 1;
- t0 = 0;
- t1 = 1;
-#endif
-
- assert(screen->is_format_supported(screen, dst_surf->format, PIPE_TEXTURE_2D,
- 0, PIPE_BIND_RENDER_TARGET, 0));
+ renderer_quad_pos(renderer, x, y, x + w, y + h, VG_FALSE);
+ if (renderer->u.filter.use_sampler) {
+ renderer_quad_texcoord(renderer, sx, sy, sx + sw, sy + sh,
+ renderer->u.filter.tex_width,
+ renderer->u.filter.tex_height);
+ }
- /* save state (restored below) */
- cso_save_blend(ctx->cso);
- cso_save_samplers(ctx->cso);
- cso_save_fragment_sampler_views(ctx->cso);
- cso_save_framebuffer(ctx->cso);
- cso_save_fragment_shader(ctx->cso);
- cso_save_vertex_shader(ctx->cso);
+ renderer_quad_draw(renderer);
+}
+
+/**
+ * End image filtering and restore the states.
+ */
+void renderer_filter_end(struct renderer *renderer)
+{
+ assert(renderer->state == RENDERER_STATE_FILTER);
- cso_save_viewport(ctx->cso);
+ if (renderer->u.filter.use_sampler) {
+ cso_restore_samplers(renderer->cso);
+ cso_restore_fragment_sampler_views(renderer->cso);
+ cso_restore_vertex_shader(renderer->cso);
+ }
+ cso_restore_framebuffer(renderer->cso);
+ cso_restore_viewport(renderer->cso);
+ cso_restore_blend(renderer->cso);
+ cso_restore_fragment_shader(renderer->cso);
- /* set misc state we care about */
- {
- struct pipe_blend_state blend;
- memset(&blend, 0, sizeof(blend));
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].colormask = PIPE_MASK_RGBA;
- cso_set_blend(ctx->cso, &blend);
+ renderer->state = RENDERER_STATE_INIT;
+}
+
+/**
+ * Prepare the renderer for polygon silhouette rendering.
+ */
+VGboolean renderer_polygon_stencil_begin(struct renderer *renderer,
+ struct pipe_vertex_element *velem,
+ VGFillRule rule,
+ VGboolean restore_dsa)
+{
+ struct pipe_depth_stencil_alpha_state *dsa;
+ VGboolean manual_two_sides;
+
+ assert(renderer->state == RENDERER_STATE_INIT);
+
+ cso_save_vertex_elements(renderer->cso);
+ cso_save_blend(renderer->cso);
+ cso_save_depth_stencil_alpha(renderer->cso);
+
+ cso_set_vertex_elements(renderer->cso, 1, velem);
+
+ /* disable color writes */
+ renderer_set_blend(renderer, 0);
+
+ manual_two_sides = VG_FALSE;
+ dsa = &renderer->u.polygon_stencil.dsa;
+ memset(dsa, 0, sizeof(*dsa));
+ if (rule == VG_EVEN_ODD) {
+ dsa->stencil[0].enabled = 1;
+ dsa->stencil[0].writemask = 1;
+ dsa->stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
+ dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
+ dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT;
+ dsa->stencil[0].func = PIPE_FUNC_ALWAYS;
+ dsa->stencil[0].valuemask = ~0;
}
+ else {
+ assert(rule == VG_NON_ZERO);
+
+ /* front face */
+ dsa->stencil[0].enabled = 1;
+ dsa->stencil[0].writemask = ~0;
+ dsa->stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
+ dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
+ dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
+ dsa->stencil[0].func = PIPE_FUNC_ALWAYS;
+ dsa->stencil[0].valuemask = ~0;
+
+ if (renderer->pipe->screen->get_param(renderer->pipe->screen,
+ PIPE_CAP_TWO_SIDED_STENCIL)) {
+ /* back face */
+ dsa->stencil[1] = dsa->stencil[0];
+ dsa->stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
+ }
+ else {
+ manual_two_sides = VG_TRUE;
+ }
+ }
+ cso_set_depth_stencil_alpha(renderer->cso, dsa);
+
+ if (manual_two_sides)
+ cso_save_rasterizer(renderer->cso);
- /* sampler */
- {
- struct pipe_sampler_state sampler;
- memset(&sampler, 0, sizeof(sampler));
- sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
- sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
- sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
- sampler.normalized_coords = 1;
- cso_single_sampler(ctx->cso, 0, &sampler);
- cso_single_sampler_done(ctx->cso);
+ renderer->u.polygon_stencil.manual_two_sides = manual_two_sides;
+ renderer->u.polygon_stencil.restore_dsa = restore_dsa;
+ renderer->state = RENDERER_STATE_POLYGON_STENCIL;
+
+ return VG_TRUE;
+}
+
+/**
+ * Render a polygon silhouette to stencil buffer.
+ */
+void renderer_polygon_stencil(struct renderer *renderer,
+ struct pipe_vertex_buffer *vbuf,
+ VGuint mode, VGuint start, VGuint count)
+{
+ assert(renderer->state == RENDERER_STATE_POLYGON_STENCIL);
+
+ renderer->pipe->set_vertex_buffers(renderer->pipe, 1, vbuf);
+
+ if (!renderer->u.polygon_stencil.manual_two_sides) {
+ util_draw_arrays(renderer->pipe, mode, start, count);
}
+ else {
+ struct pipe_rasterizer_state raster;
+ struct pipe_depth_stencil_alpha_state dsa;
- vg_set_viewport(ctx->owner, VEGA_Y0_TOP);
+ raster = renderer->g3d.rasterizer;
+ dsa = renderer->u.polygon_stencil.dsa;
- /* texture */
- cso_set_fragment_sampler_views(ctx->cso, 1, &src);
+ /* front */
+ raster.cull_face = PIPE_FACE_BACK;
+ dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
- /* shaders */
- cso_set_vertex_shader_handle(ctx->cso, vg_texture_vs(ctx->owner));
- cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
+ cso_set_rasterizer(renderer->cso, &raster);
+ cso_set_depth_stencil_alpha(renderer->cso, &dsa);
+ util_draw_arrays(renderer->pipe, mode, start, count);
- /* drawing dest */
- memset(&fb, 0, sizeof(fb));
- fb.width = dst_surf->width;
- fb.height = dst_surf->height;
- fb.nr_cbufs = 1;
- fb.cbufs[0] = dst_surf;
- {
- VGint i;
- for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
- fb.cbufs[i] = 0;
+ /* back */
+ raster.cull_face = PIPE_FACE_FRONT;
+ dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
+
+ cso_set_rasterizer(renderer->cso, &raster);
+ cso_set_depth_stencil_alpha(renderer->cso, &dsa);
+ util_draw_arrays(renderer->pipe, mode, start, count);
}
- cso_set_framebuffer(ctx->cso, &fb);
+}
+
+/**
+ * End polygon silhouette rendering.
+ */
+void renderer_polygon_stencil_end(struct renderer *renderer)
+{
+ assert(renderer->state == RENDERER_STATE_POLYGON_STENCIL);
- /* draw quad */
- buf = setup_vertex_data_tex(ctx,
- dx1, dy1,
- dx2, dy2,
- s0, t0, s1, t1,
- 0.0f);
+ if (renderer->u.polygon_stencil.manual_two_sides)
+ cso_restore_rasterizer(renderer->cso);
- if (buf) {
- cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
- util_draw_vertex_buffer(ctx->pipe, buf, 0,
- PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */
+ cso_restore_vertex_elements(renderer->cso);
+
+ /* restore color writes */
+ cso_restore_blend(renderer->cso);
+
+ if (renderer->u.polygon_stencil.restore_dsa)
+ cso_restore_depth_stencil_alpha(renderer->cso);
+
+ renderer->state = RENDERER_STATE_INIT;
+}
+
+/**
+ * Prepare the renderer for polygon filling.
+ */
+VGboolean renderer_polygon_fill_begin(struct renderer *renderer,
+ VGboolean save_dsa)
+{
+ struct pipe_depth_stencil_alpha_state dsa;
+
+ assert(renderer->state == RENDERER_STATE_INIT);
+
+ if (save_dsa)
+ cso_save_depth_stencil_alpha(renderer->cso);
+
+ /* setup stencil ops */
+ memset(&dsa, 0, sizeof(dsa));
+ dsa.stencil[0].enabled = 1;
+ dsa.stencil[0].func = PIPE_FUNC_NOTEQUAL;
+ dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
+ dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
+ dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
+ dsa.stencil[0].valuemask = ~0;
+ dsa.stencil[0].writemask = ~0;
+ dsa.depth = renderer->g3d.dsa.depth;
+ cso_set_depth_stencil_alpha(renderer->cso, &dsa);
+
+ renderer->state = RENDERER_STATE_POLYGON_FILL;
+
+ return VG_TRUE;
+}
+
+/**
+ * Fill a polygon.
+ */
+void renderer_polygon_fill(struct renderer *renderer,
+ VGfloat min_x, VGfloat min_y,
+ VGfloat max_x, VGfloat max_y)
+{
+ assert(renderer->state == RENDERER_STATE_POLYGON_FILL);
+
+ renderer_quad_pos(renderer, min_x, min_y, max_x, max_y, VG_TRUE);
+ renderer_quad_draw(renderer);
+}
+
+/**
+ * End polygon filling.
+ */
+void renderer_polygon_fill_end(struct renderer *renderer)
+{
+ assert(renderer->state == RENDERER_STATE_POLYGON_FILL);
+
+ cso_restore_depth_stencil_alpha(renderer->cso);
- pipe_resource_reference( &buf,
- NULL );
+ renderer->state = RENDERER_STATE_INIT;
+}
+
+struct renderer * renderer_create(struct vg_context *owner)
+{
+ struct renderer *renderer;
+ struct pipe_rasterizer_state *raster;
+ struct pipe_stencil_ref sr;
+ VGint i;
+
+ renderer = CALLOC_STRUCT(renderer);
+ if (!renderer)
+ return NULL;
+
+ renderer->pipe = owner->pipe;
+ renderer->cso = owner->cso_context;
+
+ /* init vertex data that doesn't change */
+ for (i = 0; i < 4; i++)
+ renderer->vertices[i][0][3] = 1.0f; /* w */
+
+ for (i = 0; i < 2; i++) {
+ renderer->velems[i].src_offset = i * 4 * sizeof(float);
+ renderer->velems[i].instance_divisor = 0;
+ renderer->velems[i].vertex_buffer_index = 0;
+ renderer->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
+ cso_set_vertex_elements(renderer->cso, 2, renderer->velems);
+
+ /* GL rasterization rules */
+ raster = &renderer->g3d.rasterizer;
+ memset(raster, 0, sizeof(*raster));
+ raster->gl_rasterization_rules = 1;
+ cso_set_rasterizer(renderer->cso, raster);
+
+ /* fixed at 0 */
+ memset(&sr, 0, sizeof(sr));
+ cso_set_stencil_ref(renderer->cso, &sr);
+
+ renderer_set_vs(renderer, RENDERER_VS_PLAIN);
+
+ renderer->state = RENDERER_STATE_INIT;
+
+ return renderer;
+}
+
+void renderer_destroy(struct renderer *ctx)
+{
+ int i;
+
+ for (i = 0; i < NUM_RENDERER_VS; i++) {
+ if (ctx->cached_vs[i])
+ cso_delete_vertex_shader(ctx->cso, ctx->cached_vs[i]);
+ }
+ for (i = 0; i < NUM_RENDERER_FS; i++) {
+ if (ctx->cached_fs[i])
+ cso_delete_fragment_shader(ctx->cso, ctx->cached_fs[i]);
+ }
+
+ pipe_resource_reference(&ctx->vs_cbuf, NULL);
+ pipe_resource_reference(&ctx->fs_cbuf, NULL);
+
+ FREE(ctx);
+}
+
+static void update_clip_state(struct renderer *renderer,
+ const struct vg_state *state)
+{
+ struct pipe_depth_stencil_alpha_state *dsa = &renderer->g3d.dsa;
+
+ memset(dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
+
+ if (state->scissoring) {
+ struct pipe_framebuffer_state *fb = &renderer->g3d.fb;
+ int i;
+
+ renderer_scissor_begin(renderer, VG_FALSE);
+
+ for (i = 0; i < state->scissor_rects_num; ++i) {
+ const float x = state->scissor_rects[i * 4 + 0].f;
+ const float y = state->scissor_rects[i * 4 + 1].f;
+ const float width = state->scissor_rects[i * 4 + 2].f;
+ const float height = state->scissor_rects[i * 4 + 3].f;
+ VGint x0, y0, x1, y1, iw, ih;
+
+ x0 = (VGint) x;
+ y0 = (VGint) y;
+ if (x0 < 0)
+ x0 = 0;
+ if (y0 < 0)
+ y0 = 0;
+
+ /* note that x1 and y1 are exclusive */
+ x1 = (VGint) ceilf(x + width);
+ y1 = (VGint) ceilf(y + height);
+ if (x1 > fb->width)
+ x1 = fb->width;
+ if (y1 > fb->height)
+ y1 = fb->height;
+
+ iw = x1 - x0;
+ ih = y1 - y0;
+ if (iw > 0 && ih> 0 )
+ renderer_scissor(renderer, x0, y0, iw, ih);
+ }
+
+ renderer_scissor_end(renderer);
+
+ dsa->depth.enabled = 1; /* glEnable(GL_DEPTH_TEST); */
+ dsa->depth.writemask = 0;/*glDepthMask(FALSE);*/
+ dsa->depth.func = PIPE_FUNC_GEQUAL;
}
+}
+
+static void renderer_validate_blend(struct renderer *renderer,
+ const struct vg_state *state,
+ enum pipe_format fb_format)
+{
+ struct pipe_blend_state blend;
+
+ memset(&blend, 0, sizeof(blend));
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- /* restore state we changed */
- cso_restore_blend(ctx->cso);
- cso_restore_samplers(ctx->cso);
- cso_restore_fragment_sampler_views(ctx->cso);
- cso_restore_framebuffer(ctx->cso);
- cso_restore_vertex_shader(ctx->cso);
- cso_restore_fragment_shader(ctx->cso);
- cso_restore_viewport(ctx->cso);
+ /* TODO alpha masking happens after blending? */
+
+ switch (state->blend_mode) {
+ case VG_BLEND_SRC:
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ break;
+ case VG_BLEND_SRC_OVER:
+ if (!util_format_has_alpha(fb_format)) {
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ blend.rt[0].blend_enable = 1;
+ }
+ break;
+ case VG_BLEND_SRC_IN:
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].blend_enable = 1;
+ break;
+ case VG_BLEND_DST_IN:
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+ blend.rt[0].blend_enable = 1;
+ break;
+ case VG_BLEND_DST_OVER:
+ case VG_BLEND_MULTIPLY:
+ case VG_BLEND_SCREEN:
+ case VG_BLEND_DARKEN:
+ case VG_BLEND_LIGHTEN:
+ case VG_BLEND_ADDITIVE:
+ /* need a shader */
+ break;
+ default:
+ assert(!"not implemented blend mode");
+ break;
+ }
- pipe_surface_reference(&dst_surf, NULL);
+ cso_set_blend(renderer->cso, &blend);
+}
+
+/**
+ * Propogate OpenVG state changes to the renderer. Only framebuffer, blending
+ * and scissoring states are relevant here.
+ */
+void renderer_validate(struct renderer *renderer,
+ VGbitfield dirty,
+ const struct st_framebuffer *stfb,
+ const struct vg_state *state)
+{
+ assert(renderer->state == RENDERER_STATE_INIT);
+
+ dirty |= renderer->dirty;
+ renderer->dirty = 0;
+
+ if (dirty & FRAMEBUFFER_DIRTY) {
+ struct pipe_framebuffer_state *fb = &renderer->g3d.fb;
+ struct matrix *proj = &renderer->projection;
+
+ memset(fb, 0, sizeof(struct pipe_framebuffer_state));
+ fb->width = stfb->width;
+ fb->height = stfb->height;
+ fb->nr_cbufs = 1;
+ fb->cbufs[0] = stfb->strb->surface;
+ fb->zsbuf = stfb->dsrb->surface;
+
+ cso_set_framebuffer(renderer->cso, fb);
+ vg_set_viewport(renderer, VEGA_Y0_BOTTOM);
+
+ matrix_load_identity(proj);
+ matrix_translate(proj, -1.0f, -1.0f);
+ matrix_scale(proj, 2.0f / fb->width, 2.0f / fb->height);
+
+ /* we also got a new depth buffer */
+ if (dirty & DEPTH_STENCIL_DIRTY) {
+ renderer->pipe->clear(renderer->pipe,
+ PIPE_CLEAR_DEPTHSTENCIL, NULL, 0.0, 0);
+ }
+ }
+
+ /* must be last because it renders to the depth buffer*/
+ if (dirty & DEPTH_STENCIL_DIRTY) {
+ update_clip_state(renderer, state);
+ cso_set_depth_stencil_alpha(renderer->cso, &renderer->g3d.dsa);
+ }
+
+ if (dirty & BLEND_DIRTY)
+ renderer_validate_blend(renderer, state, stfb->strb->format);
+}
+
+/**
+ * Prepare the renderer for OpenVG pipeline.
+ */
+void renderer_validate_for_shader(struct renderer *renderer,
+ const struct pipe_sampler_state **samplers,
+ struct pipe_sampler_view **views,
+ VGint num_samplers,
+ const struct matrix *modelview,
+ void *fs,
+ const void *const_buffer,
+ VGint const_buffer_len)
+{
+ struct matrix mvp = renderer->projection;
+
+ /* will be used in POLYGON_STENCIL and POLYGON_FILL */
+ matrix_mult(&mvp, modelview);
+ renderer_set_mvp(renderer, &mvp);
+
+ renderer_set_custom_fs(renderer, fs,
+ samplers, views, num_samplers,
+ const_buffer, const_buffer_len);
+}
+
+void renderer_validate_for_mask_rendering(struct renderer *renderer,
+ struct pipe_surface *dst,
+ const struct matrix *modelview)
+{
+ struct matrix mvp = renderer->projection;
+
+ /* will be used in POLYGON_STENCIL and POLYGON_FILL */
+ matrix_mult(&mvp, modelview);
+ renderer_set_mvp(renderer, &mvp);
+
+ renderer_set_target(renderer, dst, renderer->g3d.fb.zsbuf, VG_FALSE);
+ renderer_set_blend(renderer, ~0);
+ renderer_set_fs(renderer, RENDERER_FS_WHITE);
+
+ /* set internal dirty flags (hacky!) */
+ renderer->dirty = FRAMEBUFFER_DIRTY | BLEND_DIRTY;
}
void renderer_copy_surface(struct renderer *ctx,
@@ -409,13 +1429,11 @@ void renderer_copy_surface(struct renderer *ctx,
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_resource *buf;
struct pipe_sampler_view view_templ;
struct pipe_sampler_view *view;
+ struct pipe_box src_box;
struct pipe_resource texTemp, *tex;
- struct pipe_subresource subsrc, subdst;
- struct pipe_framebuffer_state fb;
- struct st_framebuffer *stfb = ctx->owner->draw_buffer;
+ const struct pipe_framebuffer_state *fb = &ctx->g3d.fb;
const int srcW = abs(srcX1 - srcX0);
const int srcH = abs(srcY1 - srcY0);
const int srcLeft = MIN2(srcX0, srcX1);
@@ -458,6 +1476,7 @@ void renderer_copy_surface(struct renderer *ctx,
texTemp.width0 = srcW;
texTemp.height0 = srcH;
texTemp.depth0 = 1;
+ texTemp.array_size = 1;
texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
tex = screen->resource_create(screen, &texTemp);
@@ -470,100 +1489,35 @@ void renderer_copy_surface(struct renderer *ctx,
if (!view)
return;
- subdst.face = 0;
- subdst.level = 0;
- subsrc.face = src->face;
- subsrc.level = src->level;
+ u_box_2d_zslice(srcLeft, srcTop, src->u.tex.first_layer, srcW, srcH, &src_box);
pipe->resource_copy_region(pipe,
- tex, subdst, 0, 0, 0, /* dest */
- src->texture, subsrc, srcLeft, srcTop, src->zslice, /* src */
- srcW, srcH); /* size */
-
- /* save state (restored below) */
- cso_save_blend(ctx->cso);
- cso_save_samplers(ctx->cso);
- cso_save_fragment_sampler_views(ctx->cso);
- cso_save_framebuffer(ctx->cso);
- cso_save_fragment_shader(ctx->cso);
- cso_save_vertex_shader(ctx->cso);
- cso_save_viewport(ctx->cso);
-
- /* set misc state we care about */
- {
- struct pipe_blend_state blend;
- memset(&blend, 0, sizeof(blend));
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.rt[0].colormask = PIPE_MASK_RGBA;
- cso_set_blend(ctx->cso, &blend);
+ tex, 0, 0, 0, 0, /* dest */
+ src->texture, 0, &src_box);
+
+ assert(floatsEqual(z, 0.0f));
+
+ /* draw */
+ if (fb->cbufs[0] == dst) {
+ /* transform back to surface coordinates */
+ dstY0 = dst->height - dstY0;
+ dstY1 = dst->height - dstY1;
+
+ if (renderer_drawtex_begin(ctx, view)) {
+ renderer_drawtex(ctx,
+ dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0,
+ 0, 0, view->texture->width0, view->texture->height0);
+ renderer_drawtex_end(ctx);
+ }
}
-
- vg_set_viewport(ctx->owner, VEGA_Y0_TOP);
-
- /* sampler */
- {
- struct pipe_sampler_state sampler;
- memset(&sampler, 0, sizeof(sampler));
- sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
- sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
- sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
- sampler.normalized_coords = 1;
- cso_single_sampler(ctx->cso, 0, &sampler);
- cso_single_sampler_done(ctx->cso);
- }
-
- /* texture */
- cso_set_fragment_sampler_views(ctx->cso, 1, &view);
-
- /* shaders */
- cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
- cso_set_vertex_shader_handle(ctx->cso, vg_texture_vs(ctx->owner));
-
- /* drawing dest */
- if (stfb->strb->surface != dst) {
- memset(&fb, 0, sizeof(fb));
- fb.width = dst->width;
- fb.height = dst->height;
- fb.nr_cbufs = 1;
- fb.cbufs[0] = dst;
- fb.zsbuf = stfb->dsrb->surface;
- cso_set_framebuffer(ctx->cso, &fb);
+ else {
+ if (renderer_copy_begin(ctx, dst, VG_TRUE, view)) {
+ renderer_copy(ctx,
+ dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0,
+ 0, 0, view->texture->width0, view->texture->height0);
+ renderer_copy_end(ctx);
+ }
}
-
- /* draw quad */
- buf = setup_vertex_data(ctx,
- (float) dstX0, (float) dstY0,
- (float) dstX1, (float) dstY1, z);
-
- if (buf) {
- cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
- util_draw_vertex_buffer(ctx->pipe, buf, 0,
- PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */
-
- pipe_resource_reference( &buf,
- NULL );
- }
-
-
- /* restore state we changed */
- cso_restore_blend(ctx->cso);
- cso_restore_samplers(ctx->cso);
- cso_restore_fragment_sampler_views(ctx->cso);
- cso_restore_framebuffer(ctx->cso);
- cso_restore_fragment_shader(ctx->cso);
- cso_restore_vertex_shader(ctx->cso);
- cso_restore_viewport(ctx->cso);
-
- pipe_resource_reference(&tex, NULL);
- pipe_sampler_view_reference(&view, NULL);
}
void renderer_texture_quad(struct renderer *r,
@@ -575,36 +1529,38 @@ void renderer_texture_quad(struct renderer *r,
VGfloat x3, VGfloat y3,
VGfloat x4, VGfloat y4)
{
- struct pipe_context *pipe = r->pipe;
- struct pipe_resource *buf;
- VGfloat s0, t0, s1, t1;
+ const VGfloat z = 0.0f;
+ assert(r->state == RENDERER_STATE_INIT);
assert(tex->width0 != 0);
assert(tex->height0 != 0);
- s0 = x1offset / tex->width0;
- s1 = x2offset / tex->width0;
- t0 = y1offset / tex->height0;
- t1 = y2offset / tex->height0;
-
cso_save_vertex_shader(r->cso);
- /* shaders */
- cso_set_vertex_shader_handle(r->cso, vg_texture_vs(r->owner));
- /* draw quad */
- buf = setup_vertex_data_qtex(r, x1, y1, x2, y2, x3, y3, x4, y4,
- s0, t0, s1, t1, 0.0f);
+ renderer_set_vs(r, RENDERER_VS_TEXTURE);
- if (buf) {
- cso_set_vertex_elements(r->cso, 2, r->owner->velems);
- util_draw_vertex_buffer(pipe, buf, 0,
- PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */
+ /* manually set up positions */
+ r->vertices[0][0][0] = x1;
+ r->vertices[0][0][1] = y1;
+ r->vertices[0][0][2] = z;
- pipe_resource_reference(&buf,
- NULL);
- }
+ r->vertices[1][0][0] = x2;
+ r->vertices[1][0][1] = y2;
+ r->vertices[1][0][2] = z;
+
+ r->vertices[2][0][0] = x3;
+ r->vertices[2][0][1] = y3;
+ r->vertices[2][0][2] = z;
+
+ r->vertices[3][0][0] = x4;
+ r->vertices[3][0][1] = y4;
+ r->vertices[3][0][2] = z;
+
+ /* texcoords */
+ renderer_quad_texcoord(r, x1offset, y1offset,
+ x2offset, y2offset, tex->width0, tex->height0);
+
+ renderer_quad_draw(r);
cso_restore_vertex_shader(r->cso);
}
diff --git a/src/gallium/state_trackers/vega/renderer.h b/src/gallium/state_trackers/vega/renderer.h
index b1a9fb58be6..fe719936580 100644
--- a/src/gallium/state_trackers/vega/renderer.h
+++ b/src/gallium/state_trackers/vega/renderer.h
@@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright 2009 VMware, Inc. All Rights Reserved.
+ * Copyright 2010 LunarG, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
@@ -32,23 +33,110 @@
struct renderer;
struct vg_context;
+struct vg_state;
+struct st_framebuffer;
struct pipe_resource;
+struct pipe_sampler_state;
struct pipe_sampler_view;
struct pipe_surface;
+struct pipe_vertex_element;
+struct pipe_vertex_buffer;
+struct matrix;
struct renderer *renderer_create(struct vg_context *owner);
void renderer_destroy(struct renderer *);
-void renderer_draw_quad(struct renderer *,
- VGfloat x1, VGfloat y1,
- VGfloat x2, VGfloat y2,
- VGfloat depth);
-void renderer_draw_texture(struct renderer *,
- struct pipe_resource *texture,
- VGfloat x1offset, VGfloat y1offset,
- VGfloat x2offset, VGfloat y2offset,
- VGfloat x1, VGfloat y1,
- VGfloat x2, VGfloat y2);
+void renderer_validate(struct renderer *renderer,
+ VGbitfield dirty,
+ const struct st_framebuffer *stfb,
+ const struct vg_state *state);
+
+void renderer_validate_for_shader(struct renderer *renderer,
+ const struct pipe_sampler_state **samplers,
+ struct pipe_sampler_view **views,
+ VGint num_samplers,
+ const struct matrix *modelview,
+ void *fs,
+ const void *const_buffer,
+ VGint const_buffer_len);
+
+void renderer_validate_for_mask_rendering(struct renderer *renderer,
+ struct pipe_surface *dst,
+ const struct matrix *modelview);
+
+VGboolean renderer_copy_begin(struct renderer *renderer,
+ struct pipe_surface *dst,
+ VGboolean y0_top,
+ struct pipe_sampler_view *src);
+
+void renderer_copy(struct renderer *renderer,
+ VGint x, VGint y, VGint w, VGint h,
+ VGint sx, VGint sy, VGint sw, VGint sh);
+
+void renderer_copy_end(struct renderer *renderer);
+
+VGboolean renderer_drawtex_begin(struct renderer *renderer,
+ struct pipe_sampler_view *src);
+
+void renderer_drawtex(struct renderer *renderer,
+ VGint x, VGint y, VGint w, VGint h,
+ VGint sx, VGint sy, VGint sw, VGint sh);
+
+void renderer_drawtex_end(struct renderer *renderer);
+
+VGboolean renderer_scissor_begin(struct renderer *renderer,
+ VGboolean restore_dsa);
+
+void renderer_scissor(struct renderer *renderer,
+ VGint x, VGint y, VGint width, VGint height);
+
+void renderer_scissor_end(struct renderer *renderer);
+
+VGboolean renderer_clear_begin(struct renderer *renderer);
+
+void renderer_clear(struct renderer *renderer,
+ VGint x, VGint y, VGint width, VGint height,
+ const VGfloat color[4]);
+
+void renderer_clear_end(struct renderer *renderer);
+
+VGboolean renderer_filter_begin(struct renderer *renderer,
+ struct pipe_resource *dst,
+ VGboolean y0_top,
+ VGbitfield channel_mask,
+ const struct pipe_sampler_state **samplers,
+ struct pipe_sampler_view **views,
+ VGint num_samplers,
+ void *fs,
+ const void *const_buffer,
+ VGint const_buffer_len);
+
+void renderer_filter(struct renderer *renderer,
+ VGint x, VGint y, VGint w, VGint h,
+ VGint sx, VGint sy, VGint sw, VGint sh);
+
+void renderer_filter_end(struct renderer *renderer);
+
+VGboolean renderer_polygon_stencil_begin(struct renderer *renderer,
+ struct pipe_vertex_element *velem,
+ VGFillRule rule,
+ VGboolean restore_dsa);
+
+void renderer_polygon_stencil(struct renderer *renderer,
+ struct pipe_vertex_buffer *vbuf,
+ VGuint mode, VGuint start, VGuint count);
+
+void renderer_polygon_stencil_end(struct renderer *renderer);
+
+VGboolean renderer_polygon_fill_begin(struct renderer *renderer,
+ VGboolean save_dsa);
+
+void renderer_polygon_fill(struct renderer *renderer,
+ VGfloat min_x, VGfloat min_y,
+ VGfloat max_x, VGfloat max_y);
+
+void renderer_polygon_fill_end(struct renderer *renderer);
+
void renderer_texture_quad(struct renderer *,
struct pipe_resource *texture,
VGfloat x1offset, VGfloat y1offset,
@@ -57,13 +145,7 @@ void renderer_texture_quad(struct renderer *,
VGfloat x2, VGfloat y2,
VGfloat x3, VGfloat y3,
VGfloat x4, VGfloat y4);
-void renderer_copy_texture(struct renderer *r,
- struct pipe_sampler_view *src,
- VGfloat sx1, VGfloat sy1,
- VGfloat sx2, VGfloat sy2,
- struct pipe_resource *dst,
- VGfloat dx1, VGfloat dy1,
- VGfloat dx2, VGfloat dy2);
+
void renderer_copy_surface(struct renderer *r,
struct pipe_surface *src,
int sx1, int sy1,
diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c
index eab1349639c..0ed721376cf 100644
--- a/src/gallium/state_trackers/vega/shader.c
+++ b/src/gallium/state_trackers/vega/shader.c
@@ -31,22 +31,29 @@
#include "paint.h"
#include "mask.h"
#include "image.h"
+#include "renderer.h"
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
#include "pipe/p_state.h"
#include "util/u_inlines.h"
#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_format.h"
-#define MAX_CONSTANTS 20
+#define MAX_CONSTANTS 28
struct shader {
struct vg_context *context;
+ VGboolean color_transform;
VGboolean masking;
struct vg_paint *paint;
struct vg_image *image;
+ struct matrix modelview;
+ struct matrix paint_matrix;
+
VGboolean drawing_image;
VGImageMode image_mode;
@@ -71,6 +78,11 @@ void shader_destroy(struct shader *shader)
FREE(shader);
}
+void shader_set_color_transform(struct shader *shader, VGboolean set)
+{
+ shader->color_transform = set;
+}
+
void shader_set_masking(struct shader *shader, VGboolean set)
{
shader->masking = set;
@@ -91,49 +103,64 @@ struct vg_paint * shader_paint(struct shader *shader)
return shader->paint;
}
-
-static void setup_constant_buffer(struct shader *shader)
+static VGint setup_constant_buffer(struct shader *shader)
{
- struct vg_context *ctx = shader->context;
- struct pipe_context *pipe = shader->context->pipe;
- struct pipe_resource **cbuf = &shader->cbuf;
+ const struct vg_state *state = &shader->context->state.vg;
VGint param_bytes = paint_constant_buffer_size(shader->paint);
- float temp_buf[MAX_CONSTANTS];
+ VGint i;
+
+ param_bytes += sizeof(VGfloat) * 8;
+ assert(param_bytes <= sizeof(shader->constants));
+
+ if (state->color_transform) {
+ for (i = 0; i < 8; i++) {
+ VGfloat val = (i < 4) ? 127.0f : 1.0f;
+ shader->constants[i] =
+ CLAMP(state->color_transform_values[i], -val, val);
+ }
+ }
+ else {
+ memset(shader->constants, 0, sizeof(VGfloat) * 8);
+ }
- assert(param_bytes <= sizeof(temp_buf));
- paint_fill_constant_buffer(shader->paint, temp_buf);
+ paint_fill_constant_buffer(shader->paint,
+ &shader->paint_matrix, shader->constants + 8);
- if (*cbuf == NULL ||
- memcmp(temp_buf, shader->constants, param_bytes) != 0)
- {
- pipe_resource_reference(cbuf, NULL);
+ return param_bytes;
+}
+
+static VGboolean blend_use_shader(struct vg_context *ctx)
+{
+ VGboolean advanced_blending;
- memcpy(shader->constants, temp_buf, param_bytes);
- *cbuf = pipe_user_buffer_create(pipe->screen,
- &shader->constants,
- sizeof(shader->constants),
- PIPE_BIND_VERTEX_BUFFER);
+ switch (ctx->state.vg.blend_mode) {
+ case VG_BLEND_SRC_OVER:
+ advanced_blending =
+ util_format_has_alpha(ctx->draw_buffer->strb->format);
+ break;
+ case VG_BLEND_DST_OVER:
+ case VG_BLEND_MULTIPLY:
+ case VG_BLEND_SCREEN:
+ case VG_BLEND_DARKEN:
+ case VG_BLEND_LIGHTEN:
+ case VG_BLEND_ADDITIVE:
+ advanced_blending = VG_TRUE;
+ break;
+ default:
+ advanced_blending = VG_FALSE;
+ break;
}
- ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf);
+ return advanced_blending;
}
static VGint blend_bind_samplers(struct vg_context *ctx,
struct pipe_sampler_state **samplers,
struct pipe_sampler_view **sampler_views)
{
- VGBlendMode bmode = ctx->state.vg.blend_mode;
-
- if (bmode == VG_BLEND_MULTIPLY ||
- bmode == VG_BLEND_SCREEN ||
- bmode == VG_BLEND_DARKEN ||
- bmode == VG_BLEND_LIGHTEN) {
- struct st_framebuffer *stfb = ctx->draw_buffer;
-
- vg_prepare_blend_surface(ctx);
-
+ if (blend_use_shader(ctx)) {
samplers[2] = &ctx->blend_sampler;
- sampler_views[2] = stfb->blend_texture_view;
+ sampler_views[2] = vg_prepare_blend_surface(ctx);
if (!samplers[0] || !sampler_views[0]) {
samplers[0] = samplers[2];
@@ -149,10 +176,10 @@ static VGint blend_bind_samplers(struct vg_context *ctx,
return 0;
}
-static void setup_samplers(struct shader *shader)
+static VGint setup_samplers(struct shader *shader,
+ struct pipe_sampler_state **samplers,
+ struct pipe_sampler_view **sampler_views)
{
- struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
struct vg_context *ctx = shader->context;
/* a little wonky: we use the num as a boolean that just says
* whether any sampler/textures have been set. the actual numbering
@@ -179,10 +206,7 @@ static void setup_samplers(struct shader *shader)
if (shader->drawing_image && shader->image)
num += image_bind_samplers(shader->image, samplers, sampler_views);
- if (num) {
- cso_set_samplers(ctx->cso_context, 4, (const struct pipe_sampler_state **)samplers);
- cso_set_fragment_sampler_views(ctx->cso_context, 4, sampler_views);
- }
+ return (num) ? 4 : 0;
}
static INLINE VGboolean is_format_bw(struct shader *shader)
@@ -227,6 +251,9 @@ static void setup_shader_program(struct shader *shader)
default:
abort();
}
+
+ if (paint_is_degenerate(shader->paint))
+ shader_id = VEGA_PAINT_DEGENERATE_SHADER;
}
/* second stage image */
@@ -246,43 +273,86 @@ static void setup_shader_program(struct shader *shader)
}
}
- if (shader->masking)
- shader_id |= VEGA_MASK_SHADER;
+ if (shader->color_transform)
+ shader_id |= VEGA_COLOR_TRANSFORM_SHADER;
- switch(blend_mode) {
- case VG_BLEND_MULTIPLY:
- shader_id |= VEGA_BLEND_MULTIPLY_SHADER;
- break;
- case VG_BLEND_SCREEN:
- shader_id |= VEGA_BLEND_SCREEN_SHADER;
- break;
- case VG_BLEND_DARKEN:
- shader_id |= VEGA_BLEND_DARKEN_SHADER;
- break;
- case VG_BLEND_LIGHTEN:
- shader_id |= VEGA_BLEND_LIGHTEN_SHADER;
- break;
- default:
- /* handled by pipe_blend_state */
- break;
+ if (blend_use_shader(ctx)) {
+ if (shader->drawing_image && shader->image_mode == VG_DRAW_IMAGE_STENCIL)
+ shader_id |= VEGA_ALPHA_PER_CHANNEL_SHADER;
+ else
+ shader_id |= VEGA_ALPHA_NORMAL_SHADER;
+
+ switch(blend_mode) {
+ case VG_BLEND_SRC:
+ shader_id |= VEGA_BLEND_SRC_SHADER;
+ break;
+ case VG_BLEND_SRC_OVER:
+ shader_id |= VEGA_BLEND_SRC_OVER_SHADER;
+ break;
+ case VG_BLEND_DST_OVER:
+ shader_id |= VEGA_BLEND_DST_OVER_SHADER;
+ break;
+ case VG_BLEND_SRC_IN:
+ shader_id |= VEGA_BLEND_SRC_IN_SHADER;
+ break;
+ case VG_BLEND_DST_IN:
+ shader_id |= VEGA_BLEND_DST_IN_SHADER;
+ break;
+ case VG_BLEND_MULTIPLY:
+ shader_id |= VEGA_BLEND_MULTIPLY_SHADER;
+ break;
+ case VG_BLEND_SCREEN:
+ shader_id |= VEGA_BLEND_SCREEN_SHADER;
+ break;
+ case VG_BLEND_DARKEN:
+ shader_id |= VEGA_BLEND_DARKEN_SHADER;
+ break;
+ case VG_BLEND_LIGHTEN:
+ shader_id |= VEGA_BLEND_LIGHTEN_SHADER;
+ break;
+ case VG_BLEND_ADDITIVE:
+ shader_id |= VEGA_BLEND_ADDITIVE_SHADER;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+ else {
+ /* update alpha of the source */
+ if (shader->drawing_image && shader->image_mode == VG_DRAW_IMAGE_STENCIL)
+ shader_id |= VEGA_ALPHA_PER_CHANNEL_SHADER;
}
+ if (shader->masking)
+ shader_id |= VEGA_MASK_SHADER;
+
if (black_white)
shader_id |= VEGA_BW_SHADER;
shader->fs = shaders_cache_fill(ctx->sc, shader_id);
- cso_set_fragment_shader_handle(ctx->cso_context, shader->fs);
}
void shader_bind(struct shader *shader)
{
+ struct vg_context *ctx = shader->context;
+ struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
+ VGint num_samplers, param_bytes;
+
/* first resolve the real paint type */
paint_resolve_type(shader->paint);
- setup_constant_buffer(shader);
- setup_samplers(shader);
+ num_samplers = setup_samplers(shader, samplers, sampler_views);
+ param_bytes = setup_constant_buffer(shader);
setup_shader_program(shader);
+
+ renderer_validate_for_shader(ctx->renderer,
+ (const struct pipe_sampler_state **) samplers,
+ sampler_views, num_samplers,
+ &shader->modelview,
+ shader->fs, (const void *) shader->constants, param_bytes);
}
void shader_set_image_mode(struct shader *shader, VGImageMode image_mode)
@@ -309,3 +379,28 @@ void shader_set_image(struct shader *shader, struct vg_image *img)
{
shader->image = img;
}
+
+/**
+ * Set the transformation to map a vertex to the surface coordinates.
+ */
+void shader_set_surface_matrix(struct shader *shader,
+ const struct matrix *mat)
+{
+ shader->modelview = *mat;
+}
+
+/**
+ * Set the transformation to map a pixel to the paint coordinates.
+ */
+void shader_set_paint_matrix(struct shader *shader, const struct matrix *mat)
+{
+ const struct st_framebuffer *stfb = shader->context->draw_buffer;
+ const VGfloat px_center_offset = 0.5f;
+
+ memcpy(&shader->paint_matrix, mat, sizeof(*mat));
+
+ /* make it window-to-paint for the shaders */
+ matrix_translate(&shader->paint_matrix, px_center_offset,
+ stfb->height - 1.0f + px_center_offset);
+ matrix_scale(&shader->paint_matrix, 1.0f, -1.0f);
+}
diff --git a/src/gallium/state_trackers/vega/shader.h b/src/gallium/state_trackers/vega/shader.h
index 847eee6a310..8b97e537efe 100644
--- a/src/gallium/state_trackers/vega/shader.h
+++ b/src/gallium/state_trackers/vega/shader.h
@@ -33,10 +33,13 @@ struct shader;
struct vg_paint;
struct vg_context;
struct vg_image;
+struct matrix;
struct shader *shader_create(struct vg_context *context);
void shader_destroy(struct shader *shader);
+void shader_set_color_transform(struct shader *shader, VGboolean set);
+
void shader_set_masking(struct shader *shader, VGboolean set);
VGboolean shader_is_masking(struct shader *shader);
@@ -51,6 +54,10 @@ VGboolean shader_drawing_image(struct shader *shader);
void shader_set_image(struct shader *shader, struct vg_image *img);
+void shader_set_surface_matrix(struct shader *shader,
+ const struct matrix *mat);
+void shader_set_paint_matrix(struct shader *shader, const struct matrix *mat);
+
void shader_bind(struct shader *shader);
#endif
diff --git a/src/gallium/state_trackers/vega/shaders_cache.c b/src/gallium/state_trackers/vega/shaders_cache.c
index e002a7ed428..023996ce2d8 100644
--- a/src/gallium/state_trackers/vega/shaders_cache.c
+++ b/src/gallium/state_trackers/vega/shaders_cache.c
@@ -50,14 +50,16 @@
/* Essentially we construct an ubber-shader based on the state
* of the pipeline. The stages are:
- * 1) Fill (mandatory, solid color/gradient/pattern/image draw)
- * 2) Image composition (image mode multiply and stencil)
- * 3) Mask
- * 4) Extended blend (multiply/screen/darken/lighten)
- * 5) Premultiply/Unpremultiply
- * 6) Color transform (to black and white)
+ * 1) Paint generation (color/gradient/pattern)
+ * 2) Image composition (normal/multiply/stencil)
+ * 3) Color transform
+ * 4) Per-channel alpha generation
+ * 5) Extended blend (multiply/screen/darken/lighten)
+ * 6) Mask
+ * 7) Premultiply/Unpremultiply
+ * 8) Color transform (to black and white)
*/
-#define SHADER_STAGES 6
+#define SHADER_STAGES 8
struct cached_shader {
void *driver_shader;
@@ -86,13 +88,6 @@ static INLINE struct tgsi_token *tokens_from_assembly(const char *txt, int num_t
return tokens;
}
-#define ALL_FILLS (VEGA_SOLID_FILL_SHADER | \
- VEGA_LINEAR_GRADIENT_SHADER | \
- VEGA_RADIAL_GRADIENT_SHADER | \
- VEGA_PATTERN_SHADER | \
- VEGA_IMAGE_NORMAL_SHADER)
-
-
/*
static const char max_shader_preamble[] =
"FRAG\n"
@@ -257,98 +252,126 @@ create_shader(struct pipe_context *pipe,
int id,
struct pipe_shader_state *shader)
{
- int idx = 0;
+ int idx = 0, sh;
const struct shader_asm_info * shaders[SHADER_STAGES];
- /* the shader has to have a fill */
- debug_assert(id & ALL_FILLS);
-
/* first stage */
- if (id & VEGA_SOLID_FILL_SHADER) {
- debug_assert(idx == 0);
- shaders[idx] = &shaders_asm[0];
- debug_assert(shaders_asm[0].id == VEGA_SOLID_FILL_SHADER);
- ++idx;
- }
- if ((id & VEGA_LINEAR_GRADIENT_SHADER)) {
- debug_assert(idx == 0);
- shaders[idx] = &shaders_asm[1];
- debug_assert(shaders_asm[1].id == VEGA_LINEAR_GRADIENT_SHADER);
- ++idx;
- }
- if ((id & VEGA_RADIAL_GRADIENT_SHADER)) {
- debug_assert(idx == 0);
- shaders[idx] = &shaders_asm[2];
- debug_assert(shaders_asm[2].id == VEGA_RADIAL_GRADIENT_SHADER);
- ++idx;
- }
- if ((id & VEGA_PATTERN_SHADER)) {
- debug_assert(idx == 0);
- debug_assert(shaders_asm[3].id == VEGA_PATTERN_SHADER);
- shaders[idx] = &shaders_asm[3];
- ++idx;
- }
- if ((id & VEGA_IMAGE_NORMAL_SHADER)) {
- debug_assert(idx == 0);
- debug_assert(shaders_asm[4].id == VEGA_IMAGE_NORMAL_SHADER);
- shaders[idx] = &shaders_asm[4];
- ++idx;
+ sh = SHADERS_GET_PAINT_SHADER(id);
+ switch (sh << SHADERS_PAINT_SHIFT) {
+ case VEGA_SOLID_FILL_SHADER:
+ case VEGA_LINEAR_GRADIENT_SHADER:
+ case VEGA_RADIAL_GRADIENT_SHADER:
+ case VEGA_PATTERN_SHADER:
+ case VEGA_PAINT_DEGENERATE_SHADER:
+ shaders[idx] = &shaders_paint_asm[(sh >> SHADERS_PAINT_SHIFT) - 1];
+ assert(shaders[idx]->id == sh);
+ idx++;
+ break;
+ default:
+ break;
}
/* second stage */
- if ((id & VEGA_IMAGE_MULTIPLY_SHADER)) {
- debug_assert(shaders_asm[5].id == VEGA_IMAGE_MULTIPLY_SHADER);
- shaders[idx] = &shaders_asm[5];
- ++idx;
- } else if ((id & VEGA_IMAGE_STENCIL_SHADER)) {
- debug_assert(shaders_asm[6].id == VEGA_IMAGE_STENCIL_SHADER);
- shaders[idx] = &shaders_asm[6];
- ++idx;
+ sh = SHADERS_GET_IMAGE_SHADER(id);
+ switch (sh) {
+ case VEGA_IMAGE_NORMAL_SHADER:
+ case VEGA_IMAGE_MULTIPLY_SHADER:
+ case VEGA_IMAGE_STENCIL_SHADER:
+ shaders[idx] = &shaders_image_asm[(sh >> SHADERS_IMAGE_SHIFT) - 1];
+ assert(shaders[idx]->id == sh);
+ idx++;
+ break;
+ default:
+ break;
}
+ /* sanity check */
+ assert(idx == ((!sh || sh == VEGA_IMAGE_NORMAL_SHADER) ? 1 : 2));
+
/* third stage */
- if ((id & VEGA_MASK_SHADER)) {
- debug_assert(idx == 1);
- debug_assert(shaders_asm[7].id == VEGA_MASK_SHADER);
- shaders[idx] = &shaders_asm[7];
- ++idx;
+ sh = SHADERS_GET_COLOR_TRANSFORM_SHADER(id);
+ switch (sh) {
+ case VEGA_COLOR_TRANSFORM_SHADER:
+ shaders[idx] = &shaders_color_transform_asm[
+ (sh >> SHADERS_COLOR_TRANSFORM_SHIFT) - 1];
+ assert(shaders[idx]->id == sh);
+ idx++;
+ break;
+ default:
+ break;
}
/* fourth stage */
- if ((id & VEGA_BLEND_MULTIPLY_SHADER)) {
- debug_assert(shaders_asm[8].id == VEGA_BLEND_MULTIPLY_SHADER);
- shaders[idx] = &shaders_asm[8];
- ++idx;
- } else if ((id & VEGA_BLEND_SCREEN_SHADER)) {
- debug_assert(shaders_asm[9].id == VEGA_BLEND_SCREEN_SHADER);
- shaders[idx] = &shaders_asm[9];
- ++idx;
- } else if ((id & VEGA_BLEND_DARKEN_SHADER)) {
- debug_assert(shaders_asm[10].id == VEGA_BLEND_DARKEN_SHADER);
- shaders[idx] = &shaders_asm[10];
- ++idx;
- } else if ((id & VEGA_BLEND_LIGHTEN_SHADER)) {
- debug_assert(shaders_asm[11].id == VEGA_BLEND_LIGHTEN_SHADER);
- shaders[idx] = &shaders_asm[11];
- ++idx;
+ sh = SHADERS_GET_ALPHA_SHADER(id);
+ switch (sh) {
+ case VEGA_ALPHA_NORMAL_SHADER:
+ case VEGA_ALPHA_PER_CHANNEL_SHADER:
+ shaders[idx] = &shaders_alpha_asm[
+ (sh >> SHADERS_ALPHA_SHIFT) - 1];
+ assert(shaders[idx]->id == sh);
+ idx++;
+ break;
+ default:
+ break;
}
/* fifth stage */
- if ((id & VEGA_PREMULTIPLY_SHADER)) {
- debug_assert(shaders_asm[12].id == VEGA_PREMULTIPLY_SHADER);
- shaders[idx] = &shaders_asm[12];
- ++idx;
- } else if ((id & VEGA_UNPREMULTIPLY_SHADER)) {
- debug_assert(shaders_asm[13].id == VEGA_UNPREMULTIPLY_SHADER);
- shaders[idx] = &shaders_asm[13];
- ++idx;
+ sh = SHADERS_GET_BLEND_SHADER(id);
+ switch (sh) {
+ case VEGA_BLEND_SRC_SHADER:
+ case VEGA_BLEND_SRC_OVER_SHADER:
+ case VEGA_BLEND_DST_OVER_SHADER:
+ case VEGA_BLEND_SRC_IN_SHADER:
+ case VEGA_BLEND_DST_IN_SHADER:
+ case VEGA_BLEND_MULTIPLY_SHADER:
+ case VEGA_BLEND_SCREEN_SHADER:
+ case VEGA_BLEND_DARKEN_SHADER:
+ case VEGA_BLEND_LIGHTEN_SHADER:
+ case VEGA_BLEND_ADDITIVE_SHADER:
+ shaders[idx] = &shaders_blend_asm[(sh >> SHADERS_BLEND_SHIFT) - 1];
+ assert(shaders[idx]->id == sh);
+ idx++;
+ break;
+ default:
+ break;
}
/* sixth stage */
- if ((id & VEGA_BW_SHADER)) {
- debug_assert(shaders_asm[14].id == VEGA_BW_SHADER);
- shaders[idx] = &shaders_asm[14];
- ++idx;
+ sh = SHADERS_GET_MASK_SHADER(id);
+ switch (sh) {
+ case VEGA_MASK_SHADER:
+ shaders[idx] = &shaders_mask_asm[(sh >> SHADERS_MASK_SHIFT) - 1];
+ assert(shaders[idx]->id == sh);
+ idx++;
+ break;
+ default:
+ break;
+ }
+
+ /* seventh stage */
+ sh = SHADERS_GET_PREMULTIPLY_SHADER(id);
+ switch (sh) {
+ case VEGA_PREMULTIPLY_SHADER:
+ case VEGA_UNPREMULTIPLY_SHADER:
+ shaders[idx] = &shaders_premultiply_asm[
+ (sh >> SHADERS_PREMULTIPLY_SHIFT) - 1];
+ assert(shaders[idx]->id == sh);
+ idx++;
+ break;
+ default:
+ break;
+ }
+
+ /* eighth stage */
+ sh = SHADERS_GET_BW_SHADER(id);
+ switch (sh) {
+ case VEGA_BW_SHADER:
+ shaders[idx] = &shaders_bw_asm[(sh >> SHADERS_BW_SHIFT) - 1];
+ assert(shaders[idx]->id == sh);
+ idx++;
+ break;
+ default:
+ break;
}
return combine_shaders(shaders, idx, pipe, shader);
diff --git a/src/gallium/state_trackers/vega/shaders_cache.h b/src/gallium/state_trackers/vega/shaders_cache.h
index feca58b61a9..05014f25dcc 100644
--- a/src/gallium/state_trackers/vega/shaders_cache.h
+++ b/src/gallium/state_trackers/vega/shaders_cache.h
@@ -33,26 +33,69 @@ struct pipe_context;
struct tgsi_token;
struct shaders_cache;
+#define _SHADERS_PAINT_BITS 3
+#define _SHADERS_IMAGE_BITS 2
+#define _SHADERS_COLOR_TRANSFORM_BITS 1
+#define _SHADERS_ALPHA_BITS 2
+#define _SHADERS_BLEND_BITS 4
+#define _SHADERS_MASK_BITS 1
+#define _SHADERS_PREMULTIPLY_BITS 2
+#define _SHADERS_BW_BITS 1
+
+#define SHADERS_PAINT_SHIFT (0)
+#define SHADERS_IMAGE_SHIFT (SHADERS_PAINT_SHIFT + _SHADERS_PAINT_BITS)
+#define SHADERS_COLOR_TRANSFORM_SHIFT (SHADERS_IMAGE_SHIFT + _SHADERS_IMAGE_BITS)
+#define SHADERS_ALPHA_SHIFT (SHADERS_COLOR_TRANSFORM_SHIFT + _SHADERS_COLOR_TRANSFORM_BITS)
+#define SHADERS_BLEND_SHIFT (SHADERS_ALPHA_SHIFT + _SHADERS_ALPHA_BITS)
+#define SHADERS_MASK_SHIFT (SHADERS_BLEND_SHIFT + _SHADERS_BLEND_BITS)
+#define SHADERS_PREMULTIPLY_SHIFT (SHADERS_MASK_SHIFT + _SHADERS_MASK_BITS)
+#define SHADERS_BW_SHIFT (SHADERS_PREMULTIPLY_SHIFT + _SHADERS_PREMULTIPLY_BITS)
+
+#define _SHADERS_GET_STAGE(stage, id) \
+ ((id) & (((1 << _SHADERS_ ## stage ## _BITS) - 1) << SHADERS_ ## stage ## _SHIFT))
+
+#define SHADERS_GET_PAINT_SHADER(id) _SHADERS_GET_STAGE(PAINT, id)
+#define SHADERS_GET_IMAGE_SHADER(id) _SHADERS_GET_STAGE(IMAGE, id)
+#define SHADERS_GET_COLOR_TRANSFORM_SHADER(id) _SHADERS_GET_STAGE(COLOR_TRANSFORM, id)
+#define SHADERS_GET_ALPHA_SHADER(id) _SHADERS_GET_STAGE(ALPHA, id)
+#define SHADERS_GET_BLEND_SHADER(id) _SHADERS_GET_STAGE(BLEND, id)
+#define SHADERS_GET_MASK_SHADER(id) _SHADERS_GET_STAGE(MASK, id)
+#define SHADERS_GET_PREMULTIPLY_SHADER(id) _SHADERS_GET_STAGE(PREMULTIPLY, id)
+#define SHADERS_GET_BW_SHADER(id) _SHADERS_GET_STAGE(BW, id)
+
enum VegaShaderType {
- VEGA_SOLID_FILL_SHADER = 1 << 0,
- VEGA_LINEAR_GRADIENT_SHADER = 1 << 1,
- VEGA_RADIAL_GRADIENT_SHADER = 1 << 2,
- VEGA_PATTERN_SHADER = 1 << 3,
- VEGA_IMAGE_NORMAL_SHADER = 1 << 4,
- VEGA_IMAGE_MULTIPLY_SHADER = 1 << 5,
- VEGA_IMAGE_STENCIL_SHADER = 1 << 6,
+ VEGA_SOLID_FILL_SHADER = 1 << SHADERS_PAINT_SHIFT,
+ VEGA_LINEAR_GRADIENT_SHADER = 2 << SHADERS_PAINT_SHIFT,
+ VEGA_RADIAL_GRADIENT_SHADER = 3 << SHADERS_PAINT_SHIFT,
+ VEGA_PATTERN_SHADER = 4 << SHADERS_PAINT_SHIFT,
+ VEGA_PAINT_DEGENERATE_SHADER = 5 << SHADERS_PAINT_SHIFT,
+
+ VEGA_IMAGE_NORMAL_SHADER = 1 << SHADERS_IMAGE_SHIFT,
+ VEGA_IMAGE_MULTIPLY_SHADER = 2 << SHADERS_IMAGE_SHIFT,
+ VEGA_IMAGE_STENCIL_SHADER = 3 << SHADERS_IMAGE_SHIFT,
+
+ VEGA_COLOR_TRANSFORM_SHADER = 1 << SHADERS_COLOR_TRANSFORM_SHIFT,
+
+ VEGA_ALPHA_NORMAL_SHADER = 1 << SHADERS_ALPHA_SHIFT,
+ VEGA_ALPHA_PER_CHANNEL_SHADER = 2 << SHADERS_ALPHA_SHIFT,
- VEGA_MASK_SHADER = 1 << 7,
+ VEGA_BLEND_SRC_SHADER = 1 << SHADERS_BLEND_SHIFT,
+ VEGA_BLEND_SRC_OVER_SHADER = 2 << SHADERS_BLEND_SHIFT,
+ VEGA_BLEND_DST_OVER_SHADER = 3 << SHADERS_BLEND_SHIFT,
+ VEGA_BLEND_SRC_IN_SHADER = 4 << SHADERS_BLEND_SHIFT,
+ VEGA_BLEND_DST_IN_SHADER = 5 << SHADERS_BLEND_SHIFT,
+ VEGA_BLEND_MULTIPLY_SHADER = 6 << SHADERS_BLEND_SHIFT,
+ VEGA_BLEND_SCREEN_SHADER = 7 << SHADERS_BLEND_SHIFT,
+ VEGA_BLEND_DARKEN_SHADER = 8 << SHADERS_BLEND_SHIFT,
+ VEGA_BLEND_LIGHTEN_SHADER = 9 << SHADERS_BLEND_SHIFT,
+ VEGA_BLEND_ADDITIVE_SHADER = 10<< SHADERS_BLEND_SHIFT,
- VEGA_BLEND_MULTIPLY_SHADER = 1 << 8,
- VEGA_BLEND_SCREEN_SHADER = 1 << 9,
- VEGA_BLEND_DARKEN_SHADER = 1 << 10,
- VEGA_BLEND_LIGHTEN_SHADER = 1 << 11,
+ VEGA_MASK_SHADER = 1 << SHADERS_MASK_SHIFT,
- VEGA_PREMULTIPLY_SHADER = 1 << 12,
- VEGA_UNPREMULTIPLY_SHADER = 1 << 13,
+ VEGA_PREMULTIPLY_SHADER = 1 << SHADERS_PREMULTIPLY_SHIFT,
+ VEGA_UNPREMULTIPLY_SHADER = 2 << SHADERS_PREMULTIPLY_SHIFT,
- VEGA_BW_SHADER = 1 << 14
+ VEGA_BW_SHADER = 1 << SHADERS_BW_SHIFT
};
struct vg_shader {
diff --git a/src/gallium/state_trackers/vega/st_inlines.h b/src/gallium/state_trackers/vega/st_inlines.h
deleted file mode 100644
index 7eaa67c76ae..00000000000
--- a/src/gallium/state_trackers/vega/st_inlines.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009 VMware, Inc.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE 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.
- *
- **************************************************************************/
-
-/**
- * Functions for checking if buffers/textures are referenced when we need
- * to read/write from/to them. Flush when needed.
- */
-
-#ifndef ST_INLINES_H
-#define ST_INLINES_H
-
-#include "vg_context.h"
-
-#include "pipe/p_context.h"
-#include "pipe/p_screen.h"
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
-#include "pipe/p_state.h"
-
-static INLINE struct pipe_transfer *
-st_cond_flush_get_transfer(struct vg_context *st,
- struct pipe_resource *pt,
- unsigned int face,
- unsigned int level,
- unsigned int zslice,
- enum pipe_transfer_usage usage,
- unsigned int x, unsigned int y,
- unsigned int w, unsigned int h)
-{
- struct pipe_context *pipe = st->pipe;
-
- return pipe_get_transfer(pipe, pt, face, level, zslice, usage,
- x, y, w, h);
-}
-
-static INLINE struct pipe_transfer *
-st_no_flush_get_transfer(struct vg_context *st,
- struct pipe_resource *pt,
- unsigned int face,
- unsigned int level,
- unsigned int zslice,
- enum pipe_transfer_usage usage,
- unsigned int x, unsigned int y,
- unsigned int w, unsigned int h)
-{
- struct pipe_context *pipe = st->pipe;
-
- return pipe_get_transfer(pipe, pt, face, level,
- zslice, usage, x, y, w, h);
-}
-
-
-static INLINE void
-st_cond_flush_pipe_buffer_write(struct vg_context *st,
- struct pipe_resource *buf,
- unsigned int offset,
- unsigned int size,
- const void * data)
-{
- struct pipe_context *pipe = st->pipe;
-
- pipe_buffer_write(pipe, buf, offset, size, data);
-}
-
-static INLINE void
-st_no_flush_pipe_buffer_write(struct vg_context *st,
- struct pipe_resource *buf,
- unsigned int offset,
- unsigned int size,
- const void * data)
-{
- pipe_buffer_write(st->pipe, buf, offset, size, data);
-}
-
-static INLINE void
-st_cond_flush_pipe_buffer_read(struct vg_context *st,
- struct pipe_resource *buf,
- unsigned int offset,
- unsigned int size,
- void * data)
-{
- struct pipe_context *pipe = st->pipe;
-
- pipe_buffer_read(pipe, buf, offset, size, data);
-}
-
-static INLINE void
-st_no_flush_pipe_buffer_read(struct vg_context *st,
- struct pipe_resource *buf,
- unsigned int offset,
- unsigned int size,
- void * data)
-{
- pipe_buffer_read(st->pipe, buf, offset, size, data);
-}
-
-#endif
-
diff --git a/src/gallium/state_trackers/vega/text.c b/src/gallium/state_trackers/vega/text.c
new file mode 100644
index 00000000000..01ff602f58a
--- /dev/null
+++ b/src/gallium/state_trackers/vega/text.c
@@ -0,0 +1,250 @@
+/**************************************************************************
+ *
+ * Copyright 2010 LunarG, Inc. All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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.
+ *
+ **************************************************************************/
+
+#include "util/u_memory.h"
+#include "cso_cache/cso_hash.h"
+
+#include "text.h"
+#include "image.h"
+#include "path.h"
+#include "api.h"
+
+#ifdef OPENVG_VERSION_1_1
+
+struct vg_font {
+ struct vg_object base;
+ struct cso_hash *glyphs;
+};
+
+struct vg_glyph {
+ struct vg_object *object; /* it could be NULL */
+ VGboolean is_hinted;
+ VGfloat glyph_origin[2];
+ VGfloat escapement[2];
+};
+
+static VGboolean del_glyph(struct vg_font *font,
+ VGuint glyphIndex)
+{
+ struct vg_glyph *glyph;
+
+ glyph = (struct vg_glyph *)
+ cso_hash_take(font->glyphs, (unsigned) glyphIndex);
+ if (glyph)
+ FREE(glyph);
+
+ return (glyph != NULL);
+}
+
+static void add_glyph(struct vg_font *font,
+ VGuint glyphIndex,
+ struct vg_object *obj,
+ VGboolean isHinted,
+ const VGfloat glyphOrigin[2],
+ const VGfloat escapement[2])
+{
+ struct vg_glyph *glyph;
+
+ /* remove the existing one */
+ del_glyph(font, glyphIndex);
+
+ glyph = CALLOC_STRUCT(vg_glyph);
+ glyph->object = obj;
+ glyph->is_hinted = isHinted;
+ memcpy(glyph->glyph_origin, glyphOrigin, sizeof(glyphOrigin));
+ memcpy(glyph->escapement, escapement, sizeof(escapement));
+
+ cso_hash_insert(font->glyphs, (unsigned) glyphIndex, glyph);
+}
+
+static struct vg_glyph *get_glyph(struct vg_font *font,
+ VGuint glyphIndex)
+{
+ struct cso_hash_iter iter;
+
+ iter = cso_hash_find(font->glyphs, (unsigned) glyphIndex);
+ return (struct vg_glyph *) cso_hash_iter_data(iter);
+}
+
+static void vg_render_glyph(struct vg_context *ctx,
+ struct vg_glyph *glyph,
+ VGbitfield paintModes,
+ VGboolean allowAutoHinting)
+{
+ if (glyph->object && paintModes) {
+ struct vg_state *state = &ctx->state.vg;
+ struct matrix m;
+
+ m = state->glyph_user_to_surface_matrix;
+ matrix_translate(&m,
+ state->glyph_origin[0].f - glyph->glyph_origin[0],
+ state->glyph_origin[1].f - glyph->glyph_origin[1]);
+
+ if (glyph->object->type == VG_OBJECT_PATH) {
+ path_render((struct path *) glyph->object, paintModes, &m);
+ }
+ else {
+ assert(glyph->object->type == VG_OBJECT_IMAGE);
+ image_draw((struct vg_image *) glyph->object, &m);
+ }
+ }
+}
+
+static void vg_advance_glyph(struct vg_context *ctx,
+ struct vg_glyph *glyph,
+ VGfloat adjustment_x,
+ VGfloat adjustment_y,
+ VGboolean last)
+{
+ struct vg_value *glyph_origin = ctx->state.vg.glyph_origin;
+
+ glyph_origin[0].f += glyph->escapement[0] + adjustment_x;
+ glyph_origin[1].f += glyph->escapement[1] + adjustment_y;
+
+ if (last) {
+ glyph_origin[0].i = float_to_int_floor(glyph_origin[0].f);
+ glyph_origin[1].i = float_to_int_floor(glyph_origin[1].f);
+ }
+}
+
+struct vg_font *font_create(VGint glyphCapacityHint)
+{
+ struct vg_context *ctx = vg_current_context();
+ struct vg_font *font;
+
+ font = CALLOC_STRUCT(vg_font);
+ vg_init_object(&font->base, ctx, VG_OBJECT_FONT);
+ font->glyphs = cso_hash_create();
+
+ vg_context_add_object(ctx, VG_OBJECT_FONT, font);
+
+ return font;
+}
+
+void font_destroy(struct vg_font *font)
+{
+ struct vg_context *ctx = vg_current_context();
+ struct cso_hash_iter iter;
+
+ vg_context_remove_object(ctx, VG_OBJECT_FONT, font);
+
+ iter = cso_hash_first_node(font->glyphs);
+ while (!cso_hash_iter_is_null(iter)) {
+ struct vg_glyph *glyph = (struct vg_glyph *) cso_hash_iter_data(iter);
+ FREE(glyph);
+ iter = cso_hash_iter_next(iter);
+ }
+ cso_hash_delete(font->glyphs);
+
+ FREE(font);
+}
+
+void font_set_glyph_to_path(struct vg_font *font,
+ VGuint glyphIndex,
+ struct path *path,
+ VGboolean isHinted,
+ const VGfloat glyphOrigin[2],
+ const VGfloat escapement[2])
+{
+ add_glyph(font, glyphIndex, (struct vg_object *) path,
+ isHinted, glyphOrigin, escapement);
+}
+
+void font_set_glyph_to_image(struct vg_font *font,
+ VGuint glyphIndex,
+ struct vg_image *image,
+ const VGfloat glyphOrigin[2],
+ const VGfloat escapement[2])
+{
+ add_glyph(font, glyphIndex, (struct vg_object *) image,
+ VG_TRUE, glyphOrigin, escapement);
+}
+
+void font_clear_glyph(struct vg_font *font,
+ VGuint glyphIndex)
+{
+ if (!del_glyph(font, glyphIndex)) {
+ struct vg_context *ctx = vg_current_context();
+ vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
+ }
+}
+
+void font_draw_glyph(struct vg_font *font,
+ VGuint glyphIndex,
+ VGbitfield paintModes,
+ VGboolean allowAutoHinting)
+{
+ struct vg_context *ctx = vg_current_context();
+ struct vg_glyph *glyph;
+
+ glyph = get_glyph(font, glyphIndex);
+ if (!glyph) {
+ vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
+ return;
+ }
+
+ vg_render_glyph(ctx, glyph, paintModes, allowAutoHinting);
+ vg_advance_glyph(ctx, glyph, 0.0f, 0.0f, VG_TRUE);
+}
+
+void font_draw_glyphs(struct vg_font *font,
+ VGint glyphCount,
+ const VGuint *glyphIndices,
+ const VGfloat *adjustments_x,
+ const VGfloat *adjustments_y,
+ VGbitfield paintModes,
+ VGboolean allowAutoHinting)
+{
+ struct vg_context *ctx = vg_current_context();
+ VGint i;
+
+ for (i = 0; i < glyphCount; ++i) {
+ if (!get_glyph(font, glyphIndices[i])) {
+ vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
+ return;
+ }
+ }
+
+ for (i = 0; i < glyphCount; ++i) {
+ struct vg_glyph *glyph;
+ VGfloat adj_x, adj_y;
+
+ glyph = get_glyph(font, glyphIndices[i]);
+
+ vg_render_glyph(ctx, glyph, paintModes, allowAutoHinting);
+
+ adj_x = (adjustments_x) ? adjustments_x[i] : 0.0f;
+ adj_y = (adjustments_y) ? adjustments_y[i] : 0.0f;
+ vg_advance_glyph(ctx, glyph, adj_x, adj_y, (i == glyphCount - 1));
+ }
+}
+
+VGint font_num_glyphs(struct vg_font *font)
+{
+ return cso_hash_size(font->glyphs);
+}
+
+#endif /* OPENVG_VERSION_1_1 */
diff --git a/src/gallium/state_trackers/vega/text.h b/src/gallium/state_trackers/vega/text.h
new file mode 100644
index 00000000000..6b3fa7323e9
--- /dev/null
+++ b/src/gallium/state_trackers/vega/text.h
@@ -0,0 +1,71 @@
+/**************************************************************************
+ *
+ * Copyright 2010 LunarG, Inc. All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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 _TEXT_H
+#define _TEXT_H
+
+#include "vg_context.h"
+#include "cso_cache/cso_hash.h"
+
+struct vg_font;
+struct vg_image;
+struct path;
+
+struct vg_font *font_create(VGint glyphCapacityHint);
+void font_destroy(struct vg_font *font);
+
+void font_set_glyph_to_path(struct vg_font *font,
+ VGuint glyphIndex,
+ struct path *path,
+ VGboolean isHinted,
+ const VGfloat glyphOrigin[2],
+ const VGfloat escapement[2]);
+
+void font_set_glyph_to_image(struct vg_font *font,
+ VGuint glyphIndex,
+ struct vg_image *image,
+ const VGfloat glyphOrigin[2],
+ const VGfloat escapement[2]);
+
+void font_clear_glyph(struct vg_font *font,
+ VGuint glyphIndex);
+
+void font_draw_glyph(struct vg_font *font,
+ VGuint glyphIndex,
+ VGbitfield paintModes,
+ VGboolean allowAutoHinting);
+
+void font_draw_glyphs(struct vg_font *font,
+ VGint glyphCount,
+ const VGuint *glyphIndices,
+ const VGfloat *adjustments_x,
+ const VGfloat *adjustments_y,
+ VGbitfield paintModes,
+ VGboolean allowAutoHinting);
+
+VGint font_num_glyphs(struct vg_font *font);
+
+#endif /* _TEXT_H */
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index 99e444affdf..0844012cc3b 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -31,9 +31,9 @@
#include "shaders_cache.h"
#include "shader.h"
#include "asm_util.h"
-#include "st_inlines.h"
#include "vg_manager.h"
#include "api.h"
+#include "mask.h"
#include "pipe/p_context.h"
#include "util/u_inlines.h"
@@ -44,6 +44,8 @@
#include "util/u_memory.h"
#include "util/u_blit.h"
#include "util/u_sampler.h"
+#include "util/u_surface.h"
+#include "util/u_format.h"
struct vg_context *_vg_context = 0;
@@ -52,19 +54,6 @@ struct vg_context * vg_current_context(void)
return _vg_context;
}
-static void init_clear(struct vg_context *st)
-{
- struct pipe_context *pipe = st->pipe;
-
- /* rasterizer state: bypass clipping */
- memset(&st->clear.raster, 0, sizeof(st->clear.raster));
- st->clear.raster.gl_rasterization_rules = 1;
-
- /* fragment shader state: color pass-through program */
- st->clear.fs =
- util_make_fragment_passthrough_shader(pipe);
-}
-
/**
* A depth/stencil rb will be needed regardless of what the visual says.
*/
@@ -101,7 +90,6 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
struct vg_context *share)
{
struct vg_context *ctx;
- unsigned i;
ctx = CALLOC_STRUCT(vg_context);
@@ -118,8 +106,6 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
ctx->cso_context = cso_create_context(pipe);
- init_clear(ctx);
-
ctx->default_paint = paint_create(ctx);
ctx->state.vg.stroke_paint = ctx->default_paint;
ctx->state.vg.fill_paint = ctx->default_paint;
@@ -141,13 +127,6 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
ctx->blend_sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
ctx->blend_sampler.normalized_coords = 0;
- for (i = 0; i < 2; i++) {
- ctx->velems[i].src_offset = i * 4 * sizeof(float);
- ctx->velems[i].instance_divisor = 0;
- ctx->velems[i].vertex_buffer_index = 0;
- ctx->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- }
-
vg_set_error(ctx, VG_NO_ERROR);
ctx->owned_objects[VG_OBJECT_PAINT] = cso_hash_create();
@@ -168,7 +147,6 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
void vg_destroy_context(struct vg_context *ctx)
{
struct pipe_resource **cbuf = &ctx->mask.cbuf;
- struct pipe_resource **vsbuf = &ctx->vs_const_buffer;
util_destroy_blit(ctx->blit);
renderer_destroy(ctx->renderer);
@@ -179,29 +157,6 @@ void vg_destroy_context(struct vg_context *ctx)
if (*cbuf)
pipe_resource_reference(cbuf, NULL);
- if (*vsbuf)
- pipe_resource_reference(vsbuf, NULL);
-
- if (ctx->clear.fs) {
- cso_delete_fragment_shader(ctx->cso_context, ctx->clear.fs);
- ctx->clear.fs = NULL;
- }
-
- if (ctx->plain_vs) {
- vg_shader_destroy(ctx, ctx->plain_vs);
- ctx->plain_vs = NULL;
- }
- if (ctx->clear_vs) {
- vg_shader_destroy(ctx, ctx->clear_vs);
- ctx->clear_vs = NULL;
- }
- if (ctx->texture_vs) {
- vg_shader_destroy(ctx, ctx->texture_vs);
- ctx->texture_vs = NULL;
- }
-
- if (ctx->pass_through_depth_fs)
- vg_shader_destroy(ctx, ctx->pass_through_depth_fs);
if (ctx->mask.union_fs)
vg_shader_destroy(ctx, ctx->mask.union_fs);
if (ctx->mask.intersect_fs)
@@ -268,186 +223,195 @@ void vg_context_remove_object(struct vg_context *ctx,
}
}
-static void update_clip_state(struct vg_context *ctx)
+static struct pipe_resource *
+create_texture(struct pipe_context *pipe, enum pipe_format format,
+ VGint width, VGint height)
{
- struct pipe_depth_stencil_alpha_state *dsa = &ctx->state.g3d.dsa;
- struct vg_state *state = &ctx->state.vg;
-
- memset(dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
-
- if (state->scissoring) {
- struct pipe_blend_state *blend = &ctx->state.g3d.blend;
- struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
- int i;
-
- dsa->depth.writemask = 1;/*glDepthMask(TRUE);*/
- dsa->depth.func = PIPE_FUNC_ALWAYS;
- dsa->depth.enabled = 1;
-
- cso_save_blend(ctx->cso_context);
- cso_save_fragment_shader(ctx->cso_context);
- /* set a passthrough shader */
- if (!ctx->pass_through_depth_fs)
- ctx->pass_through_depth_fs = shader_create_from_text(ctx->pipe,
- pass_through_depth_asm,
- 40,
- PIPE_SHADER_FRAGMENT);
- cso_set_fragment_shader_handle(ctx->cso_context,
- ctx->pass_through_depth_fs->driver);
- cso_set_depth_stencil_alpha(ctx->cso_context, dsa);
-
- ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0, 0);
-
- /* disable color writes */
- blend->rt[0].colormask = 0; /*disable colorwrites*/
- cso_set_blend(ctx->cso_context, blend);
-
- /* enable scissoring */
- for (i = 0; i < state->scissor_rects_num; ++i) {
- const float x = state->scissor_rects[i * 4 + 0].f;
- const float y = state->scissor_rects[i * 4 + 1].f;
- const float width = state->scissor_rects[i * 4 + 2].f;
- const float height = state->scissor_rects[i * 4 + 3].f;
- VGfloat minx, miny, maxx, maxy;
-
- minx = 0;
- miny = 0;
- maxx = fb->width;
- maxy = fb->height;
-
- if (x > minx)
- minx = x;
- if (y > miny)
- miny = y;
-
- if (x + width < maxx)
- maxx = x + width;
- if (y + height < maxy)
- maxy = y + height;
-
- /* check for null space */
- if (minx >= maxx || miny >= maxy)
- minx = miny = maxx = maxy = 0;
-
- /*glClear(GL_DEPTH_BUFFER_BIT);*/
- renderer_draw_quad(ctx->renderer, minx, miny, maxx, maxy, 0.0f);
- }
-
- cso_restore_blend(ctx->cso_context);
- cso_restore_fragment_shader(ctx->cso_context);
-
- dsa->depth.enabled = 1; /* glEnable(GL_DEPTH_TEST); */
- dsa->depth.writemask = 0;/*glDepthMask(FALSE);*/
- dsa->depth.func = PIPE_FUNC_GEQUAL;
+ struct pipe_resource templ;
+
+ memset(&templ, 0, sizeof(templ));
+
+ if (format != PIPE_FORMAT_NONE) {
+ templ.format = format;
+ }
+ else {
+ templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ }
+
+ templ.target = PIPE_TEXTURE_2D;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+ templ.array_size = 1;
+ templ.last_level = 0;
+
+ if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
+ templ.bind = PIPE_BIND_DEPTH_STENCIL;
+ } else {
+ templ.bind = (PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_SAMPLER_VIEW);
}
+
+ return pipe->screen->resource_create(pipe->screen, &templ);
}
-void vg_validate_state(struct vg_context *ctx)
+static struct pipe_sampler_view *
+create_tex_and_view(struct pipe_context *pipe, enum pipe_format format,
+ VGint width, VGint height)
{
- vg_manager_validate_framebuffer(ctx);
+ struct pipe_resource *texture;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
- if ((ctx->state.dirty & BLEND_DIRTY)) {
- struct pipe_blend_state *blend = &ctx->state.g3d.blend;
- memset(blend, 0, sizeof(struct pipe_blend_state));
- blend->rt[0].blend_enable = 1;
- blend->rt[0].colormask = PIPE_MASK_RGBA;
-
- switch (ctx->state.vg.blend_mode) {
- case VG_BLEND_SRC:
- blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend->rt[0].blend_enable = 0;
- break;
- case VG_BLEND_SRC_OVER:
- blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
- blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
- blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
- break;
- case VG_BLEND_DST_OVER:
- blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
- blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
- blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA;
- blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA;
- break;
- case VG_BLEND_SRC_IN:
- blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
- blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
- blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- break;
- case VG_BLEND_DST_IN:
- blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO;
- blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
- blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
- blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
- break;
- case VG_BLEND_MULTIPLY:
- case VG_BLEND_SCREEN:
- case VG_BLEND_DARKEN:
- case VG_BLEND_LIGHTEN:
- blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend->rt[0].blend_enable = 0;
- break;
- case VG_BLEND_ADDITIVE:
- blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
- blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
- break;
- default:
- assert(!"not implemented blend mode");
- }
- cso_set_blend(ctx->cso_context, &ctx->state.g3d.blend);
- }
- if ((ctx->state.dirty & RASTERIZER_DIRTY)) {
- struct pipe_rasterizer_state *raster = &ctx->state.g3d.rasterizer;
- memset(raster, 0, sizeof(struct pipe_rasterizer_state));
- raster->gl_rasterization_rules = 1;
- cso_set_rasterizer(ctx->cso_context, &ctx->state.g3d.rasterizer);
- }
- if ((ctx->state.dirty & VIEWPORT_DIRTY)) {
- struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
- const VGint param_bytes = 8 * sizeof(VGfloat);
- VGfloat vs_consts[8] = {
- 2.f/fb->width, 2.f/fb->height, 1, 1,
- -1, -1, 0, 0
- };
- struct pipe_resource **cbuf = &ctx->vs_const_buffer;
+ texture = create_texture(pipe, format, width, height);
- vg_set_viewport(ctx, VEGA_Y0_BOTTOM);
+ if (!texture)
+ return NULL;
- pipe_resource_reference(cbuf, NULL);
- *cbuf = pipe_buffer_create(ctx->pipe->screen,
- PIPE_BIND_CONSTANT_BUFFER,
- param_bytes);
-
- if (*cbuf) {
- st_no_flush_pipe_buffer_write(ctx, *cbuf,
- 0, param_bytes, vs_consts);
- }
- ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, *cbuf);
+ u_sampler_view_default_template(&view_templ, texture, texture->format);
+ view = pipe->create_sampler_view(pipe, texture, &view_templ);
+ /* want the texture to go away if the view is freed */
+ pipe_resource_reference(&texture, NULL);
+
+ return view;
+}
+
+static void
+vg_context_update_surface_mask_view(struct vg_context *ctx,
+ uint width, uint height)
+{
+ struct st_framebuffer *stfb = ctx->draw_buffer;
+ struct pipe_sampler_view *old_sampler_view = stfb->surface_mask_view;
+ struct pipe_context *pipe = ctx->pipe;
+
+ if (old_sampler_view &&
+ old_sampler_view->texture->width0 == width &&
+ old_sampler_view->texture->height0 == height)
+ return;
+
+ /*
+ we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to
+ this texture and use it as a sampler, so while this wastes some
+ space it makes both of those a lot simpler
+ */
+ stfb->surface_mask_view = create_tex_and_view(pipe,
+ PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
+
+ if (!stfb->surface_mask_view) {
+ if (old_sampler_view)
+ pipe_sampler_view_reference(&old_sampler_view, NULL);
+ return;
}
- if ((ctx->state.dirty & VS_DIRTY)) {
- cso_set_vertex_shader_handle(ctx->cso_context,
- vg_plain_vs(ctx));
+
+ /* XXX could this call be avoided? */
+ vg_validate_state(ctx);
+
+ /* alpha mask starts with 1.f alpha */
+ mask_fill(0, 0, width, height, 1.f);
+
+ /* if we had an old surface copy it over */
+ if (old_sampler_view) {
+ struct pipe_box src_box;
+ u_box_origin_2d(MIN2(old_sampler_view->texture->width0,
+ stfb->surface_mask_view->texture->width0),
+ MIN2(old_sampler_view->texture->height0,
+ stfb->surface_mask_view->texture->height0),
+ &src_box);
+
+ pipe->resource_copy_region(pipe,
+ stfb->surface_mask_view->texture,
+ 0, 0, 0, 0,
+ old_sampler_view->texture,
+ 0, &src_box);
}
- /* must be last because it renders to the depth buffer*/
- if ((ctx->state.dirty & DEPTH_STENCIL_DIRTY)) {
- update_clip_state(ctx);
- cso_set_depth_stencil_alpha(ctx->cso_context, &ctx->state.g3d.dsa);
+ /* Free the old texture
+ */
+ if (old_sampler_view)
+ pipe_sampler_view_reference(&old_sampler_view, NULL);
+}
+
+static void
+vg_context_update_blend_texture_view(struct vg_context *ctx,
+ uint width, uint height)
+{
+ struct pipe_context *pipe = ctx->pipe;
+ struct st_framebuffer *stfb = ctx->draw_buffer;
+ struct pipe_sampler_view *old = stfb->blend_texture_view;
+
+ if (old &&
+ old->texture->width0 == width &&
+ old->texture->height0 == height)
+ return;
+
+ stfb->blend_texture_view = create_tex_and_view(pipe,
+ PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
+
+ pipe_sampler_view_reference(&old, NULL);
+}
+
+static boolean
+vg_context_update_depth_stencil_rb(struct vg_context * ctx,
+ uint width, uint height)
+{
+ struct st_renderbuffer *dsrb = ctx->draw_buffer->dsrb;
+ struct pipe_context *pipe = ctx->pipe;
+ struct pipe_surface surf_tmpl;
+
+ if ((dsrb->width == width && dsrb->height == height) && dsrb->texture)
+ return FALSE;
+
+ /* unreference existing ones */
+ pipe_surface_reference(&dsrb->surface, NULL);
+ pipe_resource_reference(&dsrb->texture, NULL);
+ dsrb->width = dsrb->height = 0;
+
+ dsrb->texture = create_texture(pipe, dsrb->format, width, height);
+ if (!dsrb->texture)
+ return TRUE;
+
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ u_surface_default_template(&surf_tmpl, dsrb->texture,
+ PIPE_BIND_DEPTH_STENCIL);
+ dsrb->surface = pipe->create_surface(pipe,
+ dsrb->texture,
+ &surf_tmpl);
+ if (!dsrb->surface) {
+ pipe_resource_reference(&dsrb->texture, NULL);
+ return TRUE;
}
+ dsrb->width = width;
+ dsrb->height = height;
+
+ assert(dsrb->surface->width == width);
+ assert(dsrb->surface->height == height);
+
+ return TRUE;
+}
+
+void vg_validate_state(struct vg_context *ctx)
+{
+ struct st_framebuffer *stfb = ctx->draw_buffer;
+
+ vg_manager_validate_framebuffer(ctx);
+
+ if (vg_context_update_depth_stencil_rb(ctx, stfb->width, stfb->height))
+ ctx->state.dirty |= DEPTH_STENCIL_DIRTY;
+
+ /* blend state depends on fb format */
+ if (ctx->state.dirty & FRAMEBUFFER_DIRTY)
+ ctx->state.dirty |= BLEND_DIRTY;
+
+ renderer_validate(ctx->renderer, ctx->state.dirty,
+ ctx->draw_buffer, &ctx->state.vg);
+
+ ctx->state.dirty = 0;
+
shader_set_masking(ctx->shader, ctx->state.vg.masking);
shader_set_image_mode(ctx->shader, ctx->state.vg.image_mode);
-
- ctx->state.dirty = NONE_DIRTY;
+ shader_set_color_transform(ctx->shader, ctx->state.vg.color_transform);
}
VGboolean vg_object_is_valid(void *ptr, enum vg_object_type type)
@@ -470,130 +434,94 @@ void vg_set_error(struct vg_context *ctx,
ctx->_error = code;
}
-void vg_prepare_blend_surface(struct vg_context *ctx)
+static void vg_prepare_blend_texture(struct vg_context *ctx,
+ struct pipe_sampler_view *src)
+{
+ struct st_framebuffer *stfb = ctx->draw_buffer;
+ struct pipe_surface *surf;
+ struct pipe_surface surf_tmpl;
+
+ vg_context_update_blend_texture_view(ctx, stfb->width, stfb->height);
+
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ u_surface_default_template(&surf_tmpl, stfb->blend_texture_view->texture,
+ PIPE_BIND_RENDER_TARGET);
+ surf = ctx->pipe->create_surface(ctx->pipe,
+ stfb->blend_texture_view->texture,
+ &surf_tmpl);
+ if (surf) {
+ util_blit_pixels_tex(ctx->blit,
+ src, 0, 0, stfb->width, stfb->height,
+ surf, 0, 0, stfb->width, stfb->height,
+ 0.0, PIPE_TEX_MIPFILTER_NEAREST);
+
+ pipe_surface_reference(&surf, NULL);
+ }
+}
+
+struct pipe_sampler_view *vg_prepare_blend_surface(struct vg_context *ctx)
{
- struct pipe_surface *dest_surface = NULL;
struct pipe_context *pipe = ctx->pipe;
struct pipe_sampler_view *view;
struct pipe_sampler_view view_templ;
struct st_framebuffer *stfb = ctx->draw_buffer;
struct st_renderbuffer *strb = stfb->strb;
- /* first finish all pending rendering */
- vgFinish();
+ vg_validate_state(ctx);
u_sampler_view_default_template(&view_templ, strb->texture, strb->texture->format);
view = pipe->create_sampler_view(pipe, strb->texture, &view_templ);
- dest_surface = pipe->screen->get_tex_surface(pipe->screen,
- stfb->blend_texture_view->texture,
- 0, 0, 0,
- PIPE_BIND_RENDER_TARGET);
- /* flip it, because we want to use it as a sampler */
- util_blit_pixels_tex(ctx->blit,
- view,
- 0, strb->height,
- strb->width, 0,
- dest_surface,
- 0, 0,
- strb->width, strb->height,
- 0.0, PIPE_TEX_MIPFILTER_NEAREST);
-
- if (dest_surface)
- pipe_surface_reference(&dest_surface, NULL);
-
- /* make sure it's complete */
- vgFinish();
+ vg_prepare_blend_texture(ctx, view);
pipe_sampler_view_reference(&view, NULL);
+
+ return stfb->blend_texture_view;
}
-void vg_prepare_blend_surface_from_mask(struct vg_context *ctx)
+struct pipe_sampler_view *vg_prepare_blend_surface_from_mask(struct vg_context *ctx)
{
- struct pipe_surface *dest_surface = NULL;
- struct pipe_context *pipe = ctx->pipe;
struct st_framebuffer *stfb = ctx->draw_buffer;
- struct st_renderbuffer *strb = stfb->strb;
vg_validate_state(ctx);
- /* first finish all pending rendering */
- vgFinish();
-
- dest_surface = pipe->screen->get_tex_surface(pipe->screen,
- stfb->blend_texture_view->texture,
- 0, 0, 0,
- PIPE_BIND_RENDER_TARGET);
-
- /* flip it, because we want to use it as a sampler */
- util_blit_pixels_tex(ctx->blit,
- stfb->alpha_mask_view,
- 0, strb->height,
- strb->width, 0,
- dest_surface,
- 0, 0,
- strb->width, strb->height,
- 0.0, PIPE_TEX_MIPFILTER_NEAREST);
-
- /* make sure it's complete */
- vgFinish();
-
- if (dest_surface)
- pipe_surface_reference(&dest_surface, NULL);
+ vg_context_update_surface_mask_view(ctx, stfb->width, stfb->height);
+ vg_prepare_blend_texture(ctx, stfb->surface_mask_view);
+
+ return stfb->blend_texture_view;
}
-void * vg_plain_vs(struct vg_context *ctx)
+struct pipe_sampler_view *vg_get_surface_mask(struct vg_context *ctx)
{
- if (!ctx->plain_vs) {
- ctx->plain_vs = shader_create_from_text(ctx->pipe,
- vs_plain_asm,
- 200,
- PIPE_SHADER_VERTEX);
- }
+ struct st_framebuffer *stfb = ctx->draw_buffer;
- return ctx->plain_vs->driver;
-}
+ vg_context_update_surface_mask_view(ctx, stfb->width, stfb->height);
+ return stfb->surface_mask_view;
+}
-void * vg_clear_vs(struct vg_context *ctx)
+/**
+ * A transformation from window coordinates to paint coordinates.
+ */
+VGboolean vg_get_paint_matrix(struct vg_context *ctx,
+ const struct matrix *paint_to_user,
+ const struct matrix *user_to_surface,
+ struct matrix *mat)
{
- if (!ctx->clear_vs) {
- ctx->clear_vs = shader_create_from_text(ctx->pipe,
- vs_clear_asm,
- 200,
- PIPE_SHADER_VERTEX);
- }
+ struct matrix tmp;
- return ctx->clear_vs->driver;
-}
+ /* get user-to-paint matrix */
+ memcpy(mat, paint_to_user, sizeof(*paint_to_user));
+ if (!matrix_invert(mat))
+ return VG_FALSE;
-void * vg_texture_vs(struct vg_context *ctx)
-{
- if (!ctx->texture_vs) {
- ctx->texture_vs = shader_create_from_text(ctx->pipe,
- vs_texture_asm,
- 200,
- PIPE_SHADER_VERTEX);
- }
+ /* get surface-to-user matrix */
+ memcpy(&tmp, user_to_surface, sizeof(*user_to_surface));
+ if (!matrix_invert(&tmp))
+ return VG_FALSE;
- return ctx->texture_vs->driver;
-}
+ matrix_mult(mat, &tmp);
-void vg_set_viewport(struct vg_context *ctx, VegaOrientation orientation)
-{
- struct pipe_viewport_state viewport;
- struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
- VGfloat y_scale = (orientation == VEGA_Y0_BOTTOM) ? -2.f : 2.f;
-
- viewport.scale[0] = fb->width / 2.f;
- viewport.scale[1] = fb->height / y_scale;
- viewport.scale[2] = 1.0;
- viewport.scale[3] = 1.0;
- viewport.translate[0] = fb->width / 2.f;
- viewport.translate[1] = fb->height / 2.f;
- viewport.translate[2] = 0.0;
- viewport.translate[3] = 0.0;
-
- cso_set_viewport(ctx->cso_context, &viewport);
+ return VG_TRUE;
}
diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h
index 80a6c07c693..d616a20a3d9 100644
--- a/src/gallium/state_trackers/vega/vg_context.h
+++ b/src/gallium/state_trackers/vega/vg_context.h
@@ -56,7 +56,7 @@ struct st_framebuffer {
struct st_renderbuffer *strb;
struct st_renderbuffer *dsrb;
- struct pipe_sampler_view *alpha_mask_view;
+ struct pipe_sampler_view *surface_mask_view;
struct pipe_sampler_view *blend_texture_view;
@@ -78,14 +78,13 @@ enum vg_object_type {
VG_OBJECT_LAST
};
enum dirty_state {
- NONE_DIRTY = 0<<0,
- BLEND_DIRTY = 1<<1,
- RASTERIZER_DIRTY = 1<<2,
- VIEWPORT_DIRTY = 1<<3,
- VS_DIRTY = 1<<4,
- DEPTH_STENCIL_DIRTY = 1<<5,
- ALL_DIRTY = BLEND_DIRTY | RASTERIZER_DIRTY |
- VIEWPORT_DIRTY | VS_DIRTY | DEPTH_STENCIL_DIRTY
+ BLEND_DIRTY = 1 << 0,
+ FRAMEBUFFER_DIRTY = 1 << 1,
+ DEPTH_STENCIL_DIRTY = 1 << 2,
+
+ ALL_DIRTY = BLEND_DIRTY |
+ FRAMEBUFFER_DIRTY |
+ DEPTH_STENCIL_DIRTY
};
struct vg_context
@@ -98,13 +97,6 @@ struct vg_context
struct {
struct vg_state vg;
- struct {
- struct pipe_blend_state blend;
- struct pipe_rasterizer_state rasterizer;
- struct pipe_shader_state vs_state;
- struct pipe_depth_stencil_alpha_state dsa;
- struct pipe_framebuffer_state fb;
- } g3d;
VGbitfield dirty;
} state;
@@ -116,14 +108,6 @@ struct vg_context
struct cso_hash *owned_objects[VG_OBJECT_LAST];
struct {
- struct pipe_shader_state vert_shader;
- struct pipe_shader_state frag_shader;
- struct pipe_rasterizer_state raster;
- void *fs;
- float vertices[4][2][4]; /**< vertex pos + color */
- } clear;
-
- struct {
struct pipe_resource *cbuf;
struct pipe_sampler_state sampler;
@@ -133,31 +117,16 @@ struct vg_context
struct vg_shader *set_fs;
} mask;
- struct vg_shader *pass_through_depth_fs;
-
struct cso_context *cso_context;
- struct pipe_resource *stencil_quad;
- VGfloat stencil_vertices[4][2][4];
-
struct renderer *renderer;
struct shaders_cache *sc;
struct shader *shader;
struct pipe_sampler_state blend_sampler;
- struct {
- struct pipe_resource *buffer;
- void *color_matrix_fs;
- } filter;
struct vg_paint *default_paint;
struct blit_state *blit;
-
- struct vg_shader *plain_vs;
- struct vg_shader *clear_vs;
- struct vg_shader *texture_vs;
- struct pipe_resource *vs_const_buffer;
- struct pipe_vertex_element velems[2];
};
struct vg_object {
@@ -189,9 +158,15 @@ void vg_validate_state(struct vg_context *ctx);
void vg_set_error(struct vg_context *ctx,
VGErrorCode code);
-void vg_prepare_blend_surface(struct vg_context *ctx);
-void vg_prepare_blend_surface_from_mask(struct vg_context *ctx);
+struct pipe_sampler_view *vg_prepare_blend_surface(struct vg_context *ctx);
+struct pipe_sampler_view *vg_prepare_blend_surface_from_mask(struct vg_context *ctx);
+struct pipe_sampler_view *vg_get_surface_mask(struct vg_context *ctx);
+
+VGboolean vg_get_paint_matrix(struct vg_context *ctx,
+ const struct matrix *paint_to_user,
+ const struct matrix *user_to_surface,
+ struct matrix *mat);
static INLINE VGboolean is_aligned_to(const void *ptr, VGbyte alignment)
{
@@ -292,13 +267,4 @@ static INLINE void vg_bound_rect(VGfloat coords[4],
}
}
-void *vg_plain_vs(struct vg_context *ctx);
-void *vg_clear_vs(struct vg_context *ctx);
-void *vg_texture_vs(struct vg_context *ctx);
-typedef enum {
- VEGA_Y0_TOP,
- VEGA_Y0_BOTTOM
-} VegaOrientation;
-void vg_set_viewport(struct vg_context *ctx, VegaOrientation orientation);
-
#endif
diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c
index bb15ec024f2..de935768b22 100644
--- a/src/gallium/state_trackers/vega/vg_manager.c
+++ b/src/gallium/state_trackers/vega/vg_manager.c
@@ -33,168 +33,22 @@
#include "pipe/p_screen.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
-#include "util/u_format.h"
#include "util/u_sampler.h"
+#include "util/u_box.h"
+#include "util/u_surface.h"
#include "vg_api.h"
#include "vg_manager.h"
#include "vg_context.h"
#include "image.h"
-#include "mask.h"
#include "api.h"
-static struct pipe_resource *
-create_texture(struct pipe_context *pipe, enum pipe_format format,
- VGint width, VGint height)
-{
- struct pipe_resource templ;
-
- memset(&templ, 0, sizeof(templ));
-
- if (format != PIPE_FORMAT_NONE) {
- templ.format = format;
- }
- else {
- templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
- }
-
- templ.target = PIPE_TEXTURE_2D;
- templ.width0 = width;
- templ.height0 = height;
- templ.depth0 = 1;
- templ.last_level = 0;
-
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
- templ.bind = PIPE_BIND_DEPTH_STENCIL;
- } else {
- templ.bind = (PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_RENDER_TARGET |
- PIPE_BIND_SAMPLER_VIEW);
- }
-
- return pipe->screen->resource_create(pipe->screen, &templ);
-}
-
-static struct pipe_sampler_view *
-create_tex_and_view(struct pipe_context *pipe, enum pipe_format format,
- VGint width, VGint height)
-{
- struct pipe_resource *texture;
- struct pipe_sampler_view view_templ;
- struct pipe_sampler_view *view;
-
- texture = create_texture(pipe, format, width, height);
-
- if (!texture)
- return NULL;
-
- u_sampler_view_default_template(&view_templ, texture, texture->format);
- view = pipe->create_sampler_view(pipe, texture, &view_templ);
- /* want the texture to go away if the view is freed */
- pipe_resource_reference(&texture, NULL);
-
- return view;
-}
-
-static void
-setup_new_alpha_mask(struct vg_context *ctx, struct st_framebuffer *stfb)
-{
- struct pipe_context *pipe = ctx->pipe;
- struct pipe_sampler_view *old_sampler_view = stfb->alpha_mask_view;
-
- /*
- we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to
- this texture and use it as a sampler, so while this wastes some
- space it makes both of those a lot simpler
- */
- stfb->alpha_mask_view = create_tex_and_view(pipe,
- PIPE_FORMAT_B8G8R8A8_UNORM, stfb->width, stfb->height);
-
- if (!stfb->alpha_mask_view) {
- if (old_sampler_view)
- pipe_sampler_view_reference(&old_sampler_view, NULL);
- return;
- }
-
- /* XXX could this call be avoided? */
- vg_validate_state(ctx);
-
- /* alpha mask starts with 1.f alpha */
- mask_fill(0, 0, stfb->width, stfb->height, 1.f);
-
- /* if we had an old surface copy it over */
- if (old_sampler_view) {
- struct pipe_subresource subsurf, subold_surf;
- subsurf.face = 0;
- subsurf.level = 0;
- subold_surf.face = 0;
- subold_surf.level = 0;
- pipe->resource_copy_region(pipe,
- stfb->alpha_mask_view->texture,
- subsurf,
- 0, 0, 0,
- old_sampler_view->texture,
- subold_surf,
- 0, 0, 0,
- MIN2(old_sampler_view->texture->width0,
- stfb->alpha_mask_view->texture->width0),
- MIN2(old_sampler_view->texture->height0,
- stfb->alpha_mask_view->texture->height0));
- }
-
- /* Free the old texture
- */
- if (old_sampler_view)
- pipe_sampler_view_reference(&old_sampler_view, NULL);
-}
-
-static boolean
-vg_context_update_depth_stencil_rb(struct vg_context * ctx,
- uint width, uint height)
-{
- struct st_renderbuffer *dsrb = ctx->draw_buffer->dsrb;
- struct pipe_context *pipe = ctx->pipe;
- unsigned surface_usage;
-
- if ((dsrb->width == width && dsrb->height == height) && dsrb->texture)
- return FALSE;
-
- /* unreference existing ones */
- pipe_surface_reference(&dsrb->surface, NULL);
- pipe_resource_reference(&dsrb->texture, NULL);
- dsrb->width = dsrb->height = 0;
-
- /* Probably need dedicated flags for surface usage too:
- */
- surface_usage = PIPE_BIND_DEPTH_STENCIL; /* XXX: was: RENDER_TARGET */
-
- dsrb->texture = create_texture(pipe, dsrb->format, width, height);
- if (!dsrb->texture)
- return TRUE;
-
- dsrb->surface = pipe->screen->get_tex_surface(pipe->screen,
- dsrb->texture,
- 0, 0, 0,
- surface_usage);
- if (!dsrb->surface) {
- pipe_resource_reference(&dsrb->texture, NULL);
- return TRUE;
- }
-
- dsrb->width = width;
- dsrb->height = height;
-
- assert(dsrb->surface->width == width);
- assert(dsrb->surface->height == height);
-
- return TRUE;
-}
-
static boolean
vg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt)
{
struct st_renderbuffer *strb = ctx->draw_buffer->strb;
- struct pipe_screen *screen = ctx->pipe->screen;
+ struct pipe_context *pipe = ctx->pipe;
+ struct pipe_surface surf_tmpl;
if (strb->texture == pt) {
pipe_resource_reference(&pt, NULL);
@@ -207,8 +61,12 @@ vg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt)
strb->width = strb->height = 0;
strb->texture = pt;
- strb->surface = screen->get_tex_surface(screen, strb->texture, 0, 0, 0,
- PIPE_BIND_RENDER_TARGET);
+
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ u_surface_default_template(&surf_tmpl, strb->texture,
+ PIPE_BIND_RENDER_TARGET);
+ strb->surface = pipe->create_surface(pipe, strb->texture, &surf_tmpl);
+
if (!strb->surface) {
pipe_resource_reference(&strb->texture, NULL);
return TRUE;
@@ -220,49 +78,6 @@ vg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt)
return TRUE;
}
-static void
-vg_context_update_draw_buffer(struct vg_context *ctx, struct pipe_resource *pt)
-{
- struct st_framebuffer *stfb = ctx->draw_buffer;
- boolean new_cbuf, new_zsbuf, new_size;
-
- new_cbuf = vg_context_update_color_rb(ctx, pt);
- new_zsbuf =
- vg_context_update_depth_stencil_rb(ctx, pt->width0, pt->height0);
-
- new_size = (stfb->width != pt->width0 || stfb->height != pt->height0);
- stfb->width = pt->width0;
- stfb->height = pt->height0;
-
- if (new_cbuf || new_zsbuf || new_size) {
- struct pipe_framebuffer_state *state = &ctx->state.g3d.fb;
-
- memset(state, 0, sizeof(struct pipe_framebuffer_state));
- state->width = stfb->width;
- state->height = stfb->height;
- state->nr_cbufs = 1;
- state->cbufs[0] = stfb->strb->surface;
- state->zsbuf = stfb->dsrb->surface;
-
- cso_set_framebuffer(ctx->cso_context, state);
- }
-
- if (new_zsbuf || new_size) {
- ctx->state.dirty |= VIEWPORT_DIRTY;
- ctx->state.dirty |= DEPTH_STENCIL_DIRTY;/*to reset the scissors*/
-
- ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 0.0, 0);
-
- /* we need all the other state already set */
-
- setup_new_alpha_mask(ctx, stfb);
-
- pipe_sampler_view_reference( &stfb->blend_texture_view, NULL);
- stfb->blend_texture_view = create_tex_and_view(ctx->pipe,
- PIPE_FORMAT_B8G8R8A8_UNORM, stfb->width, stfb->height);
- }
-}
-
/**
* Flush the front buffer if the current context renders to the front buffer.
*/
@@ -304,15 +119,16 @@ vg_manager_validate_framebuffer(struct vg_context *ctx)
if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, 1, &pt) || !pt)
return;
- /*
- * unset draw_buffer_invalid first because vg_context_update_draw_buffer
- * will cause the framebuffer to be validated again because of a call to
- * vg_validate_state
- */
p_atomic_set(&ctx->draw_buffer_invalid, FALSE);
- vg_context_update_draw_buffer(ctx, pt);
-}
+ if (vg_context_update_color_rb(ctx, pt) ||
+ stfb->width != pt->width0 ||
+ stfb->height != pt->height0)
+ ctx->state.dirty |= FRAMEBUFFER_DIRTY;
+
+ stfb->width = pt->width0;
+ stfb->height = pt->height0;
+}
static void
vg_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
@@ -336,7 +152,10 @@ static void
vg_context_destroy(struct st_context_iface *stctxi)
{
struct vg_context *ctx = (struct vg_context *) stctxi;
+ struct pipe_context *pipe = ctx->pipe;
+
vg_destroy_context(ctx);
+ pipe->destroy(pipe);
}
static struct st_context_iface *
diff --git a/src/gallium/state_trackers/wgl/SConscript b/src/gallium/state_trackers/wgl/SConscript
index ec55f042f90..1b7597de440 100644
--- a/src/gallium/state_trackers/wgl/SConscript
+++ b/src/gallium/state_trackers/wgl/SConscript
@@ -13,7 +13,6 @@ env.Append(CPPPATH = [
env.AppendUnique(CPPDEFINES = [
'_GDI32_', # prevent wgl* being declared __declspec(dllimport)
'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers
- 'WIN32_THREADS', # use Win32 thread API
'WIN32_LEAN_AND_MEAN', # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx
])
@@ -22,6 +21,7 @@ sources = [
'stw_device.c',
'stw_ext_extensionsstring.c',
'stw_ext_gallium.c',
+ 'stw_ext_pbuffer.c',
'stw_ext_pixelformat.c',
'stw_ext_swapinterval.c',
'stw_framebuffer.c',
diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
index 86c0a28e8da..cd4f3c8b3e2 100644
--- a/src/gallium/state_trackers/wgl/stw_context.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -264,75 +264,82 @@ stw_make_current(
struct stw_context *curctx = NULL;
struct stw_context *ctx = NULL;
struct stw_framebuffer *fb = NULL;
+ BOOL ret = FALSE;
if (!stw_dev)
- goto fail;
+ return FALSE;
curctx = stw_current_context();
if (curctx != NULL) {
- if (curctx->dhglrc != dhglrc)
+ if (curctx->dhglrc == dhglrc) {
+ if (curctx->hdc == hdc) {
+ /* Return if already current. */
+ return TRUE;
+ }
+ } else {
curctx->st->flush(curctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
-
- /* Return if already current. */
- if (curctx->dhglrc == dhglrc && curctx->hdc == hdc) {
- ctx = curctx;
- fb = stw_framebuffer_from_hdc( hdc );
- goto success;
}
-
- stw_framebuffer_reference(&curctx->current_framebuffer, NULL);
}
- if (hdc == NULL || dhglrc == 0) {
- return stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
- }
-
- pipe_mutex_lock( stw_dev->ctx_mutex );
- ctx = stw_lookup_context_locked( dhglrc );
- pipe_mutex_unlock( stw_dev->ctx_mutex );
- if(!ctx)
- goto fail;
-
- fb = stw_framebuffer_from_hdc( hdc );
- if (fb) {
- stw_framebuffer_update(fb);
- }
- else {
- /* Applications should call SetPixelFormat before creating a context,
- * but not all do, and the opengl32 runtime seems to use a default pixel
- * format in some cases, so we must create a framebuffer for those here
- */
- int iPixelFormat = GetPixelFormat(hdc);
- if(iPixelFormat)
- fb = stw_framebuffer_create( hdc, iPixelFormat );
- if(!fb)
+ if (dhglrc) {
+ pipe_mutex_lock( stw_dev->ctx_mutex );
+ ctx = stw_lookup_context_locked( dhglrc );
+ pipe_mutex_unlock( stw_dev->ctx_mutex );
+ if (!ctx) {
goto fail;
- }
-
- if(fb->iPixelFormat != ctx->iPixelFormat)
- goto fail;
+ }
- /* Bind the new framebuffer */
- ctx->hdc = hdc;
+ fb = stw_framebuffer_from_hdc( hdc );
+ if (fb) {
+ stw_framebuffer_update(fb);
+ }
+ else {
+ /* Applications should call SetPixelFormat before creating a context,
+ * but not all do, and the opengl32 runtime seems to use a default pixel
+ * format in some cases, so we must create a framebuffer for those here
+ */
+ int iPixelFormat = GetPixelFormat(hdc);
+ if (iPixelFormat)
+ fb = stw_framebuffer_create( hdc, iPixelFormat );
+ if (!fb)
+ goto fail;
+ }
- if (!stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, fb->stfb, fb->stfb))
- goto fail;
+ if (fb->iPixelFormat != ctx->iPixelFormat) {
+ SetLastError(ERROR_INVALID_PIXEL_FORMAT);
+ goto fail;
+ }
- stw_framebuffer_reference(&ctx->current_framebuffer, fb);
+ /* Bind the new framebuffer */
+ ctx->hdc = hdc;
-success:
- assert(fb);
- if(fb) {
- stw_framebuffer_release(fb);
+ ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, fb->stfb, fb->stfb);
+ stw_framebuffer_reference(&ctx->current_framebuffer, fb);
+ } else {
+ ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
}
- return TRUE;
-
fail:
- if(fb)
+
+ if (fb) {
stw_framebuffer_release(fb);
- stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
- return FALSE;
+ }
+
+ /* On failure, make the thread's current rendering context not current
+ * before returning */
+ if (!ret) {
+ stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
+ ctx = NULL;
+ }
+
+ /* Unreference the previous framebuffer if any. It must be done after
+ * make_current, as it can be referenced inside.
+ */
+ if (curctx && curctx != ctx) {
+ stw_framebuffer_reference(&curctx->current_framebuffer, NULL);
+ }
+
+ return ret;
}
/**
diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c
index 37809d084ce..c4822d4d8aa 100644
--- a/src/gallium/state_trackers/wgl/stw_device.c
+++ b/src/gallium/state_trackers/wgl/stw_device.c
@@ -41,9 +41,7 @@
#include "stw_framebuffer.h"
#include "stw_st.h"
-#ifdef WIN32_THREADS
extern _glthread_Mutex OneTimeLock;
-#endif
struct stw_device *stw_dev = NULL;
@@ -76,9 +74,7 @@ stw_init(const struct stw_winsys *stw_winsys)
stw_dev->stw_winsys = stw_winsys;
-#ifdef WIN32_THREADS
_glthread_INIT_MUTEX(OneTimeLock);
-#endif
stw_dev->stapi = stw_st_create_api();
stw_dev->smapi = CALLOC_STRUCT(st_manager);
@@ -96,6 +92,10 @@ stw_init(const struct stw_winsys *stw_winsys)
stw_dev->smapi->get_param = stw_get_param;
stw_dev->screen = screen;
+ stw_dev->max_2d_levels =
+ screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
+ stw_dev->max_2d_length = 1 << (stw_dev->max_2d_levels - 1);
+
pipe_mutex_init( stw_dev->ctx_mutex );
pipe_mutex_init( stw_dev->fb_mutex );
@@ -168,11 +168,9 @@ stw_cleanup(void)
stw_dev->screen->destroy(stw_dev->screen);
-#ifdef WIN32_THREADS
_glthread_DESTROY_MUTEX(OneTimeLock);
_glapi_destroy_multithread();
-#endif
#ifdef DEBUG
debug_memory_end(stw_dev->memdbg_no);
diff --git a/src/gallium/state_trackers/wgl/stw_device.h b/src/gallium/state_trackers/wgl/stw_device.h
index 1b836960d0d..3c2b6d9c076 100644
--- a/src/gallium/state_trackers/wgl/stw_device.h
+++ b/src/gallium/state_trackers/wgl/stw_device.h
@@ -50,6 +50,10 @@ struct stw_device
struct pipe_screen *screen;
+ /* Cache some PIPE_CAP_* */
+ unsigned max_2d_levels;
+ unsigned max_2d_length;
+
struct st_api *stapi;
struct st_manager *smapi;
diff --git a/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c b/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
index 62c859e1f92..ecb326f1cf6 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
@@ -37,6 +37,7 @@
static const char *stw_extension_string =
"WGL_ARB_extensions_string "
"WGL_ARB_multisample "
+ "WGL_ARB_pbuffer "
"WGL_ARB_pixel_format "
/* "WGL_EXT_swap_interval " */
"WGL_EXT_extensions_string";
diff --git a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
new file mode 100644
index 00000000000..32636c603dc
--- /dev/null
+++ b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
@@ -0,0 +1,212 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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.
+ *
+ **************************************************************************/
+
+#include <windows.h>
+
+#define WGL_WGLEXT_PROTOTYPES
+
+#include <GL/gl.h>
+#include <GL/wglext.h>
+
+#include "pipe/p_defines.h"
+#include "pipe/p_screen.h"
+
+#include "stw_device.h"
+#include "stw_pixelformat.h"
+#include "stw_framebuffer.h"
+
+
+HPBUFFERARB WINAPI
+wglCreatePbufferARB(HDC _hDC,
+ int iPixelFormat,
+ int iWidth,
+ int iHeight,
+ const int *piAttribList)
+{
+ static boolean first = TRUE;
+ const int *piAttrib;
+ int useLargest = 0;
+ const struct stw_pixelformat_info *info;
+ struct stw_framebuffer *fb;
+ HWND hWnd;
+ HDC hDC;
+
+ info = stw_pixelformat_get_info(iPixelFormat);
+ if (!info) {
+ SetLastError(ERROR_INVALID_PIXEL_FORMAT);
+ return 0;
+ }
+
+ if (iWidth <= 0 || iHeight <= 0) {
+ SetLastError(ERROR_INVALID_DATA);
+ return 0;
+ }
+
+ for (piAttrib = piAttribList; *piAttrib; piAttrib++) {
+ switch (*piAttrib) {
+ case WGL_PBUFFER_LARGEST_ARB:
+ piAttrib++;
+ useLargest = *piAttrib;
+ break;
+ default:
+ SetLastError(ERROR_INVALID_DATA);
+ return 0;
+ }
+ }
+
+ if (iWidth > stw_dev->max_2d_length) {
+ if (useLargest) {
+ iWidth = stw_dev->max_2d_length;
+ } else {
+ SetLastError(ERROR_NO_SYSTEM_RESOURCES);
+ return 0;
+ }
+ }
+
+ if (iHeight > stw_dev->max_2d_length) {
+ if (useLargest) {
+ iHeight = stw_dev->max_2d_length;
+ } else {
+ SetLastError(ERROR_NO_SYSTEM_RESOURCES);
+ return 0;
+ }
+ }
+
+ /*
+ * Implement pbuffers through invisible windows
+ */
+
+ if (first) {
+ WNDCLASS wc;
+ memset(&wc, 0, sizeof wc);
+ wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wc.lpfnWndProc = DefWindowProc;
+ wc.lpszClassName = "wglpbuffer";
+ wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
+ RegisterClass(&wc);
+ first = FALSE;
+ }
+
+ hWnd = CreateWindowEx(0,
+ "wglpbuffer", /* wc.lpszClassName */
+ "wglpbuffer",
+#if 0 /* Useful for debugging what the application is drawing */
+ WS_VISIBLE |
+#endif
+ WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
+ CW_USEDEFAULT, CW_USEDEFAULT, /* x, y */
+ iWidth, iHeight,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (!hWnd) {
+ return 0;
+ }
+
+ hDC = GetDC(hWnd);
+ if (!hDC) {
+ return 0;
+ }
+
+ SetPixelFormat(hDC, iPixelFormat, &info->pfd);
+
+ fb = stw_framebuffer_create(hDC, iPixelFormat);
+ if (!fb) {
+ SetLastError(ERROR_NO_SYSTEM_RESOURCES);
+ }
+
+ return (HPBUFFERARB)fb;
+}
+
+
+HDC WINAPI
+wglGetPbufferDCARB(HPBUFFERARB hPbuffer)
+{
+ struct stw_framebuffer *fb;
+ HDC hDC;
+
+ fb = (struct stw_framebuffer *)hPbuffer;
+
+ hDC = GetDC(fb->hWnd);
+ SetPixelFormat(hDC, fb->iPixelFormat, &fb->pfi->pfd);
+
+ return hDC;
+}
+
+
+int WINAPI
+wglReleasePbufferDCARB(HPBUFFERARB hPbuffer,
+ HDC hDC)
+{
+ struct stw_framebuffer *fb;
+
+ fb = (struct stw_framebuffer *)hPbuffer;
+
+ return ReleaseDC(fb->hWnd, hDC);
+}
+
+
+BOOL WINAPI
+wglDestroyPbufferARB(HPBUFFERARB hPbuffer)
+{
+ struct stw_framebuffer *fb;
+
+ fb = (struct stw_framebuffer *)hPbuffer;
+
+ /* This will destroy all our data */
+ return DestroyWindow(fb->hWnd);
+}
+
+
+BOOL WINAPI
+wglQueryPbufferARB(HPBUFFERARB hPbuffer,
+ int iAttribute,
+ int *piValue)
+{
+ struct stw_framebuffer *fb;
+
+ fb = (struct stw_framebuffer *)hPbuffer;
+
+ switch (iAttribute) {
+ case WGL_PBUFFER_WIDTH_ARB:
+ *piValue = fb->width;
+ return TRUE;
+ case WGL_PBUFFER_HEIGHT_ARB:
+ *piValue = fb->width;
+ return TRUE;
+ case WGL_PBUFFER_LOST_ARB:
+ /* We assume that no content is ever lost due to display mode change */
+ *piValue = FALSE;
+ return TRUE;
+ default:
+ SetLastError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
+}
diff --git a/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c b/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
index ab56800e28d..d0a95863bb4 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
@@ -43,6 +43,7 @@
#include "pipe/p_compiler.h"
#include "util/u_memory.h"
+#include "stw_device.h"
#include "stw_pixelformat.h"
@@ -234,6 +235,23 @@ stw_query_attrib(
*pvalue = pfi->stvis.samples;
break;
+
+ /* WGL_ARB_pbuffer */
+
+ case WGL_MAX_PBUFFER_WIDTH_ARB:
+ case WGL_MAX_PBUFFER_HEIGHT_ARB:
+ *pvalue = stw_dev->max_2d_length;
+ break;
+
+ case WGL_MAX_PBUFFER_PIXELS_ARB:
+ *pvalue = stw_dev->max_2d_length * stw_dev->max_2d_length;
+ break;
+
+ case WGL_DRAW_TO_PBUFFER_ARB:
+ *pvalue = 1;
+ break;
+
+
default:
return FALSE;
}
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c
index 259b22f22c7..733222aa21c 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c
@@ -469,7 +469,7 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
{
struct stw_framebuffer *fb;
struct pipe_screen *screen;
- struct pipe_surface *surface;
+ struct pipe_resource *res;
if (!stw_dev)
return FALSE;
@@ -480,7 +480,7 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
screen = stw_dev->screen;
- surface = (struct pipe_surface *)data->pPrivateData;
+ res = (struct pipe_resource *)data->pPrivateData;
if(data->hSharedSurface != fb->hSharedSurface) {
if(fb->shared_surface) {
@@ -498,13 +498,13 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
if(fb->shared_surface) {
stw_dev->stw_winsys->compose(screen,
- surface,
+ res,
fb->shared_surface,
&fb->client_rect,
data->PresentHistoryToken);
}
else {
- stw_dev->stw_winsys->present( screen, surface, hdc );
+ stw_dev->stw_winsys->present( screen, res, hdc );
}
stw_framebuffer_update(fb);
@@ -524,7 +524,7 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
BOOL
stw_framebuffer_present_locked(HDC hdc,
struct stw_framebuffer *fb,
- struct pipe_surface *surface)
+ struct pipe_resource *res)
{
if(stw_dev->callbacks.wglCbPresentBuffers &&
stw_dev->stw_winsys->compose) {
@@ -535,7 +535,7 @@ stw_framebuffer_present_locked(HDC hdc,
data.magic2 = 0;
data.AdapterLuid = stw_dev->AdapterLuid;
data.rect = fb->client_rect;
- data.pPrivateData = (void *)surface;
+ data.pPrivateData = (void *)res;
stw_notify_current_locked(fb);
stw_framebuffer_release(fb);
@@ -545,7 +545,7 @@ stw_framebuffer_present_locked(HDC hdc,
else {
struct pipe_screen *screen = stw_dev->screen;
- stw_dev->stw_winsys->present( screen, surface, hdc );
+ stw_dev->stw_winsys->present( screen, res, hdc );
stw_framebuffer_update(fb);
stw_notify_current_locked(fb);
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.h b/src/gallium/state_trackers/wgl/stw_framebuffer.h
index 89d12300e67..6604e545cbc 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.h
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.h
@@ -32,7 +32,7 @@
#include "os/os_thread.h"
-struct pipe_surface;
+struct pipe_resource;
struct st_framebuffer_iface;
struct stw_pixelformat_info;
@@ -143,7 +143,7 @@ stw_framebuffer_from_hdc(
BOOL
stw_framebuffer_present_locked(HDC hdc,
struct stw_framebuffer *fb,
- struct pipe_surface *surface);
+ struct pipe_resource *res);
void
stw_framebuffer_update(
diff --git a/src/gallium/state_trackers/wgl/stw_getprocaddress.c b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
index d43a55fa9e6..b0aef943d30 100644
--- a/src/gallium/state_trackers/wgl/stw_getprocaddress.c
+++ b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
@@ -50,6 +50,13 @@ static const struct stw_extension_entry stw_extension_entries[] = {
/* WGL_ARB_extensions_string */
STW_EXTENSION_ENTRY( wglGetExtensionsStringARB ),
+ /* WGL_ARB_pbuffer */
+ STW_EXTENSION_ENTRY( wglCreatePbufferARB ),
+ STW_EXTENSION_ENTRY( wglGetPbufferDCARB ),
+ STW_EXTENSION_ENTRY( wglReleasePbufferDCARB ),
+ STW_EXTENSION_ENTRY( wglDestroyPbufferARB ),
+ STW_EXTENSION_ENTRY( wglQueryPbufferARB ),
+
/* WGL_ARB_pixel_format */
STW_EXTENSION_ENTRY( wglChoosePixelFormatARB ),
STW_EXTENSION_ENTRY( wglGetPixelFormatAttribfvARB ),
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c
index 18ac4823696..5ede1d43220 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c
@@ -185,7 +185,7 @@ stw_pixelformat_add(
*/
pfi->stvis.buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK;
if (doublebuffer)
- pfi->stvis.buffer_mask = ST_ATTACHMENT_BACK_LEFT_MASK;
+ pfi->stvis.buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
pfi->stvis.color_format = color->format;
pfi->stvis.depth_stencil_format = depth->format;
diff --git a/src/gallium/state_trackers/wgl/stw_st.c b/src/gallium/state_trackers/wgl/stw_st.c
index bcdd82e4f66..b58d91673b7 100644
--- a/src/gallium/state_trackers/wgl/stw_st.c
+++ b/src/gallium/state_trackers/wgl/stw_st.c
@@ -43,8 +43,6 @@ struct stw_st_framebuffer {
struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
unsigned texture_width, texture_height;
unsigned texture_mask;
-
- struct pipe_surface *front_surface, *back_surface;
};
static INLINE struct stw_st_framebuffer *
@@ -65,10 +63,6 @@ stw_st_framebuffer_validate_locked(struct st_framebuffer_iface *stfb,
struct pipe_resource templ;
unsigned i;
- /* remove outdated surface */
- pipe_surface_reference(&stwfb->front_surface, NULL);
- pipe_surface_reference(&stwfb->back_surface, NULL);
-
/* remove outdated textures */
if (stwfb->texture_width != width || stwfb->texture_height != height) {
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
@@ -80,6 +74,7 @@ stw_st_framebuffer_validate_locked(struct st_framebuffer_iface *stfb,
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
+ templ.array_size = 1;
templ.last_level = 0;
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
@@ -155,45 +150,6 @@ stw_st_framebuffer_validate(struct st_framebuffer_iface *stfb,
return TRUE;
}
-static struct pipe_surface *
-get_present_surface_locked(struct st_framebuffer_iface *stfb,
- enum st_attachment_type statt)
-{
- struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
- struct pipe_resource *ptex;
- struct pipe_surface *psurf, **cache;
-
- ptex = stwfb->textures[statt];
- if (!ptex)
- return NULL;
-
- psurf = NULL;
-
- switch (statt) {
- case ST_ATTACHMENT_FRONT_LEFT:
- cache = &stwfb->front_surface;
- break;
- case ST_ATTACHMENT_BACK_LEFT:
- cache = &stwfb->back_surface;
- break;
- default:
- cache = &psurf;
- break;
- }
-
- if (!*cache) {
- *cache = stw_dev->screen->get_tex_surface(stw_dev->screen,
- ptex, 0, 0, 0,
- PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_RENDER_TARGET);
- }
-
- if (psurf != *cache)
- pipe_surface_reference(&psurf, *cache);
-
- return psurf;
-}
-
/**
* Present an attachment of the framebuffer.
*/
@@ -202,12 +158,11 @@ stw_st_framebuffer_present_locked(struct st_framebuffer_iface *stfb,
enum st_attachment_type statt)
{
struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
- struct pipe_surface *psurf;
-
- psurf = get_present_surface_locked(&stwfb->base, statt);
- if (psurf) {
- stw_framebuffer_present_locked(stwfb->fb->hDC, stwfb->fb, psurf);
- pipe_surface_reference(&psurf, NULL);
+ struct pipe_resource *resource;
+
+ resource = stwfb->textures[statt];
+ if (resource) {
+ stw_framebuffer_present_locked(stwfb->fb->hDC, stwfb->fb, resource);
}
return TRUE;
@@ -255,9 +210,6 @@ stw_st_destroy_framebuffer_locked(struct st_framebuffer_iface *stfb)
struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
int i;
- pipe_surface_reference(&stwfb->front_surface, NULL);
- pipe_surface_reference(&stwfb->back_surface, NULL);
-
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_resource_reference(&stwfb->textures[i], NULL);
@@ -273,7 +225,6 @@ stw_st_swap_framebuffer_locked(struct st_framebuffer_iface *stfb)
struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
unsigned front = ST_ATTACHMENT_FRONT_LEFT, back = ST_ATTACHMENT_BACK_LEFT;
struct pipe_resource *ptex;
- struct pipe_surface *psurf;
unsigned mask;
/* swap the textures */
@@ -281,11 +232,6 @@ stw_st_swap_framebuffer_locked(struct st_framebuffer_iface *stfb)
stwfb->textures[front] = stwfb->textures[back];
stwfb->textures[back] = ptex;
- /* swap the surfaces */
- psurf = stwfb->front_surface;
- stwfb->front_surface = stwfb->back_surface;
- stwfb->back_surface = psurf;
-
/* convert to mask */
front = 1 << front;
back = 1 << back;
diff --git a/src/gallium/state_trackers/wgl/stw_winsys.h b/src/gallium/state_trackers/wgl/stw_winsys.h
index 270fad56a19..397065fc159 100644
--- a/src/gallium/state_trackers/wgl/stw_winsys.h
+++ b/src/gallium/state_trackers/wgl/stw_winsys.h
@@ -34,7 +34,7 @@
struct pipe_screen;
struct pipe_context;
-struct pipe_surface;
+struct pipe_resource;
struct stw_shared_surface;
@@ -43,12 +43,13 @@ struct stw_winsys
struct pipe_screen *
(*create_screen)( void );
+ /* XXX is it actually possible to have non-zero level/layer ??? */
/**
* Present the color buffer to the window associated with the device context.
*/
void
(*present)( struct pipe_screen *screen,
- struct pipe_surface *surf,
+ struct pipe_resource *res,
HDC hDC );
/**
@@ -85,7 +86,7 @@ struct stw_winsys
*/
void
(*compose)( struct pipe_screen *screen,
- struct pipe_surface *src,
+ struct pipe_resource *res,
struct stw_shared_surface *dest,
LPCRECT pRect,
ULONGLONG PresentHistoryToken );
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index 4ff48026e50..d4dc84a122b 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -473,7 +473,7 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
struct exa_pixmap_priv *pMask,
struct exa_pixmap_priv *pDst)
{
- struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pDst);
+ struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pDst);
renderer_bind_destination(exa->renderer, dst_surf,
pDst->width,
@@ -529,7 +529,7 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
struct exa_pixmap_priv *pixmap,
Pixel fg)
{
- struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pixmap);
+ struct pipe_surface *dst_surf = xorg_gpu_surface(exa->pipe, pixmap);
unsigned vs_traits, fs_traits;
struct xorg_shader shader;
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index 80af82d97b2..28e30e09ff3 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -210,6 +210,7 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
templat.target = PIPE_TEXTURE_2D;
templat.last_level = 0;
templat.depth0 = 1;
+ templat.array_size = 1;
templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
templat.width0 = 64;
templat.height0 = 64;
@@ -225,9 +226,9 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
}
transfer = pipe_get_transfer(ms->ctx, crtcp->cursor_tex,
- 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- 0, 0, 64, 64);
+ 0, 0,
+ PIPE_TRANSFER_WRITE,
+ 0, 0, 64, 64);
ptr = ms->ctx->transfer_map(ms->ctx, transfer);
util_copy_rect(ptr, crtcp->cursor_tex->format,
transfer->stride, 0, 0,
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index b723a8e9cb0..17c34b7eac8 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -129,6 +129,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
template.width0 = pDraw->width;
template.height0 = pDraw->height;
template.depth0 = 1;
+ template.array_size = 1;
template.last_level = 0;
template.bind = PIPE_BIND_DEPTH_STENCIL |
PIPE_BIND_SHARED;
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index 1ee79ae177e..66685ecec64 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -538,44 +538,37 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
return TRUE;
}
-static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
- pointer pReadmask)
+void xorg_flush(ScreenPtr pScreen)
{
- ScreenPtr pScreen = screenInfo.screens[i];
modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]);
- pScreen->BlockHandler = ms->blockHandler;
- pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
- pScreen->BlockHandler = drv_block_handler;
-
if (ms->ctx) {
- int j;
+ int j;
- ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE,
- ms->dirtyThrottling ?
- &ms->fence[XORG_NR_FENCES-1] :
- NULL);
+ ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE,
+ ms->dirtyThrottling ?
+ &ms->fence[XORG_NR_FENCES-1] :
+ NULL);
- if (ms->dirtyThrottling) {
- if (ms->fence[0])
- ms->ctx->screen->fence_finish(ms->ctx->screen,
- ms->fence[0], 0);
+ if (ms->dirtyThrottling) {
+ if (ms->fence[0])
+ ms->ctx->screen->fence_finish(ms->ctx->screen,
+ ms->fence[0], 0);
- /* The amount of rendering generated by a block handler can be
- * quite small. Let us get a fair way ahead of hardware before
- * throttling.
- */
- for (j = 0; j < XORG_NR_FENCES - 1; j++)
- ms->screen->fence_reference(ms->screen,
- &ms->fence[j],
- ms->fence[j+1]);
-
- ms->screen->fence_reference(ms->screen,
- &ms->fence[XORG_NR_FENCES-1],
- NULL);
- }
+ /* The amount of rendering generated by a block handler can be
+ * quite small. Let us get a fair way ahead of hardware before
+ * throttling.
+ */
+ for (j = 0; j < XORG_NR_FENCES - 1; j++)
+ ms->screen->fence_reference(ms->screen,
+ &ms->fence[j],
+ ms->fence[j+1]);
+
+ ms->screen->fence_reference(ms->screen,
+ &ms->fence[XORG_NR_FENCES-1],
+ NULL);
+ }
}
-
#ifdef DRM_MODE_FEATURE_DIRTYFB
{
@@ -608,6 +601,19 @@ static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
#endif
}
+static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
+ pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]);
+
+ pScreen->BlockHandler = ms->blockHandler;
+ pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
+ pScreen->BlockHandler = drv_block_handler;
+
+ xorg_flush(pScreen);
+}
+
static Bool
drv_create_screen_resources(ScreenPtr pScreen)
{
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index 4b1c02bad42..718a3453939 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -46,6 +46,8 @@
#include "util/u_math.h"
#include "util/u_debug.h"
#include "util/u_format.h"
+#include "util/u_box.h"
+#include "util/u_surface.h"
#define DEBUG_PRINT 0
#define ROUND_UP_TEXTURES 1
@@ -188,8 +190,8 @@ ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst,
if (!priv || !priv->tex)
return FALSE;
- transfer = pipe_get_transfer(exa->pipe, priv->tex, 0, 0, 0,
- PIPE_TRANSFER_READ, x, y, w, h);
+ transfer = pipe_get_transfer(exa->pipe, priv->tex, 0, 0,
+ PIPE_TRANSFER_READ, x, y, w, h);
if (!transfer)
return FALSE;
@@ -222,8 +224,8 @@ ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
if (!priv || !priv->tex)
return FALSE;
- transfer = pipe_get_transfer(exa->pipe, priv->tex, 0, 0, 0,
- PIPE_TRANSFER_WRITE, x, y, w, h);
+ transfer = pipe_get_transfer(exa->pipe, priv->tex, 0, 0,
+ PIPE_TRANSFER_WRITE, x, y, w, h);
if (!transfer)
return FALSE;
@@ -265,7 +267,7 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
assert(pPix->drawable.height <= priv->tex->height0);
priv->map_transfer =
- pipe_get_transfer(exa->pipe, priv->tex, 0, 0, 0,
+ pipe_get_transfer(exa->pipe, priv->tex, 0, 0,
#ifdef EXA_MIXED_PIXMAPS
PIPE_TRANSFER_MAP_DIRECTLY |
#endif
@@ -449,6 +451,7 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
exa->copy.use_surface_copy = TRUE;
}
else {
+ struct pipe_surface surf_tmpl;
exa->copy.use_surface_copy = FALSE;
if (exa->copy.dst == exa->copy.src)
@@ -458,11 +461,13 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
pipe_resource_reference(&exa->copy.src_texture,
exa->copy.src->tex);
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ u_surface_default_template(&surf_tmpl, exa->copy.dst->tex,
+ PIPE_BIND_RENDER_TARGET);
exa->copy.dst_surface =
- exa->scrn->get_tex_surface(exa->scrn,
- exa->copy.dst->tex,
- 0, 0, 0,
- PIPE_BIND_RENDER_TARGET);
+ exa->pipe->create_surface(exa->pipe,
+ exa->copy.dst->tex,
+ &surf_tmpl);
renderer_copy_prepare(exa->renderer,
@@ -492,19 +497,14 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
(void) priv;
if (exa->copy.use_surface_copy) {
- struct pipe_subresource subdst, subsrc;
- subdst.face = 0;
- subdst.level = 0;
- subsrc.face = 0;
- subsrc.level = 0;
+ struct pipe_box src_box;
+ u_box_2d(srcX, srcY, width, height, &src_box);
exa->pipe->resource_copy_region( exa->pipe,
exa->copy.dst->tex,
- subdst,
+ 0,
dstX, dstY, 0,
exa->copy.src->tex,
- subsrc,
- srcX, srcY, 0,
- width, height );
+ 0, &src_box);
}
else {
renderer_copy_pixmap(exa->renderer,
@@ -874,24 +874,21 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
}
template.depth0 = 1;
+ template.array_size = 1;
template.last_level = 0;
template.bind = PIPE_BIND_RENDER_TARGET | priv->flags;
priv->tex_flags = priv->flags;
texture = exa->scrn->resource_create(exa->scrn, &template);
if (priv->tex) {
- struct pipe_subresource subdst, subsrc;
-
- subdst.face = 0;
- subdst.level = 0;
- subsrc.face = 0;
- subsrc.level = 0;
+ struct pipe_box src_box;
+ u_box_origin_2d(min(width, texture->width0),
+ min(height, texture->height0),
+ &src_box);
exa->pipe->resource_copy_region(exa->pipe, texture,
- subdst, 0, 0, 0,
+ 0, 0, 0, 0,
priv->tex,
- subsrc, 0, 0, 0,
- min(width, texture->width0),
- min(height, texture->height0));
+ 0, &src_box);
}
pipe_resource_reference(&priv->tex, texture);
@@ -947,6 +944,7 @@ xorg_exa_create_root_texture(ScrnInfoPtr pScrn,
template.width0 = width;
template.height0 = height;
template.depth0 = 1;
+ template.array_size = 1;
template.last_level = 0;
template.bind |= PIPE_BIND_RENDER_TARGET;
template.bind |= PIPE_BIND_SCANOUT;
@@ -1063,10 +1061,14 @@ out_err:
}
struct pipe_surface *
-xorg_gpu_surface(struct pipe_screen *scrn, struct exa_pixmap_priv *priv)
+xorg_gpu_surface(struct pipe_context *pipe, struct exa_pixmap_priv *priv)
{
- return scrn->get_tex_surface(scrn, priv->tex, 0, 0, 0,
- PIPE_BIND_RENDER_TARGET);
+ struct pipe_surface surf_tmpl;
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ u_surface_default_template(&surf_tmpl, priv->tex,
+ PIPE_BIND_RENDER_TARGET);
+
+ return pipe->create_surface(pipe, priv->tex, &surf_tmpl);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h
index 86a1afc06e6..1f78f60be74 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa.h
@@ -72,7 +72,7 @@ do { \
} while(0)
struct pipe_surface *
-xorg_gpu_surface(struct pipe_screen *scrn, struct exa_pixmap_priv *priv);
+xorg_gpu_surface(struct pipe_context *pipe, struct exa_pixmap_priv *priv);
void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags,
struct pipe_fence_handle **fence);
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index 92f1cc50653..a3d7c5a70e2 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -10,6 +10,7 @@
#include "util/u_sampler.h"
#include "util/u_inlines.h"
+#include "util/u_box.h"
#include <math.h>
@@ -535,6 +536,7 @@ renderer_clone_texture(struct xorg_renderer *r,
templ.width0 = src->width0;
templ.height0 = src->height0;
templ.depth0 = 1;
+ templ.array_size = 1;
templ.bind = PIPE_BIND_SAMPLER_VIEW;
pt = screen->resource_create(screen, &templ);
@@ -546,19 +548,15 @@ renderer_clone_texture(struct xorg_renderer *r,
{
/* copy source framebuffer surface into texture */
- struct pipe_subresource subsrc, subdst;
- subsrc.face = 0;
- subsrc.level = 0;
- subdst.face = 0;
- subdst.level = 0;
+ struct pipe_box src_box;
+ u_box_origin_2d(src->width0, src->height0, &src_box);
+
pipe->resource_copy_region(pipe,
pt, /* dest */
- subdst,
+ 0, /* dest_level */
0, 0, 0, /* destx/y/z */
src,
- subsrc,
- 0, 0, 0,
- src->width0, src->height0);
+ 0, &src_box);
}
return pt;
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index a3fb5e5dad0..56397b8fea8 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -156,6 +156,7 @@ CustomizerPtr xorg_customizer(ScrnInfoPtr pScrn);
Bool xorg_has_gallium(ScrnInfoPtr pScrn);
+void xorg_flush(ScreenPtr pScreen);
/***********************************************************************
* xorg_exa.c
*/
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index f64959f00e9..c72ba9ef8db 100644
--- a/src/gallium/state_trackers/xorg/xorg_xv.c
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -171,6 +171,7 @@ create_component_texture(struct pipe_context *pipe,
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
+ templ.array_size = 1;
templ.bind = PIPE_BIND_SAMPLER_VIEW;
tex = screen->resource_create(screen, &templ);
@@ -312,17 +313,17 @@ copy_packed_data(ScrnInfoPtr pScrn,
int y_array_size = w * h;
ytrans = pipe_get_transfer(pipe, dst[0],
- 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- left, top, w, h);
+ 0, 0,
+ PIPE_TRANSFER_WRITE,
+ left, top, w, h);
utrans = pipe_get_transfer(pipe, dst[1],
- 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- left, top, w, h);
+ 0, 0,
+ PIPE_TRANSFER_WRITE,
+ left, top, w, h);
vtrans = pipe_get_transfer(pipe, dst[2],
- 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- left, top, w, h);
+ 0, 0,
+ PIPE_TRANSFER_WRITE,
+ left, top, w, h);
ymap = (char*)pipe->transfer_map(pipe, ytrans);
umap = (char*)pipe->transfer_map(pipe, utrans);
@@ -533,7 +534,7 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
if (!dst || !dst->tex)
XORG_FALLBACK("Xv destination %s", !dst ? "!dst" : "!dst->tex");
- dst_surf = xorg_gpu_surface(pPriv->r->pipe->screen, dst);
+ dst_surf = xorg_gpu_surface(pPriv->r->pipe, dst);
hdtv = ((src_w >= RES_720P_X) && (src_h >= RES_720P_Y));
#ifdef COMPOSITE
diff --git a/src/gallium/state_trackers/xorg/xvmc/subpicture.c b/src/gallium/state_trackers/xorg/xvmc/subpicture.c
index e0c9e303817..1c70d1deb66 100644
--- a/src/gallium/state_trackers/xorg/xvmc/subpicture.c
+++ b/src/gallium/state_trackers/xorg/xvmc/subpicture.c
@@ -135,6 +135,7 @@ Status XvMCCreateSubpicture(Display *dpy, XvMCContext *context, XvMCSubpicture *
struct pipe_video_context *vpipe;
struct pipe_resource template;
struct pipe_resource *tex;
+ struct pipe_surface surf_template;
Status ret;
XVMC_MSG(XVMC_TRACE, "[XvMC] Creating subpicture %p.\n", subpicture);
@@ -181,8 +182,11 @@ Status XvMCCreateSubpicture(Display *dpy, XvMCContext *context, XvMCSubpicture *
subpicture_priv->context = context;
tex = vpipe->screen->resource_create(vpipe->screen, &template);
- subpicture_priv->sfc = vpipe->screen->get_tex_surface(vpipe->screen, tex, 0, 0, 0,
- PIPE_BIND_SAMPLER_VIEW);
+
+ memset(&surf_template, 0, sizeof(surf_template));
+ surf_template.format = tex->format;
+ surf_template.usage = PIPE_BIND_SAMPLER_VIEW;
+ subpicture_priv->sfc = vpipe->create_surface(vpipe, tex, &surf_template);
pipe_resource_reference(&tex, NULL);
if (!subpicture_priv->sfc) {
FREE(subpicture_priv);
@@ -239,7 +243,6 @@ Status XvMCCompositeSubpicture(Display *dpy, XvMCSubpicture *subpicture, XvImage
unsigned char *src, *dst, *dst_line;
unsigned x, y;
struct pipe_box dst_box = {dstx, dsty, 0, width, height, 1};
- struct pipe_subresource sr = {0, 0};
XVMC_MSG(XVMC_TRACE, "[XvMC] Compositing subpicture %p.\n", subpicture);
@@ -264,7 +267,7 @@ Status XvMCCompositeSubpicture(Display *dpy, XvMCSubpicture *subpicture, XvImage
/* TODO: Assert rects are within bounds? Or clip? */
xfer = vpipe->get_transfer(vpipe, subpicture_priv->sfc->texture,
- sr, PIPE_TRANSFER_WRITE, &dst_box);
+ 0, PIPE_TRANSFER_WRITE, &dst_box);
if (!xfer)
return BadAlloc;
diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c
index 209dffd2c58..d7285a478fb 100644
--- a/src/gallium/state_trackers/xorg/xvmc/surface.c
+++ b/src/gallium/state_trackers/xorg/xvmc/surface.c
@@ -203,6 +203,7 @@ Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surfac
XvMCSurfacePrivate *surface_priv;
struct pipe_resource template;
struct pipe_resource *vsfc_tex;
+ struct pipe_surface surf_template;
struct pipe_surface *vsfc;
XVMC_MSG(XVMC_TRACE, "[XvMC] Creating surface %p.\n", surface);
@@ -248,8 +249,10 @@ Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surfac
return BadAlloc;
}
- vsfc = vpipe->screen->get_tex_surface(vpipe->screen, vsfc_tex, 0, 0, 0,
- PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET);
+ memset(&surf_template, 0, sizeof(surf_template));
+ surf_template.format = vsfc_tex->format;
+ surf_template.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
+ vsfc = vpipe->create_surface(vpipe, vsfc_tex, &surf_template);
pipe_resource_reference(&vsfc_tex, NULL);
if (!vsfc) {
FREE(surface_priv);
@@ -396,7 +399,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
context = surface_priv->context;
context_priv = context->privData;
- drawable_surface = vl_drawable_surface_get(context_priv->vctx->vscreen, drawable);
+ drawable_surface = vl_drawable_surface_get(context_priv->vctx, drawable);
if (!drawable_surface)
return BadDrawable;
@@ -448,7 +451,8 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
vpipe->screen->flush_frontbuffer
(
vpipe->screen,
- drawable_surface,
+ drawable_surface->texture,
+ 0, 0,
vl_contextprivate_get(context_priv->vctx, drawable_surface)
);