Browse Source

Merge branch 'gallium-sampler-view' into gallium-resources

Conflicts:
	src/gallium/auxiliary/cso_cache/cso_context.c
	src/gallium/auxiliary/util/u_blit.c
	src/gallium/drivers/llvmpipe/lp_texture.c
	src/gallium/drivers/softpipe/sp_texture.c
	src/mesa/state_tracker/st_cb_fbo.c
	src/mesa/state_tracker/st_framebuffer.c
	src/mesa/state_tracker/st_texture.c
gallium-resources
Keith Whitwell 15 years ago
parent
commit
ad88ac7903
100 changed files with 3174 additions and 1139 deletions
  1. 2
    2
      progs/objviewer/skybox.c
  2. 8
    22
      src/gallium/auxiliary/cso_cache/cso_context.c
  3. 4
    4
      src/gallium/auxiliary/gallivm/lp_bld.h
  4. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_alpha.h
  5. 36
    33
      src/gallium/auxiliary/gallivm/lp_bld_arit.c
  6. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_arit.h
  7. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_blend.h
  8. 4
    4
      src/gallium/auxiliary/gallivm/lp_bld_const.c
  9. 4
    6
      src/gallium/auxiliary/gallivm/lp_bld_const.h
  10. 17
    17
      src/gallium/auxiliary/gallivm/lp_bld_conv.c
  11. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_conv.h
  12. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_debug.h
  13. 107
    3
      src/gallium/auxiliary/gallivm/lp_bld_depth.c
  14. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_depth.h
  15. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_flow.h
  16. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_format.h
  17. 2
    2
      src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
  18. 3
    3
      src/gallium/auxiliary/gallivm/lp_bld_interp.c
  19. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_interp.h
  20. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_intr.h
  21. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_logic.c
  22. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_logic.h
  23. 2
    2
      src/gallium/auxiliary/gallivm/lp_bld_pack.c
  24. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_pack.h
  25. 3
    3
      src/gallium/auxiliary/gallivm/lp_bld_sample.c
  26. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_sample.h
  27. 252
    149
      src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
  28. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_struct.h
  29. 2
    2
      src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
  30. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_swizzle.h
  31. 1
    1
      src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
  32. 3
    3
      src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
  33. 2
    2
      src/gallium/auxiliary/gallivm/lp_bld_type.h
  34. 27
    11
      src/gallium/auxiliary/util/u_blit.c
  35. 2
    0
      src/gallium/auxiliary/util/u_blit.h
  36. 4
    2
      src/gallium/drivers/cell/ppu/cell_screen.c
  37. 1
    0
      src/gallium/drivers/cell/ppu/cell_texture.c
  38. 1
    0
      src/gallium/drivers/i965/brw_context.c
  39. 13
    6
      src/gallium/drivers/llvmpipe/README
  40. 4
    2
      src/gallium/drivers/llvmpipe/lp_screen.c
  41. 1
    1
      src/gallium/drivers/llvmpipe/lp_screen.h
  42. 1
    1
      src/gallium/drivers/llvmpipe/lp_state.h
  43. 2
    2
      src/gallium/drivers/llvmpipe/lp_state_fs.c
  44. 1
    1
      src/gallium/drivers/llvmpipe/lp_test.h
  45. 1
    1
      src/gallium/drivers/llvmpipe/lp_test_format.c
  46. 1
    1
      src/gallium/drivers/llvmpipe/lp_tex_sample.h
  47. 47
    0
      src/gallium/drivers/llvmpipe/lp_texture.c
  48. 7
    9
      src/gallium/drivers/nvfx/nvfx_state.c
  49. 2
    2
      src/gallium/drivers/r300/r300_blit.c
  50. 3
    4
      src/gallium/drivers/r300/r300_context.h
  51. 7
    6
      src/gallium/drivers/r300/r300_emit.c
  52. 11
    10
      src/gallium/drivers/r300/r300_state.c
  53. 2
    2
      src/gallium/drivers/r300/r300_state_derived.c
  54. 4
    2
      src/gallium/drivers/softpipe/sp_screen.c
  55. 52
    2
      src/gallium/drivers/softpipe/sp_texture.c
  56. 407
    0
      src/gallium/include/state_tracker/st_api.h
  57. 20
    0
      src/gallium/include/state_tracker/sw_winsys.h
  58. 1
    2
      src/gallium/state_trackers/dri/dri_context.c
  59. 1
    1
      src/gallium/state_trackers/dri/dri_drawable.c
  60. 206
    380
      src/gallium/state_trackers/egl/common/egl_g3d.c
  61. 12
    13
      src/gallium/state_trackers/egl/common/egl_g3d.h
  62. 227
    0
      src/gallium/state_trackers/egl/common/egl_g3d_st.c
  63. 46
    40
      src/gallium/state_trackers/egl/common/egl_g3d_st.h
  64. 0
    131
      src/gallium/state_trackers/egl/common/egl_st.c
  65. 0
    20
      src/gallium/state_trackers/egl/common/st_public_tmp.h
  66. 1
    0
      src/gallium/state_trackers/es/Makefile
  67. 6
    1
      src/gallium/state_trackers/es/st_es1.c
  68. 6
    1
      src/gallium/state_trackers/es/st_es2.c
  69. 2
    1
      src/gallium/state_trackers/glx/xlib/Makefile
  70. 1
    0
      src/gallium/state_trackers/glx/xlib/SConscript
  71. 1
    4
      src/gallium/state_trackers/glx/xlib/glx_api.c
  72. 161
    155
      src/gallium/state_trackers/glx/xlib/xm_api.c
  73. 23
    32
      src/gallium/state_trackers/glx/xlib/xm_api.h
  74. 8
    4
      src/gallium/state_trackers/glx/xlib/xm_public.h
  75. 332
    0
      src/gallium/state_trackers/glx/xlib/xm_st.c
  76. 51
    0
      src/gallium/state_trackers/glx/xlib/xm_st.h
  77. 1
    0
      src/gallium/state_trackers/vega/Makefile
  78. 3
    0
      src/gallium/state_trackers/vega/api_context.c
  79. 0
    4
      src/gallium/state_trackers/vega/api_masks.c
  80. 3
    0
      src/gallium/state_trackers/vega/vg_context.c
  81. 7
    0
      src/gallium/state_trackers/vega/vg_context.h
  82. 373
    0
      src/gallium/state_trackers/vega/vg_manager.c
  83. 40
    0
      src/gallium/state_trackers/vega/vg_manager.h
  84. 10
    1
      src/gallium/targets/libgl-xlib/xlib.c
  85. 1
    1
      src/gallium/winsys/drm/Makefile
  86. 1
    0
      src/gallium/winsys/drm/i965/dri/Makefile
  87. 11
    1
      src/gallium/winsys/drm/i965/gem/i965_drm_api.c
  88. 14
    0
      src/gallium/winsys/drm/sw/Makefile
  89. 97
    0
      src/gallium/winsys/drm/sw/sw_drm_api.c
  90. 34
    0
      src/gallium/winsys/drm/sw/sw_drm_api.h
  91. 282
    0
      src/gallium/winsys/drm/sw/wrapper_sw_winsys.c
  92. 35
    0
      src/gallium/winsys/drm/sw/wrapper_sw_winsys.h
  93. 25
    0
      src/gallium/winsys/gdi/gdi_sw_winsys.c
  94. 24
    0
      src/gallium/winsys/null/null_sw_winsys.c
  95. 25
    0
      src/gallium/winsys/xlib/xlib_sw_winsys.c
  96. 1
    0
      src/mesa/SConscript
  97. 1
    0
      src/mesa/sources.mak
  98. 2
    3
      src/mesa/state_tracker/st_atom.c
  99. 10
    5
      src/mesa/state_tracker/st_cb_blit.c
  100. 0
    0
      src/mesa/state_tracker/st_cb_fbo.c

+ 2
- 2
progs/objviewer/skybox.c View File

@@ -88,9 +88,9 @@ LoadSkyBoxCubeTexture(const char *filePosX,
return 0;
if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, fileNegX, GL_TRUE, GL_TRUE))
return 0;
if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, filePosY, 1+GL_FALSE, GL_TRUE))
if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, filePosY, GL_TRUE, GL_TRUE))
return 0;
if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, fileNegY, 1+GL_FALSE, GL_TRUE))
if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, fileNegY, GL_TRUE, GL_TRUE))
return 0;
if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, filePosZ, GL_TRUE, GL_TRUE))
return 0;

+ 8
- 22
src/gallium/auxiliary/cso_cache/cso_context.c View File

@@ -71,16 +71,12 @@ struct cso_context {
unsigned nr_vertex_samplers_saved;
void *vertex_samplers_saved[PIPE_MAX_VERTEX_SAMPLERS];

struct pipe_resource *textures[PIPE_MAX_SAMPLERS];
uint nr_fragment_sampler_views;
struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
uint nr_textures;

uint nr_vertex_sampler_views;
struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];

uint nr_textures_saved;
struct pipe_resource *textures_saved[PIPE_MAX_SAMPLERS];
uint nr_fragment_sampler_views_saved;
struct pipe_sampler_view *fragment_sampler_views_saved[PIPE_MAX_SAMPLERS];

@@ -299,8 +295,6 @@ void cso_release_all( struct cso_context *ctx )
}

for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
pipe_resource_reference(&ctx->textures[i], NULL);
pipe_resource_reference(&ctx->textures_saved[i], NULL);
pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL);
pipe_sampler_view_reference(&ctx->fragment_sampler_views_saved[i], NULL);
}
@@ -630,7 +624,7 @@ enum pipe_error cso_set_sampler_textures( struct cso_context *ctx,
{
uint i;

ctx->nr_textures = count;
ctx->nr_fragment_sampler_views = count;

for (i = 0; i < count; i++) {
struct pipe_sampler_view templ, *view;
@@ -638,15 +632,14 @@ enum pipe_error cso_set_sampler_textures( struct cso_context *ctx,
u_sampler_view_default_template(&templ,
textures[i],
textures[i]->format);

view = ctx->pipe->create_sampler_view(ctx->pipe,
textures[i],
&templ);

pipe_resource_reference(&ctx->textures[i], textures[i]);
pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], view);
}
for ( ; i < PIPE_MAX_SAMPLERS; i++) {
pipe_resource_reference(&ctx->textures[i], NULL);
pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL);
}

@@ -661,12 +654,10 @@ void cso_save_sampler_textures( struct cso_context *ctx )
{
uint i;

ctx->nr_textures_saved = ctx->nr_textures;
for (i = 0; i < ctx->nr_textures; i++) {
assert(!ctx->textures_saved[i]);
ctx->nr_fragment_sampler_views_saved = ctx->nr_fragment_sampler_views;
for (i = 0; i < ctx->nr_fragment_sampler_views; i++) {
assert(!ctx->fragment_sampler_views_saved[i]);

pipe_resource_reference(&ctx->textures_saved[i], ctx->textures[i]);
pipe_sampler_view_reference(&ctx->fragment_sampler_views_saved[i],
ctx->fragment_sampler_views[i]);
}
@@ -676,27 +667,22 @@ void cso_restore_sampler_textures( struct cso_context *ctx )
{
uint i;

ctx->nr_textures = ctx->nr_textures_saved;

for (i = 0; i < ctx->nr_textures; i++) {
pipe_resource_reference(&ctx->textures[i], NULL);
ctx->textures[i] = ctx->textures_saved[i];
ctx->textures_saved[i] = NULL;
ctx->nr_fragment_sampler_views = ctx->nr_fragment_sampler_views_saved;

for (i = 0; i < ctx->nr_fragment_sampler_views; i++) {
pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL);
ctx->fragment_sampler_views[i] = ctx->fragment_sampler_views_saved[i];
ctx->fragment_sampler_views_saved[i] = NULL;
}
for ( ; i < PIPE_MAX_SAMPLERS; i++) {
pipe_resource_reference(&ctx->textures[i], NULL);
pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL);
}

ctx->pipe->set_fragment_sampler_views(ctx->pipe,
ctx->nr_textures,
ctx->nr_fragment_sampler_views,
ctx->fragment_sampler_views);

ctx->nr_textures_saved = 0;
ctx->nr_fragment_sampler_views_saved = 0;
}



src/gallium/auxiliary/os/os_llvm.h → src/gallium/auxiliary/gallivm/lp_bld.h View File

@@ -31,8 +31,8 @@
*/


#ifndef OS_LLVM_H
#define OS_LLVM_H
#ifndef LP_BLD_H
#define LP_BLD_H


#include <llvm-c/Core.h>
@@ -40,8 +40,8 @@

/** Set version to 0 if missing to avoid #ifdef HAVE_LLVM everywhere */
#ifndef HAVE_LLVM
#define HAVE_LLVM 0x0
#define HAVE_LLVM 0x0207
#endif


#endif /* OS_LLVM_H */
#endif /* LP_BLD_H */

+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_alpha.h View File

@@ -35,7 +35,7 @@
#define LP_BLD_ALPHA_H


#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"

struct pipe_alpha_state;
struct lp_type;

+ 36
- 33
src/gallium/auxiliary/gallivm/lp_bld_arit.c View File

@@ -361,12 +361,12 @@ lp_build_mul_u8n(LLVMBuilderRef builder,
LLVMValueRef c8;
LLVMValueRef ab;

c8 = lp_build_int_const_scalar(i16_type, 8);
c8 = lp_build_const_int_vec(i16_type, 8);
#if 0
/* a*b/255 ~= (a*(b + 1)) >> 256 */
b = LLVMBuildAdd(builder, b, lp_build_int_const_scalar(i16_type, 1), "");
b = LLVMBuildAdd(builder, b, lp_build_const_int_vec(i16_type, 1), "");
ab = LLVMBuildMul(builder, a, b, "");

#else
@@ -374,7 +374,7 @@ lp_build_mul_u8n(LLVMBuilderRef builder,
/* ab/255 ~= (ab + (ab >> 8) + 0x80) >> 8 */
ab = LLVMBuildMul(builder, a, b, "");
ab = LLVMBuildAdd(builder, ab, LLVMBuildLShr(builder, ab, c8, ""), "");
ab = LLVMBuildAdd(builder, ab, lp_build_int_const_scalar(i16_type, 0x80), "");
ab = LLVMBuildAdd(builder, ab, lp_build_const_int_vec(i16_type, 0x80), "");

#endif
@@ -429,7 +429,7 @@ lp_build_mul(struct lp_build_context *bld,
}

if(type.fixed)
shift = lp_build_int_const_scalar(type, type.width/2);
shift = lp_build_const_int_vec(type, type.width/2);
else
shift = NULL;

@@ -491,7 +491,7 @@ lp_build_mul_imm(struct lp_build_context *bld,
* for Inf and NaN.
*/
unsigned mantissa = lp_mantissa(bld->type);
factor = lp_build_int_const_scalar(bld->type, (unsigned long long)shift << mantissa);
factor = lp_build_const_int_vec(bld->type, (unsigned long long)shift << mantissa);
a = LLVMBuildBitCast(bld->builder, a, lp_build_int_vec_type(bld->type), "");
a = LLVMBuildAdd(bld->builder, a, factor, "");
a = LLVMBuildBitCast(bld->builder, a, lp_build_vec_type(bld->type), "");
@@ -499,12 +499,12 @@ lp_build_mul_imm(struct lp_build_context *bld,
#endif
}
else {
factor = lp_build_const_scalar(bld->type, shift);
factor = lp_build_const_vec(bld->type, shift);
return LLVMBuildShl(bld->builder, a, factor, "");
}
}

factor = lp_build_const_scalar(bld->type, (double)b);
factor = lp_build_const_vec(bld->type, (double)b);
return lp_build_mul(bld, a, factor);
}

@@ -567,7 +567,7 @@ lp_build_lerp(struct lp_build_context *bld,
* but it will be wrong for other uses. Basically we need a more
* powerful lp_type, capable of further distinguishing the values
* interpretation from the value storage. */
res = LLVMBuildAnd(bld->builder, res, lp_build_int_const_scalar(bld->type, (1 << bld->type.width/2) - 1), "");
res = LLVMBuildAnd(bld->builder, res, lp_build_const_int_vec(bld->type, (1 << bld->type.width/2) - 1), "");

return res;
}
@@ -689,7 +689,7 @@ lp_build_abs(struct lp_build_context *bld,
/* vector of floats */
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
unsigned long long absMask = ~(1ULL << (type.width - 1));
LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long) absMask));
LLVMValueRef mask = lp_build_const_int_vec(type, ((unsigned long long) absMask));
a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
a = LLVMBuildAnd(bld->builder, a, mask, "");
a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
@@ -751,7 +751,7 @@ lp_build_sgn(struct lp_build_context *bld,
/* vector */
int_type = lp_build_int_vec_type(type);
vec_type = lp_build_vec_type(type);
mask = lp_build_int_const_scalar(type, maskBit);
mask = lp_build_const_int_vec(type, maskBit);
}

/* Take the sign bit and add it to 1 constant */
@@ -763,14 +763,14 @@ lp_build_sgn(struct lp_build_context *bld,
}
else
{
LLVMValueRef minus_one = lp_build_const_scalar(type, -1.0);
LLVMValueRef minus_one = lp_build_const_vec(type, -1.0);
cond = lp_build_cmp(bld, PIPE_FUNC_GREATER, a, bld->zero);
res = lp_build_select(bld, cond, bld->one, minus_one);
}

/* Handle zero */
cond = lp_build_cmp(bld, PIPE_FUNC_EQUAL, a, bld->zero);
res = lp_build_select(bld, cond, bld->zero, bld->one);
res = lp_build_select(bld, cond, bld->zero, res);

return res;
}
@@ -789,8 +789,8 @@ lp_build_set_sign(struct lp_build_context *bld,
const struct lp_type type = bld->type;
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
LLVMTypeRef vec_type = lp_build_vec_type(type);
LLVMValueRef shift = lp_build_int_const_scalar(type, type.width - 1);
LLVMValueRef mask = lp_build_int_const_scalar(type,
LLVMValueRef shift = lp_build_const_int_vec(type, type.width - 1);
LLVMValueRef mask = lp_build_const_int_vec(type,
~((unsigned long long) 1 << (type.width - 1)));
LLVMValueRef val, res;

@@ -930,7 +930,10 @@ lp_build_floor(struct lp_build_context *bld,
assert(type.floating);

if (type.length == 1) {
return LLVMBuildFPTrunc(bld->builder, a, LLVMFloatType(), "");
LLVMValueRef res;
res = lp_build_ifloor(bld, a);
res = LLVMBuildSIToFP(bld->builder, res, LLVMFloatType(), "");
return res;
}

if(util_cpu_caps.has_sse4_1)
@@ -993,7 +996,7 @@ lp_build_itrunc(struct lp_build_context *bld,

if (type.length == 1) {
LLVMTypeRef int_type = LLVMIntType(type.width);
return LLVMBuildFPTrunc(bld->builder, a, int_type, "");
return LLVMBuildFPToSI(bld->builder, a, int_type, "");
}
else {
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
@@ -1031,7 +1034,7 @@ lp_build_iround(struct lp_build_context *bld,
}
else {
LLVMTypeRef vec_type = lp_build_vec_type(type);
LLVMValueRef mask = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1));
LLVMValueRef mask = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1));
LLVMValueRef sign;
LLVMValueRef half;

@@ -1040,7 +1043,7 @@ lp_build_iround(struct lp_build_context *bld,
sign = LLVMBuildAnd(bld->builder, sign, mask, "");

/* sign * 0.5 */
half = lp_build_const_scalar(type, 0.5);
half = lp_build_const_vec(type, 0.5);
half = LLVMBuildBitCast(bld->builder, half, int_vec_type, "");
half = LLVMBuildOr(bld->builder, sign, half, "");
half = LLVMBuildBitCast(bld->builder, half, vec_type, "");
@@ -1083,18 +1086,18 @@ lp_build_ifloor(struct lp_build_context *bld,
/* Take the sign bit and add it to 1 constant */
LLVMTypeRef vec_type = lp_build_vec_type(type);
unsigned mantissa = lp_mantissa(type);
LLVMValueRef mask = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1));
LLVMValueRef mask = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1));
LLVMValueRef sign;
LLVMValueRef offset;

/* sign = a < 0 ? ~0 : 0 */
sign = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
sign = LLVMBuildAnd(bld->builder, sign, mask, "");
sign = LLVMBuildAShr(bld->builder, sign, lp_build_int_const_scalar(type, type.width - 1), "");
sign = LLVMBuildAShr(bld->builder, sign, lp_build_const_int_vec(type, type.width - 1), "");
lp_build_name(sign, "floor.sign");

/* offset = -0.99999(9)f */
offset = lp_build_const_scalar(type, -(double)(((unsigned long long)1 << mantissa) - 1)/((unsigned long long)1 << mantissa));
offset = lp_build_const_vec(type, -(double)(((unsigned long long)1 << mantissa) - 1)/((unsigned long long)1 << mantissa));
offset = LLVMConstBitCast(offset, int_vec_type);

