Conflicts: src/gallium/drivers/nouveau/nouveau_screen.c src/gallium/drivers/nvfx/nvfx_transfer.c src/gallium/winsys/drm/radeon/core/radeon_drm_buffer.cgallium-resources
if (!ctx->vbuf) { | if (!ctx->vbuf) { | ||||
ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, | ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, | ||||
32, | |||||
PIPE_BUFFER_USAGE_VERTEX, | |||||
PIPE_BIND_VERTEX_BUFFER, | |||||
max_slots * sizeof ctx->vertices); | max_slots * sizeof ctx->vertices); | ||||
} | } | ||||
filter == PIPE_TEX_MIPFILTER_LINEAR); | filter == PIPE_TEX_MIPFILTER_LINEAR); | ||||
assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D, | assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_SAMPLER, 0)); | |||||
PIPE_BIND_SAMPLER_VIEW, 0)); | |||||
assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, | assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)); | |||||
PIPE_BIND_RENDER_TARGET, 0)); | |||||
/* do the regions overlap? */ | /* do the regions overlap? */ | ||||
overlap = util_same_surface(src, dst) && | overlap = util_same_surface(src, dst) && | ||||
} | } | ||||
assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, | assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)); | |||||
PIPE_BIND_RENDER_TARGET, 0)); | |||||
/* Create a temporary texture when src and dest alias or when src | /* Create a temporary texture when src and dest alias or when src | ||||
* is anything other than a single-level 2d texture. | * is anything other than a single-level 2d texture. | ||||
} | } | ||||
texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0, | texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0, | ||||
PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
PIPE_BIND_BLIT_DESTINATION); | |||||
/* load temp texture */ | /* load temp texture */ | ||||
if (pipe->surface_copy) { | if (pipe->surface_copy) { | ||||
assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format, | assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format, | ||||
PIPE_TEXTURE_2D, | PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_RENDER_TARGET, | |||||
PIPE_BIND_RENDER_TARGET, | |||||
0)); | 0)); | ||||
/* save state (restored below) */ | /* save state (restored below) */ |
/* create the vertex buffer */ | /* create the vertex buffer */ | ||||
ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, | ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, | ||||
32, | |||||
PIPE_BUFFER_USAGE_VERTEX, | |||||
PIPE_BIND_VERTEX_BUFFER, | |||||
sizeof(ctx->vertices)); | sizeof(ctx->vertices)); | ||||
return &ctx->blitter; | return &ctx->blitter; | ||||
return; | return; | ||||
tex_surf = screen->get_tex_surface(screen, texture, 0, 0, 0, | tex_surf = screen->get_tex_surface(screen, texture, 0, 0, 0, | ||||
PIPE_BUFFER_USAGE_GPU_READ | | |||||
PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
PIPE_BIND_BLIT_SOURCE | | |||||
PIPE_BIND_BLIT_DESTINATION); | |||||
/* blit from the src to the temp */ | /* blit from the src to the temp */ | ||||
util_blitter_do_copy(blitter, tex_surf, 0, 0, | util_blitter_do_copy(blitter, tex_surf, 0, 0, | ||||
is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0; | is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0; | ||||
is_stencil = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 1) != 0; | is_stencil = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 1) != 0; | ||||
dst_tex_usage = is_depth || is_stencil ? PIPE_TEXTURE_USAGE_DEPTH_STENCIL : | |||||
PIPE_TEXTURE_USAGE_RENDER_TARGET; | |||||
dst_tex_usage = is_depth || is_stencil ? PIPE_BIND_DEPTH_STENCIL : | |||||
PIPE_BIND_RENDER_TARGET; | |||||
/* check if we can sample from and render to the surfaces */ | /* check if we can sample from and render to the surfaces */ | ||||
/* (assuming copying a stencil buffer is not possible) */ | /* (assuming copying a stencil buffer is not possible) */ | ||||
!screen->is_format_supported(screen, dst->format, dst->texture->target, | !screen->is_format_supported(screen, dst->format, dst->texture->target, | ||||
dst_tex_usage, 0) || | dst_tex_usage, 0) || | ||||
!screen->is_format_supported(screen, src->format, src->texture->target, | !screen->is_format_supported(screen, src->format, src->texture->target, | ||||
PIPE_TEXTURE_USAGE_SAMPLER, 0)) { | |||||
PIPE_BIND_SAMPLER_VIEW, 0)) { | |||||
util_surface_copy(pipe, FALSE, dst, dstx, dsty, src, srcx, srcy, | util_surface_copy(pipe, FALSE, dst, dstx, dsty, src, srcx, srcy, | ||||
width, height); | width, height); | ||||
return; | return; | ||||
/* check if we can render to the surface */ | /* check if we can render to the surface */ | ||||
if (util_format_is_depth_or_stencil(dst->format) || /* unlikely, but you never know */ | if (util_format_is_depth_or_stencil(dst->format) || /* unlikely, but you never know */ | ||||
!screen->is_format_supported(screen, dst->format, dst->texture->target, | !screen->is_format_supported(screen, dst->format, dst->texture->target, | ||||
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { | |||||
PIPE_BIND_RENDER_TARGET, 0)) { | |||||
util_surface_fill(pipe, dst, dstx, dsty, width, height, value); | util_surface_fill(pipe, dst, dstx, dsty, width, height, value); | ||||
return; | return; | ||||
} | } |
/* XXX for now, just dump image for face=0, level=0 */ | /* XXX for now, just dump image for face=0, level=0 */ | ||||
surface = screen->get_tex_surface(screen, texture, 0, 0, 0, | surface = screen->get_tex_surface(screen, texture, 0, 0, 0, | ||||
PIPE_TEXTURE_USAGE_SAMPLER); | |||||
PIPE_BIND_SAMPLER_VIEW); | |||||
if (surface) { | if (surface) { | ||||
debug_dump_surface(pipe, prefix, surface); | debug_dump_surface(pipe, prefix, surface); | ||||
screen->tex_surface_destroy(surface); | screen->tex_surface_destroy(surface); |
v[29] = 1.0; | v[29] = 1.0; | ||||
vbuf = pipe_user_buffer_create(pipe->screen, v, vertexBytes, | vbuf = pipe_user_buffer_create(pipe->screen, v, vertexBytes, | ||||
PIPE_BUFFER_USAGE_VERTEX); | |||||
PIPE_BIND_VERTEX_BUFFER); | |||||
if (!vbuf) | if (!vbuf) | ||||
goto out; | goto out; | ||||
util_dump_member_end(stream); | util_dump_member_end(stream); | ||||
util_dump_member(stream, uint, templat, last_level); | util_dump_member(stream, uint, templat, last_level); | ||||
util_dump_member(stream, uint, templat, tex_usage); | |||||
util_dump_member(stream, uint, templat, _usage); | |||||
util_dump_member(stream, uint, templat, bind); | |||||
util_dump_member(stream, uint, templat, flags); | |||||
util_dump_struct_end(stream); | util_dump_struct_end(stream); | ||||
} | } |
if (!ctx->vbuf) { | if (!ctx->vbuf) { | ||||
ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, | ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, | ||||
32, | |||||
PIPE_BUFFER_USAGE_VERTEX, | |||||
PIPE_BIND_VERTEX_BUFFER, | |||||
max_slots * sizeof ctx->vertices); | max_slots * sizeof ctx->vertices); | ||||
} | } | ||||
/* check if we can render in the texture's format */ | /* check if we can render in the texture's format */ | ||||
if (!screen->is_format_supported(screen, psv->format, PIPE_TEXTURE_2D, | if (!screen->is_format_supported(screen, psv->format, PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { | |||||
PIPE_BIND_RENDER_TARGET, 0)) { | |||||
fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel); | fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel); | ||||
return; | return; | ||||
} | } | ||||
struct pipe_surface *surf = | struct pipe_surface *surf = | ||||
screen->get_tex_surface(screen, pt, face, dstLevel, zslice, | screen->get_tex_surface(screen, pt, face, dstLevel, zslice, | ||||
PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
PIPE_BIND_RENDER_TARGET); | |||||
/* | /* | ||||
* Setup framebuffer / dest surface | * Setup framebuffer / dest surface |
static INLINE struct pipe_resource * | static INLINE struct pipe_resource * | ||||
pipe_buffer_create( struct pipe_screen *screen, | pipe_buffer_create( struct pipe_screen *screen, | ||||
unsigned alignment, unsigned usage, unsigned size ) | |||||
unsigned bind, | |||||
unsigned size ) | |||||
{ | { | ||||
struct pipe_resource buffer; | struct pipe_resource buffer; | ||||
memset(&buffer, 0, sizeof buffer); | memset(&buffer, 0, sizeof buffer); | ||||
buffer.target = PIPE_BUFFER; | buffer.target = PIPE_BUFFER; | ||||
buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */ | buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */ | ||||
buffer.usage = usage; | |||||
buffer.bind = bind; | |||||
buffer._usage = PIPE_USAGE_DEFAULT; | |||||
buffer.flags = 0; | |||||
buffer.width0 = size; | buffer.width0 = size; | ||||
buffer.height0 = 1; | buffer.height0 = 1; | ||||
buffer.depth0 = 1; | buffer.depth0 = 1; |
* pools, or obtained directly from the windowing system. | * pools, or obtained directly from the windowing system. | ||||
* | * | ||||
* This callback is invoked by the pipe_screenwhen creating a texture marked | * This callback is invoked by the pipe_screenwhen creating a texture marked | ||||
* with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying | |||||
* with the PIPE_BIND_DISPLAY_TARGET flag to get the underlying | |||||
* buffer storage. | * buffer storage. | ||||
*/ | */ | ||||
struct pipe_resource *(*surface_buffer_create)(struct pipe_winsys *ws, | struct pipe_resource *(*surface_buffer_create)(struct pipe_winsys *ws, |
boolean | boolean | ||||
util_create_rgba_surface(struct pipe_screen *screen, | util_create_rgba_surface(struct pipe_screen *screen, | ||||
uint width, uint height, | uint width, uint height, | ||||
uint bind, | |||||
struct pipe_resource **textureOut, | struct pipe_resource **textureOut, | ||||
struct pipe_surface **surfaceOut) | struct pipe_surface **surfaceOut) | ||||
{ | { | ||||
PIPE_FORMAT_NONE | PIPE_FORMAT_NONE | ||||
}; | }; | ||||
const uint target = PIPE_TEXTURE_2D; | const uint target = PIPE_TEXTURE_2D; | ||||
const uint usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; | |||||
enum pipe_format format = PIPE_FORMAT_NONE; | enum pipe_format format = PIPE_FORMAT_NONE; | ||||
struct pipe_resource templ; | struct pipe_resource templ; | ||||
uint i; | uint i; | ||||
/* Choose surface format */ | /* Choose surface format */ | ||||
for (i = 0; rgbaFormats[i]; i++) { | for (i = 0; rgbaFormats[i]; i++) { | ||||
if (screen->is_format_supported(screen, rgbaFormats[i], | if (screen->is_format_supported(screen, rgbaFormats[i], | ||||
target, usage, 0)) { | |||||
target, bind, 0)) { | |||||
format = rgbaFormats[i]; | format = rgbaFormats[i]; | ||||
break; | break; | ||||
} | } | ||||
templ.width0 = width; | templ.width0 = width; | ||||
templ.height0 = height; | templ.height0 = height; | ||||
templ.depth0 = 1; | templ.depth0 = 1; | ||||
templ.tex_usage = usage; | |||||
templ.bind = bind; | |||||
*textureOut = screen->resource_create(screen, &templ); | *textureOut = screen->resource_create(screen, &templ); | ||||
if (!*textureOut) | if (!*textureOut) | ||||
return FALSE; | return FALSE; | ||||
/* create surface / view into texture */ | /* create surface / view into texture */ | ||||
*surfaceOut = screen->get_tex_surface(screen, *textureOut, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
*surfaceOut = screen->get_tex_surface(screen, | |||||
*textureOut, | |||||
0, 0, 0, | |||||
bind); | |||||
if (!*surfaceOut) { | if (!*surfaceOut) { | ||||
pipe_resource_reference(textureOut, NULL); | pipe_resource_reference(textureOut, NULL); | ||||
return FALSE; | return FALSE; |
extern boolean | extern boolean | ||||
util_create_rgba_surface(struct pipe_screen *screen, | util_create_rgba_surface(struct pipe_screen *screen, | ||||
uint width, uint height, | |||||
uint width, uint height, uint bind, | |||||
struct pipe_resource **textureOut, | struct pipe_resource **textureOut, | ||||
struct pipe_surface **surfaceOut); | struct pipe_surface **surfaceOut); | ||||
size = align(MAX2(upload->default_size, min_size), 4096); | size = align(MAX2(upload->default_size, min_size), 4096); | ||||
upload->buffer = pipe_buffer_create( upload->pipe->screen, | upload->buffer = pipe_buffer_create( upload->pipe->screen, | ||||
upload->alignment, | |||||
upload->usage | PIPE_BUFFER_USAGE_CPU_WRITE, | |||||
upload->usage, | |||||
size ); | size ); | ||||
if (upload->buffer == NULL) | if (upload->buffer == NULL) | ||||
goto fail; | goto fail; |
( | ( | ||||
c->pipe->screen, | c->pipe->screen, | ||||
1, | 1, | ||||
PIPE_BUFFER_USAGE_VERTEX, | |||||
PIPE_BIND_VERTEX_BUFFER, | |||||
sizeof(struct vertex2f) * 4 | sizeof(struct vertex2f) * 4 | ||||
); | ); | ||||
( | ( | ||||
c->pipe->screen, | c->pipe->screen, | ||||
1, | 1, | ||||
PIPE_BUFFER_USAGE_VERTEX, | |||||
PIPE_BIND_VERTEX_BUFFER, | |||||
sizeof(struct vertex2f) * 4 | sizeof(struct vertex2f) * 4 | ||||
); | ); | ||||
( | ( | ||||
c->pipe->screen, | c->pipe->screen, | ||||
1, | 1, | ||||
PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_DISCARD, | |||||
PIPE_BIND_CONSTANT_BUFFER | PIPE_BUFFER_USAGE_DISCARD, | |||||
sizeof(struct vertex_shader_consts) | sizeof(struct vertex_shader_consts) | ||||
); | ); | ||||
( | ( | ||||
c->pipe->screen, | c->pipe->screen, | ||||
1, | 1, | ||||
PIPE_BUFFER_USAGE_CONSTANT, | |||||
PIPE_BIND_CONSTANT_BUFFER, | |||||
sizeof(struct fragment_shader_consts) | sizeof(struct fragment_shader_consts) | ||||
); | ); | ||||
template.height0 = r->pot_buffers ? | template.height0 = r->pot_buffers ? | ||||
util_next_power_of_two(r->picture_height) : r->picture_height; | util_next_power_of_two(r->picture_height) : r->picture_height; | ||||
template.depth0 = 1; | template.depth0 = 1; | ||||
template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_DYNAMIC; | |||||
template.tex_usage = PIPE_BIND_SAMPLER_VIEW | PIPE_TEXTURE_USAGE_DYNAMIC; | |||||
r->textures.individual.y = r->pipe->screen->texture_create(r->pipe->screen, &template); | r->textures.individual.y = r->pipe->screen->texture_create(r->pipe->screen, &template); | ||||
( | ( | ||||
r->pipe->screen, | r->pipe->screen, | ||||
DEFAULT_BUF_ALIGNMENT, | DEFAULT_BUF_ALIGNMENT, | ||||
PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_DISCARD, | |||||
PIPE_BIND_VERTEX_BUFFER | PIPE_BUFFER_USAGE_DISCARD, | |||||
sizeof(struct vertex2f) * 4 * 24 * r->macroblocks_per_batch | sizeof(struct vertex2f) * 4 * 24 * r->macroblocks_per_batch | ||||
); | ); | ||||
( | ( | ||||
r->pipe->screen, | r->pipe->screen, | ||||
DEFAULT_BUF_ALIGNMENT, | DEFAULT_BUF_ALIGNMENT, | ||||
PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_DISCARD, | |||||
PIPE_BIND_VERTEX_BUFFER | PIPE_BUFFER_USAGE_DISCARD, | |||||
sizeof(struct vertex2f) * 2 * 24 * r->macroblocks_per_batch | sizeof(struct vertex2f) * 2 * 24 * r->macroblocks_per_batch | ||||
); | ); | ||||
} | } | ||||
( | ( | ||||
r->pipe->screen, | r->pipe->screen, | ||||
DEFAULT_BUF_ALIGNMENT, | DEFAULT_BUF_ALIGNMENT, | ||||
PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_DISCARD, | |||||
PIPE_BIND_CONSTANT_BUFFER | PIPE_BUFFER_USAGE_DISCARD, | |||||
sizeof(struct vertex_shader_consts) | sizeof(struct vertex_shader_consts) | ||||
); | ); | ||||
( | ( | ||||
r->pipe->screen, | r->pipe->screen, | ||||
DEFAULT_BUF_ALIGNMENT, | DEFAULT_BUF_ALIGNMENT, | ||||
PIPE_BUFFER_USAGE_CONSTANT, sizeof(struct fragment_shader_consts) | |||||
PIPE_BIND_CONSTANT_BUFFER, sizeof(struct fragment_shader_consts) | |||||
); | ); | ||||
memcpy | memcpy |
format == PIPE_FORMAT_A8B8G8R8_SRGB) | format == PIPE_FORMAT_A8B8G8R8_SRGB) | ||||
return FALSE; | return FALSE; | ||||
if (tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | | |||||
PIPE_TEXTURE_USAGE_SCANOUT | | |||||
PIPE_TEXTURE_USAGE_SHARED)) { | |||||
if (tex_usage & (PIPE_BIND_DISPLAY_TARGET | | |||||
PIPE_BIND_SCANOUT | | |||||
PIPE_BIND_SHARED)) { | |||||
if (!winsys->is_displaytarget_format_supported(winsys, tex_usage, format)) | if (!winsys->is_displaytarget_format_supported(winsys, tex_usage, format)) | ||||
return FALSE; | return FALSE; | ||||
} | } |
/* Create both a displaytarget (linear) and regular texture | /* Create both a displaytarget (linear) and regular texture | ||||
* (twiddled). Convert twiddled->linear at flush_frontbuffer time. | * (twiddled). Convert twiddled->linear at flush_frontbuffer time. | ||||
*/ | */ | ||||
if (ct->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | | |||||
PIPE_TEXTURE_USAGE_SCANOUT | | |||||
PIPE_TEXTURE_USAGE_SHARED)) { | |||||
if (ct->base.tex_usage & (PIPE_BIND_DISPLAY_TARGET | | |||||
PIPE_BIND_SCANOUT | | |||||
PIPE_BIND_SHARED)) { | |||||
if (!cell_displaytarget_layout(screen, ct)) | if (!cell_displaytarget_layout(screen, ct)) | ||||
goto fail; | goto fail; | ||||
} | } |
unsigned long stride[CELL_MAX_TEXTURE_LEVELS]; | unsigned long stride[CELL_MAX_TEXTURE_LEVELS]; | ||||
/** | /** | ||||
* Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET | |||||
* Display target, for textures with the PIPE_BIND_DISPLAY_TARGET | |||||
* usage. | * usage. | ||||
*/ | */ | ||||
struct sw_displaytarget *dt; | struct sw_displaytarget *dt; |
i915_user_buffer_create(struct pipe_screen *screen, | i915_user_buffer_create(struct pipe_screen *screen, | ||||
void *ptr, | void *ptr, | ||||
unsigned bytes, | unsigned bytes, | ||||
unsigned usage) | |||||
unsigned bind) | |||||
{ | { | ||||
struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer); | struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer); | ||||
buf->b.vtbl = &i915_buffer_vtbl; | buf->b.vtbl = &i915_buffer_vtbl; | ||||
buf->b.b.screen = screen; | buf->b.b.screen = screen; | ||||
buf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */ | buf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */ | ||||
buf->b.b.usage = PIPE_BUFFER_USAGE_CPU_READ | usage; | |||||
buf->b.b._usage = PIPE_USAGE_IMMUTABLE; | |||||
buf->b.b.bind = bind; | |||||
buf->b.b.flags = 0; | |||||
buf->b.b.width0 = bytes; | buf->b.b.width0 = bytes; | ||||
buf->b.b.height0 = 1; | buf->b.b.height0 = 1; | ||||
buf->b.b.depth0 = 1; | buf->b.b.depth0 = 1; |
unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->width0); | unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->width0); | ||||
/* used for scanouts that need special layouts */ | /* used for scanouts that need special layouts */ | ||||
if (pt->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) | |||||
if (pt->bind & PIPE_BIND_SCANOUT) | |||||
if (i915_scanout_layout(tex)) | if (i915_scanout_layout(tex)) | ||||
return; | return; | ||||
/* shared buffers needs to be compatible with X servers */ | |||||
if (pt->tex_usage & PIPE_TEXTURE_USAGE_SHARED) | |||||
/* shared buffers needs to be compatible with X servers | |||||
* | |||||
* XXX: need a better name than shared for this if it is to be part | |||||
* of core gallium, and probably move the flag to resource.flags, | |||||
* rather than bindings. | |||||
*/ | |||||
if (pt->bind & PIPE_BIND_SHARED) | |||||
if (i915_display_target_layout(tex)) | if (i915_display_target_layout(tex)) | ||||
return; | return; | ||||
unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->height0); | unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->height0); | ||||
/* used for scanouts that need special layouts */ | /* used for scanouts that need special layouts */ | ||||
if (tex->b.b.tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) | |||||
if (tex->b.b.bind & PIPE_BIND_SCANOUT) | |||||
if (i915_scanout_layout(tex)) | if (i915_scanout_layout(tex)) | ||||
return; | return; | ||||
/* shared buffers needs to be compatible with X servers */ | /* shared buffers needs to be compatible with X servers */ | ||||
if (tex->b.b.tex_usage & PIPE_TEXTURE_USAGE_SHARED) | |||||
if (tex->b.b.bind & PIPE_BIND_SHARED) | |||||
if (i915_display_target_layout(tex)) | if (i915_display_target_layout(tex)) | ||||
return; | return; | ||||
tex_size = tex->stride * tex->total_nblocksy; | tex_size = tex->stride * tex->total_nblocksy; | ||||
/* for scanouts and cursors, cursors arn't scanouts */ | /* for scanouts and cursors, cursors arn't scanouts */ | ||||
if ((template->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) && template->width0 != 64) | |||||
/* XXX: use a custom flag for cursors, don't rely on magically | |||||
* guessing that this is Xorg asking for a cursor | |||||
*/ | |||||
if ((template->bind & PIPE_BIND_SCANOUT) && template->width0 != 64) | |||||
buf_usage = INTEL_NEW_SCANOUT; | buf_usage = INTEL_NEW_SCANOUT; | ||||
else | else | ||||
buf_usage = INTEL_NEW_TEXTURE; | buf_usage = INTEL_NEW_TEXTURE; |
const enum pipe_format *list; | const enum pipe_format *list; | ||||
uint i; | uint i; | ||||
if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) | |||||
if(tex_usage & PIPE_BIND_RENDER_TARGET) | |||||
list = surface_supported; | list = surface_supported; | ||||
else | else | ||||
list = tex_supported; | list = tex_supported; |
brw->vb.upload_vertex = u_upload_create( &brw->base, | brw->vb.upload_vertex = u_upload_create( &brw->base, | ||||
128 * 1024, | 128 * 1024, | ||||
64, | 64, | ||||
PIPE_BUFFER_USAGE_VERTEX ); | |||||
PIPE_BIND_VERTEX_BUFFER ); | |||||
if (brw->vb.upload_vertex == NULL) | if (brw->vb.upload_vertex == NULL) | ||||
return FALSE; | return FALSE; | ||||
brw->vb.upload_index = u_upload_create( &brw->base, | brw->vb.upload_index = u_upload_create( &brw->base, | ||||
32 * 1024, | 32 * 1024, | ||||
64, | 64, | ||||
PIPE_BUFFER_USAGE_INDEX ); | |||||
PIPE_BIND_INDEX_BUFFER ); | |||||
if (brw->vb.upload_index == NULL) | if (brw->vb.upload_index == NULL) | ||||
return FALSE; | return FALSE; | ||||
pipe_reference_init(&buf->b.b.reference, 1); | pipe_reference_init(&buf->b.b.reference, 1); | ||||
buf->b.b.screen = screen; | buf->b.b.screen = screen; | ||||
switch (template->usage & (PIPE_BUFFER_USAGE_VERTEX | | |||||
PIPE_BUFFER_USAGE_INDEX | | |||||
PIPE_BUFFER_USAGE_PIXEL | | |||||
PIPE_BUFFER_USAGE_CONSTANT)) | |||||
switch (template->bind & (PIPE_BIND_VERTEX_BUFFER | | |||||
PIPE_BIND_INDEX_BUFFER | | |||||
PIPE_BIND_CONSTANT_BUFFER)) | |||||
{ | { | ||||
case PIPE_BUFFER_USAGE_VERTEX: | |||||
case PIPE_BUFFER_USAGE_INDEX: | |||||
case (PIPE_BUFFER_USAGE_VERTEX|PIPE_BUFFER_USAGE_INDEX): | |||||
case PIPE_BIND_VERTEX_BUFFER: | |||||
case PIPE_BIND_INDEX_BUFFER: | |||||
case (PIPE_BIND_VERTEX_BUFFER|PIPE_BIND_INDEX_BUFFER): | |||||
buffer_type = BRW_BUFFER_TYPE_VERTEX; | buffer_type = BRW_BUFFER_TYPE_VERTEX; | ||||
break; | break; | ||||
case PIPE_BUFFER_USAGE_PIXEL: | |||||
buffer_type = BRW_BUFFER_TYPE_PIXEL; | |||||
break; | |||||
case PIPE_BUFFER_USAGE_CONSTANT: | |||||
case PIPE_BIND_CONSTANT_BUFFER: | |||||
buffer_type = BRW_BUFFER_TYPE_SHADER_CONSTANTS; | buffer_type = BRW_BUFFER_TYPE_SHADER_CONSTANTS; | ||||
break; | break; | ||||
brw_user_buffer_create(struct pipe_screen *screen, | brw_user_buffer_create(struct pipe_screen *screen, | ||||
void *ptr, | void *ptr, | ||||
unsigned bytes, | unsigned bytes, | ||||
unsigned usage) | |||||
unsigned bind) | |||||
{ | { | ||||
struct brw_buffer *buf; | struct brw_buffer *buf; | ||||
buf->b.vtbl = &brw_buffer_vtbl; | buf->b.vtbl = &brw_buffer_vtbl; | ||||
buf->b.b.screen = screen; | buf->b.b.screen = screen; | ||||
buf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */ | buf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */ | ||||
buf->b.b.usage = PIPE_BUFFER_USAGE_CPU_READ | usage; | |||||
buf->b.b._usage = PIPE_USAGE_IMMUTABLE; | |||||
buf->b.b.bind = bind; | |||||
buf->b.b.width0 = bytes; | buf->b.b.width0 = bytes; | ||||
buf->b.b.height0 = 1; | buf->b.b.height0 = 1; | ||||
buf->b.b.depth0 = 1; | buf->b.b.depth0 = 1; |
goto fail; | goto fail; | ||||
if (template->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT | | |||||
PIPE_TEXTURE_USAGE_SHARED)) { | |||||
if (template->bind & (PIPE_BIND_SCANOUT | | |||||
PIPE_BIND_SHARED)) { | |||||
buffer_type = BRW_BUFFER_TYPE_SCANOUT; | buffer_type = BRW_BUFFER_TYPE_SCANOUT; | ||||
} | } | ||||
else { | else { |
const enum pipe_format *list; | const enum pipe_format *list; | ||||
uint i; | uint i; | ||||
if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) | |||||
if (tex_usage & PIPE_BIND_DEPTH_STENCIL) | |||||
list = depth_supported; | list = depth_supported; | ||||
else if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) | |||||
else if (tex_usage & PIPE_BIND_RENDER_TARGET) | |||||
list = render_supported; | list = render_supported; | ||||
else | else | ||||
list = tex_supported; | list = tex_supported; |
lp_scene_map_buffers( struct lp_scene *scene ) | lp_scene_map_buffers( struct lp_scene *scene ) | ||||
{ | { | ||||
struct pipe_surface *cbuf, *zsbuf; | struct pipe_surface *cbuf, *zsbuf; | ||||
unsigned usage; | |||||
int i; | int i; | ||||
LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); | LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); | ||||
/* XXX: try to improve on this: | |||||
*/ | |||||
usage = PIPE_TRANSFER_READ_WRITE; | |||||
/* Map all color buffers | /* Map all color buffers | ||||
*/ | */ | ||||
cbuf = scene->fb.cbufs[i]; | cbuf = scene->fb.cbufs[i]; | ||||
if (cbuf) { | if (cbuf) { | ||||
scene->cbuf_map[i] = llvmpipe_resource_map(cbuf->texture, | scene->cbuf_map[i] = llvmpipe_resource_map(cbuf->texture, | ||||
cbuf->face, | |||||
cbuf->level, | |||||
cbuf->zslice); | |||||
usage, | |||||
cbuf->face, | |||||
cbuf->level, | |||||
cbuf->zslice); | |||||
if (!scene->cbuf_map[i]) | if (!scene->cbuf_map[i]) | ||||
goto fail; | goto fail; | ||||
} | } | ||||
zsbuf = scene->fb.zsbuf; | zsbuf = scene->fb.zsbuf; | ||||
if (zsbuf) { | if (zsbuf) { | ||||
scene->zsbuf_map = llvmpipe_resource_map(zsbuf->texture, | scene->zsbuf_map = llvmpipe_resource_map(zsbuf->texture, | ||||
zsbuf->face, | |||||
zsbuf->level, | |||||
zsbuf->zslice); | |||||
usage, | |||||
zsbuf->face, | |||||
zsbuf->level, | |||||
zsbuf->zslice); | |||||
if (!scene->zsbuf_map) | if (!scene->zsbuf_map) | ||||
goto fail; | goto fail; | ||||
} | } |
break; | break; | ||||
} | } | ||||
if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { | |||||
if(tex_usage & PIPE_BIND_RENDER_TARGET) { | |||||
if(format_desc->block.width != 1 || | if(format_desc->block.width != 1 || | ||||
format_desc->block.height != 1) | format_desc->block.height != 1) | ||||
return FALSE; | return FALSE; | ||||
return FALSE; | return FALSE; | ||||
} | } | ||||
if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | | |||||
PIPE_TEXTURE_USAGE_SCANOUT | | |||||
PIPE_TEXTURE_USAGE_SHARED)) { | |||||
if(tex_usage & (PIPE_BIND_DISPLAY_TARGET | | |||||
PIPE_BIND_SCANOUT | | |||||
PIPE_BIND_SHARED)) { | |||||
if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format)) | if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format)) | ||||
return FALSE; | return FALSE; | ||||
} | } | ||||
if(tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { | |||||
if(tex_usage & PIPE_BIND_DEPTH_STENCIL) { | |||||
if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) | if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) | ||||
return FALSE; | return FALSE; | ||||
} | } | ||||
/* FIXME: Temporary restrictions. See lp_bld_sample_soa.c */ | /* FIXME: Temporary restrictions. See lp_bld_sample_soa.c */ | ||||
if(tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) { | |||||
if(tex_usage & PIPE_BIND_SAMPLER_VIEW) { | |||||
if(format_desc->block.width != 1 || | if(format_desc->block.width != 1 || | ||||
format_desc->block.height != 1) | format_desc->block.height != 1) | ||||
return FALSE; | return FALSE; |
struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen); | struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen); | ||||
struct sw_winsys *winsys = screen->winsys; | struct sw_winsys *winsys = screen->winsys; | ||||
jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt, | jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt, | ||||
PIPE_BUFFER_USAGE_CPU_READ); | |||||
PIPE_TRANSFER_READ); | |||||
jit_tex->row_stride[0] = lp_tex->stride[0]; | jit_tex->row_stride[0] = lp_tex->stride[0]; | ||||
assert(jit_tex->data[0]); | assert(jit_tex->data[0]); | ||||
} | } |
pipe_reference_init(&lpt->base.reference, 1); | pipe_reference_init(&lpt->base.reference, 1); | ||||
lpt->base.screen = &screen->base; | lpt->base.screen = &screen->base; | ||||
if (lpt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | | |||||
PIPE_TEXTURE_USAGE_SCANOUT | | |||||
PIPE_TEXTURE_USAGE_SHARED)) { | |||||
if (lpt->base.tex_usage & (PIPE_BIND_DISPLAY_TARGET | | |||||
PIPE_BIND_SCANOUT | | |||||
PIPE_BIND_SHARED)) { | |||||
if (!llvmpipe_displaytarget_layout(screen, lpt)) | if (!llvmpipe_displaytarget_layout(screen, lpt)) | ||||
goto fail; | goto fail; | ||||
} | } | ||||
*/ | */ | ||||
void * | void * | ||||
llvmpipe_resource_map(struct pipe_resource *texture, | llvmpipe_resource_map(struct pipe_resource *texture, | ||||
unsigned face, | |||||
unsigned level, | |||||
unsigned zslice) | |||||
unsigned usage, | |||||
unsigned face, | |||||
unsigned level, | |||||
unsigned zslice) | |||||
{ | { | ||||
struct llvmpipe_resource *lpt = llvmpipe_resource(texture); | struct llvmpipe_resource *lpt = llvmpipe_resource(texture); | ||||
uint8_t *map; | uint8_t *map; | ||||
/* display target */ | /* display target */ | ||||
struct llvmpipe_screen *screen = llvmpipe_screen(texture->screen); | struct llvmpipe_screen *screen = llvmpipe_screen(texture->screen); | ||||
struct sw_winsys *winsys = screen->winsys; | struct sw_winsys *winsys = screen->winsys; | ||||
const unsigned usage = PIPE_BUFFER_USAGE_CPU_READ_WRITE; | |||||
assert(face == 0); | assert(face == 0); | ||||
assert(level == 0); | assert(level == 0); | ||||
unsigned face, unsigned level, unsigned zslice, | unsigned face, unsigned level, unsigned zslice, | ||||
unsigned usage) | unsigned usage) | ||||
{ | { | ||||
struct llvmpipe_resource *lpt = llvmpipe_resource(pt); | |||||
struct pipe_surface *ps; | struct pipe_surface *ps; | ||||
assert(level <= pt->last_level); | assert(level <= pt->last_level); | ||||
ps->height = u_minify(pt->height0, level); | ps->height = u_minify(pt->height0, level); | ||||
ps->usage = usage; | ps->usage = usage; | ||||
/* Because we are llvmpipe, anything that the state tracker | |||||
* thought was going to be done with the GPU will actually get | |||||
* done with the CPU. Let's adjust the flags to take that into | |||||
* account. | |||||
*/ | |||||
if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) { | |||||
/* GPU_WRITE means "render" and that can involve reads (blending) */ | |||||
ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_CPU_READ; | |||||
} | |||||
if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ) | |||||
ps->usage |= PIPE_BUFFER_USAGE_CPU_READ; | |||||
if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE | | |||||
PIPE_BUFFER_USAGE_GPU_WRITE)) { | |||||
/* Mark the surface as dirty. */ | |||||
lpt->timestamp++; | |||||
llvmpipe_screen(screen)->timestamp++; | |||||
} | |||||
ps->face = face; | ps->face = face; | ||||
ps->level = level; | ps->level = level; | ||||
ps->zslice = zslice; | ps->zslice = zslice; | ||||
FALSE); /* do_not_flush */ | FALSE); /* do_not_flush */ | ||||
map = llvmpipe_resource_map(transfer->resource, | map = llvmpipe_resource_map(transfer->resource, | ||||
transfer->usage, | |||||
transfer->sr.face, | transfer->sr.face, | ||||
transfer->sr.level, | transfer->sr.level, | ||||
transfer->box.z); | transfer->box.z); | ||||
pipe_reference_init(&buffer->base.reference, 1); | pipe_reference_init(&buffer->base.reference, 1); | ||||
buffer->base.screen = screen; | buffer->base.screen = screen; | ||||
buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */ | buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */ | ||||
buffer->base.usage = PIPE_BUFFER_USAGE_CPU_READ | usage; | |||||
buffer->base.usage = usage; | |||||
buffer->base.width0 = bytes; | buffer->base.width0 = bytes; | ||||
buffer->base.height0 = 1; | buffer->base.height0 = 1; | ||||
buffer->base.depth0 = 1; | buffer->base.depth0 = 1; |
unsigned stride[LP_MAX_TEXTURE_2D_LEVELS]; | unsigned stride[LP_MAX_TEXTURE_2D_LEVELS]; | ||||
/** | /** | ||||
* Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET | |||||
* Display target, for textures with the PIPE_BIND_DISPLAY_TARGET | |||||
* usage. | * usage. | ||||
*/ | */ | ||||
struct sw_displaytarget *dt; | struct sw_displaytarget *dt; | ||||
void * | void * | ||||
llvmpipe_resource_map(struct pipe_resource *texture, | llvmpipe_resource_map(struct pipe_resource *texture, | ||||
unsigned face, | |||||
unsigned level, | |||||
unsigned zslice); | |||||
unsigned usage, | |||||
unsigned face, | |||||
unsigned level, | |||||
unsigned zslice); | |||||
void | void | ||||
llvmpipe_resource_unmap(struct pipe_resource *texture, | llvmpipe_resource_unmap(struct pipe_resource *texture, |
if (usage & NOUVEAU_BUFFER_USAGE_TRANSFER) | if (usage & NOUVEAU_BUFFER_USAGE_TRANSFER) | ||||
flags |= NOUVEAU_BO_GART; | flags |= NOUVEAU_BO_GART; | ||||
else | else | ||||
if (usage & PIPE_BUFFER_USAGE_VERTEX) { | |||||
if (usage & NOUVEAU_BUFFER_USAGE_VERTEX) { | |||||
if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF)) | if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF)) | ||||
flags |= NOUVEAU_BO_GART; | flags |= NOUVEAU_BO_GART; | ||||
} else | } else | ||||
if (usage & PIPE_BUFFER_USAGE_INDEX) { | |||||
if (usage & NOUVEAU_BUFFER_USAGE_INDEX) { | |||||
if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF)) | if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF)) | ||||
flags |= NOUVEAU_BO_GART; | flags |= NOUVEAU_BO_GART; | ||||
} | } | ||||
if (usage & PIPE_BUFFER_USAGE_PIXEL) { | |||||
if (usage & NOUVEAU_BUFFER_USAGE_PIXEL) { | |||||
if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) | if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) | ||||
flags |= NOUVEAU_BO_GART; | flags |= NOUVEAU_BO_GART; | ||||
if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE)) | |||||
if (!(usage & NOUVEAU_BUFFER_USAGE_CPU_READ_WRITE)) | |||||
flags |= NOUVEAU_BO_VRAM; | flags |= NOUVEAU_BO_VRAM; | ||||
if (dev->chipset == 0x50 || dev->chipset >= 0x80) { | if (dev->chipset == 0x50 || dev->chipset >= 0x80) { | ||||
return flags; | return flags; | ||||
} | } | ||||
void * | void * | ||||
nouveau_screen_bo_map(struct pipe_screen *pscreen, | nouveau_screen_bo_map(struct pipe_screen *pscreen, | ||||
struct nouveau_bo *bo, | |||||
unsigned usage) | |||||
struct nouveau_bo *pb, | |||||
unsigned map_flags) | |||||
{ | { | ||||
int ret; | int ret; | ||||
ret = nouveau_bo_map(bo, nouveau_screen_map_flags(usage)); | |||||
ret = nouveau_bo_map(bo, map_flags); | |||||
if (ret) { | if (ret) { | ||||
debug_printf("map failed: %d\n", ret); | debug_printf("map failed: %d\n", ret); | ||||
return NULL; | return NULL; | ||||
void * | void * | ||||
nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct nouveau_bo *bo, | nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct nouveau_bo *bo, | ||||
unsigned offset, unsigned length, unsigned usage) | |||||
unsigned offset, unsigned length, unsigned flags) | |||||
{ | { | ||||
uint32_t flags = nouveau_screen_map_flags(usage); | |||||
int ret; | int ret; | ||||
ret = nouveau_bo_map_range(bo, offset, length, flags); | ret = nouveau_bo_map_range(bo, offset, length, flags); |
#define NOUVEAU_CAP_HW_VTXBUF (0xbeef0000) | #define NOUVEAU_CAP_HW_VTXBUF (0xbeef0000) | ||||
#define NOUVEAU_CAP_HW_IDXBUF (0xbeef0001) | #define NOUVEAU_CAP_HW_IDXBUF (0xbeef0001) | ||||
#define NOUVEAU_TEXTURE_USAGE_LINEAR (1 << 16) | |||||
/* These were poorly defined flags at the pipe interface previously. | |||||
* They have been removed, but nouveau can continue to use its own | |||||
* versions internally: | |||||
*/ | |||||
#define NOUVEAU_BUFFER_USAGE_PIXEL 0x1 | |||||
#define NOUVEAU_BUFFER_USAGE_VERTEX 0x2 | |||||
#define NOUVEAU_BUFFER_USAGE_CPU_READ_WRITE 0x4 | |||||
#define NOUVEAU_BUFFER_USAGE_GPU_WRITE 0x8 | |||||
#define NOUVEAU_BUFFER_USAGE_DISCARD 0x10 | |||||
#define NOUVEAU_BUFFER_USAGE_TEXTURE 0x20 | |||||
#define NOUVEAU_BUFFER_USAGE_ZETA 0x40 | |||||
#define NOUVEAU_BUFFER_USAGE_TRANSFER 0x80 | |||||
#define NOUVEAU_BUFFER_USAGE_TEXTURE (1 << 16) | |||||
#define NOUVEAU_BUFFER_USAGE_ZETA (1 << 17) | |||||
#define NOUVEAU_BUFFER_USAGE_TRANSFER (1 << 18) | |||||
static inline uint32_t | |||||
nouveau_screen_transfer_flags(unsigned pipe) | |||||
{ | |||||
uint32_t flags = 0; | |||||
if (pipe & PIPE_TRANSFER_READ) | |||||
flags |= NOUVEAU_BO_RD; | |||||
if (pipe & PIPE_TRANSFER_WRITE) | |||||
flags |= NOUVEAU_BO_WR; | |||||
if (pipe & PIPE_TRANSFER_DISCARD) | |||||
flags |= NOUVEAU_BO_INVAL; | |||||
if (pipe & PIPE_TRANSFER_DONTBLOCK) | |||||
flags |= NOUVEAU_BO_NOWAIT; | |||||
else | |||||
if (pipe & PIPE_TRANSFER_UNSYNCHRONIZED) | |||||
flags |= NOUVEAU_BO_NOSYNC; | |||||
return flags; | |||||
} | |||||
static INLINE unsigned | |||||
nouveau_screen_bind_flags( unsigned bind ) | |||||
{ | |||||
unsigned buf_usage = 0; | |||||
if (bind & PIPE_BIND_VERTEX_BUFFER) | |||||
buf_usage |= NOUVEAU_BUFFER_USAGE_VERTEX; | |||||
if (bind & PIPE_BIND_INDEX_BUFFER) | |||||
buf_usage |= PIPE_BIND_INDEX_BUFFER; | |||||
if (bind & (PIPE_BIND_RENDER_TARGET | | |||||
PIPE_BIND_DEPTH_STENCIL | | |||||
PIPE_BIND_BLIT_SOURCE | | |||||
PIPE_BIND_BLIT_DESTINATION | | |||||
PIPE_BIND_SCANOUT | | |||||
PIPE_BIND_DISPLAY_TARGET | | |||||
PIPE_BIND_SAMPLER_VIEW)) | |||||
buf_usage |= NOUVEAU_BUFFER_USAGE_PIXEL; | |||||
if (bind & (PIPE_BIND_TRANSFER_WRITE | | |||||
PIPE_BIND_TRANSFER_READ)) | |||||
buf_usage |= NOUVEAU_BUFFER_USAGE_CPU_READ_WRITE; | |||||
/* Not sure where these two came from: | |||||
*/ | |||||
if (0) | |||||
buf_usage |= NOUVEAU_BUFFER_USAGE_TRANSFER; | |||||
if (0) | |||||
buf_usage |= NOUVEAU_BUFFER_USAGE_ZETA; | |||||
return buf_usage; | |||||
} | |||||
/* use along with GPU_WRITE for 2D-only writes */ | |||||
#define NOUVEAU_BUFFER_USAGE_NO_RENDER (1 << 19) | |||||
extern struct pipe_screen * | extern struct pipe_screen * | ||||
nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *); | nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *); |
#include "util/u_math.h" | #include "util/u_math.h" | ||||
#include "nouveau/nouveau_screen.h" | #include "nouveau/nouveau_screen.h" | ||||
#include "nouveau/nouveau_winsys.h" | |||||
#include "nv50_resource.h" | #include "nv50_resource.h" | ||||
buffer->bo, | buffer->bo, | ||||
transfer->box.x, | transfer->box.x, | ||||
transfer->box.width, | transfer->box.width, | ||||
transfer->usage ); | |||||
nouveau_screen_transfer_flags(transfer->usage) ); | |||||
if (map == NULL) | if (map == NULL) | ||||
return NULL; | return NULL; | ||||
buffer->bo = nouveau_screen_bo_new(pscreen, | buffer->bo = nouveau_screen_bo_new(pscreen, | ||||
16, | 16, | ||||
buffer->base.usage, | |||||
nouveau_screen_bind_flags(buffer->base.bind), | |||||
buffer->base.width0); | buffer->base.width0); | ||||
if (buffer->bo == NULL) | if (buffer->bo == NULL) | ||||
nv50_user_buffer_create(struct pipe_screen *pscreen, | nv50_user_buffer_create(struct pipe_screen *pscreen, | ||||
void *ptr, | void *ptr, | ||||
unsigned bytes, | unsigned bytes, | ||||
unsigned usage) | |||||
unsigned bind) | |||||
{ | { | ||||
struct nv50_resource *buffer; | struct nv50_resource *buffer; | ||||
buffer->vtbl = &nv50_buffer_vtbl; | buffer->vtbl = &nv50_buffer_vtbl; | ||||
buffer->base.screen = pscreen; | buffer->base.screen = pscreen; | ||||
buffer->base.format = PIPE_FORMAT_R8_UNORM; | buffer->base.format = PIPE_FORMAT_R8_UNORM; | ||||
buffer->base.usage = usage; | |||||
buffer->base._usage = PIPE_USAGE_IMMUTABLE; | |||||
buffer->base.bind = bind; | |||||
buffer->base.width0 = bytes; | buffer->base.width0 = bytes; | ||||
buffer->base.height0 = 1; | buffer->base.height0 = 1; | ||||
buffer->base.depth0 = 1; | buffer->base.depth0 = 1; |
tile_flags = 0x7400; | tile_flags = 0x7400; | ||||
break; | break; | ||||
default: | default: | ||||
if ((pt->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) && | |||||
if ((pt->bind & PIPE_BIND_SCANOUT) && | |||||
util_format_get_blocksizebits(pt->format) == 32) | util_format_get_blocksizebits(pt->format) == 32) | ||||
tile_flags = 0x7a00; | tile_flags = 0x7a00; | ||||
else | else |
enum pipe_texture_target target, | enum pipe_texture_target target, | ||||
unsigned tex_usage, unsigned geom_flags) | unsigned tex_usage, unsigned geom_flags) | ||||
{ | { | ||||
if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { | |||||
if (tex_usage & PIPE_BIND_RENDER_TARGET) { | |||||
switch (format) { | switch (format) { | ||||
case PIPE_FORMAT_B8G8R8X8_UNORM: | case PIPE_FORMAT_B8G8R8X8_UNORM: | ||||
case PIPE_FORMAT_B8G8R8A8_UNORM: | case PIPE_FORMAT_B8G8R8A8_UNORM: | ||||
break; | break; | ||||
} | } | ||||
} else | } else | ||||
if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { | |||||
if (tex_usage & PIPE_BIND_DEPTH_STENCIL) { | |||||
switch (format) { | switch (format) { | ||||
case PIPE_FORMAT_Z32_FLOAT: | case PIPE_FORMAT_Z32_FLOAT: | ||||
case PIPE_FORMAT_S8Z24_UNORM: | case PIPE_FORMAT_S8Z24_UNORM: |
instanceCount); | instanceCount); | ||||
return; | return; | ||||
} else | } else | ||||
if (!(indexBuffer->usage & PIPE_BUFFER_USAGE_INDEX) || indexSize == 1) { | |||||
if (!(indexBuffer->bind & PIPE_BIND_INDEX_BUFFER) || indexSize == 1) { | |||||
nv50_draw_elements_inline(pipe, indexBuffer, indexSize, | nv50_draw_elements_inline(pipe, indexBuffer, indexSize, | ||||
mode, start, count, startInstance, | mode, start, count, startInstance, | ||||
instanceCount); | instanceCount); | ||||
for (i = 0; i < nv50->vtxbuf_nr; i++) { | for (i = 0; i < nv50->vtxbuf_nr; i++) { | ||||
if (nv50->vtxbuf[i].stride && | if (nv50->vtxbuf[i].stride && | ||||
!(nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX)) | |||||
!(nv50->vtxbuf[i].buffer->bind & PIPE_BIND_VERTEX_BUFFER)) | |||||
nv50->vbo_fifo = 0xffff; | nv50->vbo_fifo = 0xffff; | ||||
} | } | ||||
{ | { | ||||
unsigned src_pitch = ((struct nv04_surface *)src)->pitch; | unsigned src_pitch = ((struct nv04_surface *)src)->pitch; | ||||
unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch; | unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch; | ||||
int src_linear = src->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR; | |||||
int dst_linear = dst->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR; | |||||
int src_linear = src->texture->flags & NVFX_RESOURCE_FLAG_LINEAR; | |||||
int dst_linear = dst->texture->flags & NVFX_RESOURCE_FLAG_LINEAR; | |||||
assert(src->format == dst->format); | assert(src->format == dst->format); | ||||
} | } | ||||
struct nv04_surface* | struct nv04_surface* | ||||
nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d* eng2d, struct nv04_surface* ns) | |||||
nv04_surface_wrap_for_render(struct pipe_screen *pscreen, | |||||
struct nv04_surface_2d* eng2d, struct nv04_surface* ns) | |||||
{ | { | ||||
int temp_flags; | int temp_flags; | ||||
// printf("creating temp, flags is %i!\n", flags); | |||||
temp_flags = (ns->base.usage | | |||||
PIPE_BIND_BLIT_SOURCE | | |||||
PIPE_BIND_BLIT_DESTINATION); | |||||
if(0 /*ns->base.usage & PIPE_BUFFER_USAGE_DISCARD*/) | |||||
{ | |||||
temp_flags = ns->base.usage | PIPE_BUFFER_USAGE_GPU_READ; | |||||
ns->base.usage = PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER /*| PIPE_BUFFER_USAGE_DISCARD */; | |||||
} | |||||
else | |||||
{ | |||||
temp_flags = ns->base.usage | PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE; | |||||
ns->base.usage = PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER | PIPE_BUFFER_USAGE_GPU_READ; | |||||
} | |||||
ns->base.usage = PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE; | |||||
ns->base.usage = (PIPE_BIND_BLIT_SOURCE | | |||||
PIPE_BIND_BLIT_DESTINATION); | |||||
struct pipe_resource templ; | struct pipe_resource templ; | ||||
memset(&templ, 0, sizeof(templ)); | memset(&templ, 0, sizeof(templ)); | ||||
// TODO: this is probably wrong and we should specifically handle multisampling somehow once it is implemented | // TODO: this is probably wrong and we should specifically handle multisampling somehow once it is implemented | ||||
templ.nr_samples = ns->base.texture->nr_samples; | templ.nr_samples = ns->base.texture->nr_samples; | ||||
templ.tex_usage = ns->base.texture->tex_usage | PIPE_TEXTURE_USAGE_RENDER_TARGET; | |||||
templ.bind = ns->base.texture->bind | PIPE_BIND_RENDER_TARGET; | |||||
struct pipe_resource* temp_tex = pscreen->resource_create(pscreen, &templ); | struct pipe_resource* temp_tex = pscreen->resource_create(pscreen, &templ); | ||||
struct nv04_surface* temp_ns = (struct nv04_surface*)pscreen->get_tex_surface(pscreen, temp_tex, 0, 0, 0, temp_flags); | struct nv04_surface* temp_ns = (struct nv04_surface*)pscreen->get_tex_surface(pscreen, temp_tex, 0, 0, 0, temp_flags); | ||||
temp_ns->backing = ns; | temp_ns->backing = ns; | ||||
if(ns->base.usage & PIPE_BUFFER_USAGE_GPU_READ) | |||||
eng2d->copy(eng2d, &temp_ns->backing->base, 0, 0, &ns->base, 0, 0, ns->base.width, ns->base.height); | |||||
if(ns->base.usage & PIPE_BIND_BLIT_SOURCE) | |||||
eng2d->copy(eng2d, &temp_ns->backing->base, | |||||
0, 0, &ns->base, | |||||
0, 0, ns->base.width, ns->base.height); | |||||
return temp_ns; | return temp_ns; | ||||
} | } |
struct nv04_surface* | struct nv04_surface* | ||||
nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d* eng2d, struct nv04_surface* ns); | nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d* eng2d, struct nv04_surface* ns); | ||||
#define NVFX_RESOURCE_FLAG_LINEAR (PIPE_RESOURCE_FLAG_DRV_PRIV << 0) | |||||
#endif | #endif |
return NULL; | return NULL; | ||||
} | } | ||||
if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { | |||||
if (!(pt->flags & NVFX_RESOURCE_FLAG_LINEAR)) { | |||||
txp = 0; | txp = 0; | ||||
} else { | } else { | ||||
txp = nv40mt->level[0].pitch; | txp = nv40mt->level[0].pitch; |
#include "util/u_math.h" | #include "util/u_math.h" | ||||
#include "nouveau/nouveau_screen.h" | #include "nouveau/nouveau_screen.h" | ||||
#include "nouveau/nouveau_winsys.h" | |||||
#include "nvfx_resource.h" | #include "nvfx_resource.h" | ||||
buffer->bo, | buffer->bo, | ||||
transfer->box.x, | transfer->box.x, | ||||
transfer->box.width, | transfer->box.width, | ||||
transfer->usage ); | |||||
nouveau_screen_transfer_flags(transfer->usage) ); | |||||
if (map == NULL) | if (map == NULL) | ||||
return NULL; | return NULL; | ||||
struct pipe_resource * | struct pipe_resource * | ||||
nvfx_buffer_create(struct pipe_screen *pscreen, | nvfx_buffer_create(struct pipe_screen *pscreen, | ||||
const struct pipe_resource *template) | const struct pipe_resource *template) | ||||
buffer->bo = nouveau_screen_bo_new(pscreen, | buffer->bo = nouveau_screen_bo_new(pscreen, | ||||
16, | 16, | ||||
buffer->base.usage, | |||||
nouveau_screen_bind_flags(buffer->base.bind), | |||||
buffer->base.width0); | buffer->base.width0); | ||||
if (buffer->bo == NULL) | if (buffer->bo == NULL) | ||||
buffer->vtbl = &nvfx_buffer_vtbl; | buffer->vtbl = &nvfx_buffer_vtbl; | ||||
buffer->base.screen = pscreen; | buffer->base.screen = pscreen; | ||||
buffer->base.format = PIPE_FORMAT_R8_UNORM; | buffer->base.format = PIPE_FORMAT_R8_UNORM; | ||||
buffer->base.usage = usage; | |||||
buffer->base._usage = PIPE_USAGE_IMMUTABLE; | |||||
buffer->base.bind = usage; | |||||
buffer->base.width0 = bytes; | buffer->base.width0 = bytes; | ||||
buffer->base.height0 = 1; | buffer->base.height0 = 1; | ||||
buffer->base.depth0 = 1; | buffer->base.depth0 = 1; |
for (i = 0; i < nvfx->vtxbuf_nr; i++) { | for (i = 0; i < nvfx->vtxbuf_nr; i++) { | ||||
map = pipe_buffer_map(pipe, nvfx->vtxbuf[i].buffer, | map = pipe_buffer_map(pipe, nvfx->vtxbuf[i].buffer, | ||||
PIPE_BUFFER_USAGE_CPU_READ, | |||||
PIPE_TRANSFER_READ, | |||||
&vb_transfer[i]); | &vb_transfer[i]); | ||||
draw_set_mapped_vertex_buffer(nvfx->draw, i, map); | draw_set_mapped_vertex_buffer(nvfx->draw, i, map); | ||||
} | } | ||||
if (idxbuf) { | if (idxbuf) { | ||||
map = pipe_buffer_map(pipe, idxbuf, | map = pipe_buffer_map(pipe, idxbuf, | ||||
PIPE_BUFFER_USAGE_CPU_READ, | |||||
PIPE_TRANSFER_READ, | |||||
&ib_transfer); | &ib_transfer); | ||||
draw_set_mapped_element_buffer(nvfx->draw, idxbuf_size, map); | draw_set_mapped_element_buffer(nvfx->draw, idxbuf_size, map); | ||||
} else { | } else { | ||||
map = pipe_buffer_map(pipe, | map = pipe_buffer_map(pipe, | ||||
nvfx->constbuf[PIPE_SHADER_VERTEX], | nvfx->constbuf[PIPE_SHADER_VERTEX], | ||||
PIPE_BUFFER_USAGE_CPU_READ, | |||||
PIPE_TRANSFER_READ, | |||||
&cb_transfer); | &cb_transfer); | ||||
draw_set_mapped_constant_buffer(nvfx->draw, PIPE_SHADER_VERTEX, 0, | draw_set_mapped_constant_buffer(nvfx->draw, PIPE_SHADER_VERTEX, 0, | ||||
map, nr); | map, nr); |
int i; | int i; | ||||
map = pipe_buffer_map(pipe, fp->buffer, | map = pipe_buffer_map(pipe, fp->buffer, | ||||
PIPE_BUFFER_USAGE_CPU_WRITE, | |||||
PIPE_TRANSFER_WRITE, | |||||
&transfer); | &transfer); | ||||
/* Weird swapping for big-endian chips */ | /* Weird swapping for big-endian chips */ | ||||
return FALSE; | return FALSE; | ||||
} | } | ||||
fp->buffer = pipe_buffer_create(pscreen, 0x100, 0, fp->insn_len * 4); | |||||
fp->buffer = pipe_buffer_create(pscreen, | |||||
/* XXX: no alignment, maybe use a priv bind flag | |||||
* 0x100, | |||||
*/ | |||||
0, fp->insn_len * 4); | |||||
nvfx_fragprog_upload(nvfx, fp); | nvfx_fragprog_upload(nvfx, fp); | ||||
so = so_new(4, 4, 1); | so = so_new(4, 4, 1); |
uint width = pt->width0; | uint width = pt->width0; | ||||
uint offset = 0; | uint offset = 0; | ||||
int nr_faces, l, f; | int nr_faces, l, f; | ||||
uint wide_pitch = pt->tex_usage & (PIPE_TEXTURE_USAGE_SAMPLER | | |||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL | | |||||
PIPE_TEXTURE_USAGE_RENDER_TARGET | | |||||
PIPE_TEXTURE_USAGE_DISPLAY_TARGET | | |||||
PIPE_TEXTURE_USAGE_SCANOUT); | |||||
uint wide_pitch = pt->bind & (PIPE_BIND_SAMPLER_VIEW | | |||||
PIPE_BIND_DEPTH_STENCIL | | |||||
PIPE_BIND_RENDER_TARGET | | |||||
PIPE_BIND_DISPLAY_TARGET | | |||||
PIPE_BIND_SCANOUT); | |||||
if (pt->target == PIPE_TEXTURE_CUBE) { | if (pt->target == PIPE_TEXTURE_CUBE) { | ||||
nr_faces = 6; | nr_faces = 6; | ||||
} | } | ||||
for (l = 0; l <= pt->last_level; l++) { | for (l = 0; l <= pt->last_level; l++) { | ||||
if (wide_pitch && (pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) | |||||
if (wide_pitch && (pt->flags & NVFX_RESOURCE_FLAG_LINEAR)) | |||||
mt->level[l].pitch = align(util_format_get_stride(pt->format, pt->width0), 64); | mt->level[l].pitch = align(util_format_get_stride(pt->format, pt->width0), 64); | ||||
else | else | ||||
mt->level[l].pitch = util_format_get_stride(pt->format, width); | mt->level[l].pitch = util_format_get_stride(pt->format, width); | ||||
for (l = 0; l < pt->last_level; l++) { | for (l = 0; l < pt->last_level; l++) { | ||||
mt->level[l].image_offset[f] = offset; | mt->level[l].image_offset[f] = offset; | ||||
if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) && | |||||
if (!(pt->flags & NVFX_RESOURCE_FLAG_LINEAR) && | |||||
u_minify(pt->width0, l + 1) > 1 && u_minify(pt->height0, l + 1) > 1) | u_minify(pt->width0, l + 1) > 1 && u_minify(pt->height0, l + 1) > 1) | ||||
offset += align(mt->level[l].pitch * u_minify(pt->height0, l), 64); | offset += align(mt->level[l].pitch * u_minify(pt->height0, l), 64); | ||||
else | else | ||||
nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *pt) | nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *pt) | ||||
{ | { | ||||
struct nvfx_miptree *mt; | struct nvfx_miptree *mt; | ||||
unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL | | |||||
unsigned buf_usage = NOUVEAU_BUFFER_USAGE_PIXEL | | |||||
NOUVEAU_BUFFER_USAGE_TEXTURE; | NOUVEAU_BUFFER_USAGE_TEXTURE; | ||||
mt = CALLOC_STRUCT(nvfx_miptree); | mt = CALLOC_STRUCT(nvfx_miptree); | ||||
/* Swizzled textures must be POT */ | /* Swizzled textures must be POT */ | ||||
if (pt->width0 & (pt->width0 - 1) || | if (pt->width0 & (pt->width0 - 1) || | ||||
pt->height0 & (pt->height0 - 1)) | pt->height0 & (pt->height0 - 1)) | ||||
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; | |||||
mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; | |||||
else | else | ||||
if (pt->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT | | |||||
PIPE_TEXTURE_USAGE_DISPLAY_TARGET | | |||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL)) | |||||
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; | |||||
if (pt->bind & (PIPE_BIND_SCANOUT | | |||||
PIPE_BIND_DISPLAY_TARGET | | |||||
PIPE_BIND_DEPTH_STENCIL)) | |||||
mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; | |||||
else | else | ||||
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC) | |||||
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; | |||||
if (pt->_usage == PIPE_USAGE_DYNAMIC) | |||||
mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; | |||||
else { | else { | ||||
switch (pt->format) { | switch (pt->format) { | ||||
case PIPE_FORMAT_B5G6R5_UNORM: | case PIPE_FORMAT_B5G6R5_UNORM: | ||||
are just preserving the pre-unification behavior. | are just preserving the pre-unification behavior. | ||||
The whole 2D code is going to be rewritten anyway. */ | The whole 2D code is going to be rewritten anyway. */ | ||||
if(nvfx_screen(pscreen)->is_nv4x) { | if(nvfx_screen(pscreen)->is_nv4x) { | ||||
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; | |||||
mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; | |||||
break; | break; | ||||
} | } | ||||
/* TODO: Figure out which formats can be swizzled */ | /* TODO: Figure out which formats can be swizzled */ | ||||
case PIPE_FORMAT_R16_SNORM: | case PIPE_FORMAT_R16_SNORM: | ||||
{ | { | ||||
if (debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE)) | if (debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE)) | ||||
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; | |||||
mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; | |||||
break; | break; | ||||
} | } | ||||
default: | default: | ||||
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; | |||||
mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; | |||||
} | } | ||||
} | } | ||||
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC) | |||||
buf_usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE; | |||||
if (pt->_usage == PIPE_USAGE_DYNAMIC) | |||||
buf_usage |= NOUVEAU_BUFFER_USAGE_CPU_READ_WRITE; | |||||
/* apparently we can't render to swizzled surfaces smaller than 64 bytes, so make them linear. | /* apparently we can't render to swizzled surfaces smaller than 64 bytes, so make them linear. | ||||
* If the user did not ask for a render target, they can still render to it, but it will cost them an extra copy. | * If the user did not ask for a render target, they can still render to it, but it will cost them an extra copy. | ||||
* This also happens for small mipmaps of large textures. */ | * This also happens for small mipmaps of large textures. */ | ||||
if (pt->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET && util_format_get_stride(pt->format, pt->width0) < 64) | |||||
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; | |||||
if (pt->bind & PIPE_BIND_RENDER_TARGET && | |||||
util_format_get_stride(pt->format, pt->width0) < 64) | |||||
mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; | |||||
nvfx_miptree_layout(mt); | nvfx_miptree_layout(mt); | ||||
mt->base.bo = nouveau_screen_bo_new(pscreen, 256, buf_usage, mt->total_size); | |||||
mt->base.bo = nouveau_screen_bo_new(pscreen, 256, | |||||
buf_usage, mt->total_size); | |||||
if (!mt->base.bo) { | if (!mt->base.bo) { | ||||
FREE(mt); | FREE(mt); | ||||
return NULL; | return NULL; | ||||
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); | mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); | ||||
/* Assume whoever created this buffer expects it to be linear for now */ | /* Assume whoever created this buffer expects it to be linear for now */ | ||||
mt->base.base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; | |||||
mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR; | |||||
/* XXX: Need to adjust bo refcount?? | /* XXX: Need to adjust bo refcount?? | ||||
*/ | */ | ||||
ns->base.offset = mt->level[level].image_offset[0]; | ns->base.offset = mt->level[level].image_offset[0]; | ||||
} | } | ||||
/* create a linear temporary that we can render into if necessary. | |||||
* Note that ns->pitch is always a multiple of 64 for linear surfaces and swizzled surfaces are POT, so | |||||
* ns->pitch & 63 is equivalent to (ns->pitch < 64 && swizzled)*/ | |||||
if((ns->pitch & 63) && (ns->base.usage & (PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER)) == PIPE_BUFFER_USAGE_GPU_WRITE) | |||||
return &nv04_surface_wrap_for_render(pscreen, ((struct nvfx_screen*)pscreen)->eng2d, ns)->base; | |||||
/* create a linear temporary that we can render into if | |||||
* necessary. | |||||
* | |||||
* Note that ns->pitch is always a multiple of 64 for linear | |||||
* surfaces and swizzled surfaces are POT, so ns->pitch & 63 | |||||
* is equivalent to (ns->pitch < 64 && swizzled) | |||||
*/ | |||||
if ((ns->pitch & 63) && | |||||
(ns->base.usage & PIPE_BIND_RENDER_TARGET)) | |||||
{ | |||||
struct nv04_surface_2d* eng2d = | |||||
((struct nvfx_screen*)pscreen)->eng2d; | |||||
ns = nv04_surface_wrap_for_render(pscreen, eng2d, ns); | |||||
} | |||||
return &ns->base; | return &ns->base; | ||||
} | } | ||||
if(ns->backing) | if(ns->backing) | ||||
{ | { | ||||
struct nvfx_screen* screen = (struct nvfx_screen*)ps->texture->screen; | struct nvfx_screen* screen = (struct nvfx_screen*)ps->texture->screen; | ||||
if(ns->backing->base.usage & PIPE_BUFFER_USAGE_GPU_WRITE) | |||||
if(ns->backing->base.usage & PIPE_BIND_RENDER_TARGET) | |||||
screen->eng2d->copy(screen->eng2d, &ns->backing->base, 0, 0, ps, 0, 0, ns->base.width, ns->base.height); | screen->eng2d->copy(screen->eng2d, &ns->backing->base, 0, 0, ps, 0, 0, ns->base.width, ns->base.height); | ||||
nvfx_miptree_surface_del(&ns->backing->base); | nvfx_miptree_surface_del(&ns->backing->base); | ||||
} | } |
struct nvfx_screen *screen = nvfx_screen(pscreen); | struct nvfx_screen *screen = nvfx_screen(pscreen); | ||||
struct pipe_surface *front = ((struct nouveau_winsys *) pscreen->winsys)->front; | struct pipe_surface *front = ((struct nouveau_winsys *) pscreen->winsys)->front; | ||||
if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { | |||||
if (tex_usage & PIPE_BIND_RENDER_TARGET) { | |||||
switch (format) { | switch (format) { | ||||
case PIPE_FORMAT_B8G8R8A8_UNORM: | case PIPE_FORMAT_B8G8R8A8_UNORM: | ||||
case PIPE_FORMAT_B5G6R5_UNORM: | case PIPE_FORMAT_B5G6R5_UNORM: | ||||
break; | break; | ||||
} | } | ||||
} else | } else | ||||
if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { | |||||
if (tex_usage & PIPE_BIND_DEPTH_STENCIL) { | |||||
switch (format) { | switch (format) { | ||||
case PIPE_FORMAT_S8Z24_UNORM: | case PIPE_FORMAT_S8Z24_UNORM: | ||||
case PIPE_FORMAT_X8Z24_UNORM: | case PIPE_FORMAT_X8Z24_UNORM: |
if (rt_enable & (NV34TCL_RT_ENABLE_COLOR0 | NV34TCL_RT_ENABLE_COLOR1 | | if (rt_enable & (NV34TCL_RT_ENABLE_COLOR0 | NV34TCL_RT_ENABLE_COLOR1 | | ||||
NV40TCL_RT_ENABLE_COLOR2 | NV40TCL_RT_ENABLE_COLOR3)) { | NV40TCL_RT_ENABLE_COLOR2 | NV40TCL_RT_ENABLE_COLOR3)) { | ||||
/* Render to at least a colour buffer */ | /* Render to at least a colour buffer */ | ||||
if (!(rt[0]->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { | |||||
if (!(rt[0]->base.texture->flags & NVFX_RESOURCE_FLAG_LINEAR)) { | |||||
assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1))); | assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1))); | ||||
for (i = 1; i < fb->nr_cbufs; i++) | for (i = 1; i < fb->nr_cbufs; i++) | ||||
assert(!(rt[i]->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)); | |||||
assert(!(rt[i]->base.texture->flags & NVFX_RESOURCE_FLAG_LINEAR)); | |||||
rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED | | rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED | | ||||
(log2i(rt[0]->base.width) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT) | | (log2i(rt[0]->base.width) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT) | | ||||
depth_only = 1; | depth_only = 1; | ||||
/* Render to depth buffer only */ | /* Render to depth buffer only */ | ||||
if (!(zeta->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { | |||||
if (!(zeta->base.texture->flags & NVFX_RESOURCE_FLAG_LINEAR)) { | |||||
assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1))); | assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1))); | ||||
rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED | | rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED | |
static void | static void | ||||
nvfx_compatible_transfer_tex(struct pipe_resource *pt, unsigned width, unsigned height, | nvfx_compatible_transfer_tex(struct pipe_resource *pt, unsigned width, unsigned height, | ||||
unsigned bind, | |||||
struct pipe_resource *template) | struct pipe_resource *template) | ||||
{ | { | ||||
memset(template, 0, sizeof(struct pipe_resource)); | memset(template, 0, sizeof(struct pipe_resource)); | ||||
template->depth0 = 1; | template->depth0 = 1; | ||||
template->last_level = 0; | template->last_level = 0; | ||||
template->nr_samples = pt->nr_samples; | template->nr_samples = pt->nr_samples; | ||||
template->bind = bind; | |||||
template->_usage = PIPE_USAGE_DYNAMIC; | |||||
template->flags = NVFX_RESOURCE_FLAG_LINEAR; | |||||
} | |||||
static unsigned nvfx_transfer_bind_flags( unsigned transfer_usage ) | |||||
{ | |||||
unsigned bind = 0; | |||||
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | | |||||
NOUVEAU_TEXTURE_USAGE_LINEAR; | |||||
if (transfer_usage & PIPE_TRANSFER_WRITE) | |||||
bind |= PIPE_BIND_BLIT_DESTINATION; | |||||
if (transfer_usage & PIPE_TRANSFER_READ) | |||||
bind |= PIPE_BIND_BLIT_SOURCE; | |||||
return bind; | |||||
} | } | ||||
struct pipe_transfer * | struct pipe_transfer * | ||||
struct pipe_resource tx_tex_template, *tx_tex; | struct pipe_resource tx_tex_template, *tx_tex; | ||||
static boolean firsttime = TRUE; | static boolean firsttime = TRUE; | ||||
static boolean no_transfer = FALSE; | static boolean no_transfer = FALSE; | ||||
unsigned bind = nvfx_transfer_bind_flags(usage); | |||||
if (firsttime) { | if (firsttime) { | ||||
no_transfer = debug_get_bool_option("NOUVEAU_NO_TRANSFER", | no_transfer = debug_get_bool_option("NOUVEAU_NO_TRANSFER", | ||||
tx->base.stride = mt->level[sr.level].pitch; | tx->base.stride = mt->level[sr.level].pitch; | ||||
/* Direct access to texture */ | /* Direct access to texture */ | ||||
if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || no_transfer) && | |||||
pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) | |||||
if ((pt->_usage == PIPE_USAGE_DYNAMIC || | |||||
no_transfer) && | |||||
pt->flags & NVFX_RESOURCE_FLAG_LINEAR) | |||||
{ | { | ||||
tx->direct = true; | tx->direct = true; | ||||
/* XXX: just call the internal nvfx function. | |||||
*/ | |||||
tx->surface = pscreen->get_tex_surface(pscreen, pt, | tx->surface = pscreen->get_tex_surface(pscreen, pt, | ||||
sr.face, sr.level, | sr.face, sr.level, | ||||
box->z, | box->z, | ||||
usage); | |||||
bind); | |||||
return &tx->base; | return &tx->base; | ||||
} | } | ||||
tx->direct = false; | tx->direct = false; | ||||
nvfx_compatible_transfer_tex(pt, box->width, box->height, &tx_tex_template); | |||||
nvfx_compatible_transfer_tex(pt, box->width, box->height, bind, &tx_tex_template); | |||||
tx_tex = pscreen->resource_create(pscreen, &tx_tex_template); | tx_tex = pscreen->resource_create(pscreen, &tx_tex_template); | ||||
if (!tx_tex) | if (!tx_tex) | ||||
tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, | tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, | ||||
0, 0, 0, | 0, 0, 0, | ||||
tx->base.usage); | |||||
bind); | |||||
pipe_resource_reference(&tx_tex, NULL); | pipe_resource_reference(&tx_tex, NULL); | ||||
src = pscreen->get_tex_surface(pscreen, pt, | src = pscreen->get_tex_surface(pscreen, pt, | ||||
sr.face, sr.level, box->z, | sr.face, sr.level, box->z, | ||||
PIPE_BUFFER_USAGE_GPU_READ); | |||||
PIPE_BIND_BLIT_SOURCE); | |||||
/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ | /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ | ||||
/* TODO: Check if SIFM can un-swizzle */ | /* TODO: Check if SIFM can un-swizzle */ | ||||
ptx->sr.face, | ptx->sr.face, | ||||
ptx->sr.level, | ptx->sr.level, | ||||
ptx->box.z, | ptx->box.z, | ||||
PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER); | |||||
PIPE_BIND_BLIT_DESTINATION); | |||||
/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ | /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ | ||||
nvscreen->eng2d->copy(nvscreen->eng2d, | nvscreen->eng2d->copy(nvscreen->eng2d, | ||||
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx; | struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx; | ||||
struct nv04_surface *ns = (struct nv04_surface *)tx->surface; | struct nv04_surface *ns = (struct nv04_surface *)tx->surface; | ||||
struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture; | struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture; | ||||
uint8_t *map = nouveau_screen_bo_map(pscreen, mt->base.bo, ptx->usage); | |||||
nouveau_screen_transfer_flags(ptx->usage)); | |||||
if(!tx->direct) | if(!tx->direct) | ||||
return map + ns->base.offset; | return map + ns->base.offset; |
if (nvfx_vbo_format_to_hw(ve->src_format, &type, &ncomp)) | if (nvfx_vbo_format_to_hw(ve->src_format, &type, &ncomp)) | ||||
return FALSE; | return FALSE; | ||||
map = pipe_buffer_map(pipe, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ, &transfer); | |||||
map = pipe_buffer_map(pipe, vb->buffer, PIPE_TRANSFER_READ, &transfer); | |||||
map += vb->buffer_offset + ve->src_offset; | map += vb->buffer_offset + ve->src_offset; | ||||
switch (type) { | switch (type) { | ||||
struct pipe_transfer *transfer; | struct pipe_transfer *transfer; | ||||
void *map; | void *map; | ||||
map = pipe_buffer_map(pipe, ib, PIPE_BUFFER_USAGE_CPU_READ, &transfer); | |||||
map = pipe_buffer_map(pipe, ib, PIPE_TRANSFER_READ, &transfer); | |||||
if (!ib) { | if (!ib) { | ||||
NOUVEAU_ERR("failed mapping ib\n"); | NOUVEAU_ERR("failed mapping ib\n"); | ||||
return; | return; |
if (constbuf) { | if (constbuf) { | ||||
map = pipe_buffer_map(pipe, constbuf, | map = pipe_buffer_map(pipe, constbuf, | ||||
PIPE_BUFFER_USAGE_CPU_READ, | |||||
PIPE_TRANSFER_READ, | |||||
&transfer); | &transfer); | ||||
} | } | ||||
if (!pipe->screen->is_format_supported(pipe->screen, | if (!pipe->screen->is_format_supported(pipe->screen, | ||||
old_format, src->texture->target, | old_format, src->texture->target, | ||||
PIPE_TEXTURE_USAGE_RENDER_TARGET | | |||||
PIPE_TEXTURE_USAGE_SAMPLER, 0)) { | |||||
PIPE_BIND_RENDER_TARGET | | |||||
PIPE_BIND_SAMPLER_VIEW, 0)) { | |||||
switch (util_format_get_blocksize(old_format)) { | switch (util_format_get_blocksize(old_format)) { | ||||
case 1: | case 1: | ||||
new_format = PIPE_FORMAT_I8_UNORM; | new_format = PIPE_FORMAT_I8_UNORM; |
r300->sprite_coord_index = -1; | r300->sprite_coord_index = -1; | ||||
/* Open up the OQ BO. */ | /* Open up the OQ BO. */ | ||||
r300->oqbo = pipe_buffer_create(screen, 4096, | |||||
PIPE_BUFFER_USAGE_PIXEL, 4096); | |||||
r300->oqbo = pipe_buffer_create(screen, | |||||
R300_BIND_OQBO, 4096); | |||||
make_empty_list(&r300->query_list); | make_empty_list(&r300->query_list); | ||||
r300_init_flush_functions(r300); | r300_init_flush_functions(r300); | ||||
r300->upload_ib = u_upload_create(&r300->context, | r300->upload_ib = u_upload_create(&r300->context, | ||||
32 * 1024, 16, | 32 * 1024, 16, | ||||
PIPE_BUFFER_USAGE_INDEX); | |||||
PIPE_BIND_INDEX_BUFFER); | |||||
if (r300->upload_ib == NULL) | if (r300->upload_ib == NULL) | ||||
goto no_upload_ib; | goto no_upload_ib; | ||||
r300->upload_vb = u_upload_create(&r300->context, | r300->upload_vb = u_upload_create(&r300->context, | ||||
128 * 1024, 16, | 128 * 1024, 16, | ||||
PIPE_BUFFER_USAGE_VERTEX); | |||||
PIPE_BIND_VERTEX_BUFFER); | |||||
if (r300->upload_vb == NULL) | if (r300->upload_vb == NULL) | ||||
goto no_upload_vb; | goto no_upload_vb; | ||||
#define R300_MAX_TEXTURE_LEVELS 13 | #define R300_MAX_TEXTURE_LEVELS 13 | ||||
#define R300_MAX_DRAW_VBO_SIZE (1024 * 1024) | #define R300_MAX_DRAW_VBO_SIZE (1024 * 1024) | ||||
#define R300_TEXTURE_USAGE_TRANSFER PIPE_TEXTURE_USAGE_CUSTOM | |||||
#define R300_RESOURCE_FLAG_TRANSFER PIPE_RESOURCE_FLAG_DRV_PRIV | |||||
/* Non-atom dirty state flags. */ | /* Non-atom dirty state flags. */ | ||||
#define R300_NEW_FRAGMENT_SHADER 0x00000020 | #define R300_NEW_FRAGMENT_SHADER 0x00000020 |
struct r300_screen* r300screen = r300_screen(r300->context.screen); | struct r300_screen* r300screen = r300_screen(r300->context.screen); | ||||
struct r300_query *q = (struct r300_query*)query; | struct r300_query *q = (struct r300_query*)query; | ||||
struct pipe_transfer *transfer; | struct pipe_transfer *transfer; | ||||
unsigned flags = PIPE_BUFFER_USAGE_CPU_READ; | |||||
unsigned flags = PIPE_TRANSFER_READ; | |||||
uint32_t* map; | uint32_t* map; | ||||
uint32_t temp = 0; | uint32_t temp = 0; | ||||
unsigned i, num_results; | unsigned i, num_results; |
vbuf = &r300->vertex_buffer[vbi]; | vbuf = &r300->vertex_buffer[vbi]; | ||||
map[vbi] = (uint32_t*)pipe_buffer_map(&r300->context, | map[vbi] = (uint32_t*)pipe_buffer_map(&r300->context, | ||||
vbuf->buffer, | vbuf->buffer, | ||||
PIPE_BUFFER_USAGE_CPU_READ, | |||||
PIPE_TRANSFER_READ, | |||||
&transfer[vbi]); | &transfer[vbi]); | ||||
map[vbi] += vbuf->buffer_offset / 4; | map[vbi] += vbuf->buffer_offset / 4; | ||||
stride[vbi] = vbuf->stride / 4; | stride[vbi] = vbuf->stride / 4; | ||||
struct pipe_transfer *src_transfer, *dst_transfer; | struct pipe_transfer *src_transfer, *dst_transfer; | ||||
unsigned i; | unsigned i; | ||||
new_elts = pipe_buffer_create(screen, 32, | |||||
PIPE_BUFFER_USAGE_INDEX | | |||||
PIPE_BUFFER_USAGE_CPU_WRITE | | |||||
PIPE_BUFFER_USAGE_GPU_READ, | |||||
new_elts = pipe_buffer_create(screen, | |||||
PIPE_BIND_INDEX_BUFFER, | |||||
2 * count); | 2 * count); | ||||
in_map = pipe_buffer_map(context, *elts, PIPE_BUFFER_USAGE_CPU_READ, &src_transfer); | |||||
out_map = pipe_buffer_map(context, new_elts, PIPE_BUFFER_USAGE_CPU_WRITE, &dst_transfer); | |||||
in_map = pipe_buffer_map(context, *elts, PIPE_TRANSFER_READ, &src_transfer); | |||||
out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE, &dst_transfer); | |||||
in_map += start; | in_map += start; | ||||
unsigned short *in_map; | unsigned short *in_map; | ||||
unsigned short *out_map; | unsigned short *out_map; | ||||
new_elts = pipe_buffer_create(context->screen, 32, | |||||
PIPE_BUFFER_USAGE_INDEX | | |||||
PIPE_BUFFER_USAGE_CPU_WRITE | | |||||
PIPE_BUFFER_USAGE_GPU_READ, | |||||
new_elts = pipe_buffer_create(context->screen, | |||||
PIPE_BIND_INDEX_BUFFER, | |||||
2 * count); | 2 * count); | ||||
in_map = pipe_buffer_map(context, *elts, | in_map = pipe_buffer_map(context, *elts, | ||||
PIPE_BUFFER_USAGE_CPU_READ, &in_transfer); | |||||
PIPE_TRANSFER_READ, &in_transfer); | |||||
out_map = pipe_buffer_map(context, new_elts, | out_map = pipe_buffer_map(context, new_elts, | ||||
PIPE_BUFFER_USAGE_CPU_WRITE, &out_transfer); | |||||
PIPE_TRANSFER_WRITE, &out_transfer); | |||||
memcpy(out_map, in_map+start, 2 * count); | memcpy(out_map, in_map+start, 2 * count); | ||||
for (i = 0; i < r300->vertex_buffer_count; i++) { | for (i = 0; i < r300->vertex_buffer_count; i++) { | ||||
void* buf = pipe_buffer_map(pipe, | void* buf = pipe_buffer_map(pipe, | ||||
r300->vertex_buffer[i].buffer, | r300->vertex_buffer[i].buffer, | ||||
PIPE_BUFFER_USAGE_CPU_READ, | |||||
PIPE_TRANSFER_READ, | |||||
&vb_transfer[i]); | &vb_transfer[i]); | ||||
draw_set_mapped_vertex_buffer(r300->draw, i, buf); | draw_set_mapped_vertex_buffer(r300->draw, i, buf); | ||||
} | } | ||||
{ | { | ||||
pipe_resource_reference(&r300->vbo, NULL); | pipe_resource_reference(&r300->vbo, NULL); | ||||
r300render->vbo = pipe_buffer_create(screen, | r300render->vbo = pipe_buffer_create(screen, | ||||
64, | |||||
PIPE_BUFFER_USAGE_VERTEX, | |||||
PIPE_BIND_VERTEX_BUFFER, | |||||
R300_MAX_DRAW_VBO_SIZE); | R300_MAX_DRAW_VBO_SIZE); | ||||
r300render->vbo_offset = 0; | r300render->vbo_offset = 0; | ||||
r300render->vbo_size = R300_MAX_DRAW_VBO_SIZE; | r300render->vbo_size = R300_MAX_DRAW_VBO_SIZE; | ||||
r300render->vbo_ptr = pipe_buffer_map(&r300render->r300->context, | r300render->vbo_ptr = pipe_buffer_map(&r300render->r300->context, | ||||
r300render->vbo, | r300render->vbo, | ||||
PIPE_BUFFER_USAGE_CPU_WRITE, | |||||
PIPE_TRANSFER_WRITE, | |||||
&r300render->vbo_transfer); | &r300render->vbo_transfer); | ||||
return ((uint8_t*)r300render->vbo_ptr + r300render->vbo_offset); | return ((uint8_t*)r300render->vbo_ptr + r300render->vbo_offset); |
} | } | ||||
/* Check sampler format support. */ | /* Check sampler format support. */ | ||||
if ((usage & PIPE_TEXTURE_USAGE_SAMPLER) && | |||||
if ((usage & PIPE_BIND_SAMPLER_VIEW) && | |||||
/* Z24 cannot be sampled from on non-r5xx. */ | /* Z24 cannot be sampled from on non-r5xx. */ | ||||
(is_r500 || !is_z24) && | (is_r500 || !is_z24) && | ||||
r300_is_sampler_format_supported(format)) { | r300_is_sampler_format_supported(format)) { | ||||
retval |= PIPE_TEXTURE_USAGE_SAMPLER; | |||||
retval |= PIPE_BIND_SAMPLER_VIEW; | |||||
} | } | ||||
/* Check colorbuffer format support. */ | /* Check colorbuffer format support. */ | ||||
if ((usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | | |||||
PIPE_TEXTURE_USAGE_DISPLAY_TARGET | | |||||
PIPE_TEXTURE_USAGE_SCANOUT | | |||||
PIPE_TEXTURE_USAGE_SHARED)) && | |||||
if ((usage & (PIPE_BIND_RENDER_TARGET | | |||||
PIPE_BIND_DISPLAY_TARGET | | |||||
PIPE_BIND_SCANOUT | | |||||
PIPE_BIND_SHARED)) && | |||||
/* 2101010 cannot be rendered to on non-r5xx. */ | /* 2101010 cannot be rendered to on non-r5xx. */ | ||||
(is_r500 || !is_color2101010) && | (is_r500 || !is_color2101010) && | ||||
r300_is_colorbuffer_format_supported(format)) { | r300_is_colorbuffer_format_supported(format)) { | ||||
retval |= usage & | retval |= usage & | ||||
(PIPE_TEXTURE_USAGE_RENDER_TARGET | | |||||
PIPE_TEXTURE_USAGE_DISPLAY_TARGET | | |||||
PIPE_TEXTURE_USAGE_SCANOUT | | |||||
PIPE_TEXTURE_USAGE_SHARED); | |||||
(PIPE_BIND_RENDER_TARGET | | |||||
PIPE_BIND_DISPLAY_TARGET | | |||||
PIPE_BIND_SCANOUT | | |||||
PIPE_BIND_SHARED); | |||||
} | } | ||||
/* Check depth-stencil format support. */ | /* Check depth-stencil format support. */ | ||||
if (usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL && | |||||
if (usage & PIPE_BIND_DEPTH_STENCIL && | |||||
r300_is_zs_format_supported(format)) { | r300_is_zs_format_supported(format)) { | ||||
retval |= PIPE_TEXTURE_USAGE_DEPTH_STENCIL; | |||||
retval |= PIPE_BIND_DEPTH_STENCIL; | |||||
} | } | ||||
return retval == usage; | return retval == usage; |
if (rbuf->user_buffer) | if (rbuf->user_buffer) | ||||
return rbuf->user_buffer; | return rbuf->user_buffer; | ||||
if (rbuf->b.b.usage & PIPE_BUFFER_USAGE_CONSTANT) { | |||||
if (rbuf->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) { | |||||
goto just_map; | goto just_map; | ||||
} | } | ||||
rbuf->map = NULL; | rbuf->map = NULL; | ||||
rbuf->buf = r300_winsys_buffer_create(r300screen, | rbuf->buf = r300_winsys_buffer_create(r300screen, | ||||
16, | 16, | ||||
rbuf->b.b.usage, | |||||
rbuf->b.b.bind, /* XXX */ | |||||
rbuf->b.b.width0); | rbuf->b.b.width0); | ||||
break; | break; | ||||
} | } | ||||
if (rbuf->user_buffer) | if (rbuf->user_buffer) | ||||
return; | return; | ||||
if (rbuf->b.b.usage & PIPE_BUFFER_USAGE_CONSTANT) | |||||
if (rbuf->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) | |||||
return; | return; | ||||
/* mark the range as used */ | /* mark the range as used */ | ||||
{ | { | ||||
struct r300_screen *r300screen = r300_screen(screen); | struct r300_screen *r300screen = r300_screen(screen); | ||||
struct r300_buffer *rbuf; | struct r300_buffer *rbuf; | ||||
unsigned alignment = 16; | |||||
rbuf = CALLOC_STRUCT(r300_buffer); | rbuf = CALLOC_STRUCT(r300_buffer); | ||||
if (!rbuf) | if (!rbuf) | ||||
pipe_reference_init(&rbuf->b.b.reference, 1); | pipe_reference_init(&rbuf->b.b.reference, 1); | ||||
rbuf->b.b.screen = screen; | rbuf->b.b.screen = screen; | ||||
if (bind & R300_BIND_OQBO) | |||||
alignment = 4096; | |||||
rbuf->buf = r300_winsys_buffer_create(r300screen, | rbuf->buf = r300_winsys_buffer_create(r300screen, | ||||
16, | |||||
rbuf->b.b.usage, | |||||
alignment, | |||||
rbuf->b.b.bind, | |||||
rbuf->b.b.width0); | rbuf->b.b.width0); | ||||
if (!rbuf->buf) | if (!rbuf->buf) | ||||
struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen, | struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen, | ||||
void *ptr, | void *ptr, | ||||
unsigned bytes, | unsigned bytes, | ||||
unsigned usage) | |||||
unsigned bind) | |||||
{ | { | ||||
struct r300_buffer *rbuf; | struct r300_buffer *rbuf; | ||||
rbuf->b.vtbl = &r300_buffer_vtbl; | rbuf->b.vtbl = &r300_buffer_vtbl; | ||||
rbuf->b.b.screen = screen; | rbuf->b.b.screen = screen; | ||||
rbuf->b.b.format = PIPE_FORMAT_R8_UNORM; | rbuf->b.b.format = PIPE_FORMAT_R8_UNORM; | ||||
rbuf->b.b.usage = usage; | |||||
rbuf->b.b._usage = PIPE_USAGE_IMMUTABLE; | |||||
rbuf->b.b.bind = bind; | |||||
rbuf->b.b.width0 = bytes; | rbuf->b.b.width0 = bytes; | ||||
rbuf->b.b.height0 = 1; | rbuf->b.b.height0 = 1; | ||||
rbuf->b.b.depth0 = 1; | rbuf->b.b.depth0 = 1; |
int max_size = 0; | int max_size = 0; | ||||
if (buf == NULL || buf->width0 == 0 || | if (buf == NULL || buf->width0 == 0 || | ||||
(mapped = pipe_buffer_map(pipe, buf, PIPE_BUFFER_USAGE_CPU_READ, &tr)) == NULL) | |||||
(mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL) | |||||
{ | { | ||||
r300->shader_constants[shader].count = 0; | r300->shader_constants[shader].count = 0; | ||||
return; | return; |
tex->b.b.screen = screen; | tex->b.b.screen = screen; | ||||
r300_setup_flags(tex); | r300_setup_flags(tex); | ||||
if (!(template->tex_usage & R300_TEXTURE_USAGE_TRANSFER)) { | |||||
if (!(template->flags & R300_RESOURCE_FLAG_TRANSFER)) { | |||||
r300_setup_tiling(screen, tex); | r300_setup_tiling(screen, tex); | ||||
} | } | ||||
r300_setup_miptree(rscreen, tex); | r300_setup_miptree(rscreen, tex); | ||||
r300_setup_texture_state(rscreen, tex); | r300_setup_texture_state(rscreen, tex); | ||||
tex->buffer = rws->buffer_create(rws, 2048, | tex->buffer = rws->buffer_create(rws, 2048, | ||||
PIPE_BUFFER_USAGE_PIXEL, | |||||
PIPE_BIND_SAMPLER_VIEW, /* XXX */ | |||||
tex->size); | tex->size); | ||||
rws->buffer_set_tiling(rws, tex->buffer, | rws->buffer_set_tiling(rws, tex->buffer, | ||||
tex->pitch[0], | tex->pitch[0], | ||||
template.width0 = util_next_power_of_two(width); | template.width0 = util_next_power_of_two(width); | ||||
template.height0 = util_next_power_of_two(height); | template.height0 = util_next_power_of_two(height); | ||||
template.depth0 = 1; | template.depth0 = 1; | ||||
template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | | |||||
PIPE_TEXTURE_USAGE_RENDER_TARGET; | |||||
template.bind = (PIPE_BIND_SAMPLER_VIEW | | |||||
PIPE_BIND_RENDER_TARGET); | |||||
r300_vsfc->tex = screen->resource_create(screen, &template); | r300_vsfc->tex = screen->resource_create(screen, &template); | ||||
if (!r300_vsfc->tex) | if (!r300_vsfc->tex) |
transfer->sr.face, | transfer->sr.face, | ||||
transfer->sr.level, | transfer->sr.level, | ||||
transfer->box.z, | transfer->box.z, | ||||
PIPE_BUFFER_USAGE_GPU_READ | | |||||
PIPE_BUFFER_USAGE_PIXEL); | |||||
PIPE_BIND_BLIT_SOURCE); | |||||
dst = screen->get_tex_surface(screen, &r300transfer->detiled_texture->b.b, | dst = screen->get_tex_surface(screen, &r300transfer->detiled_texture->b.b, | ||||
0, 0, 0, | 0, 0, 0, | ||||
PIPE_BUFFER_USAGE_GPU_WRITE | | |||||
PIPE_BUFFER_USAGE_PIXEL); | |||||
PIPE_BIND_BLIT_DESTINATION); | |||||
ctx->surface_copy(ctx, dst, 0, 0, src, | ctx->surface_copy(ctx, dst, 0, 0, src, | ||||
transfer->box.x, transfer->box.y, | transfer->box.x, transfer->box.y, | ||||
src = screen->get_tex_surface(screen, &r300transfer->detiled_texture->b.b, | src = screen->get_tex_surface(screen, &r300transfer->detiled_texture->b.b, | ||||
0, 0, 0, | 0, 0, 0, | ||||
PIPE_BUFFER_USAGE_GPU_READ | | |||||
PIPE_BUFFER_USAGE_PIXEL); | |||||
PIPE_BIND_BLIT_SOURCE); | |||||
dst = screen->get_tex_surface(screen, tex, | dst = screen->get_tex_surface(screen, tex, | ||||
transfer->sr.face, | transfer->sr.face, | ||||
transfer->sr.level, | transfer->sr.level, | ||||
transfer->box.z, | transfer->box.z, | ||||
PIPE_BUFFER_USAGE_GPU_WRITE | | |||||
PIPE_BUFFER_USAGE_PIXEL); | |||||
PIPE_BIND_BLIT_DESTINATION); | |||||
/* XXX this flush prevents the following DRM error from occuring: | /* XXX this flush prevents the following DRM error from occuring: | ||||
* [drm:radeon_cs_ioctl] *ERROR* Failed to parse relocation ! | * [drm:radeon_cs_ioctl] *ERROR* Failed to parse relocation ! | ||||
if (tex->microtile || tex->macrotile) { | if (tex->microtile || tex->macrotile) { | ||||
trans->render_target_usage = | trans->render_target_usage = | ||||
util_format_is_depth_or_stencil(texture->format) ? | util_format_is_depth_or_stencil(texture->format) ? | ||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL : | |||||
PIPE_TEXTURE_USAGE_RENDER_TARGET; | |||||
PIPE_BIND_DEPTH_STENCIL : | |||||
PIPE_BIND_RENDER_TARGET; | |||||
template.target = PIPE_TEXTURE_2D; | template.target = PIPE_TEXTURE_2D; | ||||
template.format = texture->format; | template.format = texture->format; | ||||
template.depth0 = 0; | template.depth0 = 0; | ||||
template.last_level = 0; | template.last_level = 0; | ||||
template.nr_samples = 0; | template.nr_samples = 0; | ||||
template.tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | | |||||
R300_TEXTURE_USAGE_TRANSFER; | |||||
template._usage = PIPE_USAGE_DYNAMIC; | |||||
template.flags = R300_RESOURCE_FLAG_TRANSFER; | |||||
/* For texture reading, the temporary (detiled) texture is used as | /* For texture reading, the temporary (detiled) texture is used as | ||||
* a render target when blitting from a tiled texture. */ | * a render target when blitting from a tiled texture. */ | ||||
if (usage & PIPE_TRANSFER_READ) { | if (usage & PIPE_TRANSFER_READ) { | ||||
template.tex_usage |= trans->render_target_usage; | |||||
template.bind |= trans->render_target_usage; | |||||
} | } | ||||
/* For texture writing, the temporary texture is used as a sampler | /* For texture writing, the temporary texture is used as a sampler | ||||
* when blitting into a tiled texture. */ | * when blitting into a tiled texture. */ | ||||
if (usage & PIPE_TRANSFER_WRITE) { | if (usage & PIPE_TRANSFER_WRITE) { | ||||
template.tex_usage |= PIPE_TEXTURE_USAGE_SAMPLER; | |||||
template.bind |= PIPE_BIND_SAMPLER_VIEW; | |||||
} | } | ||||
/* Create the temporary texture. */ | /* Create the temporary texture. */ |
struct r300_winsys_buffer; | struct r300_winsys_buffer; | ||||
/* XXX: this is just a bandaid on larger problems in | |||||
* r300_screen_buffer.h which doesn't seem to be fully ported to | |||||
* gallium-resources. | |||||
*/ | |||||
#define R300_BIND_OQBO (1<<21) | |||||
enum r300_value_id { | enum r300_value_id { | ||||
R300_VID_PCI_ID, | R300_VID_PCI_ID, |
break; | break; | ||||
} | } | ||||
if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | | |||||
PIPE_TEXTURE_USAGE_SCANOUT | | |||||
PIPE_TEXTURE_USAGE_SHARED)) { | |||||
if(tex_usage & (PIPE_BIND_DISPLAY_TARGET | | |||||
PIPE_BIND_SCANOUT | | |||||
PIPE_BIND_SHARED)) { | |||||
if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format)) | if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format)) | ||||
return FALSE; | return FALSE; | ||||
} | } |
/* Round up the surface size to a multiple of the tile size? | /* Round up the surface size to a multiple of the tile size? | ||||
*/ | */ | ||||
spt->dt = winsys->displaytarget_create(winsys, | spt->dt = winsys->displaytarget_create(winsys, | ||||
spt->base.tex_usage, | |||||
spt->base.bind, | |||||
spt->base.format, | spt->base.format, | ||||
spt->base.width0, | spt->base.width0, | ||||
spt->base.height0, | spt->base.height0, | ||||
util_is_power_of_two(template->height0) && | util_is_power_of_two(template->height0) && | ||||
util_is_power_of_two(template->depth0)); | util_is_power_of_two(template->depth0)); | ||||
if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | | |||||
PIPE_TEXTURE_USAGE_SCANOUT | | |||||
PIPE_TEXTURE_USAGE_SHARED)) { | |||||
if (spt->base.bind & (PIPE_BIND_DISPLAY_TARGET | | |||||
PIPE_BIND_SCANOUT | | |||||
PIPE_BIND_SHARED)) { | |||||
if (!softpipe_displaytarget_layout(screen, spt)) | if (!softpipe_displaytarget_layout(screen, spt)) | ||||
goto fail; | goto fail; | ||||
} | } | ||||
ps->offset = spt->level_offset[level]; | ps->offset = spt->level_offset[level]; | ||||
ps->usage = usage; | ps->usage = usage; | ||||
/* Because we are softpipe, anything that the state tracker | |||||
* thought was going to be done with the GPU will actually get | |||||
* done with the CPU. Let's adjust the flags to take that into | |||||
* account. | |||||
*/ | |||||
if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) { | |||||
/* GPU_WRITE means "render" and that can involve reads (blending) */ | |||||
ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_CPU_READ; | |||||
} | |||||
if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ) | |||||
ps->usage |= PIPE_BUFFER_USAGE_CPU_READ; | |||||
if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE | | |||||
PIPE_BUFFER_USAGE_GPU_WRITE)) { | |||||
/* Mark the surface as dirty. The tile cache will look for this. */ | |||||
spt->timestamp++; | |||||
softpipe_screen(screen)->timestamp++; | |||||
} | |||||
ps->face = face; | ps->face = face; | ||||
ps->level = level; | ps->level = level; | ||||
ps->zslice = zslice; | ps->zslice = zslice; | ||||
softpipe_user_buffer_create(struct pipe_screen *screen, | softpipe_user_buffer_create(struct pipe_screen *screen, | ||||
void *ptr, | void *ptr, | ||||
unsigned bytes, | unsigned bytes, | ||||
unsigned usage) | |||||
unsigned bind_flags) | |||||
{ | { | ||||
struct softpipe_resource *buffer; | struct softpipe_resource *buffer; | ||||
if(!buffer) | if(!buffer) | ||||
return NULL; | return NULL; | ||||
pipe_reference_init(&buffer->base.reference, 1); | pipe_reference_init(&buffer->base.reference, 1); | ||||
buffer->base.screen = screen; | buffer->base.screen = screen; | ||||
buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */ | buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */ | ||||
buffer->base.usage = PIPE_BUFFER_USAGE_CPU_READ | usage; | |||||
buffer->base.bind = bind_flags; | |||||
buffer->base._usage = PIPE_USAGE_IMMUTABLE; | |||||
buffer->base.flags = 0; | |||||
buffer->base.width0 = bytes; | buffer->base.width0 = bytes; | ||||
buffer->base.height0 = 1; | buffer->base.height0 = 1; | ||||
buffer->base.depth0 = 1; | buffer->base.depth0 = 1; |
/** | /** | ||||
* Display target, only valid for PIPE_TEXTURE_2D with the | * Display target, only valid for PIPE_TEXTURE_2D with the | ||||
* PIPE_TEXTURE_USAGE_DISPLAY_TARGET usage. | |||||
* PIPE_BIND_DISPLAY_TARGET usage. | |||||
*/ | */ | ||||
struct sw_displaytarget *dt; | struct sw_displaytarget *dt; | ||||
if(!cmd) | if(!cmd) | ||||
return PIPE_ERROR_OUT_OF_MEMORY; | return PIPE_ERROR_OUT_OF_MEMORY; | ||||
swc->surface_relocation(swc, &cmd->sid, sid, PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
swc->surface_relocation(swc, &cmd->sid, sid, SVGA_RELOC_WRITE); | |||||
cmd->surfaceFlags = flags; | cmd->surfaceFlags = flags; | ||||
cmd->format = format; | cmd->format = format; | ||||
if(!cmd) | if(!cmd) | ||||
return PIPE_ERROR_OUT_OF_MEMORY; | return PIPE_ERROR_OUT_OF_MEMORY; | ||||
swc->surface_relocation(swc, &cmd->sid, sid, PIPE_BUFFER_USAGE_GPU_READ); | |||||
swc->surface_relocation(swc, &cmd->sid, sid, SVGA_RELOC_READ); | |||||
swc->commit(swc);; | swc->commit(swc);; | ||||
return PIPE_OK; | return PIPE_OK; | ||||
unsigned surface_flags; | unsigned surface_flags; | ||||
if(transfer == SVGA3D_WRITE_HOST_VRAM) { | if(transfer == SVGA3D_WRITE_HOST_VRAM) { | ||||
region_flags = PIPE_BUFFER_USAGE_GPU_READ; | |||||
surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE; | |||||
region_flags = SVGA_RELOC_READ; | |||||
surface_flags = SVGA_RELOC_WRITE; | |||||
} | } | ||||
else if(transfer == SVGA3D_READ_HOST_VRAM) { | else if(transfer == SVGA3D_READ_HOST_VRAM) { | ||||
region_flags = PIPE_BUFFER_USAGE_GPU_WRITE; | |||||
surface_flags = PIPE_BUFFER_USAGE_GPU_READ; | |||||
region_flags = SVGA_RELOC_WRITE; | |||||
surface_flags = SVGA_RELOC_READ; | |||||
} | } | ||||
else { | else { | ||||
assert(0); | assert(0); | ||||
unsigned surface_flags; | unsigned surface_flags; | ||||
if(transfer == SVGA3D_WRITE_HOST_VRAM) { | if(transfer == SVGA3D_WRITE_HOST_VRAM) { | ||||
region_flags = PIPE_BUFFER_USAGE_GPU_READ; | |||||
surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE; | |||||
region_flags = SVGA_RELOC_READ; | |||||
surface_flags = SVGA_RELOC_WRITE; | |||||
} | } | ||||
else if(transfer == SVGA3D_READ_HOST_VRAM) { | else if(transfer == SVGA3D_READ_HOST_VRAM) { | ||||
region_flags = PIPE_BUFFER_USAGE_GPU_WRITE; | |||||
surface_flags = PIPE_BUFFER_USAGE_GPU_READ; | |||||
region_flags = SVGA_RELOC_WRITE; | |||||
surface_flags = SVGA_RELOC_READ; | |||||
} | } | ||||
else { | else { | ||||
assert(0); | assert(0); | ||||
cmd->type = type; | cmd->type = type; | ||||
surface_to_surfaceid(swc, surface, &cmd->target, PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
surface_to_surfaceid(swc, surface, &cmd->target, SVGA_RELOC_WRITE); | |||||
swc->commit(swc); | swc->commit(swc); | ||||
if(!cmd) | if(!cmd) | ||||
return PIPE_ERROR_OUT_OF_MEMORY; | return PIPE_ERROR_OUT_OF_MEMORY; | ||||
surface_to_surfaceid(swc, src, &cmd->src, PIPE_BUFFER_USAGE_GPU_READ); | |||||
surface_to_surfaceid(swc, dest, &cmd->dest, PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ); | |||||
surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE); | |||||
*boxes = (SVGA3dCopyBox*) &cmd[1]; | *boxes = (SVGA3dCopyBox*) &cmd[1]; | ||||
memset(*boxes, 0, boxesSize); | memset(*boxes, 0, boxesSize); | ||||
if(!cmd) | if(!cmd) | ||||
return PIPE_ERROR_OUT_OF_MEMORY; | return PIPE_ERROR_OUT_OF_MEMORY; | ||||
surface_to_surfaceid(swc, src, &cmd->src, PIPE_BUFFER_USAGE_GPU_READ); | |||||
surface_to_surfaceid(swc, dest, &cmd->dest, PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ); | |||||
surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE); | |||||
cmd->boxSrc = *boxSrc; | cmd->boxSrc = *boxSrc; | ||||
cmd->boxDest = *boxDest; | cmd->boxDest = *boxDest; | ||||
cmd->mode = mode; | cmd->mode = mode; | ||||
cmd->type = type; | cmd->type = type; | ||||
swc->region_relocation(swc, &cmd->guestResult, buffer, 0, | swc->region_relocation(swc, &cmd->guestResult, buffer, 0, | ||||
PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
SVGA_RELOC_WRITE); | |||||
swc->commit(swc); | swc->commit(swc); | ||||
cmd->type = type; | cmd->type = type; | ||||
swc->region_relocation(swc, &cmd->guestResult, buffer, 0, | swc->region_relocation(swc, &cmd->guestResult, buffer, 0, | ||||
PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
SVGA_RELOC_WRITE); | |||||
swc->commit(swc); | swc->commit(swc); | ||||
svga->upload_ib = u_upload_create( &svga->pipe, | svga->upload_ib = u_upload_create( &svga->pipe, | ||||
32 * 1024, | 32 * 1024, | ||||
16, | 16, | ||||
PIPE_BUFFER_USAGE_INDEX ); | |||||
PIPE_BIND_INDEX_BUFFER ); | |||||
if (svga->upload_ib == NULL) | if (svga->upload_ib == NULL) | ||||
goto no_upload_ib; | goto no_upload_ib; | ||||
svga->upload_vb = u_upload_create( &svga->pipe, | svga->upload_vb = u_upload_create( &svga->pipe, | ||||
128 * 1024, | 128 * 1024, | ||||
16, | 16, | ||||
PIPE_BUFFER_USAGE_VERTEX ); | |||||
PIPE_BIND_VERTEX_BUFFER ); | |||||
if (svga->upload_vb == NULL) | if (svga->upload_vb == NULL) | ||||
goto no_upload_vb; | goto no_upload_vb; | ||||
swc->surface_relocation(swc, | swc->surface_relocation(swc, | ||||
&vdecl[i].array.surfaceId, | &vdecl[i].array.surfaceId, | ||||
vb_handle[i], | vb_handle[i], | ||||
PIPE_BUFFER_USAGE_GPU_READ); | |||||
SVGA_RELOC_READ); | |||||
} | } | ||||
memcpy( prim, | memcpy( prim, | ||||
swc->surface_relocation(swc, | swc->surface_relocation(swc, | ||||
&prim[i].indexArray.surfaceId, | &prim[i].indexArray.surfaceId, | ||||
ib_handle[i], | ib_handle[i], | ||||
PIPE_BUFFER_USAGE_GPU_READ); | |||||
SVGA_RELOC_READ); | |||||
pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL); | pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL); | ||||
} | } | ||||
struct pipe_resource *dst = NULL; | struct pipe_resource *dst = NULL; | ||||
void *dst_map = NULL; | void *dst_map = NULL; | ||||
dst = pipe_buffer_create( pipe->screen, 32, | |||||
PIPE_BUFFER_USAGE_INDEX | | |||||
PIPE_BUFFER_USAGE_CPU_WRITE | | |||||
PIPE_BUFFER_USAGE_GPU_READ, | |||||
dst = pipe_buffer_create( pipe->screen, | |||||
PIPE_BIND_INDEX_BUFFER, | |||||
size ); | size ); | ||||
if (dst == NULL) | if (dst == NULL) | ||||
goto fail; | goto fail; | ||||
dst_map = pipe_buffer_map( pipe, dst, PIPE_BUFFER_USAGE_CPU_WRITE, | |||||
dst_map = pipe_buffer_map( pipe, dst, PIPE_TRANSFER_WRITE, | |||||
&transfer); | &transfer); | ||||
if (dst_map == NULL) | if (dst_map == NULL) | ||||
goto fail; | goto fail; |
struct pipe_resource *dst = NULL; | struct pipe_resource *dst = NULL; | ||||
void *dst_map = NULL; | void *dst_map = NULL; | ||||
dst = pipe_buffer_create( pipe->screen, 32, | |||||
PIPE_BUFFER_USAGE_INDEX | | |||||
PIPE_BUFFER_USAGE_CPU_WRITE | | |||||
PIPE_BUFFER_USAGE_GPU_READ, | |||||
dst = pipe_buffer_create( pipe->screen, | |||||
PIPE_BIND_INDEX_BUFFER, | |||||
size ); | size ); | ||||
if (dst == NULL) | if (dst == NULL) | ||||
goto fail; | goto fail; | ||||
src_map = pipe_buffer_map( pipe, src, PIPE_BUFFER_USAGE_CPU_READ, &src_transfer ); | |||||
src_map = pipe_buffer_map( pipe, src, PIPE_TRANSFER_READ, &src_transfer ); | |||||
if (src_map == NULL) | if (src_map == NULL) | ||||
goto fail; | goto fail; | ||||
dst_map = pipe_buffer_map( pipe, dst, PIPE_BUFFER_USAGE_CPU_WRITE, &dst_transfer ); | |||||
dst_map = pipe_buffer_map( pipe, dst, PIPE_TRANSFER_WRITE, &dst_transfer ); | |||||
if (dst_map == NULL) | if (dst_map == NULL) | ||||
goto fail; | goto fail; | ||||
sq->queryResult = (SVGA3dQueryResult *)sws->buffer_map(sws, | sq->queryResult = (SVGA3dQueryResult *)sws->buffer_map(sws, | ||||
sq->hwbuf, | sq->hwbuf, | ||||
PIPE_BUFFER_USAGE_CPU_WRITE); | |||||
PIPE_TRANSFER_WRITE); | |||||
if(!sq->queryResult) | if(!sq->queryResult) | ||||
goto no_query_result; | goto no_query_result; | ||||
static INLINE boolean | static INLINE boolean | ||||
svga_buffer_needs_hw_storage(unsigned usage) | svga_buffer_needs_hw_storage(unsigned usage) | ||||
{ | { | ||||
return usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_INDEX); | |||||
return usage & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER); | |||||
} | } | ||||
* a flush in st_bufferobj_get_subdata, during display list replay. | * a flush in st_bufferobj_get_subdata, during display list replay. | ||||
*/ | */ | ||||
if (sbuf->b.b.usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_INDEX)) | |||||
if (sbuf->b.b.bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) | |||||
return PIPE_REFERENCED_FOR_READ; | return PIPE_REFERENCED_FOR_READ; | ||||
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; | return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; | ||||
pipe_reference_init(&sbuf->b.b.reference, 1); | pipe_reference_init(&sbuf->b.b.reference, 1); | ||||
sbuf->b.b.screen = screen; | sbuf->b.b.screen = screen; | ||||
if(svga_buffer_needs_hw_storage(template->usage)) { | |||||
if(svga_buffer_needs_hw_storage(template->bind)) { | |||||
if(svga_buffer_create_host_surface(ss, sbuf) != PIPE_OK) | if(svga_buffer_create_host_surface(ss, sbuf) != PIPE_OK) | ||||
goto error2; | goto error2; | ||||
} | } | ||||
svga_user_buffer_create(struct pipe_screen *screen, | svga_user_buffer_create(struct pipe_screen *screen, | ||||
void *ptr, | void *ptr, | ||||
unsigned bytes, | unsigned bytes, | ||||
unsigned usage) | |||||
unsigned bind) | |||||
{ | { | ||||
struct svga_buffer *sbuf; | struct svga_buffer *sbuf; | ||||
sbuf->b.vtbl = &svga_buffer_vtbl; | sbuf->b.vtbl = &svga_buffer_vtbl; | ||||
sbuf->b.b.screen = screen; | sbuf->b.b.screen = screen; | ||||
sbuf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */ | sbuf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */ | ||||
sbuf->b.b.usage = usage; | |||||
sbuf->b.b._usage = PIPE_USAGE_IMMUTABLE; | |||||
sbuf->b.b.bind = bind; | |||||
sbuf->b.b.width0 = bytes; | sbuf->b.b.width0 = bytes; | ||||
sbuf->b.b.height0 = 1; | sbuf->b.b.height0 = 1; | ||||
sbuf->b.b.depth0 = 1; | sbuf->b.b.depth0 = 1; |
sbuf->key.flags = 0; | sbuf->key.flags = 0; | ||||
sbuf->key.format = SVGA3D_BUFFER; | sbuf->key.format = SVGA3D_BUFFER; | ||||
if(sbuf->b.b.usage & PIPE_BUFFER_USAGE_VERTEX) | |||||
if(sbuf->b.b.bind & PIPE_BIND_VERTEX_BUFFER) | |||||
sbuf->key.flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER; | sbuf->key.flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER; | ||||
if(sbuf->b.b.usage & PIPE_BUFFER_USAGE_INDEX) | |||||
if(sbuf->b.b.bind & PIPE_BIND_INDEX_BUFFER) | |||||
sbuf->key.flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER; | sbuf->key.flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER; | ||||
sbuf->key.size.width = sbuf->b.b.width0; | sbuf->key.size.width = sbuf->b.b.width0; | ||||
struct pipe_resource *dummy; | struct pipe_resource *dummy; | ||||
if(transfer == SVGA3D_WRITE_HOST_VRAM) { | if(transfer == SVGA3D_WRITE_HOST_VRAM) { | ||||
region_flags = PIPE_BUFFER_USAGE_GPU_READ; | |||||
surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE; | |||||
region_flags = SVGA_RELOC_READ; | |||||
surface_flags = SVGA_RELOC_WRITE; | |||||
} | } | ||||
else if(transfer == SVGA3D_READ_HOST_VRAM) { | else if(transfer == SVGA3D_READ_HOST_VRAM) { | ||||
region_flags = PIPE_BUFFER_USAGE_GPU_WRITE; | |||||
surface_flags = PIPE_BUFFER_USAGE_GPU_READ; | |||||
region_flags = SVGA_RELOC_WRITE; | |||||
surface_flags = SVGA_RELOC_READ; | |||||
} | } | ||||
else { | else { | ||||
assert(0); | assert(0); | ||||
return ret; | return ret; | ||||
pipe_mutex_lock(ss->swc_mutex); | pipe_mutex_lock(ss->swc_mutex); | ||||
map = ss->sws->buffer_map(ss->sws, sbuf->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE); | |||||
map = ss->sws->buffer_map(ss->sws, sbuf->hwbuf, PIPE_TRANSFER_WRITE); | |||||
assert(map); | assert(map); | ||||
if(!map) { | if(!map) { | ||||
pipe_mutex_unlock(ss->swc_mutex); | pipe_mutex_unlock(ss->swc_mutex); |
sws->fence_reference(sws, &fence, NULL); | sws->fence_reference(sws, &fence, NULL); | ||||
} | } | ||||
hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE); | |||||
hw = sws->buffer_map(sws, st->hwbuf, PIPE_TRANSFER_WRITE); | |||||
assert(hw); | assert(hw); | ||||
if(hw) { | if(hw) { | ||||
memcpy(hw, sw, length); | memcpy(hw, sw, length); | ||||
svga_screen_flush(screen, &fence); | svga_screen_flush(screen, &fence); | ||||
sws->fence_finish(sws, fence, 0); | sws->fence_finish(sws, fence, 0); | ||||
hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_READ); | |||||
hw = sws->buffer_map(sws, st->hwbuf, PIPE_TRANSFER_READ); | |||||
assert(hw); | assert(hw); | ||||
if(hw) { | if(hw) { | ||||
memcpy(sw, hw, length); | memcpy(sw, hw, length); | ||||
tex->key.cachable = 1; | tex->key.cachable = 1; | ||||
if(template->tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) | |||||
if (template->bind & PIPE_BIND_SAMPLER_VIEW) | |||||
tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE; | tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE; | ||||
if(template->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { | |||||
if (template->bind & PIPE_BIND_DISPLAY_TARGET) { | |||||
tex->key.cachable = 0; | tex->key.cachable = 0; | ||||
} | } | ||||
if(template->tex_usage & PIPE_TEXTURE_USAGE_SHARED) { | |||||
if (template->bind & PIPE_BIND_SHARED) { | |||||
tex->key.cachable = 0; | tex->key.cachable = 0; | ||||
} | } | ||||
if(template->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) { | |||||
if (template->bind & PIPE_BIND_SCANOUT) { | |||||
tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT; | tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT; | ||||
tex->key.cachable = 0; | tex->key.cachable = 0; | ||||
} | } | ||||
/* | /* | ||||
* XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot | * XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot | ||||
* know beforehand whether a texture will be used as a rendertarget or not | * know beforehand whether a texture will be used as a rendertarget or not | ||||
* and it always requests PIPE_TEXTURE_USAGE_RENDER_TARGET, therefore | |||||
* and it always requests PIPE_BIND_RENDER_TARGET, therefore | |||||
* passing the SVGA3D_SURFACE_HINT_RENDERTARGET here defeats its purpose. | * passing the SVGA3D_SURFACE_HINT_RENDERTARGET here defeats its purpose. | ||||
*/ | */ | ||||
#if 0 | #if 0 | ||||
if((template->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) && | |||||
if((template->tex_usage & PIPE_BIND_RENDER_TARGET) && | |||||
!util_format_is_compressed(template->format)) | !util_format_is_compressed(template->format)) | ||||
tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET; | tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET; | ||||
#endif | #endif | ||||
if(template->tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) | |||||
if(template->bind & PIPE_BIND_DEPTH_STENCIL) | |||||
tex->key.flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL; | tex->key.flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL; | ||||
tex->key.numMipLevels = template->last_level + 1; | tex->key.numMipLevels = template->last_level + 1; |
assert(tex_usage); | assert(tex_usage); | ||||
/* Override host capabilities */ | /* Override host capabilities */ | ||||
if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { | |||||
if (tex_usage & PIPE_BIND_RENDER_TARGET) { | |||||
switch(format) { | switch(format) { | ||||
/* Often unsupported/problematic. This means we end up with the same | /* Often unsupported/problematic. This means we end up with the same | ||||
SVGA3dSurfaceFormatCaps mask; | SVGA3dSurfaceFormatCaps mask; | ||||
mask.value = 0; | mask.value = 0; | ||||
if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) | |||||
if (tex_usage & PIPE_BIND_RENDER_TARGET) | |||||
mask.offscreenRenderTarget = 1; | mask.offscreenRenderTarget = 1; | ||||
if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) | |||||
if (tex_usage & PIPE_BIND_DEPTH_STENCIL) | |||||
mask.zStencil = 1; | mask.zStencil = 1; | ||||
if (tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) | |||||
if (tex_usage & PIPE_BIND_SAMPLER_VIEW) | |||||
mask.texture = 1; | mask.texture = 1; | ||||
if ((result.u & mask.value) == mask.value) | if ((result.u & mask.value) == mask.value) | ||||
* duplicated list of supported formats which is prone to getting | * duplicated list of supported formats which is prone to getting | ||||
* out of sync: | * out of sync: | ||||
*/ | */ | ||||
if(tex_usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DEPTH_STENCIL)) | |||||
if(tex_usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL)) | |||||
return svga_translate_format_render(format) != SVGA3D_FORMAT_INVALID; | return svga_translate_format_render(format) != SVGA3D_FORMAT_INVALID; | ||||
else | else | ||||
return svga_translate_format(format) != SVGA3D_FORMAT_INVALID; | return svga_translate_format(format) != SVGA3D_FORMAT_INVALID; |
data = (const float (*)[4])pipe_buffer_map(&svga->pipe, | data = (const float (*)[4])pipe_buffer_map(&svga->pipe, | ||||
svga->curr.cb[unit], | svga->curr.cb[unit], | ||||
PIPE_BUFFER_USAGE_CPU_READ, | |||||
PIPE_TRANSFER_READ, | |||||
&transfer); | &transfer); | ||||
if (data == NULL) { | if (data == NULL) { | ||||
ret = PIPE_ERROR_OUT_OF_MEMORY; | ret = PIPE_ERROR_OUT_OF_MEMORY; |
svga->swc->surface_relocation(svga->swc, | svga->swc->surface_relocation(svga->swc, | ||||
&ts[i].value, | &ts[i].value, | ||||
queue.bind[i].view->v->handle, | queue.bind[i].view->v->handle, | ||||
PIPE_BUFFER_USAGE_GPU_READ); | |||||
SVGA_RELOC_READ); | |||||
} | } | ||||
else { | else { | ||||
ts[i].value = SVGA3D_INVALID_ID; | ts[i].value = SVGA3D_INVALID_ID; |
vbuffer->buffer, | vbuffer->buffer, | ||||
vel->src_offset, | vel->src_offset, | ||||
util_format_get_blocksize(vel->src_format), | util_format_get_blocksize(vel->src_format), | ||||
PIPE_BUFFER_USAGE_CPU_READ, | |||||
PIPE_TRANSFER_READ, | |||||
&transfer); | &transfer); | ||||
translate->set_buffer(translate, vel->vertex_buffer_index, | translate->set_buffer(translate, vel->vertex_buffer_index, |
{ | { | ||||
struct svga_texture *tex = svga_texture(pt); | struct svga_texture *tex = svga_texture(pt); | ||||
struct svga_surface *s; | struct svga_surface *s; | ||||
boolean render = flags & PIPE_BUFFER_USAGE_GPU_WRITE ? TRUE : FALSE; | |||||
boolean render = (flags & (PIPE_BIND_RENDER_TARGET | | |||||
PIPE_BIND_DEPTH_STENCIL)) ? TRUE : FALSE; | |||||
boolean view = FALSE; | boolean view = FALSE; | ||||
SVGA3dSurfaceFormat format; | SVGA3dSurfaceFormat format; | ||||
format = svga_translate_format_render(pt->format); | format = svga_translate_format_render(pt->format); | ||||
assert(format != SVGA3D_FORMAT_INVALID); | assert(format != SVGA3D_FORMAT_INVALID); | ||||
assert(!(flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE)); | |||||
if (svga_screen(screen)->debug.force_surface_view) | if (svga_screen(screen)->debug.force_surface_view) | ||||
view = TRUE; | view = TRUE; |
if (!svga_render->vbuf) { | if (!svga_render->vbuf) { | ||||
svga_render->vbuf_size = MAX2(size, svga_render->vbuf_alloc_size); | svga_render->vbuf_size = MAX2(size, svga_render->vbuf_alloc_size); | ||||
svga_render->vbuf = pipe_buffer_create(screen, | svga_render->vbuf = pipe_buffer_create(screen, | ||||
16, | |||||
PIPE_BUFFER_USAGE_VERTEX, | |||||
PIPE_BIND_VERTEX_BUFFER, | |||||
svga_render->vbuf_size); | svga_render->vbuf_size); | ||||
if(!svga_render->vbuf) { | if(!svga_render->vbuf) { | ||||
svga_context_flush(svga, NULL); | svga_context_flush(svga, NULL); | ||||
svga_render->vbuf = pipe_buffer_create(screen, | svga_render->vbuf = pipe_buffer_create(screen, | ||||
16, | |||||
PIPE_BUFFER_USAGE_VERTEX, | |||||
PIPE_BIND_VERTEX_BUFFER, | |||||
svga_render->vbuf_size); | svga_render->vbuf_size); | ||||
assert(svga_render->vbuf); | assert(svga_render->vbuf); | ||||
} | } | ||||
if (!svga_render->ibuf) { | if (!svga_render->ibuf) { | ||||
svga_render->ibuf_size = MAX2(size, svga_render->ibuf_alloc_size); | svga_render->ibuf_size = MAX2(size, svga_render->ibuf_alloc_size); | ||||
svga_render->ibuf = pipe_buffer_create(screen, | svga_render->ibuf = pipe_buffer_create(screen, | ||||
2, | |||||
PIPE_BUFFER_USAGE_VERTEX, | |||||
PIPE_BIND_INDEX_BUFFER, | |||||
svga_render->ibuf_size); | svga_render->ibuf_size); | ||||
svga_render->ibuf_offset = 0; | svga_render->ibuf_offset = 0; | ||||
} | } |
for (i = 0; i < svga->curr.num_vertex_buffers; i++) { | for (i = 0; i < svga->curr.num_vertex_buffers; i++) { | ||||
map = pipe_buffer_map(&svga->pipe, | map = pipe_buffer_map(&svga->pipe, | ||||
svga->curr.vb[i].buffer, | svga->curr.vb[i].buffer, | ||||
PIPE_BUFFER_USAGE_CPU_READ, | |||||
PIPE_TRANSFER_READ, | |||||
&vb_transfer[i]); | &vb_transfer[i]); | ||||
draw_set_mapped_vertex_buffer(draw, i, map); | draw_set_mapped_vertex_buffer(draw, i, map); | ||||
/* Map index buffer, if present */ | /* Map index buffer, if present */ | ||||
if (indexBuffer) { | if (indexBuffer) { | ||||
map = pipe_buffer_map(&svga->pipe, indexBuffer, | map = pipe_buffer_map(&svga->pipe, indexBuffer, | ||||
PIPE_BUFFER_USAGE_CPU_READ, | |||||
PIPE_TRANSFER_READ, | |||||
&ib_transfer); | &ib_transfer); | ||||
draw_set_mapped_element_buffer_range(draw, | draw_set_mapped_element_buffer_range(draw, | ||||
if (svga->curr.cb[PIPE_SHADER_VERTEX]) { | if (svga->curr.cb[PIPE_SHADER_VERTEX]) { | ||||
map = pipe_buffer_map(&svga->pipe, | map = pipe_buffer_map(&svga->pipe, | ||||
svga->curr.cb[PIPE_SHADER_VERTEX], | svga->curr.cb[PIPE_SHADER_VERTEX], | ||||
PIPE_BUFFER_USAGE_CPU_READ, | |||||
PIPE_TRANSFER_READ, | |||||
&cb_transfer); | &cb_transfer); | ||||
assert(map); | assert(map); | ||||
draw_set_mapped_constant_buffer( | draw_set_mapped_constant_buffer( |
struct winsys_handle; | struct winsys_handle; | ||||
#define SVGA_BUFFER_USAGE_PINNED (PIPE_BUFFER_USAGE_CUSTOM << 0) | |||||
#define SVGA_BUFFER_USAGE_WRAPPED (PIPE_BUFFER_USAGE_CUSTOM << 1) | |||||
#define SVGA_BUFFER_USAGE_PINNED (1 << 0) | |||||
#define SVGA_BUFFER_USAGE_WRAPPED (1 << 1) | |||||
#define SVGA_RELOC_WRITE 0x1 | |||||
#define SVGA_RELOC_READ 0x2 | |||||
/** Opaque surface handle */ | /** Opaque surface handle */ |
trace_dump_member_end(); | trace_dump_member_end(); | ||||
trace_dump_member(uint, templat, last_level); | trace_dump_member(uint, templat, last_level); | ||||
trace_dump_member(uint, templat, tex_usage); | |||||
trace_dump_member(uint, templat, _usage); | |||||
trace_dump_member(uint, templat, bind); | |||||
trace_dump_member(uint, templat, flags); | |||||
trace_dump_struct_end(); | trace_dump_struct_end(); | ||||
} | } |
util_format_get_blocksize(t->format), | util_format_get_blocksize(t->format), | ||||
t->last_level, | t->last_level, | ||||
t->nr_samples, | t->nr_samples, | ||||
t->tex_usage, | |||||
t->bind, | |||||
NULL); | NULL); | ||||
pipe_mutex_unlock(tr_scr->list_mutex); | pipe_mutex_unlock(tr_scr->list_mutex); |
trace_dump_call_end(); | trace_dump_call_end(); | ||||
if(result) { | if(result) { | ||||
assert(!(result->usage & TRACE_BUFFER_USAGE_USER)); | |||||
result->usage |= TRACE_BUFFER_USAGE_USER; | |||||
assert(!(result->flags & TRACE_FLAG_USER_BUFFER)); | |||||
result->flags |= TRACE_FLAG_USER_BUFFER; | |||||
} | } | ||||
return trace_resource_create(tr_scr, result); | return trace_resource_create(tr_scr, result); |
* without mapping/unmapping. This flag marks user buffers, so that their | * without mapping/unmapping. This flag marks user buffers, so that their | ||||
* contents can be dumpped before being used by the pipe context. | * contents can be dumpped before being used by the pipe context. | ||||
*/ | */ | ||||
#define TRACE_BUFFER_USAGE_USER (1 << 31) | |||||
#define TRACE_FLAG_USER_BUFFER (1 << 31) | |||||
struct trace_screen | struct trace_screen |
#define PIPE_TEX_COMPARE_NONE 0 | #define PIPE_TEX_COMPARE_NONE 0 | ||||
#define PIPE_TEX_COMPARE_R_TO_TEXTURE 1 | #define PIPE_TEX_COMPARE_R_TO_TEXTURE 1 | ||||
#define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1 | |||||
#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* windows presentable buffer, ie a backbuffer */ | |||||
#define PIPE_TEXTURE_USAGE_SCANOUT 0x4 /* ie a frontbuffer */ | |||||
#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x8 | |||||
#define PIPE_TEXTURE_USAGE_SAMPLER 0x10 | |||||
#define PIPE_TEXTURE_USAGE_DYNAMIC 0x20 | |||||
#define PIPE_TEXTURE_USAGE_SHARED 0x40 | |||||
/** Pipe driver custom usage flags should be greater or equal to this value */ | |||||
#define PIPE_TEXTURE_USAGE_CUSTOM (1 << 16) | |||||
#define PIPE_TEXTURE_GEOM_NON_SQUARE 0x1 | |||||
#define PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO 0x2 | |||||
/** | /** | ||||
* Surface layout | |||||
* Surface layout -- a hint? Or some driver-internal poking out into | |||||
* the interface? | |||||
*/ | */ | ||||
#define PIPE_SURFACE_LAYOUT_LINEAR 0 | #define PIPE_SURFACE_LAYOUT_LINEAR 0 | ||||
/* | /* | ||||
* Buffer usage flags | |||||
* Resource binding flags -- state tracker must specify in advance all | |||||
* the ways a resource might be used. | |||||
*/ | */ | ||||
#define PIPE_BIND_DEPTH_STENCIL (1 << 0) /* get_tex_surface */ | |||||
#define PIPE_BIND_RENDER_TARGET (1 << 1) /* get_tex_surface */ | |||||
#define PIPE_BIND_SAMPLER_VIEW (1 << 2) /* get_sampler_view */ | |||||
#define PIPE_BIND_VERTEX_BUFFER (1 << 3) /* set_vertex_buffers */ | |||||
#define PIPE_BIND_INDEX_BUFFER (1 << 4) /* draw_elements */ | |||||
#define PIPE_BIND_CONSTANT_BUFFER (1 << 5) /* set_constant_buffer */ | |||||
#define PIPE_BIND_BLIT_SOURCE (1 << 6) /* surface_copy */ | |||||
#define PIPE_BIND_BLIT_DESTINATION (1 << 7) /* surface_copy, fill */ | |||||
#define PIPE_BIND_DISPLAY_TARGET (1 << 8) /* flush_front_buffer */ | |||||
#define PIPE_BIND_TRANSFER_WRITE (1 << 9) /* get_transfer */ | |||||
#define PIPE_BIND_TRANSFER_READ (1 << 10) /* get_transfer */ | |||||
#define PIPE_BIND_CUSTOM (1 << 16) /* state-tracker/winsys usages */ | |||||
/* The first two flags were previously part of the amorphous | |||||
* TEXTURE_USAGE, most of which are now descriptions of the ways a | |||||
* particular texture can be bound to the gallium pipeline. These two | |||||
* do not fit within that and probably need to be migrated to some | |||||
* other place. | |||||
* | |||||
* It seems like scanout is used by the Xorg state tracker to ask for | |||||
* a texture suitable for actual scanout (hence the name), which | |||||
* implies extra layout constraints on some hardware. It may also | |||||
* have some special meaning regarding mouse cursor images. | |||||
* | |||||
* The shared flag is quite underspecified, but certainly isn't a | |||||
* binding flag - it seems more like a message to the winsys to create | |||||
* a shareable allocation. Could it mean that this texture is a valid argument for | |||||
*/ | |||||
#define PIPE_BIND_SCANOUT (1 << 14) /* */ | |||||
#define PIPE_BIND_SHARED (1 << 15) /* get_texture_handle ??? */ | |||||
#define PIPE_BUFFER_USAGE_CPU_READ (1 << 0) | |||||
#define PIPE_BUFFER_USAGE_CPU_WRITE (1 << 1) | |||||
#define PIPE_BUFFER_USAGE_GPU_READ (1 << 2) | |||||
#define PIPE_BUFFER_USAGE_GPU_WRITE (1 << 3) | |||||
#define PIPE_BUFFER_USAGE_PIXEL (1 << 4) | |||||
#define PIPE_BUFFER_USAGE_VERTEX (1 << 5) | |||||
#define PIPE_BUFFER_USAGE_INDEX (1 << 6) | |||||
#define PIPE_BUFFER_USAGE_CONSTANT (1 << 7) | |||||
#define PIPE_BUFFER_USAGE_CUSTOM (1 << 16) | |||||
/* Convenient shortcuts */ | |||||
#define PIPE_BUFFER_USAGE_CPU_READ_WRITE \ | |||||
( PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE ) | |||||
#define PIPE_BUFFER_USAGE_GPU_READ_WRITE \ | |||||
( PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE ) | |||||
#define PIPE_BUFFER_USAGE_WRITE \ | |||||
( PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_GPU_WRITE ) | |||||
/* Flags for the driver about resource behaviour: | |||||
*/ | |||||
#define PIPE_RESOURCE_FLAG_GEN_MIPS (1 << 0) /* Driver performs autogen mips */ | |||||
#define PIPE_RESOURCE_FLAG_DRV_PRIV (1 << 16) /* driver/winsys private */ | |||||
#define PIPE_RESOURCE_FLAG_ST_PRIV (1 << 24) /* state-tracker/winsys private */ | |||||
/* Hint about the expected lifecycle of a resource. | |||||
*/ | |||||
#define PIPE_USAGE_DEFAULT 0 /* many uploads, draws intermixed */ | |||||
#define PIPE_USAGE_DYNAMIC 1 /* many uploads, draws intermixed */ | |||||
#define PIPE_USAGE_STATIC 2 /* same as immutable?? */ | |||||
#define PIPE_USAGE_IMMUTABLE 3 /* no change after first upload */ | |||||
#define PIPE_USAGE_STREAM 4 /* upload, draw, upload, draw */ | |||||
/* These are intended to be used in calls to is_format_supported, but | |||||
* no driver actually uses these flags, and only the glx/xlib state | |||||
* tracker issues them. | |||||
* | |||||
* Deprecate? | |||||
*/ | |||||
#define PIPE_TEXTURE_GEOM_NON_SQUARE 0x1 | |||||
#define PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO 0x2 | |||||
/** | /** |
unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */ | unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */ | ||||
unsigned offset; /**< offset from start of buffer, in bytes */ | unsigned offset; /**< offset from start of buffer, in bytes */ | ||||
unsigned usage; /**< bitmask of PIPE_BUFFER_USAGE_x */ | |||||
unsigned usage; /**< bitmask of PIPE_BIND_x */ | |||||
unsigned zslice; | unsigned zslice; | ||||
unsigned face; | unsigned face; | ||||
unsigned width0; | unsigned width0; | ||||
unsigned height0; | unsigned height0; | ||||
unsigned depth0; | unsigned depth0; | ||||
unsigned last_level:8; /**< Index of last mipmap level present/defined */ | unsigned last_level:8; /**< Index of last mipmap level present/defined */ | ||||
unsigned nr_samples:8; /**< for multisampled surfaces, nr of samples */ | unsigned nr_samples:8; /**< for multisampled surfaces, nr of samples */ | ||||
unsigned _usage:8; /* PIPE_USAGE_x (not a bitmask) */ | |||||
unsigned usage; /* xxx: unify with tex_usage */ | |||||
unsigned tex_usage; /**< bitmask of PIPE_TEXTURE_USAGE_* */ | |||||
unsigned bind; /* PIPE_BIND_x */ | |||||
unsigned flags; /* PIPE_RESOURCE_FLAG_x */ | |||||
}; | }; | ||||
* pools, or obtained directly from the windowing system. | * pools, or obtained directly from the windowing system. | ||||
* | * | ||||
* This callback is invoked by the pipe_screen when creating a texture marked | * This callback is invoked by the pipe_screen when creating a texture marked | ||||
* with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying | |||||
* with the PIPE_BIND_DISPLAY_TARGET flag to get the underlying | |||||
* storage. | * storage. | ||||
*/ | */ | ||||
struct sw_displaytarget * | struct sw_displaytarget * |
case ST_ATTACHMENT_FRONT_RIGHT: | case ST_ATTACHMENT_FRONT_RIGHT: | ||||
case ST_ATTACHMENT_BACK_RIGHT: | case ST_ATTACHMENT_BACK_RIGHT: | ||||
format = drawable->stvis.color_format; | format = drawable->stvis.color_format; | ||||
tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET | | |||||
PIPE_TEXTURE_USAGE_RENDER_TARGET; | |||||
tex_usage = PIPE_BIND_DISPLAY_TARGET | | |||||
PIPE_BIND_RENDER_TARGET; | |||||
break; | break; | ||||
case ST_ATTACHMENT_DEPTH_STENCIL: | case ST_ATTACHMENT_DEPTH_STENCIL: | ||||
format = drawable->stvis.depth_stencil_format; | format = drawable->stvis.depth_stencil_format; | ||||
tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; | |||||
tex_usage = PIPE_BIND_DEPTH_STENCIL; | |||||
break; | break; | ||||
default: | default: | ||||
format = PIPE_FORMAT_NONE; | format = PIPE_FORMAT_NONE; |
pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM, | pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM, | ||||
PIPE_TEXTURE_2D, | PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); | |||||
PIPE_BIND_DEPTH_STENCIL, 0); | |||||
pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM, | pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM, | ||||
PIPE_TEXTURE_2D, | PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); | |||||
PIPE_BIND_DEPTH_STENCIL, 0); | |||||
pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM, | pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM, | ||||
PIPE_TEXTURE_2D, | PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); | |||||
PIPE_BIND_DEPTH_STENCIL, 0); | |||||
pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8Z24_UNORM, | pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8Z24_UNORM, | ||||
PIPE_TEXTURE_2D, | PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); | |||||
PIPE_BIND_DEPTH_STENCIL, 0); | |||||
pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM, | pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM, | ||||
PIPE_TEXTURE_2D, | PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); | |||||
PIPE_BIND_RENDER_TARGET, 0); | |||||
pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM, | pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM, | ||||
PIPE_TEXTURE_2D, | PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); | |||||
PIPE_BIND_RENDER_TARGET, 0); | |||||
pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM, | pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM, | ||||
PIPE_TEXTURE_2D, | PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); | |||||
PIPE_BIND_RENDER_TARGET, 0); | |||||
/* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */ | /* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */ | ||||
if (screen->sPriv->dri2.loader && | if (screen->sPriv->dri2.loader && | ||||
(screen->sPriv->dri2.loader->getBuffersWithFormat != NULL)) { | (screen->sPriv->dri2.loader->getBuffersWithFormat != NULL)) { | ||||
pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM, | pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM, | ||||
PIPE_TEXTURE_2D, | PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); | |||||
PIPE_BIND_DEPTH_STENCIL, 0); | |||||
pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM, | pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM, | ||||
PIPE_TEXTURE_2D, | PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); | |||||
PIPE_BIND_DEPTH_STENCIL, 0); | |||||
} else { | } else { | ||||
pf_z16 = FALSE; | pf_z16 = FALSE; | ||||
pf_z32 = FALSE; | pf_z32 = FALSE; |
pipe_resource_reference(&drawable->textures[i], NULL); | pipe_resource_reference(&drawable->textures[i], NULL); | ||||
memset(&templ, 0, sizeof(templ)); | memset(&templ, 0, sizeof(templ)); | ||||
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; | |||||
templ.tex_usage = PIPE_BIND_RENDER_TARGET; | |||||
templ.target = PIPE_TEXTURE_2D; | templ.target = PIPE_TEXTURE_2D; | ||||
templ.last_level = 0; | templ.last_level = 0; | ||||
templ.width0 = dri_drawable->w; | templ.width0 = dri_drawable->w; |
*/ | */ | ||||
static struct pipe_surface * | static struct pipe_surface * | ||||
get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf, | get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf, | ||||
enum native_attachment natt) | |||||
enum native_attachment natt, | |||||
unsigned bind) | |||||
{ | { | ||||
struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS]; | struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS]; | ||||
struct pipe_surface *psurf; | struct pipe_surface *psurf; | ||||
return NULL; | return NULL; | ||||
psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt], | psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt], | ||||
0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
0, 0, 0, bind); | |||||
pipe_resource_reference(&textures[natt], NULL); | pipe_resource_reference(&textures[natt], NULL); | ||||
return psurf; | return psurf; | ||||
return EGL_FALSE; | return EGL_FALSE; | ||||
} | } | ||||
psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); | |||||
psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT, | |||||
PIPE_BIND_BLIT_DESTINATION); | |||||
if (psurf) { | if (psurf) { | ||||
struct pipe_surface *psrc; | struct pipe_surface *psrc; | ||||
psrc = screen->get_tex_surface(screen, gsurf->render_texture, | psrc = screen->get_tex_surface(screen, gsurf->render_texture, | ||||
0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ); | |||||
0, 0, 0, PIPE_BIND_BLIT_SOURCE); | |||||
if (psrc) { | if (psrc) { | ||||
gdpy->pipe->surface_copy(gdpy->pipe, psurf, 0, 0, | gdpy->pipe->surface_copy(gdpy->pipe, psurf, 0, 0, | ||||
psrc, 0, 0, psurf->width, psurf->height); | psrc, 0, 0, psurf->width, psurf->height); |
templ.height0 = ksurf->height; | templ.height0 = ksurf->height; | ||||
templ.depth0 = 1; | templ.depth0 = 1; | ||||
templ.format = ksurf->color_format; | templ.format = ksurf->color_format; | ||||
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; | |||||
templ.tex_usage = PIPE_BIND_RENDER_TARGET; | |||||
if (ksurf->type == KMS_SURFACE_TYPE_SCANOUT) | if (ksurf->type == KMS_SURFACE_TYPE_SCANOUT) | ||||
templ.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT; | |||||
templ.tex_usage |= PIPE_BIND_SCANOUT; | |||||
} | } | ||||
/* create textures */ | /* create textures */ | ||||
{ | { | ||||
return ndpy->screen->is_format_supported(ndpy->screen, | return ndpy->screen->is_format_supported(ndpy->screen, | ||||
fmt, PIPE_TEXTURE_2D, | fmt, PIPE_TEXTURE_2D, | ||||
(is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET : | |||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); | |||||
(is_color) ? PIPE_BIND_RENDER_TARGET : | |||||
PIPE_BIND_DEPTH_STENCIL, 0); | |||||
} | } | ||||
static const struct native_config ** | static const struct native_config ** |
templ.height0 = dri2surf->height; | templ.height0 = dri2surf->height; | ||||
templ.depth0 = 1; | templ.depth0 = 1; | ||||
templ.format = dri2surf->color_format; | templ.format = dri2surf->color_format; | ||||
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; | |||||
templ.bind = PIPE_BIND_RENDER_TARGET; | |||||
valid_mask = 0x0; | valid_mask = 0x0; | ||||
for (i = 0; i < num_xbufs; i++) { | for (i = 0; i < num_xbufs; i++) { | ||||
templ.height0 = dri2surf->height; | templ.height0 = dri2surf->height; | ||||
templ.depth0 = 1; | templ.depth0 = 1; | ||||
templ.format = dri2surf->color_format; | templ.format = dri2surf->color_format; | ||||
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; | |||||
templ.bind = PIPE_BIND_RENDER_TARGET; | |||||
for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { | for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { | ||||
if (native_attachment_mask_test(buffer_mask, att)) { | if (native_attachment_mask_test(buffer_mask, att)) { | ||||
enum pipe_format fmt, boolean is_color) | enum pipe_format fmt, boolean is_color) | ||||
{ | { | ||||
return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, | return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, | ||||
(is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET : | |||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); | |||||
(is_color) ? PIPE_BIND_RENDER_TARGET : | |||||
PIPE_BIND_DEPTH_STENCIL, 0); | |||||
} | } | ||||
static boolean | static boolean |
templ.width0 = xsurf->width; | templ.width0 = xsurf->width; | ||||
templ.height0 = xsurf->height; | templ.height0 = xsurf->height; | ||||
templ.depth0 = 1; | templ.depth0 = 1; | ||||
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; | |||||
templ.bind = PIPE_BIND_RENDER_TARGET; | |||||
if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) { | if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) { | ||||
switch (which) { | switch (which) { | ||||
case NATIVE_ATTACHMENT_FRONT_LEFT: | case NATIVE_ATTACHMENT_FRONT_LEFT: | ||||
case NATIVE_ATTACHMENT_FRONT_RIGHT: | case NATIVE_ATTACHMENT_FRONT_RIGHT: | ||||
templ.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT; | |||||
templ.bind |= PIPE_BIND_SCANOUT; | |||||
break; | break; | ||||
case NATIVE_ATTACHMENT_BACK_LEFT: | case NATIVE_ATTACHMENT_BACK_LEFT: | ||||
case NATIVE_ATTACHMENT_BACK_RIGHT: | case NATIVE_ATTACHMENT_BACK_RIGHT: | ||||
templ.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; | |||||
templ.bind |= PIPE_BIND_DISPLAY_TARGET; | |||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
pipe_surface_reference(&xsurf->draw_surface, NULL); | pipe_surface_reference(&xsurf->draw_surface, NULL); | ||||
psurf = screen->get_tex_surface(screen, | psurf = screen->get_tex_surface(screen, | ||||
xbuf->texture, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ); | |||||
xbuf->texture, 0, 0, 0, PIPE_BIND_DISPLAY_TARGET); | |||||
if (!psurf) | if (!psurf) | ||||
return FALSE; | return FALSE; | ||||
choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil) | choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil) | ||||
{ | { | ||||
const enum pipe_texture_target target = PIPE_TEXTURE_2D; | const enum pipe_texture_target target = PIPE_TEXTURE_2D; | ||||
const unsigned tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; | |||||
const unsigned tex_usage = PIPE_BIND_DEPTH_STENCIL; | |||||
const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE | | const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE | | ||||
PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO); | PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO); | ||||
enum pipe_format formats[8], fmt; | enum pipe_format formats[8], fmt; |
pipe_surface_reference(&xstfb->display_surface, NULL); | pipe_surface_reference(&xstfb->display_surface, NULL); | ||||
psurf = xstfb->screen->get_tex_surface(xstfb->screen, | psurf = xstfb->screen->get_tex_surface(xstfb->screen, | ||||
ptex, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ); | |||||
ptex, 0, 0, 0, PIPE_BIND_DISPLAY_TARGET); | |||||
if (!psurf) | if (!psurf) | ||||
return FALSE; | return FALSE; | ||||
} | } | ||||
src = xstfb->screen->get_tex_surface(xstfb->screen, | src = xstfb->screen->get_tex_surface(xstfb->screen, | ||||
src_ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ); | |||||
src_ptex, 0, 0, 0, PIPE_BIND_BLIT_SOURCE); | |||||
dst = xstfb->screen->get_tex_surface(xstfb->screen, | dst = xstfb->screen->get_tex_surface(xstfb->screen, | ||||
dst_ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
dst_ptex, 0, 0, 0, PIPE_BIND_BLIT_DESTINATION); | |||||
if (src && dst) | if (src && dst) | ||||
pipe->surface_copy(pipe, dst, x, y, src, x, y, width, height); | pipe->surface_copy(pipe, dst, x, y, src, x, y, width, height); | ||||
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { | for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { | ||||
enum pipe_format format; | enum pipe_format format; | ||||
unsigned tex_usage; | |||||
unsigned bind; | |||||
/* the texture already exists or not requested */ | /* the texture already exists or not requested */ | ||||
if (xstfb->textures[i] || !(mask & (1 << i))) { | if (xstfb->textures[i] || !(mask & (1 << i))) { | ||||
case ST_ATTACHMENT_FRONT_RIGHT: | case ST_ATTACHMENT_FRONT_RIGHT: | ||||
case ST_ATTACHMENT_BACK_RIGHT: | case ST_ATTACHMENT_BACK_RIGHT: | ||||
format = xstfb->stvis.color_format; | format = xstfb->stvis.color_format; | ||||
tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET | | |||||
PIPE_TEXTURE_USAGE_RENDER_TARGET; | |||||
bind = PIPE_BIND_DISPLAY_TARGET | | |||||
PIPE_BIND_RENDER_TARGET; | |||||
break; | break; | ||||
case ST_ATTACHMENT_DEPTH_STENCIL: | case ST_ATTACHMENT_DEPTH_STENCIL: | ||||
format = xstfb->stvis.depth_stencil_format; | format = xstfb->stvis.depth_stencil_format; | ||||
tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; | |||||
bind = PIPE_BIND_DEPTH_STENCIL; | |||||
break; | break; | ||||
default: | default: | ||||
format = PIPE_FORMAT_NONE; | format = PIPE_FORMAT_NONE; | ||||
if (format != PIPE_FORMAT_NONE) { | if (format != PIPE_FORMAT_NONE) { | ||||
templ.format = format; | templ.format = format; | ||||
templ.tex_usage = tex_usage; | |||||
templ.bind = bind; | |||||
xstfb->textures[i] = | xstfb->textures[i] = | ||||
xstfb->screen->resource_create(xstfb->screen, &templ); | xstfb->screen->resource_create(xstfb->screen, &templ); |
templ.width0 = color_data_len; | templ.width0 = color_data_len; | ||||
templ.height0 = 1; | templ.height0 = 1; | ||||
templ.depth0 = 1; | templ.depth0 = 1; | ||||
templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; | |||||
templ.bind = PIPE_BIND_SAMPLER_VIEW; | |||||
tex = screen->resource_create(screen, &templ); | tex = screen->resource_create(screen, &templ); | ||||
struct pipe_framebuffer_state fb; | struct pipe_framebuffer_state fb; | ||||
struct pipe_surface *dst_surf = pipe->screen->get_tex_surface( | struct pipe_surface *dst_surf = pipe->screen->get_tex_surface( | ||||
pipe->screen, dst->sampler_view->texture, 0, 0, 0, | pipe->screen, dst->sampler_view->texture, 0, 0, 0, | ||||
PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
PIPE_BIND_RENDER_TARGET); | |||||
/* drawing dest */ | /* drawing dest */ | ||||
memset(&fb, 0, sizeof(fb)); | memset(&fb, 0, sizeof(fb)); | ||||
* avoid gratuitous rendering synchronization. */ | * avoid gratuitous rendering synchronization. */ | ||||
pipe_resource_reference(cbuf, NULL); | pipe_resource_reference(cbuf, NULL); | ||||
*cbuf = pipe_buffer_create(pipe->screen, 16, | |||||
PIPE_BUFFER_USAGE_CONSTANT, | |||||
*cbuf = pipe_buffer_create(pipe->screen, | |||||
PIPE_BIND_CONSTANT_BUFFER, | |||||
param_bytes); | param_bytes); | ||||
if (*cbuf) { | if (*cbuf) { |
buf = pipe_user_buffer_create(pipe->screen, | buf = pipe_user_buffer_create(pipe->screen, | ||||
st->clear.vertices, | st->clear.vertices, | ||||
sizeof(st->clear.vertices), | sizeof(st->clear.vertices), | ||||
PIPE_BUFFER_USAGE_VERTEX); | |||||
PIPE_BIND_VERTEX_BUFFER); | |||||
/* draw */ | /* draw */ |
image->sampler.normalized_coords = 1; | image->sampler.normalized_coords = 1; | ||||
assert(screen->is_format_supported(screen, pformat, PIPE_TEXTURE_2D, | assert(screen->is_format_supported(screen, pformat, PIPE_TEXTURE_2D, | ||||
PIPE_TEXTURE_USAGE_SAMPLER, 0)); | |||||
PIPE_BIND_SAMPLER_VIEW, 0)); | |||||
memset(&pt, 0, sizeof(pt)); | memset(&pt, 0, sizeof(pt)); | ||||
pt.target = PIPE_TEXTURE_2D; | pt.target = PIPE_TEXTURE_2D; | ||||
pt.width0 = width; | pt.width0 = width; | ||||
pt.height0 = height; | pt.height0 = height; | ||||
pt.depth0 = 1; | pt.depth0 = 1; | ||||
pt.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; | |||||
pt.bind = PIPE_BIND_SAMPLER_VIEW; | |||||
newtex = screen->resource_create(screen, &pt); | newtex = screen->resource_create(screen, &pt); | ||||
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); | pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); | ||||
surf = screen->get_tex_surface(screen, image_texture(src), 0, 0, 0, | surf = screen->get_tex_surface(screen, image_texture(src), 0, 0, 0, | ||||
PIPE_BUFFER_USAGE_GPU_READ); | |||||
PIPE_BIND_BLIT_SOURCE); | |||||
vg_copy_surface(ctx, strb->surface, dx, dy, | vg_copy_surface(ctx, strb->surface, dx, dy, | ||||
surf, sx+src->x, sy+src->y, width, height); | surf, sx+src->x, sy+src->y, width, height); | ||||
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); | pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); | ||||
surf = screen->get_tex_surface(screen, image_texture(dst), 0, 0, 0, | surf = screen->get_tex_surface(screen, image_texture(dst), 0, 0, 0, | ||||
PIPE_BUFFER_USAGE_GPU_WRITE | | |||||
PIPE_BUFFER_USAGE_GPU_READ); | |||||
PIPE_BIND_BLIT_SOURCE); | |||||
vg_copy_surface(ctx, surf, dst->x + dx, dst->y + dy, | vg_copy_surface(ctx, surf, dst->x + dx, dst->y + dy, | ||||
strb->surface, sx, sy, width, height); | strb->surface, sx, sy, width, height); | ||||
*/ | */ | ||||
pipe_resource_reference(cbuf, NULL); | pipe_resource_reference(cbuf, NULL); | ||||
*cbuf = pipe_buffer_create(ctx->pipe->screen, 1, | |||||
PIPE_BUFFER_USAGE_CONSTANT, | |||||
*cbuf = pipe_buffer_create(ctx->pipe->screen, | |||||
PIPE_BIND_CONSTANT_BUFFER, | |||||
param_bytes); | param_bytes); | ||||
if (*cbuf) { | if (*cbuf) { | ||||
st_no_flush_pipe_buffer_write(ctx, *cbuf, | st_no_flush_pipe_buffer_write(ctx, *cbuf, | ||||
*/ | */ | ||||
pipe_resource_reference(cbuf, NULL); | pipe_resource_reference(cbuf, NULL); | ||||
*cbuf = pipe_buffer_create(ctx->pipe->screen, 1, | |||||
PIPE_BUFFER_USAGE_CONSTANT, | |||||
*cbuf = pipe_buffer_create(ctx->pipe->screen, | |||||
PIPE_BIND_CONSTANT_BUFFER, | |||||
param_bytes); | param_bytes); | ||||
if (*cbuf) { | if (*cbuf) { | ||||
st_no_flush_pipe_buffer_write(ctx, *cbuf, 0, param_bytes, color); | st_no_flush_pipe_buffer_write(ctx, *cbuf, 0, param_bytes, color); | ||||
struct vg_context *ctx = vg_current_context(); | struct vg_context *ctx = vg_current_context(); | ||||
struct pipe_resource *texture = sampler_view->texture; | struct pipe_resource *texture = sampler_view->texture; | ||||
struct pipe_surface *surface = | struct pipe_surface *surface = | ||||
alpha_mask_surface(ctx, PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
alpha_mask_surface(ctx, PIPE_BIND_RENDER_TARGET); | |||||
VGint offsets[4], loc[4]; | VGint offsets[4], loc[4]; | ||||
if (!surface) | if (!surface) | ||||
pt.width0 = width; | pt.width0 = width; | ||||
pt.height0 = height; | pt.height0 = height; | ||||
pt.depth0 = 1; | pt.depth0 = 1; | ||||
pt.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; | |||||
pt.tex_usage = PIPE_BIND_SAMPLER_VIEW; | |||||
pt.compressed = 0; | pt.compressed = 0; | ||||
texture = screen->resource_create(screen, &pt); | texture = screen->resource_create(screen, &pt); | ||||
struct vg_context *ctx = vg_current_context(); | struct vg_context *ctx = vg_current_context(); | ||||
VGfloat alpha_color[4] = {.0f, .0f, .0f, value}; | VGfloat alpha_color[4] = {.0f, .0f, .0f, value}; | ||||
struct pipe_surface *surf = alpha_mask_surface( | struct pipe_surface *surf = alpha_mask_surface( | ||||
ctx, PIPE_BUFFER_USAGE_GPU_WRITE); | |||||
ctx, PIPE_BIND_RENDER_TARGET); | |||||
#if DEBUG_MASKS | #if DEBUG_MASKS | ||||
debug_printf("mask_fill(%d, %d, %d, %d) with rgba(%f, %f, %f, %f)\n", | debug_printf("mask_fill(%d, %d, %d, %d) with rgba(%f, %f, %f, %f)\n", |
templ.width0 = 1024; | templ.width0 = 1024; | ||||
templ.height0 = 1; | templ.height0 = 1; | ||||
templ.depth0 = 1; | templ.depth0 = 1; | ||||
templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; | |||||
templ.bind = PIPE_BIND_SAMPLER_VIEW; | |||||
tex = screen->resource_create(screen, &templ); | tex = screen->resource_create(screen, &templ); | ||||
poly->vbuf= pipe_user_buffer_create(poly->screen, | poly->vbuf= pipe_user_buffer_create(poly->screen, | ||||
poly->data, | poly->data, | ||||
vert_size, | vert_size, | ||||
PIPE_BUFFER_USAGE_VERTEX); | |||||
PIPE_BIND_VERTEX_BUFFER); | |||||
poly->dirty = VG_FALSE; | poly->dirty = VG_FALSE; | ||||
} | } | ||||