/* offset = a < 0 ? -0.99999(9)f : 0.0f */
@@ -1265,7 +1268,7 @@ lp_build_exp(struct lp_build_context *bld,
LLVMValueRef x)
{
/* log2(e) = 1/log(2) */
LLVMValueRef log2e = lp_build_const_scalar(bld->type, 1.4426950408889634);
LLVMValueRef log2e = lp_build_const_vec(bld->type, 1.4426950408889634);

return lp_build_mul(bld, log2e, lp_build_exp2(bld, x));
}
@@ -1279,7 +1282,7 @@ lp_build_log(struct lp_build_context *bld,
LLVMValueRef x)
{
/* log(2) */
LLVMValueRef log2 = lp_build_const_scalar(bld->type, 0.69314718055994529);
LLVMValueRef log2 = lp_build_const_vec(bld->type, 0.69314718055994529);

return lp_build_mul(bld, log2, lp_build_exp2(bld, x));
}
@@ -1315,7 +1318,7 @@ lp_build_polynomial(struct lp_build_context *bld,
if (type.length == 1)
coeff = LLVMConstReal(float_type, coeffs[i]);
else
coeff = lp_build_const_scalar(type, coeffs[i]);
coeff = lp_build_const_vec(type, coeffs[i]);

if(res)
res = lp_build_add(bld, coeff, lp_build_mul(bld, x, res));
@@ -1372,11 +1375,11 @@ lp_build_exp2_approx(struct lp_build_context *bld,

assert(type.floating && type.width == 32);

x = lp_build_min(bld, x, lp_build_const_scalar(type, 129.0));
x = lp_build_max(bld, x, lp_build_const_scalar(type, -126.99999));
x = lp_build_min(bld, x, lp_build_const_vec(type, 129.0));
x = lp_build_max(bld, x, lp_build_const_vec(type, -126.99999));

/* ipart = int(x - 0.5) */
ipart = LLVMBuildSub(bld->builder, x, lp_build_const_scalar(type, 0.5f), "");
ipart = LLVMBuildSub(bld->builder, x, lp_build_const_vec(type, 0.5f), "");
ipart = LLVMBuildFPToSI(bld->builder, ipart, int_vec_type, "");

/* fpart = x - ipart */
@@ -1386,8 +1389,8 @@ lp_build_exp2_approx(struct lp_build_context *bld,

if(p_exp2_int_part || p_exp2) {
/* expipart = (float) (1 << ipart) */
expipart = LLVMBuildAdd(bld->builder, ipart, lp_build_int_const_scalar(type, 127), "");
expipart = LLVMBuildShl(bld->builder, expipart, lp_build_int_const_scalar(type, 23), "");
expipart = LLVMBuildAdd(bld->builder, ipart, lp_build_const_int_vec(type, 127), "");
expipart = LLVMBuildShl(bld->builder, expipart, lp_build_const_int_vec(type, 23), "");
expipart = LLVMBuildBitCast(bld->builder, expipart, vec_type, "");
}

@@ -1453,8 +1456,8 @@ lp_build_log2_approx(struct lp_build_context *bld,
LLVMTypeRef vec_type = lp_build_vec_type(type);
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);

LLVMValueRef expmask = lp_build_int_const_scalar(type, 0x7f800000);
LLVMValueRef mantmask = lp_build_int_const_scalar(type, 0x007fffff);
LLVMValueRef expmask = lp_build_const_int_vec(type, 0x7f800000);
LLVMValueRef mantmask = lp_build_const_int_vec(type, 0x007fffff);
LLVMValueRef one = LLVMConstBitCast(bld->one, int_vec_type);

LLVMValueRef i = NULL;
@@ -1479,8 +1482,8 @@ lp_build_log2_approx(struct lp_build_context *bld,
}

if(p_floor_log2 || p_log2) {
logexp = LLVMBuildLShr(bld->builder, exp, lp_build_int_const_scalar(type, 23), "");
logexp = LLVMBuildSub(bld->builder, logexp, lp_build_int_const_scalar(type, 127), "");
logexp = LLVMBuildLShr(bld->builder, exp, lp_build_const_int_vec(type, 23), "");
logexp = LLVMBuildSub(bld->builder, logexp, lp_build_const_int_vec(type, 127), "");
logexp = LLVMBuildSIToFP(bld->builder, logexp, vec_type, "");
}


+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_arit.h View File

@@ -37,7 +37,7 @@
#define LP_BLD_ARIT_H


#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"


struct lp_type;

+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_blend.h View File

@@ -40,7 +40,7 @@
* for a standalone example.
*/

#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"
#include "pipe/p_format.h"


+ 4
- 4
src/gallium/auxiliary/gallivm/lp_bld_const.c View File

@@ -263,7 +263,7 @@ lp_build_one(struct lp_type type)
if(type.sign)
/* TODO: Unfortunately this caused "Tried to create a shift operation
* on a non-integer type!" */
vec = LLVMConstLShr(vec, lp_build_int_const_scalar(type, 1));
vec = LLVMConstLShr(vec, lp_build_const_int_vec(type, 1));
#endif

return vec;
@@ -283,8 +283,8 @@ lp_build_one(struct lp_type type)
* Build constant-valued vector from a scalar value.
*/
LLVMValueRef
lp_build_const_scalar(struct lp_type type,
double val)
lp_build_const_vec(struct lp_type type,
double val)
{
LLVMTypeRef elem_type = lp_build_elem_type(type);
LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
@@ -309,7 +309,7 @@ lp_build_const_scalar(struct lp_type type,


LLVMValueRef
lp_build_int_const_scalar(struct lp_type type,
lp_build_const_int_vec(struct lp_type type,
long long val)
{
LLVMTypeRef elem_type = lp_build_int_elem_type(type);

+ 4
- 6
src/gallium/auxiliary/gallivm/lp_bld_const.h View File

@@ -37,9 +37,9 @@
#define LP_BLD_CONST_H


#include "os/os_llvm.h"
#include "pipe/p_compiler.h"
#include "gallivm/lp_bld.h"

#include <pipe/p_compiler.h>


struct lp_type;
@@ -85,13 +85,11 @@ lp_build_one(struct lp_type type);


LLVMValueRef
lp_build_const_scalar(struct lp_type type,
double val);
lp_build_const_vec(struct lp_type type, double val);


LLVMValueRef
lp_build_int_const_scalar(struct lp_type type,
long long val);
lp_build_const_int_vec(struct lp_type type, long long val);


LLVMValueRef

+ 17
- 17
src/gallium/auxiliary/gallivm/lp_bld_conv.c View File

@@ -114,13 +114,13 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
scale = (double)mask/ubound;
bias = (double)((unsigned long long)1 << (mantissa - n));

res = LLVMBuildMul(builder, src, lp_build_const_scalar(src_type, scale), "");
res = LLVMBuildAdd(builder, res, lp_build_const_scalar(src_type, bias), "");
res = LLVMBuildMul(builder, src, lp_build_const_vec(src_type, scale), "");
res = LLVMBuildAdd(builder, res, lp_build_const_vec(src_type, bias), "");
res = LLVMBuildBitCast(builder, res, int_vec_type, "");

if(dst_width > n) {
int shift = dst_width - n;
res = LLVMBuildShl(builder, res, lp_build_int_const_scalar(src_type, shift), "");
res = LLVMBuildShl(builder, res, lp_build_const_int_vec(src_type, shift), "");

/* TODO: Fill in the empty lower bits for additional precision? */
/* YES: this fixes progs/trivial/tri-z-eq.c.
@@ -130,21 +130,21 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
#if 0
{
LLVMValueRef msb;
msb = LLVMBuildLShr(builder, res, lp_build_int_const_scalar(src_type, dst_width - 1), "");
msb = LLVMBuildShl(builder, msb, lp_build_int_const_scalar(src_type, shift), "");
msb = LLVMBuildSub(builder, msb, lp_build_int_const_scalar(src_type, 1), "");
msb = LLVMBuildLShr(builder, res, lp_build_const_int_vec(src_type, dst_width - 1), "");
msb = LLVMBuildShl(builder, msb, lp_build_const_int_vec(src_type, shift), "");
msb = LLVMBuildSub(builder, msb, lp_build_const_int_vec(src_type, 1), "");
res = LLVMBuildOr(builder, res, msb, "");
}
#elif 0
while(shift > 0) {
res = LLVMBuildOr(builder, res, LLVMBuildLShr(builder, res, lp_build_int_const_scalar(src_type, n), ""), "");
res = LLVMBuildOr(builder, res, LLVMBuildLShr(builder, res, lp_build_const_int_vec(src_type, n), ""), "");
shift -= n;
n *= 2;
}
#endif
}
else
res = LLVMBuildAnd(builder, res, lp_build_int_const_scalar(src_type, mask), "");
res = LLVMBuildAnd(builder, res, lp_build_const_int_vec(src_type, mask), "");

return res;
}
@@ -183,10 +183,10 @@ lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,

if(src_width > mantissa) {
int shift = src_width - mantissa;
res = LLVMBuildLShr(builder, res, lp_build_int_const_scalar(dst_type, shift), "");
res = LLVMBuildLShr(builder, res, lp_build_const_int_vec(dst_type, shift), "");
}

bias_ = lp_build_const_scalar(dst_type, bias);
bias_ = lp_build_const_vec(dst_type, bias);

res = LLVMBuildOr(builder,
res,
@@ -195,7 +195,7 @@ lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
res = LLVMBuildBitCast(builder, res, vec_type, "");

res = LLVMBuildSub(builder, res, bias_, "");
res = LLVMBuildMul(builder, res, lp_build_const_scalar(dst_type, scale), "");
res = LLVMBuildMul(builder, res, lp_build_const_vec(dst_type, scale), "");

return res;
}
@@ -251,7 +251,7 @@ lp_build_conv(LLVMBuilderRef builder,
if(dst_min == 0.0)
thres = bld.zero;
else
thres = lp_build_const_scalar(src_type, dst_min);
thres = lp_build_const_vec(src_type, dst_min);
for(i = 0; i < num_tmps; ++i)
tmp[i] = lp_build_max(&bld, tmp[i], thres);
}
@@ -260,7 +260,7 @@ lp_build_conv(LLVMBuilderRef builder,
if(dst_max == 1.0)
thres = bld.one;
else
thres = lp_build_const_scalar(src_type, dst_max);
thres = lp_build_const_vec(src_type, dst_max);
for(i = 0; i < num_tmps; ++i)
tmp[i] = lp_build_min(&bld, tmp[i], thres);
}
@@ -288,7 +288,7 @@ lp_build_conv(LLVMBuilderRef builder,
LLVMTypeRef tmp_vec_type;

if (dst_scale != 1.0) {
LLVMValueRef scale = lp_build_const_scalar(tmp_type, dst_scale);
LLVMValueRef scale = lp_build_const_vec(tmp_type, dst_scale);
for(i = 0; i < num_tmps; ++i)
tmp[i] = LLVMBuildMul(builder, tmp[i], scale, "");
}
@@ -315,7 +315,7 @@ lp_build_conv(LLVMBuilderRef builder,

/* FIXME: compensate different offsets too */
if(src_shift > dst_shift) {
LLVMValueRef shift = lp_build_int_const_scalar(tmp_type, src_shift - dst_shift);
LLVMValueRef shift = lp_build_const_int_vec(tmp_type, src_shift - dst_shift);
for(i = 0; i < num_tmps; ++i)
if(src_type.sign)
tmp[i] = LLVMBuildAShr(builder, tmp[i], shift, "");
@@ -388,7 +388,7 @@ lp_build_conv(LLVMBuilderRef builder,
}

if (src_scale != 1.0) {
LLVMValueRef scale = lp_build_const_scalar(tmp_type, 1.0/src_scale);
LLVMValueRef scale = lp_build_const_vec(tmp_type, 1.0/src_scale);
for(i = 0; i < num_tmps; ++i)
tmp[i] = LLVMBuildMul(builder, tmp[i], scale, "");
}
@@ -400,7 +400,7 @@ lp_build_conv(LLVMBuilderRef builder,

/* FIXME: compensate different offsets too */
if(src_shift < dst_shift) {
LLVMValueRef shift = lp_build_int_const_scalar(tmp_type, dst_shift - src_shift);
LLVMValueRef shift = lp_build_const_int_vec(tmp_type, dst_shift - src_shift);
for(i = 0; i < num_tmps; ++i)
tmp[i] = LLVMBuildShl(builder, tmp[i], shift, "");
}

+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_conv.h View File

@@ -37,7 +37,7 @@
#define LP_BLD_CONV_H


#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"


struct lp_type;

+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_debug.h View File

@@ -30,7 +30,7 @@
#define LP_BLD_DEBUG_H


#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"

#include "pipe/p_compiler.h"
#include "util/u_string.h"

+ 107
- 3
src/gallium/auxiliary/gallivm/lp_bld_depth.c View File

@@ -61,11 +61,104 @@
#include "util/u_format.h"

#include "lp_bld_type.h"
#include "lp_bld_arit.h"
#include "lp_bld_const.h"
#include "lp_bld_logic.h"
#include "lp_bld_flow.h"
#include "lp_bld_debug.h"
#include "lp_bld_depth.h"
#include "lp_bld_swizzle.h"



/**
* Do the stencil test comparison (compare fb Z values against ref value.
* \param stencilVals vector of stencil values from framebuffer
* \param stencilRef the stencil reference value, replicated as a vector
* \return mask of pass/fail values
*/
static LLVMValueRef
lp_build_stencil_test(struct lp_build_context *bld,
const struct pipe_stencil_state *stencil,
LLVMValueRef stencilVals,
LLVMValueRef stencilRef)
{
const unsigned stencilMax = 255; /* XXX fix */
struct lp_type type = bld->type;
LLVMValueRef res;

assert(stencil->enabled);

if (stencil->valuemask != stencilMax) {
/* compute stencilRef = stencilRef & valuemask */
LLVMValueRef valuemask = lp_build_const_int_vec(type, stencil->valuemask);
stencilRef = LLVMBuildAnd(bld->builder, stencilRef, valuemask, "");
/* compute stencilVals = stencilVals & valuemask */
stencilVals = LLVMBuildAnd(bld->builder, stencilVals, valuemask, "");
}

res = lp_build_compare(bld->builder, bld->type, stencil->func,
stencilVals, stencilRef);

return res;
}


/**
* Apply the stencil operator (add/sub/keep/etc) to the given vector
* of stencil values.
* \return new stencil values vector
*/
static LLVMValueRef
lp_build_stencil_op(struct lp_build_context *bld,
unsigned stencil_op,
LLVMValueRef stencilRef,
const struct pipe_stencil_state *stencil,
LLVMValueRef stencilVals)

{
const unsigned stencilMax = 255; /* XXX fix */
struct lp_type type = bld->type;
LLVMValueRef res;
LLVMValueRef max = lp_build_const_int_vec(type, stencilMax);

switch (stencil_op) {
case PIPE_STENCIL_OP_KEEP:
res = stencilVals;
case PIPE_STENCIL_OP_ZERO:
res = bld->zero;
case PIPE_STENCIL_OP_REPLACE:
res = lp_build_broadcast_scalar(bld, stencilRef);
case PIPE_STENCIL_OP_INCR:
res = lp_build_add(bld, stencilVals, bld->one);
res = lp_build_min(bld, res, max);
case PIPE_STENCIL_OP_DECR:
res = lp_build_sub(bld, stencilVals, bld->one);
res = lp_build_max(bld, res, bld->zero);
case PIPE_STENCIL_OP_INCR_WRAP:
res = lp_build_add(bld, stencilVals, bld->one);
res = LLVMBuildAnd(bld->builder, res, max, "");
case PIPE_STENCIL_OP_DECR_WRAP:
res = lp_build_sub(bld, stencilVals, bld->one);
res = LLVMBuildAnd(bld->builder, res, max, "");
case PIPE_STENCIL_OP_INVERT:
res = LLVMBuildNot(bld->builder, stencilVals, "");
default:
assert(0 && "bad stencil op mode");
res = NULL;
}

if (stencil->writemask != stencilMax) {
/* compute res = (res & mask) | (stencilVals & ~mask) */
LLVMValueRef mask = lp_build_const_int_vec(type, stencil->writemask);
LLVMValueRef cmask = LLVMBuildNot(bld->builder, mask, "notWritemask");
LLVMValueRef t1 = LLVMBuildAnd(bld->builder, res, mask, "t1");
LLVMValueRef t2 = LLVMBuildAnd(bld->builder, stencilVals, cmask, "t2");
res = LLVMBuildOr(bld->builder, t1, t2, "t1_or_t2");
}

return res;
}


/**
@@ -109,7 +202,14 @@ lp_depth_type(const struct util_format_description *format_desc,


/**
* Depth test.
* Generate code for performing depth and/or stencil tests.
* We operate on a vector of values (typically a 2x2 quad).
*
* \param type the data type of the fragment depth/stencil values
* \param format_desc description of the depth/stencil surface
* \param mask the alive/dead pixel mask for the quad
* \param src the incoming depth/stencil values (a 2x2 quad)
* \param dst_ptr the outgoing/updated depth/stencil values
*/
void
lp_build_depth_test(LLVMBuilderRef builder,
@@ -126,6 +226,9 @@ lp_build_depth_test(LLVMBuilderRef builder,
LLVMValueRef z_bitmask = NULL;
LLVMValueRef test;

(void) lp_build_stencil_test;
(void) lp_build_stencil_op;

if(!state->enabled)
return;

@@ -185,11 +288,11 @@ lp_build_depth_test(LLVMBuilderRef builder,
if(padding_left || padding_right) {
const unsigned long long mask_left = ((unsigned long long)1 << (format_desc->block.bits - padding_left)) - 1;
const unsigned long long mask_right = ((unsigned long long)1 << (padding_right)) - 1;
z_bitmask = lp_build_int_const_scalar(type, mask_left ^ mask_right);
z_bitmask = lp_build_const_int_vec(type, mask_left ^ mask_right);
}

if(padding_left)
src = LLVMBuildLShr(builder, src, lp_build_int_const_scalar(type, padding_left), "");
src = LLVMBuildLShr(builder, src, lp_build_const_int_vec(type, padding_left), "");
if(padding_right)
src = LLVMBuildAnd(builder, src, z_bitmask, "");
if(padding_left || padding_right)
@@ -198,6 +301,7 @@ lp_build_depth_test(LLVMBuilderRef builder,

lp_build_name(dst, "zsbuf.z");

/* compare src Z to dst Z, returning 'pass' mask */
test = lp_build_cmp(&bld, state->func, src, dst);
lp_build_mask_update(mask, test);


+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_depth.h View File

@@ -36,7 +36,7 @@
#define LP_BLD_DEPTH_H


#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"

struct pipe_depth_state;

+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_flow.h View File

@@ -35,7 +35,7 @@
#define LP_BLD_FLOW_H


#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"


struct lp_type;

+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_format.h View File

@@ -34,7 +34,7 @@
* Pixel format helpers.
*/

#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"

#include "pipe/p_format.h"


+ 2
- 2
src/gallium/auxiliary/gallivm/lp_bld_format_soa.c View File

@@ -114,10 +114,10 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
case UTIL_FORMAT_TYPE_UNSIGNED:
if(type.floating) {
if(start)
input = LLVMBuildLShr(builder, input, lp_build_int_const_scalar(type, start), "");
input = LLVMBuildLShr(builder, input, lp_build_const_int_vec(type, start), "");
if(stop < format_desc->block.bits) {
unsigned mask = ((unsigned long long)1 << width) - 1;
input = LLVMBuildAnd(builder, input, lp_build_int_const_scalar(type, mask), "");
input = LLVMBuildAnd(builder, input, lp_build_const_int_vec(type, mask), "");
}

if(format_desc->channel[chan].normalized)

+ 3
- 3
src/gallium/auxiliary/gallivm/lp_bld_interp.c View File

@@ -289,17 +289,17 @@ pos_update(struct lp_build_interp_soa_context *bld, int quad_index)
/* top-right or bottom-right quad in block */
/* build x += xstep */
x = lp_build_add(&bld->base, x,
lp_build_const_scalar(bld->base.type, xstep));
lp_build_const_vec(bld->base.type, xstep));
}

if (quad_index == 2) {
/* bottom-left quad in block */
/* build y += ystep */
y = lp_build_add(&bld->base, y,
lp_build_const_scalar(bld->base.type, ystep));
lp_build_const_vec(bld->base.type, ystep));
/* build x -= xstep */
x = lp_build_sub(&bld->base, x,
lp_build_const_scalar(bld->base.type, xstep));
lp_build_const_vec(bld->base.type, xstep));
}

lp_build_name(x, "pos.x");

+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_interp.h View File

@@ -41,7 +41,7 @@
#define LP_BLD_INTERP_H


#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"

#include "tgsi/tgsi_exec.h"


+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_intr.h View File

@@ -37,7 +37,7 @@
#define LP_BLD_INTR_H


#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"


/**

+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_logic.c View File

@@ -193,7 +193,7 @@ lp_build_compare(LLVMBuilderRef builder,
if(table[func].gt &&
((type.width == 8 && type.sign) ||
(type.width != 8 && !type.sign))) {
LLVMValueRef msb = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1));
LLVMValueRef msb = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1));
a = LLVMBuildXor(builder, a, msb, "");
b = LLVMBuildXor(builder, b, msb, "");
}

+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_logic.h View File

@@ -37,7 +37,7 @@
#define LP_BLD_LOGIC_H


#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"

#include "pipe/p_defines.h" /* For PIPE_FUNC_xxx */


+ 2
- 2
src/gallium/auxiliary/gallivm/lp_bld_pack.c View File

@@ -164,7 +164,7 @@ lp_build_unpack2(LLVMBuilderRef builder,

if(dst_type.sign && src_type.sign) {
/* Replicate the sign bit in the most significant bits */
msb = LLVMBuildAShr(builder, src, lp_build_int_const_scalar(src_type, src_type.width - 1), "");
msb = LLVMBuildAShr(builder, src, lp_build_const_int_vec(src_type, src_type.width - 1), "");
}
else
/* Most significant bits always zero */
@@ -361,7 +361,7 @@ lp_build_packs2(LLVMBuilderRef builder,
if(clamp) {
struct lp_build_context bld;
unsigned dst_bits = dst_type.sign ? dst_type.width - 1 : dst_type.width;
LLVMValueRef dst_max = lp_build_int_const_scalar(src_type, ((unsigned long long)1 << dst_bits) - 1);
LLVMValueRef dst_max = lp_build_const_int_vec(src_type, ((unsigned long long)1 << dst_bits) - 1);
lp_build_context_init(&bld, builder, src_type);
lo = lp_build_min(&bld, lo, dst_max);
hi = lp_build_min(&bld, hi, dst_max);

+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_pack.h View File

@@ -37,7 +37,7 @@
#define LP_BLD_PACK_H


#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"


struct lp_type;

+ 3
- 3
src/gallium/auxiliary/gallivm/lp_bld_sample.c View File

@@ -173,7 +173,7 @@ lp_build_sample_offset(struct lp_build_context *bld,
LLVMValueRef x_stride;
LLVMValueRef offset;

x_stride = lp_build_const_scalar(bld->type, format_desc->block.bits/8);
x_stride = lp_build_const_vec(bld->type, format_desc->block.bits/8);

if(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
LLVMValueRef x_lo, x_hi;
@@ -195,9 +195,9 @@ lp_build_sample_offset(struct lp_build_context *bld,
y_hi = LLVMBuildLShr(bld->builder, y, bld->one, "");

x_stride_lo = x_stride;
y_stride_lo = lp_build_const_scalar(bld->type, 2*format_desc->block.bits/8);
y_stride_lo = lp_build_const_vec(bld->type, 2*format_desc->block.bits/8);

x_stride_hi = lp_build_const_scalar(bld->type, 4*format_desc->block.bits/8);
x_stride_hi = lp_build_const_vec(bld->type, 4*format_desc->block.bits/8);
y_stride_hi = LLVMBuildShl(bld->builder, y_stride, bld->one, "");

x_offset_lo = lp_build_mul(bld, x_lo, x_stride_lo);

+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_sample.h View File

@@ -36,7 +36,7 @@
#define LP_BLD_SAMPLE_H


#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"

struct pipe_resource;
struct pipe_sampler_state;

+ 252
- 149
src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c View File

@@ -292,7 +292,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
int chan;
for (chan = 0; chan < 4; chan++) {
LLVMValueRef border_chan =
lp_build_const_scalar(bld->texel_type,
lp_build_const_vec(bld->texel_type,
bld->static_state->border_color[chan]);
texel[chan] = lp_build_select(&bld->texel_bld, use_border,
border_chan, texel[chan]);
@@ -457,8 +457,8 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
struct lp_build_context *coord_bld = &bld->coord_bld;
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
struct lp_build_context *uint_coord_bld = &bld->uint_coord_bld;
LLVMValueRef two = lp_build_const_scalar(coord_bld->type, 2.0);
LLVMValueRef half = lp_build_const_scalar(coord_bld->type, 0.5);
LLVMValueRef two = lp_build_const_vec(coord_bld->type, 2.0);
LLVMValueRef half = lp_build_const_vec(coord_bld->type, 0.5);
LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length);
LLVMValueRef length_minus_one = lp_build_sub(uint_coord_bld, length, uint_coord_bld->one);
LLVMValueRef length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one);
@@ -512,7 +512,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
else {
LLVMValueRef min, max;
/* clamp to [0.5, length - 0.5] */
min = lp_build_const_scalar(coord_bld->type, 0.5F);
min = lp_build_const_vec(coord_bld->type, 0.5F);
max = lp_build_sub(coord_bld, length_f, min);
coord = lp_build_clamp(coord_bld, coord, min, max);
}
@@ -533,7 +533,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
if (bld->static_state->normalized_coords) {
/* min = -1.0 / (2 * length) = -0.5 / length */
min = lp_build_mul(coord_bld,
lp_build_const_scalar(coord_bld->type, -0.5F),
lp_build_const_vec(coord_bld->type, -0.5F),
lp_build_rcp(coord_bld, length_f));
/* max = 1.0 - min */
max = lp_build_sub(coord_bld, coord_bld->one, min);
@@ -545,7 +545,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
}
else {
/* clamp to [-0.5, length + 0.5] */
min = lp_build_const_scalar(coord_bld->type, -0.5F);
min = lp_build_const_vec(coord_bld->type, -0.5F);
max = lp_build_sub(coord_bld, length_f, min);
coord = lp_build_clamp(coord_bld, coord, min, max);
coord = lp_build_sub(coord_bld, coord, half);
@@ -620,7 +620,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
LLVMValueRef min, max;
/* min = -1.0 / (2 * length) = -0.5 / length */
min = lp_build_mul(coord_bld,
lp_build_const_scalar(coord_bld->type, -0.5F),
lp_build_const_vec(coord_bld->type, -0.5F),
lp_build_rcp(coord_bld, length_f));
/* max = 1.0 - min */
max = lp_build_sub(coord_bld, coord_bld->one, min);
@@ -665,7 +665,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
struct lp_build_context *coord_bld = &bld->coord_bld;
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
struct lp_build_context *uint_coord_bld = &bld->uint_coord_bld;
LLVMValueRef two = lp_build_const_scalar(coord_bld->type, 2.0);
LLVMValueRef two = lp_build_const_vec(coord_bld->type, 2.0);
LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length);
LLVMValueRef length_minus_one = lp_build_sub(uint_coord_bld, length, uint_coord_bld->one);
LLVMValueRef length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one);
@@ -708,7 +708,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
}
else {
/* clamp to [0.5, length - 0.5] */
min = lp_build_const_scalar(coord_bld->type, 0.5F);
min = lp_build_const_vec(coord_bld->type, 0.5F);
max = lp_build_sub(coord_bld, length_f, min);
}
/* coord = clamp(coord, min, max) */
@@ -724,7 +724,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
if (bld->static_state->normalized_coords) {
/* min = -1.0 / (2 * length) = -0.5 / length */
min = lp_build_mul(coord_bld,
lp_build_const_scalar(coord_bld->type, -0.5F),
lp_build_const_vec(coord_bld->type, -0.5F),
lp_build_rcp(coord_bld, length_f));
/* max = length - min */
max = lp_build_sub(coord_bld, length_f, min);
@@ -733,7 +733,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
}
else {
/* clamp to [-0.5, length + 0.5] */
min = lp_build_const_scalar(coord_bld->type, -0.5F);
min = lp_build_const_vec(coord_bld->type, -0.5F);
max = lp_build_sub(coord_bld, length_f, min);
}
/* coord = clamp(coord, min, max) */
@@ -843,87 +843,98 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
LLVMValueRef depth)

{
const int dims = texture_dims(bld->static_state->target);
struct lp_build_context *float_bld = &bld->float_bld;
LLVMValueRef lod_bias = LLVMConstReal(LLVMFloatType(), bld->static_state->lod_bias);
LLVMValueRef min_lod = LLVMConstReal(LLVMFloatType(), bld->static_state->min_lod);
LLVMValueRef max_lod = LLVMConstReal(LLVMFloatType(), bld->static_state->max_lod);

LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
LLVMValueRef index1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
LLVMValueRef index2 = LLVMConstInt(LLVMInt32Type(), 2, 0);

LLVMValueRef s0, s1, s2;
LLVMValueRef t0, t1, t2;
LLVMValueRef r0, r1, r2;
LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy;
LLVMValueRef rho, lod;

/*
* dsdx = abs(s[1] - s[0]);
* dsdy = abs(s[2] - s[0]);
* dtdx = abs(t[1] - t[0]);
* dtdy = abs(t[2] - t[0]);
* drdx = abs(r[1] - r[0]);
* drdy = abs(r[2] - r[0]);
* XXX we're assuming a four-element quad in 2x2 layout here.
*/
s0 = LLVMBuildExtractElement(bld->builder, s, index0, "s0");
s1 = LLVMBuildExtractElement(bld->builder, s, index1, "s1");
s2 = LLVMBuildExtractElement(bld->builder, s, index2, "s2");
dsdx = LLVMBuildSub(bld->builder, s1, s0, "");
dsdx = lp_build_abs(float_bld, dsdx);
dsdy = LLVMBuildSub(bld->builder, s2, s0, "");
dsdy = lp_build_abs(float_bld, dsdy);
if (dims > 1) {
t0 = LLVMBuildExtractElement(bld->builder, t, index0, "t0");
t1 = LLVMBuildExtractElement(bld->builder, t, index1, "t1");
t2 = LLVMBuildExtractElement(bld->builder, t, index2, "t2");
dtdx = LLVMBuildSub(bld->builder, t1, t0, "");
dtdx = lp_build_abs(float_bld, dtdx);
dtdy = LLVMBuildSub(bld->builder, t2, t0, "");
dtdy = lp_build_abs(float_bld, dtdy);
if (dims > 2) {
r0 = LLVMBuildExtractElement(bld->builder, r, index0, "r0");
r1 = LLVMBuildExtractElement(bld->builder, r, index1, "r1");
r2 = LLVMBuildExtractElement(bld->builder, r, index2, "r2");
drdx = LLVMBuildSub(bld->builder, r1, r0, "");
drdx = lp_build_abs(float_bld, drdx);
drdy = LLVMBuildSub(bld->builder, r2, r0, "");
drdy = lp_build_abs(float_bld, drdy);
}
if (bld->static_state->min_lod == bld->static_state->max_lod) {
/* User is forcing sampling from a particular mipmap level.
* This is hit during mipmap generation.
*/
return LLVMConstReal(LLVMFloatType(), bld->static_state->min_lod);
}
else {
const int dims = texture_dims(bld->static_state->target);
struct lp_build_context *float_bld = &bld->float_bld;
LLVMValueRef lod_bias = LLVMConstReal(LLVMFloatType(),
bld->static_state->lod_bias);
LLVMValueRef min_lod = LLVMConstReal(LLVMFloatType(),
bld->static_state->min_lod);
LLVMValueRef max_lod = LLVMConstReal(LLVMFloatType(),
bld->static_state->max_lod);

LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
LLVMValueRef index1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
LLVMValueRef index2 = LLVMConstInt(LLVMInt32Type(), 2, 0);

LLVMValueRef s0, s1, s2;
LLVMValueRef t0, t1, t2;
LLVMValueRef r0, r1, r2;
LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy;
LLVMValueRef rho, lod;

/*
* dsdx = abs(s[1] - s[0]);
* dsdy = abs(s[2] - s[0]);
* dtdx = abs(t[1] - t[0]);
* dtdy = abs(t[2] - t[0]);
* drdx = abs(r[1] - r[0]);
* drdy = abs(r[2] - r[0]);
* XXX we're assuming a four-element quad in 2x2 layout here.
*/
s0 = LLVMBuildExtractElement(bld->builder, s, index0, "s0");
s1 = LLVMBuildExtractElement(bld->builder, s, index1, "s1");
s2 = LLVMBuildExtractElement(bld->builder, s, index2, "s2");
dsdx = LLVMBuildSub(bld->builder, s1, s0, "");
dsdx = lp_build_abs(float_bld, dsdx);
dsdy = LLVMBuildSub(bld->builder, s2, s0, "");
dsdy = lp_build_abs(float_bld, dsdy);
if (dims > 1) {
t0 = LLVMBuildExtractElement(bld->builder, t, index0, "t0");
t1 = LLVMBuildExtractElement(bld->builder, t, index1, "t1");
t2 = LLVMBuildExtractElement(bld->builder, t, index2, "t2");
dtdx = LLVMBuildSub(bld->builder, t1, t0, "");
dtdx = lp_build_abs(float_bld, dtdx);
dtdy = LLVMBuildSub(bld->builder, t2, t0, "");
dtdy = lp_build_abs(float_bld, dtdy);
if (dims > 2) {
r0 = LLVMBuildExtractElement(bld->builder, r, index0, "r0");
r1 = LLVMBuildExtractElement(bld->builder, r, index1, "r1");
r2 = LLVMBuildExtractElement(bld->builder, r, index2, "r2");
drdx = LLVMBuildSub(bld->builder, r1, r0, "");
drdx = lp_build_abs(float_bld, drdx);
drdy = LLVMBuildSub(bld->builder, r2, r0, "");
drdy = lp_build_abs(float_bld, drdy);
}
}

/* Compute rho = max of all partial derivatives scaled by texture size.
* XXX this could be vectorized somewhat
*/
rho = LLVMBuildMul(bld->builder,
lp_build_max(float_bld, dsdx, dsdy),
lp_build_int_to_float(float_bld, width), "");
if (dims > 1) {
LLVMValueRef max;
max = LLVMBuildMul(bld->builder,
lp_build_max(float_bld, dtdx, dtdy),
lp_build_int_to_float(float_bld, height), "");
rho = lp_build_max(float_bld, rho, max);
if (dims > 2) {
/* Compute rho = max of all partial derivatives scaled by texture size.
* XXX this could be vectorized somewhat
*/
rho = LLVMBuildMul(bld->builder,
lp_build_max(float_bld, dsdx, dsdy),
lp_build_int_to_float(float_bld, width), "");
if (dims > 1) {
LLVMValueRef max;
max = LLVMBuildMul(bld->builder,
lp_build_max(float_bld, drdx, drdy),
lp_build_int_to_float(float_bld, depth), "");
lp_build_max(float_bld, dtdx, dtdy),
lp_build_int_to_float(float_bld, height), "");
rho = lp_build_max(float_bld, rho, max);
if (dims > 2) {
max = LLVMBuildMul(bld->builder,
lp_build_max(float_bld, drdx, drdy),
lp_build_int_to_float(float_bld, depth), "");
rho = lp_build_max(float_bld, rho, max);
}
}
}

/* compute lod = log2(rho) */
lod = lp_build_log2(float_bld, rho);
/* compute lod = log2(rho) */
lod = lp_build_log2(float_bld, rho);

/* add lod bias */
lod = LLVMBuildAdd(bld->builder, lod, lod_bias, "LOD bias");
/* add lod bias */
lod = LLVMBuildAdd(bld->builder, lod, lod_bias, "LOD bias");

/* clamp lod */
lod = lp_build_clamp(float_bld, lod, min_lod, max_lod);
/* clamp lod */
lod = lp_build_clamp(float_bld, lod, min_lod, max_lod);

return lod;
return lod;
}
}


@@ -986,7 +997,7 @@ lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
last_level);
/* compute level 1 and clamp to legal range of levels */
*level1_out = lp_build_add(int_bld, *level0_out, int_bld->one);
*level1_out = lp_build_min(int_bld, *level1_out, int_bld->zero);
*level1_out = lp_build_min(int_bld, *level1_out, last_level);

*weight_out = lp_build_fract(float_bld, lod);
}
@@ -1215,7 +1226,7 @@ static LLVMValueRef
lp_build_cube_ima(struct lp_build_context *coord_bld, LLVMValueRef coord)
{
/* ima = -0.5 / abs(coord); */
LLVMValueRef negHalf = lp_build_const_scalar(coord_bld->type, -0.5);
LLVMValueRef negHalf = lp_build_const_vec(coord_bld->type, -0.5);
LLVMValueRef absCoord = lp_build_abs(coord_bld, coord);
LLVMValueRef ima = lp_build_mul(coord_bld, negHalf,
lp_build_rcp(coord_bld, absCoord));
@@ -1235,7 +1246,7 @@ lp_build_cube_coord(struct lp_build_context *coord_bld,
LLVMValueRef coord, LLVMValueRef ima)
{
/* return negate(coord) * ima * sign + 0.5; */
LLVMValueRef half = lp_build_const_scalar(coord_bld->type, 0.5);
LLVMValueRef half = lp_build_const_vec(coord_bld->type, 0.5);
LLVMValueRef res;

assert(negate_coord == +1 || negate_coord == -1);
@@ -1413,6 +1424,85 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,



/**
* Sample the texture/mipmap using given image filter and mip filter.
* data0_ptr and data1_ptr point to the two mipmap levels to sample
* from. width0/1_vec, height0/1_vec, depth0/1_vec indicate their sizes.
* If we're using nearest miplevel sampling the '1' values will be null/unused.
*/
static void
lp_build_sample_mipmap(struct lp_build_sample_context *bld,
unsigned img_filter,
unsigned mip_filter,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
LLVMValueRef lod_fpart,
LLVMValueRef width0_vec,
LLVMValueRef width1_vec,
LLVMValueRef height0_vec,
LLVMValueRef height1_vec,
LLVMValueRef depth0_vec,
LLVMValueRef depth1_vec,
LLVMValueRef row_stride0_vec,
LLVMValueRef row_stride1_vec,
LLVMValueRef img_stride0_vec,
LLVMValueRef img_stride1_vec,
LLVMValueRef data_ptr0,
LLVMValueRef data_ptr1,
LLVMValueRef *colors_out)
{
LLVMValueRef colors0[4], colors1[4];
int chan;

if (img_filter == PIPE_TEX_FILTER_NEAREST) {
lp_build_sample_image_nearest(bld,
width0_vec, height0_vec, depth0_vec,
row_stride0_vec, img_stride0_vec,
data_ptr0, s, t, r, colors0);

if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
/* sample the second mipmap level, and interp */
lp_build_sample_image_nearest(bld,
width1_vec, height1_vec, depth1_vec,
row_stride1_vec, img_stride1_vec,
data_ptr1, s, t, r, colors1);
}
}
else {
assert(img_filter == PIPE_TEX_FILTER_LINEAR);

lp_build_sample_image_linear(bld,
width0_vec, height0_vec, depth0_vec,
row_stride0_vec, img_stride0_vec,
data_ptr0, s, t, r, colors0);

if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
/* sample the second mipmap level, and interp */
lp_build_sample_image_linear(bld,
width1_vec, height1_vec, depth1_vec,
row_stride1_vec, img_stride1_vec,
data_ptr1, s, t, r, colors1);
}
}

if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
/* interpolate samples from the two mipmap levels */
for (chan = 0; chan < 4; chan++) {
colors_out[chan] = lp_build_lerp(&bld->texel_bld, lod_fpart,
colors0[chan], colors1[chan]);
}
}
else {
/* use first/only level's colors */
for (chan = 0; chan < 4; chan++) {
colors_out[chan] = colors0[chan];
}
}
}



/**
* General texture sampling codegen.
* This function handles texture sampling for all texture targets (1D,
@@ -1435,6 +1525,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
LLVMValueRef data_array,
LLVMValueRef *colors_out)
{
struct lp_build_context *float_bld = &bld->float_bld;
const unsigned mip_filter = bld->static_state->min_mip_filter;
const unsigned min_filter = bld->static_state->min_img_filter;
const unsigned mag_filter = bld->static_state->mag_img_filter;
@@ -1446,7 +1537,6 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
LLVMValueRef row_stride0_vec = NULL, row_stride1_vec = NULL;
LLVMValueRef img_stride0_vec = NULL, img_stride1_vec = NULL;
LLVMValueRef data_ptr0, data_ptr1;
int chan;

/*
printf("%s mip %d min %d mag %d\n", __FUNCTION__,
@@ -1454,16 +1544,24 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
*/

/*
* Compute the level of detail (mipmap level index(es)).
* Compute the level of detail (float).
*/
if (min_filter != mag_filter ||
mip_filter != PIPE_TEX_MIPFILTER_NONE) {
/* Need to compute lod either to choose mipmap levels or to
* distinguish between minification/magnification with one mipmap level.
*/
lod = lp_build_lod_selector(bld, s, t, r, width, height, depth);
}

/*
* Compute integer mipmap level(s) to fetch texels from.
*/
if (mip_filter == PIPE_TEX_MIPFILTER_NONE) {
/* always use mip level 0 */
ilevel0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
}
else {
/* compute float LOD */
lod = lp_build_lod_selector(bld, s, t, r, width, height, depth);

if (mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
lp_build_nearest_mip_level(bld, unit, lod, &ilevel0);
}
@@ -1499,7 +1597,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
}
}
if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
/* compute width, height, depth for second mipmap level at ilevel1 */
/* compute width, height, depth for second mipmap level at 'ilevel1' */
width1_vec = lp_build_minify(bld, width_vec, ilevel1_vec);
if (dims >= 2) {
height1_vec = lp_build_minify(bld, height_vec, ilevel1_vec);
@@ -1516,7 +1614,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
}

/*
* Choose cube face, recompute texcoords.
* Choose cube face, recompute per-face texcoords.
*/
if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
LLVMValueRef face, face_s, face_t;
@@ -1538,62 +1636,67 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
/*
* Get/interpolate texture colors.
*/
/* XXX temporarily force this path: */
if (1 /*min_filter == mag_filter*/) {
/* same filter for minification or magnification */
LLVMValueRef colors0[4], colors1[4];

if (min_filter == PIPE_TEX_FILTER_NEAREST) {
lp_build_sample_image_nearest(bld,
width0_vec, height0_vec, depth0_vec,
row_stride0_vec, img_stride0_vec,
data_ptr0, s, t, r, colors0);

if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
/* sample the second mipmap level, and interp */
lp_build_sample_image_nearest(bld,
width1_vec, height1_vec, depth1_vec,
row_stride1_vec, img_stride1_vec,
data_ptr1, s, t, r, colors1);
}
}
else {
assert(min_filter == PIPE_TEX_FILTER_LINEAR);
if (min_filter == mag_filter) {
/* no need to distinquish between minification and magnification */
lp_build_sample_mipmap(bld, min_filter, mip_filter, s, t, r, lod_fpart,
width0_vec, width1_vec,
height0_vec, height1_vec,
depth0_vec, depth1_vec,
row_stride0_vec, row_stride1_vec,
img_stride0_vec, img_stride1_vec,
data_ptr0, data_ptr1,
colors_out);
}
else {
/* Emit conditional to choose min image filter or mag image filter
* depending on the lod being >0 or <= 0, respectively.
*/
struct lp_build_flow_context *flow_ctx;
struct lp_build_if_state if_ctx;
LLVMValueRef minify;

lp_build_sample_image_linear(bld,
width0_vec, height0_vec, depth0_vec,
row_stride0_vec, img_stride0_vec,
data_ptr0, s, t, r, colors0);
flow_ctx = lp_build_flow_create(bld->builder);
lp_build_flow_scope_begin(flow_ctx);

lp_build_flow_scope_declare(flow_ctx, &colors_out[0]);
lp_build_flow_scope_declare(flow_ctx, &colors_out[1]);
lp_build_flow_scope_declare(flow_ctx, &colors_out[2]);
lp_build_flow_scope_declare(flow_ctx, &colors_out[3]);

if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
/* sample the second mipmap level, and interp */
lp_build_sample_image_linear(bld,
width1_vec, height1_vec, depth1_vec,
row_stride1_vec, img_stride1_vec,
data_ptr1, s, t, r, colors1);
}
}
/* minify = lod > 0.0 */
minify = LLVMBuildFCmp(bld->builder, LLVMRealUGE,
lod, float_bld->zero, "");

if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
/* interpolate samples from the two mipmap levels */
for (chan = 0; chan < 4; chan++) {
colors_out[chan] = lp_build_lerp(&bld->texel_bld, lod_fpart,
colors0[chan], colors1[chan]);
}
lp_build_if(&if_ctx, flow_ctx, bld->builder, minify);
{
/* Use the minification filter */
lp_build_sample_mipmap(bld, min_filter, mip_filter,
s, t, r, lod_fpart,
width0_vec, width1_vec,
height0_vec, height1_vec,
depth0_vec, depth1_vec,
row_stride0_vec, row_stride1_vec,
img_stride0_vec, img_stride1_vec,
data_ptr0, data_ptr1,
colors_out);
}
else {
/* use first/only level's colors */
for (chan = 0; chan < 4; chan++) {
colors_out[chan] = colors0[chan];
}
lp_build_else(&if_ctx);
{
/* Use the magnification filter */
lp_build_sample_mipmap(bld, mag_filter, mip_filter,
s, t, r, lod_fpart,
width0_vec, width1_vec,
height0_vec, height1_vec,
depth0_vec, depth1_vec,
row_stride0_vec, row_stride1_vec,
img_stride0_vec, img_stride1_vec,
data_ptr0, data_ptr1,
colors_out);
}
}
else {
/* emit conditional to choose min image filter or mag image filter
* depending on the lod being >0 or <= 0, respectively.
*/
abort();
lp_build_endif(&if_ctx);

lp_build_flow_scope_end(flow_ctx);
lp_build_flow_destroy(flow_ctx);
}
}

@@ -1605,7 +1708,7 @@ lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder,
LLVMValueRef packed,
LLVMValueRef *rgba)
{
LLVMValueRef mask = lp_build_int_const_scalar(dst_type, 0xff);
LLVMValueRef mask = lp_build_const_int_vec(dst_type, 0xff);
unsigned chan;

/* Decode the input vector components */
@@ -1617,7 +1720,7 @@ lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder,
input = packed;

if(start)
input = LLVMBuildLShr(builder, input, lp_build_int_const_scalar(dst_type, start), "");
input = LLVMBuildLShr(builder, input, lp_build_const_int_vec(dst_type, start), "");

if(stop < 32)
input = LLVMBuildAnd(builder, input, mask, "");
@@ -1679,17 +1782,17 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
t = LLVMBuildFPToSI(builder, t, i32_vec_type, "");

/* subtract 0.5 (add -128) */
i32_c128 = lp_build_int_const_scalar(i32.type, -128);
i32_c128 = lp_build_const_int_vec(i32.type, -128);
s = LLVMBuildAdd(builder, s, i32_c128, "");
t = LLVMBuildAdd(builder, t, i32_c128, "");

/* compute floor (shift right 8) */
i32_c8 = lp_build_int_const_scalar(i32.type, 8);
i32_c8 = lp_build_const_int_vec(i32.type, 8);
s_ipart = LLVMBuildAShr(builder, s, i32_c8, "");
t_ipart = LLVMBuildAShr(builder, t, i32_c8, "");

/* compute fractional part (AND with 0xff) */
i32_c255 = lp_build_int_const_scalar(i32.type, 255);
i32_c255 = lp_build_const_int_vec(i32.type, 255);
s_fpart = LLVMBuildAnd(builder, s, i32_c255, "");
t_fpart = LLVMBuildAnd(builder, t, i32_c255, "");

@@ -1856,7 +1959,7 @@ lp_build_sample_compare(struct lp_build_sample_context *bld,
}

assert(res);
res = lp_build_mul(texel_bld, res, lp_build_const_scalar(texel_bld->type, 0.25));
res = lp_build_mul(texel_bld, res, lp_build_const_vec(texel_bld->type, 0.25));

/* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
for(chan = 0; chan < 3; ++chan)

+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_struct.h View File

@@ -37,7 +37,7 @@
#define LP_BLD_STRUCT_H


#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"
#include <llvm-c/Target.h>

#include "util/u_debug.h"

+ 2
- 2
src/gallium/auxiliary/gallivm/lp_bld_swizzle.c View File

@@ -144,9 +144,9 @@ lp_build_broadcast_aos(struct lp_build_context *bld,
#endif

if(shift > 0)
tmp = LLVMBuildLShr(bld->builder, a, lp_build_int_const_scalar(type4, shift*type.width), "");
tmp = LLVMBuildLShr(bld->builder, a, lp_build_const_int_vec(type4, shift*type.width), "");
if(shift < 0)
tmp = LLVMBuildShl(bld->builder, a, lp_build_int_const_scalar(type4, -shift*type.width), "");
tmp = LLVMBuildShl(bld->builder, a, lp_build_const_int_vec(type4, -shift*type.width), "");

assert(tmp);
if(tmp)

+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_swizzle.h View File

@@ -37,7 +37,7 @@
#define LP_BLD_SWIZZLE_H


#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"


struct lp_type;

+ 1
- 1
src/gallium/auxiliary/gallivm/lp_bld_tgsi.h View File

@@ -35,7 +35,7 @@
#ifndef LP_BLD_TGSI_H
#define LP_BLD_TGSI_H

#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"


struct tgsi_token;

+ 3
- 3
src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c View File

@@ -475,7 +475,7 @@ emit_store(
break;

case TGSI_SAT_MINUS_PLUS_ONE:
value = lp_build_max(&bld->base, value, lp_build_const_scalar(bld->base.type, -1.0));
value = lp_build_max(&bld->base, value, lp_build_const_vec(bld->base.type, -1.0));
value = lp_build_min(&bld->base, value, bld->base.one);
break;

@@ -996,7 +996,7 @@ emit_instruction(
src0 = emit_fetch( bld, inst, 0, chan_index );
src1 = emit_fetch( bld, inst, 1, chan_index );
src2 = emit_fetch( bld, inst, 2, chan_index );
tmp1 = lp_build_const_scalar(bld->base.type, 0.5);
tmp1 = lp_build_const_vec(bld->base.type, 0.5);
tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src2, tmp1);
dst0[chan_index] = lp_build_select( &bld->base, tmp0, src0, src1 );
}
@@ -1713,7 +1713,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
assert(num_immediates < LP_MAX_IMMEDIATES);
for( i = 0; i < size; ++i )
bld.immediates[num_immediates][i] =
lp_build_const_scalar(type, parse.FullToken.FullImmediate.u[i].Float);
lp_build_const_vec(type, parse.FullToken.FullImmediate.u[i].Float);
for( i = size; i < 4; ++i )
bld.immediates[num_immediates][i] = bld.base.undef;
num_immediates++;

+ 2
- 2
src/gallium/auxiliary/gallivm/lp_bld_type.h View File

@@ -37,9 +37,9 @@
#define LP_BLD_TYPE_H


#include "os/os_llvm.h"
#include "pipe/p_compiler.h"
#include "gallivm/lp_bld.h"

#include <pipe/p_compiler.h>


/**

+ 27
- 11
src/gallium/auxiliary/util/u_blit.c View File

@@ -45,6 +45,7 @@
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_sampler.h"
#include "util/u_simple_shaders.h"
#include "util/u_surface.h"
#include "util/u_rect.h"
@@ -280,6 +281,7 @@ regions_overlap(int srcX0, int srcY0,
void
util_blit_pixels_writemask(struct blit_state *ctx,
struct pipe_surface *src,
struct pipe_sampler_view *src_sampler_view,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
@@ -290,7 +292,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_resource *tex = NULL;
struct pipe_sampler_view *sampler_view = NULL;
struct pipe_framebuffer_state fb;
const int srcW = abs(srcX1 - srcX0);
const int srcH = abs(srcY1 - srcY0);
@@ -345,6 +347,8 @@ util_blit_pixels_writemask(struct blit_state *ctx,
src->texture->last_level != 0)
{
struct pipe_resource texTemp;
struct pipe_resource *tex;
struct pipe_sampler_view sv_templ;
struct pipe_surface *texSurf;
const int srcLeft = MIN2(srcX0, srcX1);
const int srcTop = MIN2(srcY0, srcY1);
@@ -376,6 +380,14 @@ util_blit_pixels_writemask(struct blit_state *ctx,
if (!tex)
return;

u_sampler_view_default_template(&sv_templ, tex, tex->format);

sampler_view = ctx->pipe->create_sampler_view(ctx->pipe, tex, &sv_templ);
if (!sampler_view) {
pipe_texture_reference(&tex, NULL);
return;
}

texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);

@@ -399,22 +411,25 @@ util_blit_pixels_writemask(struct blit_state *ctx,
s1 = 1.0f;
t0 = 0.0f;
t1 = 1.0f;

pipe_texture_reference(&tex, NULL);
}
else {
pipe_resource_reference(&tex, src->texture);
s0 = srcX0 / (float)tex->width0;
s1 = srcX1 / (float)tex->width0;
t0 = srcY0 / (float)tex->height0;
t1 = srcY1 / (float)tex->height0;
pipe_sampler_view_reference(&sampler_view, src_sampler_view);
s0 = srcX0 / (float)src->texture->width0;
s1 = srcX1 / (float)src->texture->width0;
t0 = srcY0 / (float)src->texture->height0;
t1 = srcY1 / (float)src->texture->height0;
}


/* save state (restored below) */
cso_save_blend(ctx->cso);
cso_save_depth_stencil_alpha(ctx->cso);
cso_save_rasterizer(ctx->cso);
cso_save_samplers(ctx->cso);
cso_save_sampler_textures(ctx->cso);
cso_save_fragment_sampler_views(ctx->cso);
cso_save_viewport(ctx->cso);
cso_save_framebuffer(ctx->cso);
cso_save_fragment_shader(ctx->cso);
@@ -447,7 +462,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_set_viewport(ctx->cso, &ctx->viewport);

/* texture */
cso_set_sampler_textures(ctx->cso, 1, &tex);
cso_set_fragment_sampler_views(ctx->cso, 1, &sampler_view);

if (ctx->fs[writemask] == NULL)
ctx->fs[writemask] =
@@ -486,7 +501,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_restore_depth_stencil_alpha(ctx->cso);
cso_restore_rasterizer(ctx->cso);
cso_restore_samplers(ctx->cso);
cso_restore_sampler_textures(ctx->cso);
cso_restore_fragment_sampler_views(ctx->cso);
cso_restore_viewport(ctx->cso);
cso_restore_framebuffer(ctx->cso);
cso_restore_fragment_shader(ctx->cso);
@@ -494,13 +509,14 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_restore_clip(ctx->cso);
cso_restore_vertex_elements(ctx->cso);

pipe_resource_reference(&tex, NULL);
pipe_sampler_view_reference(&sampler_view, NULL);
}


void
util_blit_pixels(struct blit_state *ctx,
struct pipe_surface *src,
struct pipe_sampler_view *src_sampler_view,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
@@ -508,7 +524,7 @@ util_blit_pixels(struct blit_state *ctx,
int dstX1, int dstY1,
float z, uint filter )
{
util_blit_pixels_writemask( ctx, src,
util_blit_pixels_writemask( ctx, src, src_sampler_view,
srcX0, srcY0,
srcX1, srcY1,
dst,

+ 2
- 0
src/gallium/auxiliary/util/u_blit.h View File

@@ -53,6 +53,7 @@ util_destroy_blit(struct blit_state *ctx);
extern void
util_blit_pixels(struct blit_state *ctx,
struct pipe_surface *src,
struct pipe_sampler_view *src_sampler_view,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
@@ -63,6 +64,7 @@ util_blit_pixels(struct blit_state *ctx,
void
util_blit_pixels_writemask(struct blit_state *ctx,
struct pipe_surface *src,
struct pipe_sampler_view *src_sampler_view,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,

+ 4
- 2
src/gallium/drivers/cell/ppu/cell_screen.c View File

@@ -142,8 +142,10 @@ cell_is_format_supported( struct pipe_screen *screen,
format == PIPE_FORMAT_A8B8G8R8_SRGB)
return FALSE;

if (tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
if (!winsys->is_displaytarget_format_supported(winsys, format))
if (tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_SHARED)) {
if (!winsys->is_displaytarget_format_supported(winsys, tex_usage, format))
return FALSE;
}


+ 1
- 0
src/gallium/drivers/cell/ppu/cell_texture.c View File

@@ -105,6 +105,7 @@ cell_displaytarget_layout(struct pipe_screen *screen,
/* Round up the surface size to a multiple of the tile size?
*/
ct->dt = winsys->displaytarget_create(winsys,
ct->base->tex_usage,
ct->base.format,
ct->base.width0,
ct->base.height0,

+ 1
- 0
src/gallium/drivers/i965/brw_context.c View File

@@ -118,6 +118,7 @@ struct pipe_context *brw_create_context(struct pipe_screen *screen,
brw->sws = brw_screen(screen)->sws;
brw->chipset = brw_screen(screen)->chipset;

brw_tex_init( brw );
brw_pipe_blend_init( brw );
brw_pipe_depth_stencil_init( brw );
brw_pipe_framebuffer_init( brw );

+ 13
- 6
src/gallium/drivers/llvmpipe/README View File

@@ -12,7 +12,11 @@ Done so far is:
- depth testing
- texture sampling (not all state/formats are supported)
- texture sampling
- 1D/2D/3D/cube maps supported
- all texture wrap modes supported
- all texture filtering modes supported
- perhaps not all texture formats yet supported
- fragment shader TGSI translation
- same level of support as the TGSI SSE2 exec machine, with the exception
@@ -37,8 +41,6 @@ To do (probably by this order):

- code generate stipple and stencil testing

- translate the remaining bits of texture sampling state

- translate TGSI control flow instructions, and all other remaining opcodes
- integrate with the draw module for VS code generation
@@ -57,7 +59,7 @@ Requirements
See /proc/cpuinfo to know what your CPU supports.
- LLVM 2.6.
- LLVM 2.6 (or later)
For Linux, on a recent Debian based distribution do:
@@ -67,6 +69,9 @@ Requirements
http://people.freedesktop.org/~jrfonseca/llvm/ and set the LLVM environment
variable to the extracted path.

The version of LLVM from SVN ("2.7svn") from mid-March 2010 seems pretty
stable and has some features not in version 2.6.

- scons (optional)

- udis86, http://udis86.sourceforge.net/ (optional):
@@ -140,11 +145,13 @@ Development Notes
then skim through the lp_bld_* functions called in there, and the comments
at the top of the lp_bld_*.c functions.

- All lp_bld_*.[ch] are isolated from the rest of the driver, and could/may be
put in a stand-alone Gallium state -> LLVM IR translation module.
- The driver-independent parts of the LLVM / Gallium code are found in
src/gallium/auxiliary/gallivm/. The filenames and function prefixes
need to be renamed from "lp_bld_" to something else though.

- We use LLVM-C bindings for now. They are not documented, but follow the C++
interfaces very closely, and appear to be complete enough for code
generation. See
http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html
for a stand-alone example.
See the llvm-c/Core.h file for reference.

+ 4
- 2
src/gallium/drivers/llvmpipe/lp_screen.c View File

@@ -203,8 +203,10 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
return FALSE;
}

if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
if(!winsys->is_displaytarget_format_supported(winsys, format))
if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_SHARED)) {
if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format))
return FALSE;
}


+ 1
- 1
src/gallium/drivers/llvmpipe/lp_screen.h View File

@@ -34,7 +34,7 @@
#ifndef LP_SCREEN_H
#define LP_SCREEN_H

#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"
#include <llvm-c/ExecutionEngine.h>

#include "pipe/p_screen.h"

+ 1
- 1
src/gallium/drivers/llvmpipe/lp_state.h View File

@@ -31,7 +31,7 @@
#ifndef LP_STATE_H
#define LP_STATE_H

#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"

#include "pipe/p_state.h"
#include "tgsi/tgsi_scan.h"

+ 2
- 2
src/gallium/drivers/llvmpipe/lp_state_fs.c View File

@@ -251,7 +251,7 @@ generate_tri_edge_mask(LLVMBuilderRef builder,
LLVMConstInt(LLVMInt32Type(), INT_MIN, 0),
"");

in_out_mask = lp_build_int_const_scalar(i32_type, ~0);
in_out_mask = lp_build_const_int_vec(i32_type, ~0);


lp_build_flow_scope_declare(flow, &in_out_mask);
@@ -366,7 +366,7 @@ build_int32_vec_const(int value)
i32_type.norm = FALSE; /* values are not normalized */
i32_type.width = 32; /* 32-bit int values */
i32_type.length = 4; /* 4 elements per vector */
return lp_build_int_const_scalar(i32_type, value);
return lp_build_const_int_vec(i32_type, value);
}



+ 1
- 1
src/gallium/drivers/llvmpipe/lp_test.h View File

@@ -41,7 +41,7 @@
#include <stdio.h>
#include <float.h>

#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"
#include <llvm-c/Analysis.h>
#include <llvm-c/ExecutionEngine.h>
#include <llvm-c/Target.h>

+ 1
- 1
src/gallium/drivers/llvmpipe/lp_test_format.c View File

@@ -29,7 +29,7 @@
#include <stdlib.h>
#include <stdio.h>

#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"
#include <llvm-c/Analysis.h>
#include <llvm-c/ExecutionEngine.h>
#include <llvm-c/Target.h>

+ 1
- 1
src/gallium/drivers/llvmpipe/lp_tex_sample.h View File

@@ -29,7 +29,7 @@
#define LP_TEX_SAMPLE_H


#include "os/os_llvm.h"
#include "gallivm/lp_bld.h"


struct lp_sampler_static_state;

+ 47
- 0
src/gallium/drivers/llvmpipe/lp_texture.c View File

@@ -105,6 +105,7 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
unsigned height = align(lpt->base.height0, TILE_SIZE);

lpt->dt = winsys->displaytarget_create(winsys,
lpt->base.tex_usage,
lpt->base.format,
width, height,
16,
@@ -253,6 +254,51 @@ llvmpipe_resource_unmap(struct pipe_resource *texture,
}


static struct pipe_texture *
llvmpipe_texture_from_handle(struct pipe_screen *screen,
const struct pipe_texture *template,
struct winsys_handle *whandle)
{
struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture);
if (!lpt)
return NULL;

lpt->base = *template;
pipe_reference_init(&lpt->base.reference, 1);
lpt->base.screen = screen;

lpt->dt = winsys->displaytarget_from_handle(winsys,
template,
whandle,
&lpt->stride[0]);
if (!lpt->dt)
goto fail;

return &lpt->base;

fail:
FREE(lpt);
return NULL;
}


static boolean
llvmpipe_resource_get_handle(struct pipe_screen *screen,
struct pipe_resource *pt,
struct winsys_handle *whandle)
{
struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
struct llvmpipe_resource *lpt = llvmpipe_resource(pt);

assert(lpt->dt);
if (!lpt->dt)
return FALSE;

return winsys->displaytarget_get_handle(winsys, lpt->dt, whandle);
}


static struct pipe_surface *
llvmpipe_get_tex_surface(struct pipe_screen *screen,
struct pipe_resource *pt,
@@ -464,6 +510,7 @@ llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
{
screen->resource_create = llvmpipe_resource_create;
screen->resource_destroy = llvmpipe_resource_destroy;
screen->resource_get_handle = llvmpipe_resource_get_handle;
screen->user_buffer_create = llvmpipe_user_buffer_create;

screen->get_tex_surface = llvmpipe_get_tex_surface;

+ 7
- 9
src/gallium/drivers/nvfx/nvfx_state.c View File

@@ -145,18 +145,14 @@ nvfx_set_fragment_sampler_views(struct pipe_context *pipe,
unsigned unit;

for (unit = 0; unit < nr; unit++) {
pipe_sampler_view_reference(&nv30->fragment_sampler_views[unit],
pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
views[unit]);
pipe_texture_reference((struct pipe_texture **)
&nvfx->tex_miptree[unit], miptree[unit]);
nvfx->dirty_samplers |= (1 << unit);
}

for (unit = nr; unit < nvfx->nr_textures; unit++) {
pipe_sampler_view_reference(&nv30->fragment_sampler_views[unit],
pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
NULL);
pipe_texture_reference((struct pipe_texture **)
&nvfx->tex_miptree[unit], NULL);
nvfx->dirty_samplers |= (1 << unit);
}

@@ -166,7 +162,7 @@ nvfx_set_fragment_sampler_views(struct pipe_context *pipe,


static struct pipe_sampler_view *
nv30_create_sampler_view(struct pipe_context *pipe,
nvfx_create_sampler_view(struct pipe_context *pipe,
struct pipe_texture *texture,
const struct pipe_sampler_view *templ)
{
@@ -185,7 +181,7 @@ nv30_create_sampler_view(struct pipe_context *pipe,


static void
nv30_sampler_view_destroy(struct pipe_context *pipe,
nvfx_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view)
{
pipe_texture_reference(&view->texture, NULL);
@@ -614,7 +610,9 @@ nvfx_init_state_functions(struct nvfx_context *nvfx)
nvfx->pipe.create_sampler_state = nvfx_sampler_state_create;
nvfx->pipe.bind_fragment_sampler_states = nvfx_sampler_state_bind;
nvfx->pipe.delete_sampler_state = nvfx_sampler_state_delete;
nvfx->pipe.set_fragment_sampler_textures = nvfx_set_sampler_texture;
nvfx->pipe.set_fragment_sampler_views = nvfx_set_fragment_sampler_views;
nvfx->pipe.create_sampler_view = nvfx_create_sampler_view;
nvfx->pipe.sampler_view_destroy = nvfx_sampler_view_destroy;

nvfx->pipe.create_rasterizer_state = nvfx_rasterizer_state_create;
nvfx->pipe.bind_rasterizer_state = nvfx_rasterizer_state_bind;

+ 2
- 2
src/gallium/drivers/r300/r300_blit.c View File

@@ -114,8 +114,8 @@ static void r300_hw_copy(struct pipe_context* pipe,
r300->blitter, state->sampler_count, (void**)state->sampler_states);

util_blitter_save_fragment_sampler_views(
r300->blitter, r300->fragment_sampler_view_count,
r300->fragment_sampler_views);
r300->blitter, state->texture_count,
state->fragment_sampler_views);

/* Do a copy */
util_blitter_copy(r300->blitter,

+ 3
- 4
src/gallium/drivers/r300/r300_context.h View File

@@ -139,7 +139,7 @@ struct r300_texture_fb_state {

struct r300_textures_state {
/* Textures. */
struct r300_texture *textures[8];
struct pipe_sampler_view *fragment_sampler_views[8];
int texture_count;
/* Sampler states. */
struct r300_sampler_state *sampler_states[8];
@@ -343,9 +343,8 @@ struct r300_context {
struct r300_atom rs_block_state;
/* Scissor state. */
struct r300_atom scissor_state;
/* Sampler view states. */
struct pipe_sampler_view* fragment_sampler_views[8];
int fragment_sampler_view_count;
/* Textures state. */
struct r300_atom textures_state;
/* Vertex stream formatting state. */
struct r300_atom vertex_stream_state;
/* VAP (vertex shader) output mapping state. */

+ 7
- 6
src/gallium/drivers/r300/r300_emit.c View File

@@ -165,7 +165,7 @@ static const float * get_shader_constant(
/* Factor for converting rectangle coords to
* normalized coords. Should only show up on non-r500. */
case RC_STATE_R300_TEXRECT_FACTOR:
tex = r300->fragment_sampler_views[constant->u.State[1]]->texture;
tex = texstate->fragment_sampler_views[constant->u.State[1]]->texture;
vec[0] = 1.0 / tex->width0;
vec[1] = 1.0 / tex->height0;
break;
@@ -749,8 +749,9 @@ void r300_emit_textures_state(struct r300_context *r300,
OUT_CS_REG(R300_TX_FORMAT2_0 + (i * 4), texstate->format[2]);

OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (i * 4), 1);
OUT_CS_TEX_RELOC(allstate->textures[i], texstate->tile_config,
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0);
OUT_CS_TEX_RELOC((struct r300_texture *)allstate->fragment_sampler_views[i]->texture,
texstate->tile_config,
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0);
}
}
END_CS;
@@ -1042,10 +1043,10 @@ validate:
}
}
/* ...textures... */
for (i = 0; i < r300->fragment_sampler_view_count; i++) {
if (!r300->fragment_sampler_views[i])
for (i = 0; i < texstate->count; i++) {
tex = (struct r300_texture*)texstate->fragment_sampler_views[i]->texture;
if (!tex || !texstate->sampler_states[i])
continue;
tex = (struct r300_texture *)r300->fragment_sampler_views[i]->texture;
if (!r300_add_texture(r300->rws, tex,
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
r300->context.flush(&r300->context, 0, NULL);

+ 11
- 10
src/gallium/drivers/r300/r300_state.c View File

@@ -938,6 +938,8 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
struct pipe_sampler_view** views)
{
struct r300_context* r300 = r300_context(pipe);
struct r300_textures_state* state =
(struct r300_textures_state*)r300->textures_state.state;
unsigned i;
boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
boolean dirty_tex = FALSE;
@@ -948,16 +950,16 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
}

for (i = 0; i < count; i++) {
if (r300->fragment_sampler_views[i] != views[i]) {
if (state->fragment_sampler_views[i] != views[i]) {
struct r300_texture *texture;
pipe_sampler_view_reference(&r300->fragment_sampler_views[i],
views[i]);
pipe_sampler_view_reference(&state->fragment_sampler_views[i],
views[i]);
dirty_tex = TRUE;

texture = (struct r300_texture *)views[i]->texture;

/* R300-specific - set the texrect factor in a fragment shader */
/* R300-specific - set the texrect factor in the fragment shader */
if (!is_r500 && texture->is_npot) {
/* XXX It would be nice to re-emit just 1 constant,
* XXX not all of them */
@@ -967,13 +969,13 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
}

for (i = count; i < 8; i++) {
if (r300->fragment_sampler_views[i]) {
pipe_sampler_view_reference(&r300->fragment_sampler_views[i],
NULL);
if (state->fragment_sampler_views[i]) {
pipe_sampler_view_reference(&state->fragment_sampler_views[i],
NULL);
}
}

r300->fragment_sampler_view_count = count;
state->texture_count = count;

r300->textures_state.dirty = TRUE;

@@ -987,7 +989,6 @@ r300_create_sampler_view(struct pipe_context *pipe,
struct pipe_texture *texture,
const struct pipe_sampler_view *templ)
{
struct r300_context *r300 = r300_context(pipe);
struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);

if (view) {

+ 2
- 2
src/gallium/drivers/r300/r300_state_derived.c View File

@@ -340,10 +340,10 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
size = 2;

for (i = 0; i < count; i++) {
if (state->textures[i] && state->sampler_states[i]) {
if (state->fragment_sampler_views[i] && state->sampler_states[i]) {
state->tx_enable |= 1 << i;

tex = state->textures[i];
tex = (struct r300_texture *)state->fragment_sampler_views[i]->texture;
sampler = state->sampler_states[i];

texstate = &state->regs[i];

+ 4
- 2
src/gallium/drivers/softpipe/sp_screen.c View File

@@ -172,8 +172,10 @@ softpipe_is_format_supported( struct pipe_screen *screen,
break;
}

if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
if(!winsys->is_displaytarget_format_supported(winsys, format))
if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_SHARED)) {
if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format))
return FALSE;
}


+ 52
- 2
src/gallium/drivers/softpipe/sp_texture.c View File

@@ -92,6 +92,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen,
/* Round up the surface size to a multiple of the tile size?
*/
spt->dt = winsys->displaytarget_create(winsys,
spt->base.tex_usage,
spt->base.format,
spt->base.width0,
spt->base.height0,
@@ -142,8 +143,6 @@ softpipe_resource_create(struct pipe_screen *screen,
}




static void
softpipe_resource_destroy(struct pipe_screen *pscreen,
struct pipe_resource *pt)
@@ -165,6 +164,55 @@ softpipe_resource_destroy(struct pipe_screen *pscreen,
}


static struct pipe_resource *
softpipe_resource_from_handle(struct pipe_screen *screen,
const struct pipe_resource *template,
struct winsys_handle *whandle)
{
struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
struct softpipe_resource *spt = CALLOC_STRUCT(softpipe_resource);
if (!spt)
return NULL;

spt->base = *template;
pipe_reference_init(&spt->base.reference, 1);
spt->base.screen = screen;

spt->pot = (util_is_power_of_two(template->width0) &&
util_is_power_of_two(template->height0) &&
util_is_power_of_two(template->depth0));

spt->dt = winsys->displaytarget_from_handle(winsys,
template,
whandle,
&spt->stride[0]);
if (!spt->dt)
goto fail;

return &spt->base;

fail:
FREE(spt);
return NULL;
}


static boolean
softpipe_resource_get_handle(struct pipe_screen *screen,
struct pipe_resource *pt,
struct winsys_handle *whandle)
{
struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
struct softpipe_resource *spt = softpipe_resource(pt);

assert(spt->dt);
if (!spt->dt)
return FALSE;

return winsys->displaytarget_get_handle(winsys, spt->dt, whandle);
}


/**
* Get a pipe_surface "view" into a texture.
*/
@@ -428,6 +476,8 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->resource_create = softpipe_resource_create;
screen->resource_destroy = softpipe_resource_destroy;
screen->resource_from_handle = softpipe_resource_from_handle;
screen->resource_get_handle = softpipe_resource_get_handle;
screen->user_buffer_create = softpipe_user_buffer_create;

screen->get_tex_surface = softpipe_get_tex_surface;

+ 407
- 0
src/gallium/include/state_tracker/st_api.h View File

@@ -0,0 +1,407 @@
/**********************************************************
* 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, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* 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 _ST_API_H_
#define _ST_API_H_

#include "pipe/p_compiler.h"
#include "pipe/p_format.h"

/**
* \file API for communication between state trackers and state tracker
* managers.
*
* While both are state tackers, we use the term state tracker for rendering
* APIs such as OpenGL or OpenVG, and state tracker manager for window system
* APIs such as EGL or GLX in this file.
*
* This file defines an API to be implemented by both state trackers and state
* tracker managers.
*/

/**
* The entry points of the state trackers.
*/
#define ST_MODULE_OPENGL_SYMBOL "st_module_OpenGL"
#define ST_MODULE_OPENGL_ES1_SYMBOL "st_module_OpenGL_ES1"
#define ST_MODULE_OPENGL_ES2_SYMBOL "st_module_OpenGL_ES2"
#define ST_MODULE_OPENVG_SYMBOL "st_module_OpenVG"

/**
* The supported rendering API of a state tracker.
*/
enum st_api_type {
ST_API_OPENGL,
ST_API_OPENGL_ES1,
ST_API_OPENGL_ES2,
ST_API_OPENVG,

ST_API_COUNT
};

/**
* Used in st_context_iface->teximage.
*/
enum st_texture_type {
ST_TEXTURE_1D,
ST_TEXTURE_2D,
ST_TEXTURE_3D,
ST_TEXTURE_RECT,
};

/**
* Available attachments of framebuffer.
*/
enum st_attachment_type {
ST_ATTACHMENT_FRONT_LEFT,
ST_ATTACHMENT_BACK_LEFT,
ST_ATTACHMENT_FRONT_RIGHT,
ST_ATTACHMENT_BACK_RIGHT,
ST_ATTACHMENT_DEPTH_STENCIL,
ST_ATTACHMENT_ACCUM,
ST_ATTACHMENT_SAMPLE,

ST_ATTACHMENT_COUNT,
ST_ATTACHMENT_INVALID = -1
};

/* for buffer_mask in st_visual */
#define ST_ATTACHMENT_FRONT_LEFT_MASK (1 << ST_ATTACHMENT_FRONT_LEFT)
#define ST_ATTACHMENT_BACK_LEFT_MASK (1 << ST_ATTACHMENT_BACK_LEFT)
#define ST_ATTACHMENT_FRONT_RIGHT_MASK (1 << ST_ATTACHMENT_FRONT_RIGHT)
#define ST_ATTACHMENT_BACK_RIGHT_MASK (1 << ST_ATTACHMENT_BACK_RIGHT)
#define ST_ATTACHMENT_DEPTH_STENCIL_MASK (1 << ST_ATTACHMENT_DEPTH_STENCIL)
#define ST_ATTACHMENT_ACCUM_MASK (1 << ST_ATTACHMENT_ACCUM)
#define ST_ATTACHMENT_SAMPLE_MASK (1 << ST_ATTACHMENT_SAMPLE)

/**
* Enumerations of state tracker context resources.
*/
enum st_context_resource_type {
ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_2D,
ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_3D,
ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_X,
ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_X,
ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_Y,
ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_Z,
ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
ST_CONTEXT_RESOURCE_OPENGL_RENDERBUFFER,
ST_CONTEXT_RESOURCE_OPENVG_PARENT_IMAGE,
};

/**
* The return type of st_api->get_proc_address.
*/
typedef void (*st_proc_t)(void);

struct pipe_context;
struct pipe_texture;
struct pipe_fence_handle;

/**
* Used in st_context_iface->get_resource_for_egl_image.
*/
struct st_context_resource
{
/* these fields are filled by the caller */
enum st_context_resource_type type;
void *resource;

/* this is owned by the caller */
struct pipe_texture *texture;
};

/**
* Used in st_manager_iface->get_egl_image.
*/
struct st_egl_image
{
/* these fields are filled by the caller */
struct st_context_iface *stctxi;
void *egl_image;

/* this is owned by the caller */
struct pipe_texture *texture;

unsigned face;
unsigned level;
unsigned zslice;
};

/**
* Represent the visual of a framebuffer.
*/
struct st_visual
{
/**
* Available buffers. Tested with ST_FRAMEBUFFER_*_MASK.
*/
unsigned buffer_mask;

/**
* Buffer formats. The formats are always set even when the buffer is
* not available.
*/
enum pipe_format color_format;
enum pipe_format depth_stencil_format;
enum pipe_format accum_format;
int samples;

/**
* Desired render buffer.
*/
enum st_attachment_type render_buffer;
};

/**
* Represent a windowing system drawable.
*
* The framebuffer is implemented by the state tracker manager and
* used by the state trackers.
*
* Instead of the winsys pokeing into the API context to figure
* out what buffers that might be needed in the future by the API
* context, it calls into the framebuffer to get the textures.
*
* This structure along with the notify_invalid_framebuffer
* allows framebuffers to be shared between different threads
* but at the same make the API context free from thread
* syncronisation primitves, with the exception of a small
* atomic flag used for notification of framebuffer dirty status.
*
* The thread syncronisation is put inside the framebuffer
* and only called once the framebuffer has become dirty.
*/
struct st_framebuffer_iface
{
/**
* Available for the state tracker manager to use.
*/
void *st_manager_private;

/**
* The visual of a framebuffer.
*/
const struct st_visual *visual;

/**
* Flush the front buffer.
*
* On some window systems, changes to the front buffers are not immediately
* visible. They need to be flushed.
*
* @att is one of the front buffer attachments.
*/
boolean (*flush_front)(struct st_framebuffer_iface *stfbi,
enum st_attachment_type statt);

/**
* The state tracker asks for the textures it needs.
*
* It should try to only ask for attachments that it currently renders
* to, thus allowing the winsys to delay the allocation of textures not
* needed. For example front buffer attachments are not needed if you
* only do back buffer rendering.
*
* The implementor of this function needs to also ensure
* thread safty as this call might be done from multiple threads.
*
* The returned textures are owned by the caller. They should be
* unreferenced when no longer used. If this function is called multiple
* times with different sets of attachments, those buffers not included in
* the last call might be destroyed. This behavior might change in the
* future.
*/
boolean (*validate)(struct st_framebuffer_iface *stfbi,
const enum st_attachment_type *statts,
unsigned count,
struct pipe_texture **out);
};

/**
* Represent a rendering context.
*
* This entity is created from st_api and used by the state tracker manager.
*/
struct st_context_iface
{
/**
* Available for the state tracker and the manager to use.
*/
void *st_context_private;
void *st_manager_private;

/**
* Destroy the context.
*/
void (*destroy)(struct st_context_iface *stctxi);

/**
* Invalidate the current textures that was taken from a framebuffer.
*
* The state tracker manager calls this function to let the rendering
* context know that it should update the textures it got from
* st_framebuffer_iface::validate. It should do so at the latest time possible.
* Possible right before sending triangles to the pipe context.
*
* For certain platforms this function might be called from a thread other
* than the thread that the context is currently bound in, and must
* therefore be thread safe. But it is the state tracker manager's
* responsibility to make sure that the framebuffer is bound to the context
* and the API context is current for the duration of this call.
*
* Thus reducing the sync primitive needed to a single atomic flag.
*/
void (*notify_invalid_framebuffer)(struct st_context_iface *stctxi,
struct st_framebuffer_iface *stfbi);

/**
* Flush all drawing from context to the pipe also flushes the pipe.
*/
void (*flush)(struct st_context_iface *stctxi, unsigned flags,
struct pipe_fence_handle **fence);

/**
* Replace the texture image of a texture object at the specified level.
*
* This function is optional.
*/
boolean (*teximage)(struct st_context_iface *stctxi, enum st_texture_type target,
int level, enum pipe_format internal_format,
struct pipe_texture *tex, boolean mipmap);

/**
* Used to implement glXCopyContext.
*/
void (*copy)(struct st_context_iface *stctxi,
struct st_context_iface *stsrci, unsigned mask);

/**
* Look up and return the info of a resource for EGLImage.
*
* This function is optional.
*/
boolean (*get_resource_for_egl_image)(struct st_context_iface *stctxi,
struct st_context_resource *stres);
};


/**
* Represent a state tracker manager.
*
* This interface is implemented by the state tracker manager. It corresponds
* to a "display" in the window system.
*/
struct st_manager
{
struct pipe_screen *screen;

/**
* Look up and return the info of an EGLImage.
*
* This function is optional.
*/
boolean (*get_egl_image)(struct st_manager *smapi,
struct st_egl_image *stimg);
};

/**
* Represent a rendering API such as OpenGL or OpenVG.
*
* Implemented by the state tracker and used by the state tracker manager.
*/
struct st_api
{
/**
* Destroy the API.
*/
void (*destroy)(struct st_api *stapi);

/**
* Return an API entry point.
*
* For GL this is the same as _glapi_get_proc_address.
*/
st_proc_t (*get_proc_address)(struct st_api *stapi, const char *procname);

/**
* Return true if the visual is supported by the state tracker.
*/
boolean (*is_visual_supported)(struct st_api *stapi,
const struct st_visual *visual);

/**
* Create a rendering context.
*/
struct st_context_iface *(*create_context)(struct st_api *stapi,
struct st_manager *smapi,
const struct st_visual *visual,
struct st_context_iface *stsharei);

/**
* Bind the context to the calling thread with draw and read as drawables.
*
* The framebuffers might have different visuals than the context does.
*/
boolean (*make_current)(struct st_api *stapi,
struct st_context_iface *stctxi,
struct st_framebuffer_iface *stdrawi,
struct st_framebuffer_iface *streadi);

/**
* Get the currently bound context in the calling thread.
*/
struct st_context_iface *(*get_current)(struct st_api *stapi);
};

/**
* Represent a state tracker.
*
* This is the entry point of a state tracker.
*/
struct st_module
{
enum st_api_type api;
struct st_api *(*create_api)(void);
};

/**
* Return true if the visual has the specified buffers.
*/
static INLINE boolean
st_visual_have_buffers(const struct st_visual *visual, unsigned mask)
{
return ((visual->buffer_mask & mask) == mask);
}

/* these symbols may need to be dynamically lookup up */
extern PUBLIC const struct st_module st_module_OpenGL;
extern PUBLIC const struct st_module st_module_OpenGL_ES1;
extern PUBLIC const struct st_module st_module_OpenGL_ES2;
extern PUBLIC const struct st_module st_module_OpenVG;

#endif /* _ST_API_H_ */

+ 20
- 0
src/gallium/include/state_tracker/sw_winsys.h View File

@@ -44,6 +44,7 @@ extern "C" {
#endif


struct winsys_handle;
struct pipe_screen;
struct pipe_context;

@@ -68,6 +69,7 @@ struct sw_winsys

boolean
(*is_displaytarget_format_supported)( struct sw_winsys *ws,
unsigned tex_usage,
enum pipe_format format );
/**
@@ -83,11 +85,29 @@ struct sw_winsys
*/
struct sw_displaytarget *
(*displaytarget_create)( struct sw_winsys *ws,
unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
unsigned *stride );

/**
* Used to implement texture_from_handle.
*/
struct sw_displaytarget *
(*displaytarget_from_handle)( struct sw_winsys *ws,
const struct pipe_texture *templat,
struct winsys_handle *whandle,
unsigned *stride );

/**
* Used to implement texture_get_handle.
*/
boolean
(*displaytarget_get_handle)( struct sw_winsys *ws,
struct sw_displaytarget *dt,
struct winsys_handle *whandle );

/**
* \param flags bitmask of PIPE_BUFFER_USAGE_x flags
*/

+ 1
- 2
src/gallium/state_trackers/dri/dri_context.c View File

@@ -35,7 +35,6 @@
#include "state_tracker/drm_api.h"
#include "state_tracker/dri1_api.h"
#include "state_tracker/st_public.h"
#include "state_tracker/st_context.h"
#include "pipe/p_context.h"

#include "dri_context.h"
@@ -167,7 +166,7 @@ dri_make_current(__DRIcontext * cPriv,
* flush_frontbuffer directly (in front-buffer rendering), it
* will have access to the drawable argument:
*/
st_make_current(ctx->st, draw->stfb, read->stfb, NULL);
st_make_current(ctx->st, draw->stfb, read->stfb, ctx);

if (__dri1_api_hooks) {
dri1_update_drawables(ctx, draw, read);

+ 1
- 1
src/gallium/state_trackers/dri/dri_drawable.c View File

@@ -39,8 +39,8 @@
#include "main/renderbuffer.h"
#include "state_tracker/drm_api.h"
#include "state_tracker/dri1_api.h"
#include "state_tracker/st_public.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
#include "state_tracker/st_cb_fbo.h"

#include "util/u_format.h"

+ 206
- 380
src/gallium/state_trackers/egl/common/egl_g3d.c View File

@@ -36,234 +36,27 @@

#include "native.h"
#include "egl_g3d.h"
#include "egl_g3d_st.h"
#include "egl_g3d_image.h"
#include "egl_st.h"

/**
* Validate the draw/read surfaces of the context.
*/
static void
egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct pipe_screen *screen = gdpy->native->screen;
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
const uint st_att_map[NUM_NATIVE_ATTACHMENTS] = {
ST_SURFACE_FRONT_LEFT,
ST_SURFACE_BACK_LEFT,
ST_SURFACE_FRONT_RIGHT,
ST_SURFACE_BACK_RIGHT,
};
EGLint num_surfaces, s;

/* validate draw and/or read buffers */
num_surfaces = (gctx->base.ReadSurface == gctx->base.DrawSurface) ? 1 : 2;
for (s = 0; s < num_surfaces; s++) {
struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
struct egl_g3d_surface *gsurf;
struct egl_g3d_buffer *gbuf;
EGLint att;

if (s == 0) {
gsurf = egl_g3d_surface(gctx->base.DrawSurface);
gbuf = &gctx->draw;
}
else {
gsurf = egl_g3d_surface(gctx->base.ReadSurface);
gbuf = &gctx->read;
}

if (!gctx->force_validate) {
unsigned int seq_num;

gsurf->native->validate(gsurf->native, gbuf->attachment_mask,
&seq_num, NULL, NULL, NULL);
/* skip validation */
if (gsurf->sequence_number == seq_num)
continue;
}

pipe_surface_reference(&gsurf->render_surface, NULL);
memset(textures, 0, sizeof(textures));

gsurf->native->validate(gsurf->native, gbuf->attachment_mask,
&gsurf->sequence_number, textures,
&gsurf->base.Width, &gsurf->base.Height);
for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
struct pipe_texture *pt = textures[att];
struct pipe_surface *ps;

if (native_attachment_mask_test(gbuf->attachment_mask, att) && pt) {
ps = screen->get_tex_surface(screen, pt, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE);
gctx->stapi->st_set_framebuffer_surface(gbuf->st_fb,
st_att_map[att], ps);

if (gsurf->render_att == att)
pipe_surface_reference(&gsurf->render_surface, ps);

pipe_surface_reference(&ps, NULL);
pipe_texture_reference(&pt, NULL);
}
}

gctx->stapi->st_resize_framebuffer(gbuf->st_fb,
gsurf->base.Width, gsurf->base.Height);
}

gctx->force_validate = EGL_FALSE;

}

/**
* Create a st_framebuffer.
*/
static struct st_framebuffer *
create_framebuffer(_EGLContext *ctx, _EGLSurface *surf)
{
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config);

return gctx->stapi->st_create_framebuffer(&gconf->native->mode,
gconf->native->color_format, gconf->native->depth_format,
gconf->native->stencil_format,
gsurf->base.Width, gsurf->base.Height, &gsurf->base);
}

/**
* Update the attachments of draw/read surfaces.
*/
static void
egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx)
{
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
EGLint s;

/* route draw and read buffers' attachments */
for (s = 0; s < 2; s++) {
struct egl_g3d_surface *gsurf;
struct egl_g3d_buffer *gbuf;

if (s == 0) {
gsurf = egl_g3d_surface(gctx->base.DrawSurface);
gbuf = &gctx->draw;
}
else {
gsurf = egl_g3d_surface(gctx->base.ReadSurface);
gbuf = &gctx->read;
}

gbuf->attachment_mask = (1 << gsurf->render_att);

/* FIXME OpenGL defaults to draw the front or back buffer when the
* context is single-buffered or double-buffered respectively. In EGL,
* however, the buffer to be drawn is determined by the surface, instead
* of the context. As a result, rendering to a pixmap surface with a
* double-buffered context does not work as expected.
*
* gctx->stapi->st_draw_front_buffer(gctx->st_ctx, natt ==
* NATIVE_ATTACHMENT_FRONT_LEFT);
*/

/*
* FIXME If the back buffer is asked for here, and the front buffer is
* later needed by the client API (e.g. glDrawBuffer is called to draw
* the front buffer), it will create a new pipe texture and draw there.
* One fix is to ask for both buffers here, but it would be a waste if
* the front buffer is never used. A better fix is to add a callback to
* the pipe screen with context private (just like flush_frontbuffer).
*/
}
}

/**
* Reallocate the context's framebuffers after draw/read surfaces change.
*/
static EGLBoolean
egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx)
{
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
struct egl_g3d_surface *gdraw = egl_g3d_surface(gctx->base.DrawSurface);
struct egl_g3d_surface *gread = egl_g3d_surface(gctx->base.ReadSurface);

/* unreference the old framebuffers */
if (gctx->draw.st_fb) {
EGLBoolean is_equal = (gctx->draw.st_fb == gctx->read.st_fb);
void *priv;

priv = gctx->stapi->st_framebuffer_private(gctx->draw.st_fb);
if (!gdraw || priv != (void *) &gdraw->base) {
gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
gctx->draw.st_fb = NULL;
gctx->draw.attachment_mask = 0x0;
}

if (is_equal) {
gctx->read.st_fb = NULL;
gctx->draw.attachment_mask = 0x0;
}
else {
priv = gctx->stapi->st_framebuffer_private(gctx->read.st_fb);
if (!gread || priv != (void *) &gread->base) {
gctx->stapi->st_unreference_framebuffer(gctx->read.st_fb);
gctx->read.st_fb = NULL;
gctx->draw.attachment_mask = 0x0;
}
}
}

if (!gdraw)
return EGL_TRUE;

/* create the draw fb */
if (!gctx->draw.st_fb) {
gctx->draw.st_fb = create_framebuffer(&gctx->base, &gdraw->base);
if (!gctx->draw.st_fb)
return EGL_FALSE;
}

/* create the read fb */
if (!gctx->read.st_fb) {
if (gread != gdraw) {
gctx->read.st_fb = create_framebuffer(&gctx->base, &gread->base);
if (!gctx->read.st_fb) {
gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
gctx->draw.st_fb = NULL;
return EGL_FALSE;
}
}
else {
/* there is no st_reference_framebuffer... */
gctx->read.st_fb = gctx->draw.st_fb;
}
}

egl_g3d_route_context(dpy, &gctx->base);
gctx->force_validate = EGL_TRUE;

return EGL_TRUE;
}

/**
* Return the state tracker for the given context.
*/
static const struct egl_g3d_st *
static struct st_api *
egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
const struct egl_g3d_st *stapi;
struct st_api *stapi;
EGLint idx = -1;

switch (ctx->ClientAPI) {
case EGL_OPENGL_ES_API:
switch (ctx->ClientVersion) {
case 1:
idx = EGL_G3D_ST_OPENGL_ES;
idx = ST_API_OPENGL_ES1;
break;
case 2:
idx = EGL_G3D_ST_OPENGL_ES2;
idx = ST_API_OPENGL_ES2;
break;
default:
_eglLog(_EGL_WARNING, "unknown client version %d",
@@ -272,10 +65,10 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
}
break;
case EGL_OPENVG_API:
idx = EGL_G3D_ST_OPENVG;
idx = ST_API_OPENVG;
break;
case EGL_OPENGL_API:
idx = EGL_G3D_ST_OPENGL;
idx = ST_API_OPENGL;
break;
default:
_eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI);
@@ -299,10 +92,10 @@ egl_g3d_init_st(_EGLDriver *drv)
if (gdrv->api_mask)
return;

for (i = 0; i < NUM_EGL_G3D_STS; i++) {
gdrv->stapis[i] = egl_g3d_get_st(i);
for (i = 0; i < ST_API_COUNT; i++) {
gdrv->stapis[i] = egl_g3d_create_st_api(i);
if (gdrv->stapis[i])
gdrv->api_mask |= gdrv->stapis[i]->api_bit;
gdrv->api_mask |= egl_g3d_st_api_bit(i);
}

if (gdrv->api_mask)
@@ -351,35 +144,6 @@ egl_g3d_destroy_probe(_EGLDriver *drv, _EGLDisplay *dpy)
}
}

/**
* Return an API mask that consists of the state trackers that supports the
* given mode.
*
* FIXME add st_is_mode_supported()?
*/
static EGLint
get_mode_api_mask(const __GLcontextModes *mode, EGLint api_mask)
{
EGLint check;

/* OpenGL ES 1.x and 2.x are checked together */
check = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT;
if (api_mask & check) {
/* this is required by EGL, not by OpenGL ES */
if (mode->drawableType & GLX_WINDOW_BIT && !mode->doubleBufferMode)
api_mask &= ~check;
}

check = EGL_OPENVG_BIT;
if (api_mask & check) {
/* vega st needs the depth/stencil rb */
if (!mode->depthBits && !mode->stencilBits)
api_mask &= ~check;
}

return api_mask;
}

#ifdef EGL_MESA_screen_surface

static void
@@ -443,19 +207,89 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)

#endif /* EGL_MESA_screen_surface */

/**
* Initialize an EGL config from the native config.
*/
static EGLBoolean
egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLConfig *conf, const struct native_config *nconf)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
struct egl_g3d_config *gconf = egl_g3d_config(conf);
const __GLcontextModes *mode = &nconf->mode;
EGLint buffer_mask, api_mask;
EGLBoolean valid;
EGLint i;

buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK;
if (mode->doubleBufferMode)
buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
if (mode->stereoMode) {
buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
if (mode->doubleBufferMode)
buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
}

gconf->stvis.buffer_mask = buffer_mask;
gconf->stvis.color_format = nconf->color_format;
gconf->stvis.depth_stencil_format = nconf->depth_format;
gconf->stvis.accum_format = PIPE_FORMAT_NONE;
gconf->stvis.samples = 0;

gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT) ?
ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT;

api_mask = 0;
for (i = 0; i < ST_API_COUNT; i++) {
struct st_api *stapi = gdrv->stapis[i];
if (stapi) {
if (stapi->is_visual_supported(stapi, &gconf->stvis))
api_mask |= egl_g3d_st_api_bit(i);
}
}
/* this is required by EGL, not by OpenGL ES */
if ((mode->drawableType & GLX_WINDOW_BIT) && !mode->doubleBufferMode)
api_mask &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);

if (!api_mask) {
_eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
mode->visualID);
}

valid = _eglConfigFromContextModesRec(&gconf->base,
mode, api_mask, api_mask);
if (valid) {
#ifdef EGL_MESA_screen_surface
/* check if scanout surface bit is set */
if (nconf->scanout_bit) {
EGLint val = GET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE);
val |= EGL_SCREEN_BIT_MESA;
SET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE, val);
}
#endif
valid = _eglValidateConfig(&gconf->base, EGL_FALSE);
}
if (!valid) {
_eglLog(_EGL_DEBUG, "skip invalid config 0x%x", mode->visualID);
return EGL_FALSE;
}

gconf->native = nconf;

return EGL_TRUE;
}

/**
* Add configs to display and return the next config ID.
*/
static EGLint
egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
const struct native_config **native_configs;
int num_configs, i;

native_configs = gdpy->native->get_configs(gdpy->native,
&num_configs);
native_configs = gdpy->native->get_configs(gdpy->native, &num_configs);
if (!num_configs) {
if (native_configs)
free(native_configs);
@@ -463,61 +297,25 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
}

for (i = 0; i < num_configs; i++) {
EGLint api_mask;
struct egl_g3d_config *gconf;
EGLBoolean valid;

gconf = CALLOC_STRUCT(egl_g3d_config);
if (!gconf)
continue;

_eglInitConfig(&gconf->base, dpy, id);

api_mask = get_mode_api_mask(&native_configs[i]->mode, gdrv->api_mask);
if (!api_mask) {
_eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
native_configs[i]->mode.visualID);
}

valid = _eglConfigFromContextModesRec(&gconf->base,
&native_configs[i]->mode, api_mask, api_mask);
if (valid) {
#ifdef EGL_MESA_screen_surface
/* check if scanout surface bit is set */
if (native_configs[i]->scanout_bit) {
EGLint val = GET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE);
val |= EGL_SCREEN_BIT_MESA;
SET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE, val);
if (gconf) {
_eglInitConfig(&gconf->base, dpy, id);
if (!egl_g3d_init_config(drv, dpy, &gconf->base, native_configs[i])) {
free(gconf);
continue;
}
#endif
valid = _eglValidateConfig(&gconf->base, EGL_FALSE);
}
if (!valid) {
_eglLog(_EGL_DEBUG, "skip invalid config 0x%x",
native_configs[i]->mode.visualID);
free(gconf);
continue;
}

gconf->native = native_configs[i];
_eglAddConfig(dpy, &gconf->base);
id++;
_eglAddConfig(dpy, &gconf->base);
id++;
}
}

free(native_configs);
return id;
}

/**
* Re-validate the context.
*/
static void
egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private)
{
struct egl_g3d_context *gctx = egl_g3d_context(context_private);
egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base);
}

static void
egl_g3d_invalid_surface(struct native_display *ndpy,
struct native_surface *nsurf,
@@ -525,11 +323,15 @@ egl_g3d_invalid_surface(struct native_display *ndpy,
{
/* XXX not thread safe? */
struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
struct egl_g3d_context *gctx = egl_g3d_context(gsurf->base.CurrentContext);

/* set force_validate to skip an unnecessary check */
struct egl_g3d_context *gctx;
/*
* Some functions such as egl_g3d_copy_buffers create a temporary native
* surface. There is no gsurf associated with it.
*/
gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL;
if (gctx)
gctx->force_validate = TRUE;
gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
}

static struct native_event_handler egl_g3d_native_event_handler = {
@@ -545,6 +347,9 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
_eglReleaseDisplayResources(drv, dpy);
_eglCleanupDisplay(dpy);

if (gdpy->pipe)
gdpy->pipe->destroy(gdpy->pipe);

if (dpy->Screens) {
for (i = 0; i < dpy->NumScreens; i++) {
struct egl_g3d_screen *gscr = egl_g3d_screen(dpy->Screens[i]);
@@ -554,6 +359,9 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
free(dpy->Screens);
}

if (gdpy->smapi)
egl_g3d_destroy_st_manager(gdpy->smapi);

if (gdpy->native)
gdpy->native->destroy(gdpy->native);

@@ -588,11 +396,17 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
}

gdpy->native->user_data = (void *) dpy;
gdpy->native->screen->update_buffer = egl_g3d_update_buffer;

egl_g3d_init_st(&gdrv->base);
dpy->ClientAPIsMask = gdrv->api_mask;

gdpy->smapi = egl_g3d_create_st_manager(dpy);
if (!gdpy->smapi) {
_eglError(EGL_NOT_INITIALIZED,
"eglInitialize(failed to create st manager)");
goto fail;
}

#ifdef EGL_MESA_screen_surface
/* enable MESA_screen_surface before adding (and validating) configs */
if (gdpy->native->modeset) {
@@ -629,7 +443,6 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
struct egl_g3d_context *gshare = egl_g3d_context(share);
struct egl_g3d_config *gconf = egl_g3d_config(conf);
struct egl_g3d_context *gctx;
const __GLcontextModes *mode;

gctx = CALLOC_STRUCT(egl_g3d_context);
if (!gctx) {
@@ -648,24 +461,14 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
return NULL;
}

mode = &gconf->native->mode;

gctx->pipe = gdpy->native->screen->context_create(
gdpy->native->screen,
(void *) &gctx->base);

if (!gctx->pipe) {
gctx->stctxi = gctx->stapi->create_context(gctx->stapi, gdpy->smapi,
&gconf->stvis, (gshare) ? gshare->stctxi : NULL);
if (!gctx->stctxi) {
free(gctx);
return NULL;
}

gctx->st_ctx = gctx->stapi->st_create_context(gctx->pipe, mode,
(gshare) ? gshare->st_ctx : NULL);
if (!gctx->st_ctx) {
gctx->pipe->destroy(gctx->pipe);
free(gctx);
return NULL;
}
gctx->stctxi->st_manager_private = (void *) &gctx->base;

return &gctx->base;
}
@@ -682,9 +485,7 @@ destroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
if (!dpy->Initialized)
_eglLog(_EGL_FATAL, "destroy a context with an unitialized display");

egl_g3d_realloc_context(dpy, &gctx->base);
/* it will destroy the associated pipe context */
gctx->stapi->st_destroy_context(gctx->st_ctx);
gctx->stctxi->destroy(gctx->stctxi);

free(gctx);
}
@@ -786,14 +587,20 @@ egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
return NULL;
}

gsurf->stvis = gconf->stvis;
if (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER)
gsurf->stvis.render_buffer = ST_ATTACHMENT_FRONT_LEFT;

gsurf->stfbi = egl_g3d_create_st_framebuffer(&gsurf->base);
if (!gsurf->stfbi) {
gsurf->native->destroy(gsurf->native);
free(gsurf);
return NULL;
}

nsurf->user_data = &gsurf->base;
gsurf->native = nsurf;

gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER) ?
NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
if (!gconf->native->mode.doubleBufferMode)
gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT;

return &gsurf->base;
}

@@ -849,7 +656,8 @@ destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
if (!dpy->Initialized)
_eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");

pipe_surface_reference(&gsurf->render_surface, NULL);
pipe_texture_reference(&gsurf->render_texture, NULL);
egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
gsurf->native->destroy(gsurf->native);
free(gsurf);
}
@@ -868,6 +676,7 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
{
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
struct egl_g3d_surface *gdraw = egl_g3d_surface(draw);
struct egl_g3d_surface *gread = egl_g3d_surface(read);
struct egl_g3d_context *old_gctx;
EGLBoolean ok = EGL_TRUE;

@@ -878,39 +687,29 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,

if (old_gctx) {
/* flush old context */
old_gctx->stapi->st_flush(old_gctx->st_ctx,
old_gctx->stctxi->flush(old_gctx->stctxi,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);

/*
* The old context is no longer current, and egl_g3d_realloc_context()
* should be called to destroy the framebuffers. However, it is possible
* that it will be made current again with the same draw/read surfaces.
* It might be better to keep it around.
*/
}

if (gctx) {
ok = egl_g3d_realloc_context(dpy, &gctx->base);
ok = gctx->stapi->make_current(gctx->stapi, gctx->stctxi,
(gdraw) ? gdraw->stfbi : NULL, (gread) ? gread->stfbi : NULL);
if (ok) {
/* XXX: need to pass the winsys argument for
* flush_frontbuffer in the fourth parameter here:
*/
ok = gctx->stapi->st_make_current(gctx->st_ctx,
gctx->draw.st_fb,
gctx->read.st_fb,
NULL);
if (ok) {
egl_g3d_validate_context(dpy, &gctx->base);
if (gdraw->base.Type == EGL_WINDOW_BIT) {
gctx->base.WindowRenderBuffer =
(gdraw->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) ?
EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
}
gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gdraw->stfbi);
if (gread != gdraw) {
gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi,
gread->stfbi);
}

if (gdraw->base.Type == EGL_WINDOW_BIT) {
gctx->base.WindowRenderBuffer =
(gdraw->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT) ?
EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
}
}
}
else if (old_gctx) {
ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL, NULL);
ok = old_gctx->stapi->make_current(old_gctx->stapi, NULL, NULL, NULL);
old_gctx->base.WindowRenderBuffer = EGL_NONE;
}

@@ -937,15 +736,17 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
return EGL_TRUE;

/* or when the surface is single-buffered */
if (gsurf->render_att == NATIVE_ATTACHMENT_FRONT_LEFT)
if (gsurf->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT)
return EGL_TRUE;

if (ctx && ctx->DrawSurface == surf)
gctx = egl_g3d_context(ctx);

/* flush if the surface is current */
if (gctx)
gctx->stapi->st_notify_swapbuffers(gctx->draw.st_fb);
if (gctx) {
gctx->stctxi->flush(gctx->stctxi,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
}

return gsurf->native->swap_buffers(gsurf->native);
}
@@ -985,7 +786,7 @@ get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf,
return NULL;

psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt],
0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE);
0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
pipe_texture_reference(&textures[natt], NULL);

return psurf;
@@ -1003,7 +804,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
struct pipe_screen *screen = gdpy->native->screen;
struct pipe_surface *psurf;

if (!gsurf->render_surface)
if (!gsurf->render_texture)
return EGL_TRUE;

gconf = egl_g3d_config(egl_g3d_find_pixmap_config(dpy, target));
@@ -1018,26 +819,33 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
/* flush if the surface is current */
if (ctx && ctx->DrawSurface == &gsurf->base) {
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
gctx->stapi->st_flush(gctx->st_ctx,
gctx->stctxi->flush(gctx->stctxi,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
}

/* create a pipe context to copy surfaces */
if (!gdpy->pipe) {
gdpy->pipe =
gdpy->native->screen->context_create(gdpy->native->screen, NULL);
if (!gdpy->pipe)
return EGL_FALSE;
}

psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
if (psurf) {
struct pipe_context pipe;
struct pipe_surface *psrc;

/**
* XXX This is hacky. If we might allow the EGLDisplay to create a pipe
* context of its own and use the blitter context for this.
*/
memset(&pipe, 0, sizeof(pipe));
pipe.screen = screen;
psrc = screen->get_tex_surface(screen, gsurf->render_texture,
0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ);
if (psrc) {
gdpy->pipe->surface_copy(gdpy->pipe, psurf, 0, 0,
psrc, 0, 0, psurf->width, psurf->height);
pipe_surface_reference(&psrc, NULL);

util_surface_copy(&pipe, FALSE, psurf, 0, 0,
gsurf->render_surface, 0, 0, psurf->width, psurf->height);
nsurf->flush_frontbuffer(nsurf);
}

pipe_surface_reference(&psurf, NULL);
nsurf->flush_frontbuffer(nsurf);
}

nsurf->destroy(nsurf);
@@ -1048,8 +856,16 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
static EGLBoolean
egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
gctx->stapi->st_finish(gctx->st_ctx);
struct pipe_screen *screen = gdpy->native->screen;
struct pipe_fence_handle *fence = NULL;

gctx->stctxi->flush(gctx->stctxi,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence);
screen->fence_finish(screen, fence, 0);
screen->fence_reference(screen, &fence, NULL);

return EGL_TRUE;
}

@@ -1079,10 +895,10 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
/* in case this is called before a display is initialized */
egl_g3d_init_st(&gdrv->base);

for (i = 0; i < NUM_EGL_G3D_STS; i++) {
const struct egl_g3d_st *stapi = gdrv->stapis[i];
for (i = 0; i < ST_API_COUNT; i++) {
struct st_api *stapi = gdrv->stapis[i];
if (stapi) {
proc = (_EGLProc) stapi->st_get_proc_address(procname);
proc = (_EGLProc) stapi->get_proc_address(stapi, procname);
if (proc)
return proc;
}
@@ -1098,8 +914,8 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
_EGLContext *es1 = _eglGetAPIContext(EGL_OPENGL_ES_API);
struct egl_g3d_context *gctx;
enum pipe_format target_format;
int target;
enum pipe_format internal_format;
enum st_texture_type target;

if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT)
return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
@@ -1110,10 +926,10 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,

switch (gsurf->base.TextureFormat) {
case EGL_TEXTURE_RGB:
target_format = PIPE_FORMAT_R8G8B8_UNORM;
internal_format = PIPE_FORMAT_R8G8B8_UNORM;
break;
case EGL_TEXTURE_RGBA:
target_format = PIPE_FORMAT_B8G8R8A8_UNORM;
internal_format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
default:
return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
@@ -1129,21 +945,24 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,

if (!es1)
return EGL_TRUE;
if (!gsurf->render_surface)
if (!gsurf->render_texture)
return EGL_FALSE;

/* flush properly if the surface is bound */
if (gsurf->base.CurrentContext) {
gctx = egl_g3d_context(gsurf->base.CurrentContext);
gctx->stapi->st_flush(gctx->st_ctx,
gctx->stctxi->flush(gctx->stctxi,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
}

gctx = egl_g3d_context(es1);
gctx->stapi->st_bind_texture_surface(gsurf->render_surface,
target, gsurf->base.MipmapLevel, target_format);

gsurf->base.BoundToTexture = EGL_TRUE;
if (gctx->stctxi->teximage) {
if (!gctx->stctxi->teximage(gctx->stctxi, target,
gsurf->base.MipmapLevel, internal_format,
gsurf->render_texture, gsurf->base.MipmapTexture))
return EGL_FALSE;
gsurf->base.BoundToTexture = EGL_TRUE;
}

return EGL_TRUE;
}
@@ -1160,14 +979,15 @@ egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
if (buffer != EGL_BACK_BUFFER)
return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");

if (gsurf->render_surface) {
if (gsurf->render_texture) {
_EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API);
struct egl_g3d_context *gctx = egl_g3d_context(ctx);

/* what if the context the surface binds to is no longer current? */
if (gctx)
gctx->stapi->st_unbind_texture_surface(gsurf->render_surface,
ST_TEXTURE_2D, gsurf->base.MipmapLevel);
if (gctx) {
gctx->stctxi->teximage(gctx->stctxi, ST_TEXTURE_2D,
gsurf->base.MipmapLevel, PIPE_FORMAT_NONE, NULL, FALSE);
}
}

gsurf->base.BoundToTexture = EGL_FALSE;
@@ -1279,6 +1099,12 @@ static void
egl_g3d_unload(_EGLDriver *drv)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
EGLint i;

for (i = 0; i < ST_API_COUNT; i++) {
if (gdrv->stapis[i])
gdrv->stapis[i]->destroy(gdrv->stapis[i]);
}

egl_g3d_destroy_probe(drv, NULL);
free(gdrv);

+ 12
- 13
src/gallium/state_trackers/egl/common/egl_g3d.h View File

@@ -39,11 +39,11 @@
#include "eglmode.h"

#include "native.h"
#include "egl_st.h"
#include "egl_g3d_st.h"

struct egl_g3d_driver {
_EGLDriver base;
const struct egl_g3d_st *stapis[NUM_EGL_G3D_STS];
struct st_api *stapis[ST_API_COUNT];
EGLint api_mask;

EGLint probe_key;
@@ -51,35 +51,34 @@ struct egl_g3d_driver {

struct egl_g3d_display {
struct native_display *native;
};

struct egl_g3d_buffer {
struct st_framebuffer *st_fb;
uint attachment_mask;
struct st_manager *smapi;
struct pipe_context *pipe;
};

struct egl_g3d_context {
_EGLContext base;

const struct egl_g3d_st *stapi;
struct pipe_context *pipe;
struct st_api *stapi;

struct st_context *st_ctx;
EGLBoolean force_validate;
struct egl_g3d_buffer draw, read;
struct st_context_iface *stctxi;
};

struct egl_g3d_surface {
_EGLSurface base;

struct st_visual stvis;
struct st_framebuffer_iface *stfbi;

struct native_surface *native;
enum native_attachment render_att;
struct pipe_surface *render_surface;
struct pipe_texture *render_texture;
unsigned int sequence_number;
};

struct egl_g3d_config {
_EGLConfig base;
const struct native_config *native;
struct st_visual stvis;
};

struct egl_g3d_image {

+ 227
- 0
src/gallium/state_trackers/egl/common/egl_g3d_st.c View File

@@ -0,0 +1,227 @@
/*
* Mesa 3-D graphics library
* Version: 7.9
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/

#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/u_dl.h"
#include "eglimage.h"
#include "eglmutex.h"

#include "egl_g3d.h"
#include "egl_g3d_st.h"

struct egl_g3d_st_manager {
struct st_manager base;
_EGLDisplay *display;
};

static INLINE struct egl_g3d_st_manager *
egl_g3d_st_manager(struct st_manager *smapi)
{
return (struct egl_g3d_st_manager *) smapi;
}

struct st_api *
egl_g3d_create_st_api(enum st_api_type api)
{
const char *stmod_name;
struct util_dl_library *lib;
const struct st_module *mod;

switch (api) {
case ST_API_OPENGL:
stmod_name = ST_MODULE_OPENGL_SYMBOL;
break;
case ST_API_OPENGL_ES1:
stmod_name = ST_MODULE_OPENGL_ES1_SYMBOL;
break;
case ST_API_OPENGL_ES2:
stmod_name = ST_MODULE_OPENGL_ES2_SYMBOL;
break;
case ST_API_OPENVG:
stmod_name = ST_MODULE_OPENVG_SYMBOL;
break;
default:
stmod_name = NULL;
break;
}
if (!stmod_name)
return NULL;

mod = NULL;
lib = util_dl_open(NULL);
if (lib) {
mod = (const struct st_module *)
util_dl_get_proc_address(lib, stmod_name);
util_dl_close(lib);
}
if (!mod || mod->api != api)
return NULL;

return mod->create_api();
}

struct st_manager *
egl_g3d_create_st_manager(_EGLDisplay *dpy)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_st_manager *gsmapi;

gsmapi = CALLOC_STRUCT(egl_g3d_st_manager);
if (gsmapi) {
gsmapi->display = dpy;

gsmapi->base.screen = gdpy->native->screen;
}

return &gsmapi->base;;
}

void
egl_g3d_destroy_st_manager(struct st_manager *smapi)
{
struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi);
free(gsmapi);
}

static boolean
egl_g3d_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
enum st_attachment_type statt)
{
_EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);

return gsurf->native->flush_frontbuffer(gsurf->native);
}

static boolean
egl_g3d_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
const enum st_attachment_type *statts,
unsigned count,
struct pipe_texture **out)
{
_EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
uint attachment_mask = 0;
unsigned i;

for (i = 0; i < count; i++) {
int natt;

switch (statts[i]) {
case ST_ATTACHMENT_FRONT_LEFT:
natt = NATIVE_ATTACHMENT_FRONT_LEFT;
break;
case ST_ATTACHMENT_BACK_LEFT:
natt = NATIVE_ATTACHMENT_BACK_LEFT;
break;
case ST_ATTACHMENT_FRONT_RIGHT:
natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
break;
case ST_ATTACHMENT_BACK_RIGHT:
natt = NATIVE_ATTACHMENT_BACK_RIGHT;
default:
natt = -1;
break;
}

if (natt >= 0)
attachment_mask |= 1 << natt;
}

if (!gsurf->native->validate(gsurf->native, attachment_mask,
&gsurf->sequence_number, textures, &gsurf->base.Width,
&gsurf->base.Height))
return FALSE;

for (i = 0; i < count; i++) {
struct pipe_texture *tex;
int natt;

switch (statts[i]) {
case ST_ATTACHMENT_FRONT_LEFT:
natt = NATIVE_ATTACHMENT_FRONT_LEFT;
break;
case ST_ATTACHMENT_BACK_LEFT:
natt = NATIVE_ATTACHMENT_BACK_LEFT;
break;
case ST_ATTACHMENT_FRONT_RIGHT:
natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
break;
case ST_ATTACHMENT_BACK_RIGHT:
natt = NATIVE_ATTACHMENT_BACK_RIGHT;
break;
default:
natt = -1;
break;
}

if (natt >= 0) {
tex = textures[natt];

if (statts[i] == stfbi->visual->render_buffer)
pipe_texture_reference(&gsurf->render_texture, tex);

if (attachment_mask & (1 << natt)) {
/* transfer the ownership to the caller */
out[i] = tex;
attachment_mask &= ~(1 << natt);
}
else {
/* the attachment is listed more than once */
pipe_texture_reference(&out[i], tex);
}
}
}

return TRUE;
}

struct st_framebuffer_iface *
egl_g3d_create_st_framebuffer(_EGLSurface *surf)
{
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
struct st_framebuffer_iface *stfbi;

stfbi = CALLOC_STRUCT(st_framebuffer_iface);
if (!stfbi)
return NULL;

stfbi->visual = &gsurf->stvis;
stfbi->flush_front = egl_g3d_st_framebuffer_flush_front;
stfbi->validate = egl_g3d_st_framebuffer_validate;
stfbi->st_manager_private = (void *) &gsurf->base;

return stfbi;
}

void
egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
{
free(stfbi);
}

src/gallium/state_trackers/egl/common/egl_st.h → src/gallium/state_trackers/egl/common/egl_g3d_st.h View File

@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
* Version: 7.8
* Version: 7.9
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -20,54 +20,60 @@
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/

#ifndef _EGL_ST_H_
#define _EGL_ST_H_

#include "GL/gl.h" /* for GL types */
#include "GL/internal/glcore.h" /* for __GLcontextModes */
#ifndef _EGL_G3D_ST_H_
#define _EGL_G3D_ST_H_

#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
#include "pipe/p_context.h"
#include "state_tracker/st_api.h"
#include "egltypedefs.h"

/* avoid calling st functions directly */
#if 1
struct st_api *
egl_g3d_create_st_api(enum st_api_type api);

#define ST_SURFACE_FRONT_LEFT 0
#define ST_SURFACE_BACK_LEFT 1
#define ST_SURFACE_FRONT_RIGHT 2
#define ST_SURFACE_BACK_RIGHT 3
struct st_manager *
egl_g3d_create_st_manager(_EGLDisplay *dpy);

#define ST_TEXTURE_2D 0x2
void
egl_g3d_destroy_st_manager(struct st_manager *smapi);

struct st_context;
struct st_framebuffer;
typedef void (*st_proc)();
struct st_framebuffer_iface *
egl_g3d_create_st_framebuffer(_EGLSurface *surf);

#else
#include "state_tracker/st_public.h"
#endif
void
egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);

/* remember to update egl_g3d_get_st() when update the enums */
enum egl_g3d_st_api {
EGL_G3D_ST_OPENGL_ES = 0,
EGL_G3D_ST_OPENVG,
EGL_G3D_ST_OPENGL_ES2,
EGL_G3D_ST_OPENGL,

NUM_EGL_G3D_STS
};
/**
* Return the EGL_<api>_BIT of the st api.
*/
static INLINE int
egl_g3d_st_api_bit(enum st_api_type api)
{
int bit;

struct egl_g3d_st {
#define ST_PUBLIC(name, ret, ...) ret (*name)(__VA_ARGS__);
#include "st_public_tmp.h"
/* fields must be added here */
EGLint api_bit;
};
switch (api) {
case ST_API_OPENGL:
bit = EGL_OPENGL_BIT;
break;
case ST_API_OPENGL_ES1:
bit = EGL_OPENGL_ES_BIT;
break;
case ST_API_OPENGL_ES2:
bit = EGL_OPENGL_ES2_BIT;
break;
case ST_API_OPENVG:
bit = EGL_OPENVG_BIT;
break;
default:
bit = 0;
break;
}

const struct egl_g3d_st *
egl_g3d_get_st(enum egl_g3d_st_api api);
return bit;
}

#endif /* _EGL_ST_H_ */
#endif /* _EGL_G3D_ST_H_ */

+ 0
- 131
src/gallium/state_trackers/egl/common/egl_st.c View File

@@ -1,131 +0,0 @@
/*
* Mesa 3-D graphics library
* Version: 7.8
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <dlfcn.h>
#include "pipe/p_compiler.h"
#include "util/u_memory.h"
#include "egllog.h"
#include "EGL/egl.h" /* for EGL_api_BIT */

#include "egl_st.h"

#ifndef HAVE_DLADDR
#define HAVE_DLADDR 1
#endif

#if HAVE_DLADDR

static const char *
egl_g3d_st_names[] = {
#define ST_PUBLIC(name, ...) #name,
#include "st_public_tmp.h"
NULL
};

static boolean
egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym)
{
st_proc *procs = (st_proc *) stapi;
void *handle;
Dl_info info;
const char **name;

if (!dladdr(sym, &info))
return FALSE;
handle = dlopen(info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE);
if (!handle)
return FALSE;

for (name = egl_g3d_st_names; *name; name++) {
st_proc proc = (st_proc) dlsym(handle, *name);
if (!proc) {
_eglLog(_EGL_WARNING, "%s is missing in %s", *name, info.dli_fname);
memset(stapi, 0, sizeof(*stapi));
dlclose(handle);
return FALSE;
}
*procs++ = proc;
}

dlclose(handle);
return TRUE;
}

#else /* HAVE_DLADDR */

static boolean
egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym)
{
#define ST_PUBLIC(name, ...) stapi->name = name;
#include "st_public_tmp.h"
return TRUE;
}

#endif /* HAVE_DLADDR */

static boolean
egl_g3d_init_st(struct egl_g3d_st *stapi, const char *api)
{
void *handle, *sym;
boolean res = FALSE;

/* already initialized */
if (stapi->st_notify_swapbuffers != NULL)
return TRUE;

handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL);
if (!handle)
return FALSE;

sym = dlsym(handle, api);
if (sym && egl_g3d_fill_st(stapi, sym))
res = TRUE;

dlclose(handle);
return res;
}

static struct {
const char *symbol;
EGLint api_bit;
} egl_g3d_st_info[NUM_EGL_G3D_STS] = {
{ "st_api_OpenGL_ES1", EGL_OPENGL_ES_BIT },
{ "st_api_OpenVG", EGL_OPENVG_BIT },
{ "st_api_OpenGL_ES2", EGL_OPENGL_ES2_BIT },
{ "st_api_OpenGL", EGL_OPENGL_BIT },
};

const struct egl_g3d_st *
egl_g3d_get_st(enum egl_g3d_st_api api)
{
static struct egl_g3d_st all_trackers[NUM_EGL_G3D_STS];

if (egl_g3d_init_st(&all_trackers[api], egl_g3d_st_info[api].symbol)) {
all_trackers[api].api_bit = egl_g3d_st_info[api].api_bit;
return &all_trackers[api];
}
else {
return NULL;
}
}

+ 0
- 20
src/gallium/state_trackers/egl/common/st_public_tmp.h View File

@@ -1,20 +0,0 @@
ST_PUBLIC(st_create_context, struct st_context *, struct pipe_context *pipe, const __GLcontextModes *visual, struct st_context *share)
ST_PUBLIC(st_destroy_context, void, struct st_context *st)
ST_PUBLIC(st_copy_context_state, void, struct st_context *dst, struct st_context *src, uint mask)
ST_PUBLIC(st_create_framebuffer, struct st_framebuffer *, const __GLcontextModes *visual, enum pipe_format colorFormat, enum pipe_format depthFormat, enum pipe_format stencilFormat, uint width, uint height, void *privateData)
ST_PUBLIC(st_resize_framebuffer, void, struct st_framebuffer *stfb, uint width, uint height)
ST_PUBLIC(st_set_framebuffer_surface, void, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface *surf)
ST_PUBLIC(st_get_framebuffer_dimensions, void, struct st_framebuffer *stfb, uint *width, uint *height)
ST_PUBLIC(st_get_framebuffer_surface, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface **surface)
ST_PUBLIC(st_get_framebuffer_texture, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_texture **texture)
ST_PUBLIC(st_framebuffer_private, void *, struct st_framebuffer *stfb)
ST_PUBLIC(st_unreference_framebuffer, void, struct st_framebuffer *stfb)
ST_PUBLIC(st_make_current, GLboolean, struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read, void *winsys_drawable_handle)
ST_PUBLIC(st_get_current, struct st_context *, void)
ST_PUBLIC(st_flush, void, struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence)
ST_PUBLIC(st_finish, void, struct st_context *st)
ST_PUBLIC(st_notify_swapbuffers, void, struct st_framebuffer *stfb)
ST_PUBLIC(st_bind_texture_surface, int, struct pipe_surface *ps, int target, int level, enum pipe_format format)
ST_PUBLIC(st_unbind_texture_surface, int, struct pipe_surface *ps, int target, int level)
ST_PUBLIC(st_get_proc_address, st_proc, const char *procname)
#undef ST_PUBLIC

+ 1
- 0
src/gallium/state_trackers/es/Makefile View File

@@ -38,6 +38,7 @@ SYS_LIBS = -lm -pthread


INCLUDE_DIRS = \
-I$(TOP)/src/mesa \
-I$(TOP)/src/gallium/include

.c.o:

+ 6
- 1
src/gallium/state_trackers/es/st_es1.c View File

@@ -1,3 +1,8 @@
#include "pipe/p_compiler.h"
#include "state_tracker/st_manager.h"

PUBLIC const int st_api_OpenGL_ES1 = 1;

PUBLIC const struct st_module st_module_OpenGL_ES1 = {
.api = ST_API_OPENGL_ES1,
.create_api = st_manager_create_api
};

+ 6
- 1
src/gallium/state_trackers/es/st_es2.c View File

@@ -1,3 +1,8 @@
#include "pipe/p_compiler.h"
#include "state_tracker/st_manager.h"

PUBLIC const int st_api_OpenGL_ES2 = 1;

PUBLIC const struct st_module st_module_OpenGL_ES2 = {
.api = ST_API_OPENGL_ES2,
.create_api = st_manager_create_api
};

+ 2
- 1
src/gallium/state_trackers/glx/xlib/Makefile View File

@@ -12,6 +12,7 @@ C_SOURCES = \
glx_api.c \
glx_getproc.c \
glx_usefont.c \
xm_api.c
xm_api.c \
xm_st.c

include ../../../Makefile.template

+ 1
- 0
src/gallium/state_trackers/glx/xlib/SConscript View File

@@ -20,6 +20,7 @@ if env['platform'] == 'linux' \
'glx_getproc.c',
'glx_usefont.c',
'xm_api.c',
'xm_st.c',
]
)
Export('st_xlib')

+ 1
- 4
src/gallium/state_trackers/glx/xlib/glx_api.c View File

@@ -35,12 +35,9 @@

#include "xm_api.h"
#include "main/context.h"
#include "main/config.h"
#include "main/macros.h"
#include "main/imports.h"
#include "main/version.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"


/* This indicates the client-side GLX API and GLX encoder version. */
@@ -1304,7 +1301,7 @@ glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
if (MakeCurrent_PrevContext == src) {
_mesa_Flush();
}
st_copy_context_state( xm_src->st, xm_dst->st, (GLuint) mask );
XMesaCopyContext(xm_src, xm_dst, mask);
}



+ 161
- 155
src/gallium/state_trackers/glx/xlib/xm_api.c View File

@@ -54,11 +54,9 @@
#endif

#include "xm_api.h"
#include "main/context.h"
#include "main/framebuffer.h"
#include "xm_st.h"

#include "state_tracker/st_public.h"
#include "state_tracker/st_context.h"
#include "main/context.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
@@ -72,19 +70,56 @@
* global.
*/
static struct xm_driver driver;
static struct st_api *stapi;

void xmesa_set_driver( const struct xm_driver *templ )
{
driver = *templ;
stapi = driver.create_st_api();
}

/**
* Global X driver lock
*/
pipe_mutex _xmesa_lock;
static XMesaDisplay
xmesa_init_display( Display *display )
{
pipe_static_mutex(init_mutex);
static struct xmesa_display xm_display;
XMesaDisplay xmdpy;
pipe_mutex_lock(init_mutex);

/* TODO support for multiple displays */
xmdpy = &xm_display;

if (!xmdpy->display && display) {
xmdpy->display = display;
xmdpy->screen = driver.create_pipe_screen(display);
xmdpy->smapi = CALLOC_STRUCT(st_manager);
if (xmdpy->smapi)
xmdpy->smapi->screen = xmdpy->screen;

if (xmdpy->screen && xmdpy->smapi) {
pipe_mutex_init(xmdpy->mutex);
}
else {
if (xmdpy->screen) {
xmdpy->screen->destroy(xmdpy->screen);
xmdpy->screen = NULL;
}
if (xmdpy->smapi) {
FREE(xmdpy->smapi);
xmdpy->smapi = NULL;
}

static struct pipe_screen *screen = NULL;
xmdpy->display = NULL;
}
}
if (!xmdpy->display || xmdpy->display != display)
xmdpy = NULL;

pipe_mutex_unlock(init_mutex);

return xmdpy;
}

/**********************************************************************/
/***** X Utility Functions *****/
@@ -194,12 +229,13 @@ void
xmesa_get_window_size(Display *dpy, XMesaBuffer b,
GLuint *width, GLuint *height)
{
XMesaDisplay xmdpy = xmesa_init_display(dpy);
Status stat;

pipe_mutex_lock(_xmesa_lock);
pipe_mutex_lock(xmdpy->mutex);
XSync(b->xm_visual->display, 0); /* added for Chromium */
stat = get_drawable_size(dpy, b->ws.drawable, width, height);
pipe_mutex_unlock(_xmesa_lock);
pipe_mutex_unlock(xmdpy->mutex);

if (!stat) {
/* probably querying a window that's recently been destroyed */
@@ -273,49 +309,43 @@ choose_pixel_format(XMesaVisual v)
return 0;
}



/**
* Query the default gallium screen for a Z/Stencil format that
* at least matches the given depthBits and stencilBits.
* Choose a depth/stencil format that is "better" than the given depth and
* stencil sizes.
*/
static void
xmesa_choose_z_stencil_format(int depthBits, int stencilBits,
enum pipe_format *depthFormat,
enum pipe_format *stencilFormat)
static enum pipe_format
choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil)
{
const enum pipe_texture_target target = PIPE_TEXTURE_2D;
const unsigned tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE |
PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO);
static enum pipe_format formats[] = {
PIPE_FORMAT_S8Z24_UNORM,
PIPE_FORMAT_Z24S8_UNORM,
PIPE_FORMAT_Z16_UNORM,
PIPE_FORMAT_Z32_UNORM
};
int i;
enum pipe_format formats[8], fmt;
int count, i;

assert(screen);
count = 0;
if (depth <= 24 && stencil <= 8) {
formats[count++] = PIPE_FORMAT_S8Z24_UNORM;
formats[count++] = PIPE_FORMAT_Z24S8_UNORM;
}

*depthFormat = *stencilFormat = PIPE_FORMAT_NONE;
if (!stencil) {
if (depth <= 16)
formats[count++] = PIPE_FORMAT_Z16_UNORM;
if (depth <= 32)
formats[count++] = PIPE_FORMAT_Z32_UNORM;
}

/* search for supported format */
for (i = 0; i < Elements(formats); i++) {
if (screen->is_format_supported(screen, formats[i],
fmt = PIPE_FORMAT_NONE;
for (i = 0; i < count; i++) {
if (xmdpy->screen->is_format_supported(xmdpy->screen, formats[i],
target, tex_usage, geom_flags)) {
*depthFormat = formats[i];
fmt = formats[i];
break;
}
}

if (stencilBits) {
*stencilFormat = *depthFormat;
}

/* XXX we should check that he chosen format has at least as many bits
* as what was requested.
*/
return fmt;
}


@@ -324,7 +354,7 @@ xmesa_choose_z_stencil_format(int depthBits, int stencilBits,
/***** Linked list of XMesaBuffers *****/
/**********************************************************************/

XMesaBuffer XMesaBufferList = NULL;
static XMesaBuffer XMesaBufferList = NULL;


/**
@@ -342,13 +372,15 @@ static XMesaBuffer
create_xmesa_buffer(Drawable d, BufferType type,
XMesaVisual vis, Colormap cmap)
{
XMesaDisplay xmdpy = xmesa_init_display(vis->display);
XMesaBuffer b;
GLframebuffer *fb;
enum pipe_format colorFormat, depthFormat, stencilFormat;
uint width, height;

ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);

if (!xmdpy)
return NULL;

b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
if (!b)
return NULL;
@@ -361,24 +393,12 @@ create_xmesa_buffer(Drawable d, BufferType type,
b->type = type;
b->cmap = cmap;

/* determine PIPE_FORMATs for buffers */
colorFormat = choose_pixel_format(vis);

xmesa_choose_z_stencil_format(vis->mesa_visual.depthBits,
vis->mesa_visual.stencilBits,
&depthFormat, &stencilFormat);


get_drawable_size(vis->display, d, &width, &height);

/*
* Create framebuffer, but we'll plug in our own renderbuffers below.
*/
b->stfb = st_create_framebuffer(&vis->mesa_visual,
colorFormat, depthFormat, stencilFormat,
width, height,
(void *) b);
fb = &b->stfb->Base;
b->stfb = xmesa_create_st_framebuffer(xmdpy, b);

/* GLX_EXT_texture_from_pixmap */
b->TextureTarget = 0;
@@ -422,24 +442,21 @@ xmesa_free_buffer(XMesaBuffer buffer)

for (b = XMesaBufferList; b; b = b->Next) {
if (b == buffer) {
struct gl_framebuffer *fb = &buffer->stfb->Base;

/* unlink buffer from list */
if (prev)
prev->Next = buffer->Next;
else
XMesaBufferList = buffer->Next;

/* mark as delete pending */
fb->DeletePending = GL_TRUE;

/* Since the X window for the XMesaBuffer is going away, we don't
* want to dereference this pointer in the future.
*/
b->ws.drawable = 0;

/* Unreference. If count = zero we'll really delete the buffer */
_mesa_reference_framebuffer(&fb, NULL);
/* XXX we should move the buffer to a delete-pending list and destroy
* the buffer until it is no longer current.
*/
xmesa_destroy_st_framebuffer(buffer->stfb);

free(buffer);

@@ -596,10 +613,12 @@ XMesaVisual XMesaCreateVisual( Display *display,
GLint level,
GLint visualCaveat )
{
XMesaDisplay xmdpy = xmesa_init_display(display);
XMesaVisual v;
GLint red_bits, green_bits, blue_bits, alpha_bits;

xmesa_init( display );
if (!xmdpy)
return NULL;

/* For debugging only */
if (_mesa_getenv("MESA_XSYNC")) {
@@ -681,6 +700,26 @@ XMesaVisual XMesaCreateVisual( Display *display,
accum_blue_size, accum_alpha_size,
0 );

v->stvis.buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK;
if (db_flag)
v->stvis.buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
if (stereo_flag) {
v->stvis.buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
if (db_flag)
v->stvis.buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
}

v->stvis.color_format = choose_pixel_format(v);
v->stvis.depth_stencil_format =
choose_depth_stencil_format(xmdpy, depth_size, stencil_size);

v->stvis.accum_format = (accum_red_size +
accum_green_size + accum_blue_size + accum_alpha_size) ?
PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;

v->stvis.samples = num_samples;
v->stvis.render_buffer = ST_ATTACHMENT_INVALID;

/* XXX minor hack */
v->mesa_visual.level = level;
return v;
@@ -696,17 +735,12 @@ void XMesaDestroyVisual( XMesaVisual v )


/**
* Do one-time initializations.
* Do per-display initializations.
*/
void
xmesa_init( Display *display )
{
static GLboolean firstTime = GL_TRUE;
if (firstTime) {
pipe_mutex_init(_xmesa_lock);
screen = driver.create_pipe_screen( display );
firstTime = GL_FALSE;
}
xmesa_init_display(display);
}


@@ -720,51 +754,33 @@ xmesa_init( Display *display )
PUBLIC
XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
{
struct pipe_context *pipe = NULL;
XMesaDisplay xmdpy = xmesa_init_display(v->display);
XMesaContext c;
GLcontext *mesaCtx;
uint pf;

xmesa_init( v->display );
if (!xmdpy)
return NULL;

/* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */
c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
if (!c)
return NULL;

pf = choose_pixel_format(v);
assert(pf);

c->xm_visual = v;
c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */
c->xm_read_buffer = NULL;

if (screen == NULL)
goto fail;

/* Trace screen knows how to properly wrap context creation in the
* wrapped screen, so nothing special to do here:
*/
pipe = screen->context_create(screen, (void *) c);
if (pipe == NULL)
goto fail;

c->st = st_create_context(pipe,
&v->mesa_visual,
share_list ? share_list->st : NULL);
c->st = stapi->create_context(stapi, xmdpy->smapi,
&v->stvis, (share_list) ? share_list->st : NULL);
if (c->st == NULL)
goto fail;

mesaCtx = c->st->ctx;
c->st->ctx->DriverCtx = c;
c->st->st_manager_private = (void *) c;

return c;

fail:
if (c->st)
st_destroy_context(c->st);
else if (pipe)
pipe->destroy(pipe);
c->st->destroy(c->st);

free(c);
return NULL;
@@ -775,7 +791,7 @@ fail:
PUBLIC
void XMesaDestroyContext( XMesaContext c )
{
st_destroy_context(c->st);
c->st->destroy(c->st);

/* FIXME: We should destroy the screen here, but if we do so, surfaces may
* outlive it, causing segfaults
@@ -881,7 +897,6 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
{
GET_CURRENT_CONTEXT(ctx);
XMesaBuffer b;
GLuint width, height;

assert(v);

@@ -889,19 +904,18 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
if (!b)
return NULL;

/* get pixmap size, update framebuffer/renderbuffer dims */
xmesa_get_window_size(v->display, b, &width, &height);
_mesa_resize_framebuffer(NULL, &(b->stfb->Base), width, height);
/* get pixmap size */
xmesa_get_window_size(v->display, b, &b->width, &b->height);

if (target == 0) {
/* examine dims */
if (ctx->Extensions.ARB_texture_non_power_of_two) {
target = GLX_TEXTURE_2D_EXT;
}
else if ( _mesa_bitcount(width) == 1
&& _mesa_bitcount(height) == 1) {
else if ( _mesa_bitcount(b->width) == 1
&& _mesa_bitcount(b->height) == 1) {
/* power of two size */
if (height == 1) {
if (b->height == 1) {
target = GLX_TEXTURE_1D_EXT;
}
else {
@@ -974,23 +988,20 @@ XMesaDestroyBuffer(XMesaBuffer b)


/**
* Query the current window size and update the corresponding GLframebuffer
* and all attached renderbuffers.
* Called when:
* 1. the first time a buffer is bound to a context.
* 2. SwapBuffers. XXX probabaly from xm_flush_frontbuffer() too...
* Note: it's possible (and legal) for xmctx to be NULL. That can happen
* when resizing a buffer when no rendering context is bound.
* Query the current drawable size and notify the binding context.
*/
void
xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
xmesa_check_buffer_size(XMesaBuffer b)
{
GLuint width, height;
xmesa_get_window_size(drawBuffer->xm_visual->display, drawBuffer, &width, &height);
st_resize_framebuffer(drawBuffer->stfb, width, height);
}
XMesaContext xmctx = XMesaGetCurrentContext();

if (b->type == PBUFFER)
return;

xmesa_get_window_size(b->xm_visual->display, b, &b->width, &b->height);
if (xmctx && xmctx->xm_buffer == b)
xmctx->st->notify_invalid_framebuffer(xmctx->st, b->stfb);
}


/*
@@ -1017,22 +1028,21 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
c->xm_read_buffer == readBuffer)
return GL_TRUE;

xmesa_check_buffer_size(drawBuffer);
if (readBuffer != drawBuffer)
xmesa_check_buffer_size(readBuffer);

c->xm_buffer = drawBuffer;
c->xm_read_buffer = readBuffer;

st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb,
&drawBuffer->ws);

xmesa_check_and_update_buffer_size(c, drawBuffer);
if (readBuffer != drawBuffer)
xmesa_check_and_update_buffer_size(c, readBuffer);
stapi->make_current(stapi, c->st, drawBuffer->stfb, readBuffer->stfb);

/* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */
drawBuffer->wasCurrent = GL_TRUE;
}
else {
/* Detach */
st_make_current( NULL, NULL, NULL, NULL );
stapi->make_current(stapi, NULL, NULL, NULL);

}
return GL_TRUE;
@@ -1051,14 +1061,8 @@ GLboolean XMesaUnbindContext( XMesaContext c )

XMesaContext XMesaGetCurrentContext( void )
{
GET_CURRENT_CONTEXT(ctx);
if (ctx) {
XMesaContext xmesa = xmesa_context(ctx);
return xmesa;
}
else {
return 0;
}
struct st_context_iface *st = stapi->get_current(stapi);
return (XMesaContext) (st) ? st->st_manager_private : NULL;
}


@@ -1070,17 +1074,17 @@ XMesaContext XMesaGetCurrentContext( void )
PUBLIC
void XMesaSwapBuffers( XMesaBuffer b )
{
struct pipe_surface *frontLeftSurf;
st_swapbuffers(b->stfb, &frontLeftSurf, NULL);
if (frontLeftSurf) {
screen->flush_frontbuffer( screen,
frontLeftSurf,
&b->ws );
XMesaContext xmctx = XMesaGetCurrentContext();
if (xmctx && xmctx->xm_buffer == b) {
xmctx->st->flush( xmctx->st,
PIPE_FLUSH_RENDER_CACHE |
PIPE_FLUSH_SWAPBUFFERS |
PIPE_FLUSH_FRAME,
NULL);
}

xmesa_check_and_update_buffer_size(NULL, b);
xmesa_swap_st_framebuffer(b->stfb);
}


@@ -1090,21 +1094,9 @@ void XMesaSwapBuffers( XMesaBuffer b )
*/
void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
{
struct pipe_surface *surf_front;
struct pipe_surface *surf_back;
struct pipe_context *pipe = NULL; /* XXX fix */

st_get_framebuffer_surface(b->stfb, ST_SURFACE_FRONT_LEFT, &surf_front);
st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT, &surf_back);

if (!surf_front || !surf_back)
return;

assert(pipe);
pipe->surface_copy(pipe,
surf_front, x, y, /* dest */
surf_back, x, y, /* src */
width, height);
xmesa_copy_st_framebuffer(b->stfb,
ST_ATTACHMENT_BACK_LEFT, ST_ATTACHMENT_FRONT_LEFT,
x, y, width, height);
}


@@ -1112,7 +1104,14 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
void XMesaFlush( XMesaContext c )
{
if (c && c->xm_visual->display) {
st_finish(c->st);
XMesaDisplay xmdpy = xmesa_init_display(c->xm_visual->display);
struct pipe_fence_handle *fence = NULL;

c->st->flush(c->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence);
if (fence) {
xmdpy->screen->fence_finish(xmdpy->screen, fence, 0);
xmdpy->screen->fence_reference(xmdpy->screen, &fence, NULL);
}
XSync( c->xm_visual->display, False );
}
}
@@ -1186,3 +1185,10 @@ XMesaReleaseTexImage(Display *dpy, XMesaBuffer drawable, int buffer)
{
}


void
XMesaCopyContext(XMesaContext src, XMesaContext dst, unsigned long mask)
{
if (dst->st->copy)
dst->st->copy(dst->st, src->st, mask);
}

+ 23
- 32
src/gallium/state_trackers/glx/xlib/xm_api.h View File

@@ -58,8 +58,7 @@ and create a window, you must do the following to use the X/Mesa interface:


#include "main/mtypes.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
#include "state_tracker/st_api.h"
#include "os/os_thread.h"

#include "state_tracker/xlib_sw_winsys.h"
@@ -68,11 +67,22 @@ and create a window, you must do the following to use the X/Mesa interface:
# include <X11/Xlibint.h>
# include <X11/Xutil.h>

typedef struct xmesa_display *XMesaDisplay;
typedef struct xmesa_buffer *XMesaBuffer;
typedef struct xmesa_context *XMesaContext;
typedef struct xmesa_visual *XMesaVisual;


struct xmesa_display {
pipe_mutex mutex;

Display *display;
struct pipe_screen *screen;
struct st_manager *smapi;

struct pipe_context *pipe;
};


/*
* Create a new X/Mesa visual.
@@ -258,16 +268,13 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
int format, int target, int mipmap);


extern void
XMesaCopyContext(XMesaContext src, XMesaContext dst, unsigned long mask);


/***********************************************************************
*/

extern pipe_mutex _xmesa_lock;

extern struct xmesa_buffer *XMesaBufferList;


/**
* Visual inforation, derived from GLvisual.
* Basically corresponds to an XVisualInfo.
@@ -280,6 +287,8 @@ struct xmesa_visual {
GLint BitsPerPixel; /* True bits per pixel for XImages */

GLboolean ximage_flag; /* Use XImage for back buffer (not pixmap)? */

struct st_visual stvis;
};


@@ -288,7 +297,7 @@ struct xmesa_visual {
* Basically corresponds to a GLXContext.
*/
struct xmesa_context {
struct st_context *st;
struct st_context_iface *st;
XMesaVisual xm_visual; /** pixel format info */
XMesaBuffer xm_buffer; /** current drawbuffer */
XMesaBuffer xm_read_buffer; /** current readbuffer */
@@ -311,7 +320,7 @@ typedef enum {
* Basically corresponds to a GLXDrawable.
*/
struct xmesa_buffer {
struct st_framebuffer *stfb;
struct st_framebuffer_iface *stfb;
struct xlib_drawable ws;

GLboolean wasCurrent; /* was ever the current buffer? */
@@ -335,33 +344,15 @@ struct xmesa_buffer {
GLint TextureMipmap; /** 0 or 1 */

struct xmesa_buffer *Next; /* Linked list pointer: */
};



/** cast wrapper */
static INLINE XMesaContext
xmesa_context(GLcontext *ctx)
{
return (XMesaContext) ctx->DriverCtx;
}

unsigned width, height;
};

/** cast wrapper */
static INLINE XMesaBuffer
xmesa_buffer(GLframebuffer *fb)
{
struct st_framebuffer *stfb = (struct st_framebuffer *) fb;
return (XMesaBuffer) st_framebuffer_private(stfb);
}


extern void
xmesa_init(Display *dpy);

extern void
xmesa_delete_framebuffer(struct gl_framebuffer *fb);

extern XMesaBuffer
xmesa_find_buffer(Display *dpy, Colormap cmap, XMesaBuffer notThis);

@@ -370,7 +361,7 @@ xmesa_get_window_size(Display *dpy, XMesaBuffer b,
GLuint *width, GLuint *height);

extern void
xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer);
xmesa_check_buffer_size(XMesaBuffer b);

extern void
xmesa_destroy_buffers_on_display(Display *dpy);
@@ -378,13 +369,13 @@ xmesa_destroy_buffers_on_display(Display *dpy);
static INLINE GLuint
xmesa_buffer_width(XMesaBuffer b)
{
return b->stfb->Base.Width;
return b->width;
}

static INLINE GLuint
xmesa_buffer_height(XMesaBuffer b)
{
return b->stfb->Base.Height;
return b->height;
}



+ 8
- 4
src/gallium/state_trackers/glx/xlib/xm_public.h View File

@@ -26,19 +26,23 @@
*
**************************************************************************/

#ifndef XM_WINSYS_H
#define XM_WINSYS_H
#ifndef XM_PUBLIC_H
#define XM_PUBLIC_H

struct xm_driver;
#include <X11/Xlib.h>

struct pipe_screen;
struct st_api;

/* This is the driver interface required by the glx/xlib state tracker.
*/
struct xm_driver {
struct pipe_screen *(*create_pipe_screen)( Display *display );
struct st_api *(*create_st_api)( void );
};

extern void
xmesa_set_driver( const struct xm_driver *driver );


#endif
#endif /* XM_PUBLIC_H */

+ 332
- 0
src/gallium/state_trackers/glx/xlib/xm_st.c View File

@@ -0,0 +1,332 @@
/*
* Mesa 3-D graphics library
* Version: 7.9
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/

#include "util/u_memory.h"
#include "util/u_inlines.h"

#include "xm_api.h"
#include "xm_st.h"

struct xmesa_st_framebuffer {
XMesaDisplay display;
XMesaBuffer buffer;
struct pipe_screen *screen;

struct st_visual stvis;

unsigned texture_width, texture_height, texture_mask;
struct pipe_texture *textures[ST_ATTACHMENT_COUNT];

struct pipe_surface *display_surface;
};

static INLINE struct xmesa_st_framebuffer *
xmesa_st_framebuffer(struct st_framebuffer_iface *stfbi)
{
return (struct xmesa_st_framebuffer *) stfbi->st_manager_private;
}

/**
* Display an attachment to the xlib_drawable of the framebuffer.
*/
static boolean
xmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi,
enum st_attachment_type statt)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
struct pipe_texture *ptex = xstfb->textures[statt];
struct pipe_surface *psurf;

if (!ptex)
return TRUE;

psurf = xstfb->display_surface;
/* (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_BUFFER_USAGE_CPU_READ);
if (!psurf)
return FALSE;

xstfb->display_surface = psurf;
}

xstfb->screen->flush_frontbuffer(xstfb->screen, psurf, &xstfb->buffer->ws);

return TRUE;
}

/**
* Copy the contents between the attachments.
*/
static void
xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi,
enum st_attachment_type src_statt,
enum st_attachment_type dst_statt,
unsigned x, unsigned y,
unsigned width, unsigned height)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
struct pipe_texture *src_ptex = xstfb->textures[src_statt];
struct pipe_texture *dst_ptex = xstfb->textures[dst_statt];
struct pipe_surface *src, *dst;
struct pipe_context *pipe;

if (!src_ptex || !dst_ptex)
return;

pipe = xstfb->display->pipe;
if (!pipe) {
pipe = xstfb->screen->context_create(xstfb->screen, NULL);
if (!pipe)
return;
xstfb->display->pipe = pipe;
}

src = xstfb->screen->get_tex_surface(xstfb->screen,
src_ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ);
dst = xstfb->screen->get_tex_surface(xstfb->screen,
dst_ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);

if (src && dst)
pipe->surface_copy(pipe, dst, x, y, src, x, y, width, height);

pipe_surface_reference(&src, NULL);
pipe_surface_reference(&dst, NULL);
}

/**
* Remove outdated textures and create the requested ones.
*/
static void
xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
unsigned width, unsigned height,
unsigned mask)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
struct pipe_texture templ;
unsigned i;

/* remove outdated textures */
if (xstfb->texture_width != width || xstfb->texture_height != height) {
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_texture_reference(&xstfb->textures[i], NULL);
}

memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
templ.last_level = 0;

for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
enum pipe_format format;
unsigned tex_usage;

/* the texture already exists or not requested */
if (xstfb->textures[i] || !(mask & (1 << i))) {
/* remember the texture */
if (xstfb->textures[i])
mask |= (1 << i);
continue;
}

switch (i) {
case ST_ATTACHMENT_FRONT_LEFT:
case ST_ATTACHMENT_BACK_LEFT:
case ST_ATTACHMENT_FRONT_RIGHT:
case ST_ATTACHMENT_BACK_RIGHT:
format = xstfb->stvis.color_format;
tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_RENDER_TARGET;
break;
case ST_ATTACHMENT_DEPTH_STENCIL:
format = xstfb->stvis.depth_stencil_format;
tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
break;
default:
format = PIPE_FORMAT_NONE;
break;
}

if (format != PIPE_FORMAT_NONE) {
templ.format = format;
templ.tex_usage = tex_usage;

xstfb->textures[i] =
xstfb->screen->texture_create(xstfb->screen, &templ);
}
}

xstfb->texture_width = width;
xstfb->texture_height = height;
xstfb->texture_mask = mask;
}

static boolean
xmesa_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
const enum st_attachment_type *statts,
unsigned count,
struct pipe_texture **out)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
unsigned statt_mask, new_mask, i;
boolean resized;

statt_mask = 0x0;
for (i = 0; i < count; i++)
statt_mask |= 1 << statts[i];
/* record newly allocated textures */
new_mask = statt_mask & ~xstfb->texture_mask;

resized = (xstfb->buffer->width != xstfb->texture_width ||
xstfb->buffer->height != xstfb->texture_height);

/* revalidate textures */
if (resized || new_mask) {
xmesa_st_framebuffer_validate_textures(stfbi,
xstfb->buffer->width, xstfb->buffer->height, statt_mask);

if (!resized) {
enum st_attachment_type back, front;

back = ST_ATTACHMENT_BACK_LEFT;
front = ST_ATTACHMENT_FRONT_LEFT;
/* copy the contents if front is newly allocated and back is not */
if ((statt_mask & (1 << back)) &&
(new_mask & (1 << front)) &&
!(new_mask & (1 << back))) {
xmesa_st_framebuffer_copy_textures(stfbi, back, front,
0, 0, xstfb->texture_width, xstfb->texture_height);
}
}
}

for (i = 0; i < count; i++) {
out[i] = NULL;
pipe_texture_reference(&out[i], xstfb->textures[statts[i]]);
}

return TRUE;
}

static boolean
xmesa_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
enum st_attachment_type statt)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
boolean ret;

ret = xmesa_st_framebuffer_display(stfbi, statt);
if (ret)
xmesa_check_buffer_size(xstfb->buffer);

return ret;
}

struct st_framebuffer_iface *
xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b)
{
struct st_framebuffer_iface *stfbi;
struct xmesa_st_framebuffer *xstfb;

assert(xmdpy->display == b->xm_visual->display);

stfbi = CALLOC_STRUCT(st_framebuffer_iface);
xstfb = CALLOC_STRUCT(xmesa_st_framebuffer);
if (!stfbi || !xstfb) {
if (stfbi)
FREE(stfbi);
if (xstfb)
FREE(xstfb);
return NULL;
}

xstfb->display = xmdpy;
xstfb->buffer = b;
xstfb->screen = xmdpy->screen;
xstfb->stvis = b->xm_visual->stvis;

stfbi->visual = &xstfb->stvis;
stfbi->flush_front = xmesa_st_framebuffer_flush_front;
stfbi->validate = xmesa_st_framebuffer_validate;
stfbi->st_manager_private = (void *) xstfb;

return stfbi;
}

void
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);

for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_texture_reference(&xstfb->textures[i], NULL);

FREE(xstfb);
FREE(stfbi);
}

void
xmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
boolean ret;

ret = xmesa_st_framebuffer_display(stfbi, ST_ATTACHMENT_BACK_LEFT);
if (ret) {
struct pipe_texture **front, **back, *tmp;

front = &xstfb->textures[ST_ATTACHMENT_FRONT_LEFT];
back = &xstfb->textures[ST_ATTACHMENT_BACK_LEFT];
/* swap textures only if the front texture has been allocated */
if (*front) {
tmp = *front;
*front = *back;
*back = tmp;
}

xmesa_check_buffer_size(xstfb->buffer);
}
}

void
xmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi,
enum st_attachment_type src,
enum st_attachment_type dst,
int x, int y, int w, int h)
{
xmesa_st_framebuffer_copy_textures(stfbi, src, dst, x, y, w, h);
if (dst == ST_ATTACHMENT_FRONT_LEFT)
xmesa_st_framebuffer_display(stfbi, dst);
}

+ 51
- 0
src/gallium/state_trackers/glx/xlib/xm_st.h View File

@@ -0,0 +1,51 @@
/*
* Mesa 3-D graphics library
* Version: 7.9
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/

#ifndef _XM_ST_H_
#define _XM_ST_H_

#include "pipe/p_compiler.h"
#include "state_tracker/st_api.h"

#include "xm_api.h"

struct st_framebuffer_iface *
xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b);

void
xmesa_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);

void
xmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi);

void
xmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi,
enum st_attachment_type src,
enum st_attachment_type dst,
int x, int y, int w, int h);

#endif /* _XM_ST_H_ */

+ 1
- 0
src/gallium/state_trackers/vega/Makefile View File

@@ -25,6 +25,7 @@ VG_SOURCES = \
api_transform.c \
vgu.c \
vg_context.c \
vg_manager.c \
vg_state.c \
vg_tracker.c \
vg_translate.c \

+ 3
- 0
src/gallium/state_trackers/vega/api_context.c View File

@@ -26,6 +26,7 @@

#include "VG/openvg.h"

#include "vg_manager.h"
#include "vg_context.h"

#include "pipe/p_context.h"
@@ -55,6 +56,8 @@ void vgFlush(void)

pipe = ctx->pipe;
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);

vg_manager_flush_frontbuffer(ctx);
}

void vgFinish(void)

+ 0
- 4
src/gallium/state_trackers/vega/api_masks.c View File

@@ -118,10 +118,6 @@ clear_with_quad(struct vg_context *st, float x0, float y0,
x1, y1);
*/

if (st->pipe->screen && st->pipe->screen->update_buffer)
st->pipe->screen->update_buffer( st->pipe->screen,
st->pipe->priv );

cso_save_blend(st->cso_context);
cso_save_rasterizer(st->cso_context);
cso_save_fragment_shader(st->cso_context);

+ 3
- 0
src/gallium/state_trackers/vega/vg_context.c View File

@@ -32,6 +32,7 @@
#include "shader.h"
#include "asm_util.h"
#include "st_inlines.h"
#include "vg_manager.h"

#include "pipe/p_context.h"
#include "util/u_inlines.h"
@@ -305,6 +306,8 @@ static void update_clip_state(struct vg_context *ctx)

void vg_validate_state(struct vg_context *ctx)
{
vg_manager_validate_framebuffer(ctx);

if ((ctx->state.dirty & BLEND_DIRTY)) {
struct pipe_blend_state *blend = &ctx->state.g3d.blend;
memset(blend, 0, sizeof(struct pipe_blend_state));

+ 7
- 0
src/gallium/state_trackers/vega/vg_context.h View File

@@ -33,6 +33,7 @@
#include "pipe/p_state.h"
#include "util/u_pointer.h"
#include "util/u_math.h"
#include "state_tracker/st_api.h"

#include "cso_cache/cso_hash.h"
#include "cso_cache/cso_context.h"
@@ -58,6 +59,9 @@ struct st_framebuffer {

struct pipe_resource *blend_texture;

struct st_framebuffer_iface *iface;
enum st_attachment_type strb_att;

void *privateData;
};

@@ -84,6 +88,8 @@ enum dirty_state {

struct vg_context
{
struct st_context_iface iface;

struct pipe_context *pipe;

struct {
@@ -101,6 +107,7 @@ struct vg_context
VGErrorCode _error;

struct st_framebuffer *draw_buffer;
int32_t draw_buffer_invalid;

struct cso_hash *owned_objects[VG_OBJECT_LAST];


+ 373
- 0
src/gallium/state_trackers/vega/vg_manager.c View File

@@ -0,0 +1,373 @@
/*
* Mesa 3-D graphics library
* Version: 7.9
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/

#include "state_tracker/st_api.h"

#include "pipe/p_context.h"
#include "pipe/p_screen.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"

#include "vg_manager.h"
#include "vg_context.h"
#include "vg_tracker.h" /* for st_resize_framebuffer */
#include "image.h"

/**
* Flush the front buffer if the current context renders to the front buffer.
*/
void
vg_manager_flush_frontbuffer(struct vg_context *ctx)
{
struct st_framebuffer *stfb = ctx->draw_buffer;

if (!stfb)
return;

/* st_public.h is used */
if (!stfb->iface) {
struct pipe_screen *screen = ctx->pipe->screen;
if (screen->flush_frontbuffer) {
screen->flush_frontbuffer(screen,
stfb->strb->surface, ctx->pipe->priv);
}
return;
}

switch (stfb->strb_att) {
case ST_ATTACHMENT_FRONT_LEFT:
case ST_ATTACHMENT_FRONT_RIGHT:
stfb->iface->flush_front(stfb->iface, stfb->strb_att);
break;
default:
break;
}
}

/**
* Re-validate the framebuffer.
*/
void
vg_manager_validate_framebuffer(struct vg_context *ctx)
{
struct pipe_screen *screen = ctx->pipe->screen;
struct st_framebuffer *stfb = ctx->draw_buffer;
struct st_renderbuffer *rb;
struct pipe_texture *pt;

/* no binding surface */
if (!stfb)
return;

/* st_public.h is used */
if (!stfb->iface) {
struct pipe_screen *screen = ctx->pipe->screen;
if (screen->update_buffer)
screen->update_buffer(screen, ctx->pipe->priv);
return;
}

if (!p_atomic_read(&ctx->draw_buffer_invalid))
return;

/* validate the fb */
if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, 1, &pt) || !pt)
return;

rb = stfb->strb;
if (rb->texture == pt) {
pipe_texture_reference(&pt, NULL);
return;
}

/* unreference existing ones */
pipe_surface_reference(&rb->surface, NULL);
pipe_texture_reference(&rb->texture, NULL);

rb->texture = pt;
rb->surface = screen->get_tex_surface(screen, rb->texture, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE);

rb->width = rb->surface->width;
rb->height = rb->surface->height;

st_resize_framebuffer(stfb, rb->width, rb->height);

p_atomic_set(&ctx->draw_buffer_invalid, FALSE);
}


static void
vg_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
struct st_framebuffer_iface *stfbi)
{
struct vg_context *ctx = (struct vg_context *) stctxi;
p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
}

static void
vg_context_flush(struct st_context_iface *stctxi, unsigned flags,
struct pipe_fence_handle **fence)
{
struct vg_context *ctx = (struct vg_context *) stctxi;
ctx->pipe->flush(ctx->pipe, flags, fence);
if (flags & PIPE_FLUSH_RENDER_CACHE)
vg_manager_flush_frontbuffer(ctx);
}

static void
vg_context_destroy(struct st_context_iface *stctxi)
{
struct vg_context *ctx = (struct vg_context *) stctxi;
vg_destroy_context(ctx);
}

static struct st_context_iface *
vg_api_create_context(struct st_api *stapi, struct st_manager *smapi,
const struct st_visual *visual,
struct st_context_iface *shared_stctxi)
{
struct vg_context *shared_ctx = (struct vg_context *) shared_stctxi;
struct vg_context *ctx;
struct pipe_context *pipe;

pipe = smapi->screen->context_create(smapi->screen, NULL);
if (!pipe)
return NULL;
ctx = vg_create_context(pipe, NULL, shared_ctx);
if (!ctx) {
pipe->destroy(pipe);
return NULL;
}

ctx->iface.destroy = vg_context_destroy;

ctx->iface.notify_invalid_framebuffer =
vg_context_notify_invalid_framebuffer;
ctx->iface.flush = vg_context_flush;

ctx->iface.teximage = NULL;
ctx->iface.copy = NULL;

ctx->iface.st_context_private = (void *) smapi;

return &ctx->iface;
}

static struct st_renderbuffer *
create_renderbuffer(enum pipe_format format)
{
struct st_renderbuffer *strb;

strb = CALLOC_STRUCT(st_renderbuffer);
if (strb)
strb->format = format;

return strb;
}

static void
destroy_renderbuffer(struct st_renderbuffer *strb)
{
pipe_surface_reference(&strb->surface, NULL);
pipe_texture_reference(&strb->texture, NULL);
free(strb);
}

/**
* Decide the buffer to render to.
*/
static enum st_attachment_type
choose_attachment(struct st_framebuffer_iface *stfbi)
{
enum st_attachment_type statt;

statt = stfbi->visual->render_buffer;
if (statt != ST_ATTACHMENT_INVALID) {
/* use the buffer given by the visual, unless it is unavailable */
if (!st_visual_have_buffers(stfbi->visual, 1 << statt)) {
switch (statt) {
case ST_ATTACHMENT_BACK_LEFT:
statt = ST_ATTACHMENT_FRONT_LEFT;
break;
case ST_ATTACHMENT_BACK_RIGHT:
statt = ST_ATTACHMENT_FRONT_RIGHT;
break;
default:
break;
}

if (!st_visual_have_buffers(stfbi->visual, 1 << statt))
statt = ST_ATTACHMENT_INVALID;
}
}

return statt;
}

/**
* Bind the context to the given framebuffers.
*/
static boolean
vg_context_bind_framebuffers(struct st_context_iface *stctxi,
struct st_framebuffer_iface *stdrawi,
struct st_framebuffer_iface *streadi)
{
struct vg_context *ctx = (struct vg_context *) stctxi;
struct st_framebuffer *stfb;
enum st_attachment_type strb_att;

/* the draw and read framebuffers must be the same */
if (stdrawi != streadi)
return FALSE;

p_atomic_set(&ctx->draw_buffer_invalid, TRUE);

strb_att = (stdrawi) ? choose_attachment(stdrawi) : ST_ATTACHMENT_INVALID;

if (ctx->draw_buffer) {
stfb = ctx->draw_buffer;

/* free the existing fb */
if (!stdrawi ||
stfb->strb_att != strb_att ||
stfb->strb->format != stdrawi->visual->color_format ||
stfb->dsrb->format != stdrawi->visual->depth_stencil_format) {
destroy_renderbuffer(stfb->strb);
destroy_renderbuffer(stfb->dsrb);
free(stfb);

ctx->draw_buffer = NULL;
}
}

if (!stdrawi)
return TRUE;

if (strb_att == ST_ATTACHMENT_INVALID)
return FALSE;

/* create a new fb */
if (!ctx->draw_buffer) {
stfb = CALLOC_STRUCT(st_framebuffer);
if (!stfb)
return FALSE;

stfb->strb = create_renderbuffer(stdrawi->visual->color_format);
if (!stfb->strb) {
free(stfb);
return FALSE;
}

stfb->dsrb = create_renderbuffer(stdrawi->visual->depth_stencil_format);
if (!stfb->dsrb) {
free(stfb->strb);
free(stfb);
return FALSE;
}

stfb->width = 0;
stfb->height = 0;
stfb->strb_att = strb_att;

ctx->draw_buffer = stfb;
}

ctx->draw_buffer->iface = stdrawi;

return TRUE;
}

static boolean
vg_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
struct st_framebuffer_iface *stdrawi,
struct st_framebuffer_iface *streadi)
{
struct vg_context *ctx = (struct vg_context *) stctxi;

if (stctxi)
vg_context_bind_framebuffers(stctxi, stdrawi, streadi);
vg_set_current_context(ctx);

return TRUE;
}

static struct st_context_iface *
vg_api_get_current(struct st_api *stapi)
{
struct vg_context *ctx = vg_current_context();

return (ctx) ? &ctx->iface : NULL;
}

static boolean
vg_api_is_visual_supported(struct st_api *stapi,
const struct st_visual *visual)
{
/* the impl requires a depth/stencil buffer */
if (visual->depth_stencil_format == PIPE_FORMAT_NONE)
return FALSE;

return TRUE;
}

static st_proc_t
vg_api_get_proc_address(struct st_api *stapi, const char *procname)
{
/* TODO */
return (st_proc_t) NULL;
}

static void
vg_api_destroy(struct st_api *stapi)
{
free(stapi);
}

static struct st_api *
vg_module_create_api(void)
{
struct st_api *stapi;

stapi = CALLOC_STRUCT(st_api);
if (stapi) {
stapi->destroy = vg_api_destroy;
stapi->get_proc_address = vg_api_get_proc_address;
stapi->is_visual_supported = vg_api_is_visual_supported;

stapi->create_context = vg_api_create_context;
stapi->make_current = vg_api_make_current;
stapi->get_current = vg_api_get_current;
}

return stapi;
}

PUBLIC const struct st_module st_module_OpenVG = {
.api = ST_API_OPENVG,
.create_api = vg_module_create_api,
};

+ 40
- 0
src/gallium/state_trackers/vega/vg_manager.h View File

@@ -0,0 +1,40 @@
/*
* Mesa 3-D graphics library
* Version: 7.9
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/

#ifndef VG_MANAGER_H
#define VG_MANAGER_H

#include "state_tracker/st_api.h"
#include "vg_context.h"

void
vg_manager_flush_frontbuffer(struct vg_context *ctx);

void
vg_manager_validate_framebuffer(struct vg_context *ctx);

#endif /* VG_MANAGER_H */

+ 10
- 1
src/gallium/targets/libgl-xlib/xlib.c View File

@@ -39,9 +39,15 @@
#include "target-helpers/wrap_screen.h"
#include "xm_public.h"

#include "state_tracker/st_manager.h"

/* advertise OpenGL support */
PUBLIC const int st_api_OpenGL = 1;

PUBLIC const struct st_module st_module_OpenGL = {
.api = ST_API_OPENGL,
.create_api = st_manager_create_api
};

/* Helper function to build a subset of a driver stack consisting of
* one of the software rasterizers (cell, llvmpipe, softpipe) and the
@@ -81,8 +87,10 @@ swrast_xlib_create_screen( Display *display )
screen = llvmpipe_create_screen( winsys );
#endif

#if defined(GALLIUM_SOFTPIPE)
if (screen == NULL)
screen = softpipe_create_screen( winsys );
#endif

if (screen == NULL)
goto fail;
@@ -98,9 +106,10 @@ fail:
return NULL;
}

struct xm_driver xlib_driver =
static struct xm_driver xlib_driver =
{
.create_pipe_screen = swrast_xlib_create_screen,
.create_st_api = st_manager_create_api,
};



+ 1
- 1
src/gallium/winsys/drm/Makefile View File

@@ -2,7 +2,7 @@
TOP = ../../../..
include $(TOP)/configs/current

SUBDIRS = $(GALLIUM_WINSYS_DRM_DIRS)
SUBDIRS = sw $(GALLIUM_WINSYS_DRM_DIRS)

default install clean:
@for dir in $(SUBDIRS) ; do \

+ 1
- 0
src/gallium/winsys/drm/i965/dri/Makefile View File

@@ -7,6 +7,7 @@ PIPE_DRIVERS = \
$(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
$(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/winsys/drm/sw/libswdrm.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/identity/libidentity.a \
$(TOP)/src/gallium/drivers/i965/libi965.a

+ 11
- 1
src/gallium/winsys/drm/i965/gem/i965_drm_api.c View File

@@ -10,6 +10,8 @@

#include "trace/tr_drm.h"

#include "../../sw/sw_drm_api.h"

/*
* Helper functions
*/
@@ -108,5 +110,13 @@ struct drm_api i965_libdrm_api =
struct drm_api *
drm_api_create()
{
return trace_drm_create(&i965_libdrm_api);
struct drm_api *api = NULL;

if (api == NULL && debug_get_bool_option("BRW_SOFTPIPE", FALSE))
api = sw_drm_api_create(&i965_libdrm_api);

if (api == NULL)
api = &i965_libdrm_api;

return trace_drm_create(api);
}

+ 14
- 0
src/gallium/winsys/drm/sw/Makefile View File

@@ -0,0 +1,14 @@
TOP = ../../../../..
include $(TOP)/configs/current

LIBNAME = swdrm

C_SOURCES = \
wrapper_sw_winsys.c \
sw_drm_api.c

LIBRARY_INCLUDES =

LIBRARY_DEFINES =

include ../../../Makefile.template

+ 97
- 0
src/gallium/winsys/drm/sw/sw_drm_api.c View File

@@ -0,0 +1,97 @@
/**********************************************************
* 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, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* 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 "softpipe/sp_public.h"
#include "state_tracker/drm_api.h"
#include "wrapper_sw_winsys.h"
#include "sw_drm_api.h"


/*
* Defines
*/


struct sw_drm_api
{
struct drm_api base;
struct drm_api *api;
struct sw_winsys *sw;
};

static INLINE struct sw_drm_api *
sw_drm_api(struct drm_api *api)
{
return (struct sw_drm_api *)api;
}


/*
* Exported functions
*/


static struct pipe_screen *
sw_drm_create_screen(struct drm_api *_api, int drmFD,
struct drm_create_screen_arg *arg)
{
struct sw_drm_api *swapi = sw_drm_api(_api);
struct drm_api *api = swapi->api;
struct sw_winsys *sww;
struct pipe_screen *screen;

screen = api->create_screen(api, drmFD, arg);

sww = wrapper_sw_winsys_warp_pipe_screen(screen);

return softpipe_create_screen(sww);
}

static void
sw_drm_destroy(struct drm_api *api)
{
struct sw_drm_api *swapi = sw_drm_api(api);
if (swapi->api->destroy)
swapi->api->destroy(swapi->api);

FREE(swapi);
}

struct drm_api *
sw_drm_api_create(struct drm_api *api)
{
struct sw_drm_api *swapi = CALLOC_STRUCT(sw_drm_api);

swapi->base.name = "sw";
swapi->base.driver_name = api->driver_name;
swapi->base.create_screen = sw_drm_create_screen;
swapi->base.destroy = sw_drm_destroy;

swapi->api = api;

return &swapi->base;
}

+ 34
- 0
src/gallium/winsys/drm/sw/sw_drm_api.h View File

@@ -0,0 +1,34 @@
/**********************************************************
* 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, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* 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 SW_DRM_API_H
#define SW_DRM_API_H

struct drm_api;

struct drm_api * sw_drm_api_create(struct drm_api *api);

#endif

+ 282
- 0
src/gallium/winsys/drm/sw/wrapper_sw_winsys.c View File

@@ -0,0 +1,282 @@
/**********************************************************
* 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, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* 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 "wrapper_sw_winsys.h"

#include "pipe/p_format.h"
#include "pipe/p_state.h"

#include "state_tracker/sw_winsys.h"

#include "util/u_memory.h"
#include "util/u_inlines.h"

/*
* This code wraps a pipe_screen and exposes a sw_winsys interface for use
* with software resterizers. This code is used by the DRM based winsys to
* allow access to the drm driver.
*
* We must borrow the whole stack because only the pipe screen knows how
* to decode the content of a buffer. Or how to create a buffer that
* can still be used by drivers using real hardware (as the case is
* with software st/xorg but hw st/dri).
*
* We also need a pipe context for the transfers.
*/

struct wrapper_sw_winsys
{
struct sw_winsys base;
struct pipe_screen *screen;
struct pipe_context *pipe;
};

struct wrapper_sw_displaytarget
{
struct wrapper_sw_winsys *winsys;
struct pipe_texture *tex;
struct pipe_transfer *transfer;

unsigned width;
unsigned height;
unsigned map_count;
unsigned stride; /**< because we give stride at create */
void *ptr;
};

static INLINE struct wrapper_sw_winsys *
wrapper_sw_winsys(struct sw_winsys *ws)
{
return (struct wrapper_sw_winsys *)ws;
}

static INLINE struct wrapper_sw_displaytarget *
wrapper_sw_displaytarget(struct sw_displaytarget *dt)
{
return (struct wrapper_sw_displaytarget *)dt;
}


/*
* Functions
*/


static boolean
wsw_dt_get_stride(struct wrapper_sw_displaytarget *wdt, unsigned *stride)
{
struct pipe_context *pipe = wdt->winsys->pipe;
struct pipe_texture *tex = wdt->tex;
struct pipe_transfer *tr;

tr = pipe->get_tex_transfer(pipe, tex, 0, 0, 0,
PIPE_TRANSFER_READ_WRITE,
0, 0, wdt->width, wdt->height);
if (!tr)
return FALSE;

*stride = tr->stride;
wdt->stride = tr->stride;

pipe->tex_transfer_destroy(pipe, tr);

return TRUE;
}

static struct sw_displaytarget *
wsw_dt_wrap_texture(struct wrapper_sw_winsys *wsw,
struct pipe_texture *tex, unsigned *stride)
{
struct wrapper_sw_displaytarget *wdt = CALLOC_STRUCT(wrapper_sw_displaytarget);
if (!wdt)
goto err_unref;

wdt->tex = tex;
wdt->winsys = wsw;

if (!wsw_dt_get_stride(wdt, stride))
goto err_free;

return (struct sw_displaytarget *)wdt;

err_free:
FREE(wdt);
err_unref:
pipe_texture_reference(&tex, NULL);
return NULL;
}

static struct sw_displaytarget *
wsw_dt_create(struct sw_winsys *ws,
unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
unsigned *stride)
{
struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
struct pipe_texture templ;
struct pipe_texture *tex;

/*
* XXX Why don't we just get the template.
*/
memset(&templ, 0, sizeof(templ));
templ.width0 = width;
templ.height0 = height;
templ.format = format;
templ.tex_usage = tex_usage;

/* XXX alignment: we can't do anything about this */

tex = wsw->screen->texture_create(wsw->screen, &templ);
if (!tex)
return NULL;

return wsw_dt_wrap_texture(wsw, tex, stride);
}

static struct sw_displaytarget *
wsw_dt_from_handle(struct sw_winsys *ws,
const struct pipe_texture *templ,
struct winsys_handle *whandle,
unsigned *stride)
{
struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
struct pipe_texture *tex;

tex = wsw->screen->texture_from_handle(wsw->screen, templ, whandle);
if (!tex)
return NULL;

return wsw_dt_wrap_texture(wsw, tex, stride);
}

static void *
wsw_dt_map(struct sw_winsys *ws,
struct sw_displaytarget *dt,
unsigned flags)
{
struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
struct pipe_context *pipe = wdt->winsys->pipe;
struct pipe_texture *tex = wdt->tex;
struct pipe_transfer *tr;
void *ptr;

if (!wdt->map_count) {

assert(!wdt->transfer);

tr = pipe->get_tex_transfer(pipe, tex, 0, 0, 0,
PIPE_TRANSFER_READ_WRITE,
0, 0, wdt->width, wdt->height);
if (!tr)
return NULL;

ptr = pipe->transfer_map(pipe, tr);
if (!ptr)
goto err;

wdt->transfer = tr;
wdt->ptr = ptr;

/* XXX Handle this case */
assert(tr->stride == wdt->stride);
}

wdt->map_count++;

return wdt->ptr;

err:
pipe->tex_transfer_destroy(pipe, tr);
return NULL;
}

static void
wsw_dt_unmap(struct sw_winsys *ws,
struct sw_displaytarget *dt)
{
struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
struct pipe_context *pipe = wdt->winsys->pipe;

assert(wdt->transfer);

wdt->map_count--;

if (wdt->map_count)
return;

pipe->transfer_unmap(pipe, wdt->transfer);
pipe->tex_transfer_destroy(pipe, wdt->transfer);
wdt->transfer = NULL;
}

static void
wsw_dt_destroy(struct sw_winsys *ws,
struct sw_displaytarget *dt)
{
struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);

pipe_texture_reference(&wdt->tex, NULL);

FREE(wdt);
}

static void
wsw_destroy(struct sw_winsys *ws)
{
struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);

wsw->pipe->destroy(wsw->pipe);
wsw->screen->destroy(wsw->screen);

FREE(wsw);
}

struct sw_winsys *
wrapper_sw_winsys_warp_pipe_screen(struct pipe_screen *screen)
{
struct wrapper_sw_winsys *wsw = CALLOC_STRUCT(wrapper_sw_winsys);

wsw->base.displaytarget_create = wsw_dt_create;
wsw->base.displaytarget_from_handle = wsw_dt_from_handle;
wsw->base.displaytarget_map = wsw_dt_map;
wsw->base.displaytarget_unmap = wsw_dt_unmap;
wsw->base.displaytarget_destroy = wsw_dt_destroy;
wsw->base.destroy = wsw_destroy;

wsw->screen = screen;
wsw->pipe = screen->context_create(screen, NULL);
if (!wsw->pipe)
goto err;

return &wsw->base;

err:
FREE(wsw);
return NULL;
}

+ 35
- 0
src/gallium/winsys/drm/sw/wrapper_sw_winsys.h View File

@@ -0,0 +1,35 @@
/**********************************************************
* 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, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* 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 WRAPPER_SW_WINSYS
#define WRAPPER_SW_WINSYS

struct sw_winsys;
struct pipe_screen;

struct sw_winsys *wrapper_sw_winsys_warp_pipe_screen(struct pipe_screen *screen);

#endif

+ 25
- 0
src/gallium/winsys/gdi/gdi_sw_winsys.c View File

@@ -71,6 +71,7 @@ gdi_sw_displaytarget( struct sw_displaytarget *buf )

static boolean
gdi_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
unsigned tex_usage,
enum pipe_format format )
{
switch(format) {
@@ -119,6 +120,7 @@ gdi_sw_displaytarget_destroy(struct sw_winsys *winsys,

static struct sw_displaytarget *
gdi_sw_displaytarget_create(struct sw_winsys *winsys,
unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
@@ -168,6 +170,27 @@ no_gdt:
}


static struct sw_displaytarget *
gdi_sw_displaytarget_from_handle(struct sw_winsys *winsys,
const struct pipe_texture *templet,
struct winsys_handle *whandle,
unsigned *stride)
{
assert(0);
return NULL;
}


static boolean
gdi_sw_displaytarget_get_handle(struct sw_winsys *winsys,
struct sw_displaytarget *dt,
struct winsys_handle *whandle)
{
assert(0);
return FALSE;
}


void
gdi_sw_display( struct sw_winsys *winsys,
struct sw_displaytarget *dt,
@@ -212,6 +235,8 @@ gdi_create_sw_winsys(void)
winsys->destroy = gdi_sw_destroy;
winsys->is_displaytarget_format_supported = gdi_sw_is_displaytarget_format_supported;
winsys->displaytarget_create = gdi_sw_displaytarget_create;
winsys->displaytarget_from_handle = gdi_sw_displaytarget_from_handle;
winsys->displaytarget_get_handle = gdi_sw_displaytarget_get_handle;
winsys->displaytarget_map = gdi_sw_displaytarget_map;
winsys->displaytarget_unmap = gdi_sw_displaytarget_unmap;
winsys->displaytarget_display = gdi_sw_displaytarget_display;

+ 24
- 0
src/gallium/winsys/null/null_sw_winsys.c View File

@@ -44,6 +44,7 @@

static boolean
null_sw_is_displaytarget_format_supported(struct sw_winsys *ws,
unsigned tex_usage,
enum pipe_format format )
{
return FALSE;
@@ -78,6 +79,7 @@ null_sw_displaytarget_destroy(struct sw_winsys *winsys,

static struct sw_displaytarget *
null_sw_displaytarget_create(struct sw_winsys *winsys,
unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
@@ -87,6 +89,26 @@ null_sw_displaytarget_create(struct sw_winsys *winsys,
}


static struct sw_displaytarget *
null_sw_displaytarget_from_handle(struct sw_winsys *winsys,
const struct pipe_texture *templet,
struct winsys_handle *whandle,
unsigned *stride)
{
return NULL;
}


static boolean
null_sw_displaytarget_get_handle(struct sw_winsys *winsys,
struct sw_displaytarget *dt,
struct winsys_handle *whandle)
{
assert(0);
return FALSE;
}


static void
null_sw_displaytarget_display(struct sw_winsys *winsys,
struct sw_displaytarget *dt,
@@ -115,6 +137,8 @@ null_sw_create(void)
winsys->destroy = null_sw_destroy;
winsys->is_displaytarget_format_supported = null_sw_is_displaytarget_format_supported;
winsys->displaytarget_create = null_sw_displaytarget_create;
winsys->displaytarget_from_handle = null_sw_displaytarget_from_handle;
winsys->displaytarget_get_handle = null_sw_displaytarget_get_handle;
winsys->displaytarget_map = null_sw_displaytarget_map;
winsys->displaytarget_unmap = null_sw_displaytarget_unmap;
winsys->displaytarget_display = null_sw_displaytarget_display;

+ 25
- 0
src/gallium/winsys/xlib/xlib_sw_winsys.c View File

@@ -208,6 +208,7 @@ alloc_ximage(struct xm_displaytarget *xm_dt,

static boolean
xm_is_displaytarget_format_supported( struct sw_winsys *ws,
unsigned tex_usage,
enum pipe_format format )
{
/* TODO: check visuals or other sensible thing here */
@@ -358,6 +359,7 @@ xm_displaytarget_display(struct sw_winsys *ws,

static struct sw_displaytarget *
xm_displaytarget_create(struct sw_winsys *winsys,
unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
@@ -406,6 +408,27 @@ no_xm_dt:
}


static struct sw_displaytarget *
xm_displaytarget_from_handle(struct sw_winsys *winsys,
const struct pipe_texture *templet,
struct winsys_handle *whandle,
unsigned *stride)
{
assert(0);
return NULL;
}


static boolean
xm_displaytarget_get_handle(struct sw_winsys *winsys,
struct sw_displaytarget *dt,
struct winsys_handle *whandle)
{
assert(0);
return FALSE;
}


static void
xm_destroy( struct sw_winsys *ws )
{
@@ -428,6 +451,8 @@ xlib_create_sw_winsys( Display *display )
ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported;

ws->base.displaytarget_create = xm_displaytarget_create;
ws->base.displaytarget_from_handle = xm_displaytarget_from_handle;
ws->base.displaytarget_get_handle = xm_displaytarget_get_handle;
ws->base.displaytarget_map = xm_displaytarget_map;
ws->base.displaytarget_unmap = xm_displaytarget_unmap;
ws->base.displaytarget_destroy = xm_displaytarget_destroy;

+ 1
- 0
src/mesa/SConscript View File

@@ -182,6 +182,7 @@ if env['platform'] != 'winddk':
'state_tracker/st_format.c',
'state_tracker/st_framebuffer.c',
'state_tracker/st_gen_mipmap.c',
'state_tracker/st_manager.c',
'state_tracker/st_mesa_to_tgsi.c',
'state_tracker/st_program.c',
'state_tracker/st_texture.c',

+ 1
- 0
src/mesa/sources.mak View File

@@ -214,6 +214,7 @@ STATETRACKER_SOURCES = \
state_tracker/st_format.c \
state_tracker/st_framebuffer.c \
state_tracker/st_gen_mipmap.c \
state_tracker/st_manager.c \
state_tracker/st_mesa_to_tgsi.c \
state_tracker/st_program.c \
state_tracker/st_texture.c

+ 2
- 3
src/mesa/state_tracker/st_atom.c View File

@@ -34,6 +34,7 @@
#include "st_atom.h"
#include "st_cb_bitmap.h"
#include "st_program.h"
#include "st_manager.h"

#include "pipe/p_context.h"

@@ -136,9 +137,7 @@ void st_validate_state( struct st_context *st )

check_program_state( st );

if (st->pipe->screen->update_buffer)
st->pipe->screen->update_buffer(st->pipe->screen,
st->pipe->priv);
st_manager_validate_framebuffers(st);

if (state->st == 0)
return;

+ 10
- 5
src/mesa/state_tracker/st_cb_blit.c View File

@@ -69,6 +69,7 @@ st_BlitFramebuffer(GLcontext *ctx,
const GLbitfield depthStencil = (GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT);
struct st_context *st = ctx->st;
struct pipe_context *pipe = st->pipe;
const uint pFilter = ((filter == GL_NEAREST)
? PIPE_TEX_MIPFILTER_NEAREST
: PIPE_TEX_MIPFILTER_LINEAR);
@@ -111,8 +112,8 @@ st_BlitFramebuffer(GLcontext *ctx,
&readFB->Attachment[readFB->_ColorReadBufferIndex];

if(srcAtt->Type == GL_TEXTURE) {
struct pipe_screen *screen = ctx->st->pipe->screen;
const struct st_texture_object *srcObj =
struct pipe_screen *screen = pipe->screen;
struct st_texture_object *srcObj =
st_texture_object(srcAtt->Texture);
struct st_renderbuffer *dstRb =
st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
@@ -132,7 +133,8 @@ st_BlitFramebuffer(GLcontext *ctx,
return;

util_blit_pixels(st->blit,
srcSurf, srcX0, srcY0, srcX1, srcY1,
srcSurf, st_get_stobj_sampler_view(srcObj),
srcX0, srcY0, srcX1, srcY1,
dstSurf, dstX0, dstY0, dstX1, dstY1,
0.0, pFilter);

@@ -144,10 +146,11 @@ st_BlitFramebuffer(GLcontext *ctx,
struct st_renderbuffer *dstRb =
st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
struct pipe_surface *srcSurf = srcRb->surface;
struct pipe_sampler_view *srcView = st_renderbuffer_get_sampler_view(srcRb, pipe);
struct pipe_surface *dstSurf = dstRb->surface;

util_blit_pixels(st->blit,
srcSurf, srcX0, srcY0, srcX1, srcY1,
srcSurf, srcView, srcX0, srcY0, srcX1, srcY1,
dstSurf, dstX0, dstY0, dstX1, dstY1,
0.0, pFilter);
}
@@ -179,11 +182,13 @@ st_BlitFramebuffer(GLcontext *ctx,
if ((mask & depthStencil) == depthStencil &&
srcDepthSurf == srcStencilSurf &&
dstDepthSurf == dstStencilSurf) {
struct pipe_sampler_view *srcView = st_renderbuffer_get_sampler_view(srcDepthRb, pipe);

/* Blitting depth and stencil values between combined
* depth/stencil buffers. This is the ideal case for such buffers.
*/
util_blit_pixels(st->blit,
srcDepthSurf, srcX0, srcY0, srcX1, srcY1,
srcDepthSurf, srcView, srcX0, srcY0, srcX1, srcY1,
dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
0.0, pFilter);
}

+ 0
- 0
src/mesa/state_tracker/st_cb_fbo.c View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save