mesa/st: add ARB_texture_view support
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> Reviewed-by: Roland Scheidegger <sroland@vmware.com>
This commit is contained in:
@@ -194,7 +194,7 @@ get_texture_format_swizzle(const struct st_texture_object *stObj)
|
||||
|
||||
|
||||
/**
|
||||
* Return TRUE if the texture's sampler view swizzle is equal to
|
||||
* Return TRUE if the texture's sampler view swizzle is not equal to
|
||||
* the texture's swizzle.
|
||||
*
|
||||
* \param stObj the st texture object,
|
||||
@@ -214,9 +214,20 @@ check_sampler_swizzle(const struct st_texture_object *stObj,
|
||||
|
||||
static unsigned last_level(struct st_texture_object *stObj)
|
||||
{
|
||||
return MIN2(stObj->base._MaxLevel, stObj->pt->last_level);
|
||||
unsigned ret = MIN2(stObj->base.MinLevel + stObj->base._MaxLevel,
|
||||
stObj->pt->last_level);
|
||||
if (stObj->base.Immutable)
|
||||
ret = MIN2(ret, stObj->base.MinLevel + stObj->base.NumLevels - 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned last_layer(struct st_texture_object *stObj)
|
||||
{
|
||||
if (stObj->base.Immutable)
|
||||
return MIN2(stObj->base.MinLayer + stObj->base.NumLayers - 1,
|
||||
stObj->pt->array_size - 1);
|
||||
return stObj->pt->array_size - 1;
|
||||
}
|
||||
|
||||
static struct pipe_sampler_view *
|
||||
st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
|
||||
@@ -249,9 +260,13 @@ st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
|
||||
templ.u.buf.first_element = f;
|
||||
templ.u.buf.last_element = f + (n - 1);
|
||||
} else {
|
||||
templ.u.tex.first_level = stObj->base.BaseLevel;
|
||||
templ.u.tex.first_level = stObj->base.MinLevel + stObj->base.BaseLevel;
|
||||
templ.u.tex.last_level = last_level(stObj);
|
||||
assert(templ.u.tex.first_level <= templ.u.tex.last_level);
|
||||
templ.u.tex.first_layer = stObj->base.MinLayer;
|
||||
templ.u.tex.last_layer = last_layer(stObj);
|
||||
assert(templ.u.tex.first_layer <= templ.u.tex.last_layer);
|
||||
templ.target = gl_target_to_pipe(stObj->base.Target);
|
||||
}
|
||||
|
||||
if (swizzle != SWIZZLE_NOOP) {
|
||||
@@ -287,8 +302,11 @@ st_get_texture_sampler_view_from_stobj(struct st_context *st,
|
||||
if (*sv) {
|
||||
if (check_sampler_swizzle(stObj, *sv) ||
|
||||
(format != (*sv)->format) ||
|
||||
stObj->base.BaseLevel != (*sv)->u.tex.first_level ||
|
||||
last_level(stObj) != (*sv)->u.tex.last_level) {
|
||||
gl_target_to_pipe(stObj->base.Target) != (*sv)->target ||
|
||||
stObj->base.MinLevel + stObj->base.BaseLevel != (*sv)->u.tex.first_level ||
|
||||
last_level(stObj) != (*sv)->u.tex.last_level ||
|
||||
stObj->base.MinLayer != (*sv)->u.tex.first_layer ||
|
||||
last_layer(stObj) != (*sv)->u.tex.last_layer) {
|
||||
pipe_sampler_view_reference(sv, NULL);
|
||||
}
|
||||
}
|
||||
|
@@ -450,6 +450,16 @@ st_update_renderbuffer_surface(struct st_context *st,
|
||||
last_layer = strb->rtt_face + strb->rtt_slice;
|
||||
}
|
||||
|
||||
/* Adjust for texture views */
|
||||
if (strb->is_rtt) {
|
||||
struct gl_texture_object *tex = strb->Base.TexImage->TexObject;
|
||||
first_layer += tex->MinLayer;
|
||||
if (!strb->rtt_layered)
|
||||
last_layer += tex->MinLayer;
|
||||
else
|
||||
last_layer = MIN2(first_layer + tex->NumLayers - 1, last_layer);
|
||||
}
|
||||
|
||||
if (!strb->surface ||
|
||||
strb->surface->texture->nr_samples != strb->Base.NumSamples ||
|
||||
strb->surface->format != format ||
|
||||
|
@@ -829,12 +829,12 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims,
|
||||
blit.src.level = 0;
|
||||
blit.src.format = src_format;
|
||||
blit.dst.resource = dst;
|
||||
blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level;
|
||||
blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->TexObject->MinLevel + texImage->Level;
|
||||
blit.dst.format = dst_format;
|
||||
blit.src.box.x = blit.src.box.y = blit.src.box.z = 0;
|
||||
blit.dst.box.x = xoffset;
|
||||
blit.dst.box.y = yoffset;
|
||||
blit.dst.box.z = zoffset + texImage->Face;
|
||||
blit.dst.box.z = zoffset + texImage->Face + texImage->TexObject->MinLayer;
|
||||
blit.src.box.width = blit.dst.box.width = width;
|
||||
blit.src.box.height = blit.dst.box.height = height;
|
||||
blit.src.box.depth = blit.dst.box.depth = depth;
|
||||
@@ -916,7 +916,8 @@ st_GetTexImage(struct gl_context * ctx,
|
||||
GLuint height = texImage->Height;
|
||||
GLuint depth = texImage->Depth;
|
||||
struct st_texture_image *stImage = st_texture_image(texImage);
|
||||
struct pipe_resource *src = st_texture_object(texImage->TexObject)->pt;
|
||||
struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
|
||||
struct pipe_resource *src = stObj->pt;
|
||||
struct pipe_resource *dst = NULL;
|
||||
struct pipe_resource dst_templ;
|
||||
enum pipe_format dst_format, src_format;
|
||||
@@ -970,7 +971,10 @@ st_GetTexImage(struct gl_context * ctx,
|
||||
* - Luminance alpha must be returned as (L,0,0,A).
|
||||
* - Intensity must be returned as (I,0,0,1)
|
||||
*/
|
||||
src_format = util_format_linear(src->format);
|
||||
if (stObj->surface_based)
|
||||
src_format = util_format_linear(stObj->surface_format);
|
||||
else
|
||||
src_format = util_format_linear(src->format);
|
||||
src_format = util_format_luminance_to_red(src_format);
|
||||
src_format = util_format_intensity_to_red(src_format);
|
||||
|
||||
@@ -1069,14 +1073,14 @@ st_GetTexImage(struct gl_context * ctx,
|
||||
|
||||
memset(&blit, 0, sizeof(blit));
|
||||
blit.src.resource = src;
|
||||
blit.src.level = texImage->Level;
|
||||
blit.src.level = texImage->Level + texImage->TexObject->MinLevel;
|
||||
blit.src.format = src_format;
|
||||
blit.dst.resource = dst;
|
||||
blit.dst.level = 0;
|
||||
blit.dst.format = dst->format;
|
||||
blit.src.box.x = blit.dst.box.x = 0;
|
||||
blit.src.box.y = blit.dst.box.y = 0;
|
||||
blit.src.box.z = texImage->Face;
|
||||
blit.src.box.z = texImage->Face + texImage->TexObject->MinLayer;
|
||||
blit.dst.box.z = 0;
|
||||
blit.src.box.width = blit.dst.box.width = width;
|
||||
blit.src.box.height = blit.dst.box.height = height;
|
||||
@@ -1441,10 +1445,10 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
|
||||
blit.src.box.depth = 1;
|
||||
blit.dst.resource = stImage->pt;
|
||||
blit.dst.format = dst_format;
|
||||
blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level;
|
||||
blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level + texImage->TexObject->MinLevel;
|
||||
blit.dst.box.x = destX;
|
||||
blit.dst.box.y = destY;
|
||||
blit.dst.box.z = stImage->base.Face + slice;
|
||||
blit.dst.box.z = stImage->base.Face + slice + texImage->TexObject->MinLayer;
|
||||
blit.dst.box.width = width;
|
||||
blit.dst.box.height = height;
|
||||
blit.dst.box.depth = 1;
|
||||
@@ -1545,6 +1549,9 @@ st_finalize_texture(struct gl_context *ctx,
|
||||
enum pipe_format firstImageFormat;
|
||||
GLuint ptWidth, ptHeight, ptDepth, ptLayers, ptNumSamples;
|
||||
|
||||
if (tObj->Immutable)
|
||||
return GL_TRUE;
|
||||
|
||||
if (_mesa_is_texture_complete(tObj, &tObj->Sampler)) {
|
||||
/* The texture is complete and we know exactly how many mipmap levels
|
||||
* are present/needed. This is conditional because we may be called
|
||||
@@ -1824,6 +1831,44 @@ st_TestProxyTexImage(struct gl_context *ctx, GLenum target,
|
||||
}
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
st_TextureView(struct gl_context *ctx,
|
||||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_object *origTexObj)
|
||||
{
|
||||
struct st_texture_object *orig = st_texture_object(origTexObj);
|
||||
struct st_texture_object *tex = st_texture_object(texObj);
|
||||
struct gl_texture_image *image = texObj->Image[0][0];
|
||||
|
||||
const int numFaces = _mesa_num_tex_faces(texObj->Target);
|
||||
const int numLevels = texObj->NumLevels;
|
||||
|
||||
int face;
|
||||
int level;
|
||||
|
||||
pipe_resource_reference(&tex->pt, orig->pt);
|
||||
|
||||
/* Set image resource pointers */
|
||||
for (level = 0; level < numLevels; level++) {
|
||||
for (face = 0; face < numFaces; face++) {
|
||||
struct st_texture_image *stImage =
|
||||
st_texture_image(texObj->Image[face][level]);
|
||||
pipe_resource_reference(&stImage->pt, tex->pt);
|
||||
}
|
||||
}
|
||||
|
||||
tex->surface_based = GL_TRUE;
|
||||
tex->surface_format =
|
||||
st_mesa_format_to_pipe_format(st_context(ctx), image->TexFormat);
|
||||
|
||||
tex->width0 = image->Width;
|
||||
tex->height0 = image->Height;
|
||||
tex->depth0 = image->Depth;
|
||||
tex->lastLevel = numLevels - 1;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
st_init_texture_functions(struct dd_function_table *functions)
|
||||
@@ -1855,4 +1900,5 @@ st_init_texture_functions(struct dd_function_table *functions)
|
||||
functions->TestProxyTexImage = st_TestProxyTexImage;
|
||||
|
||||
functions->AllocTextureStorage = st_AllocTextureStorage;
|
||||
functions->TextureView = st_TextureView;
|
||||
}
|
||||
|
@@ -463,6 +463,7 @@ void st_init_extensions(struct pipe_screen *screen,
|
||||
{ o(ARB_draw_indirect), PIPE_CAP_DRAW_INDIRECT },
|
||||
{ o(ARB_derivative_control), PIPE_CAP_TGSI_FS_FINE_DERIVATIVE },
|
||||
{ o(ARB_conditional_render_inverted), PIPE_CAP_CONDITIONAL_RENDER_INVERTED },
|
||||
{ o(ARB_texture_view), PIPE_CAP_SAMPLER_VIEW_TARGET },
|
||||
};
|
||||
|
||||
/* Required: render target and sampler support */
|
||||
|
@@ -879,6 +879,7 @@ struct format_mapping
|
||||
|
||||
#define DEFAULT_SRGBA_FORMATS \
|
||||
PIPE_FORMAT_B8G8R8A8_SRGB, \
|
||||
PIPE_FORMAT_R8G8B8A8_SRGB, \
|
||||
PIPE_FORMAT_A8R8G8B8_SRGB, \
|
||||
PIPE_FORMAT_A8B8G8R8_SRGB, \
|
||||
0
|
||||
@@ -919,11 +920,11 @@ static const struct format_mapping format_map[] = {
|
||||
},
|
||||
{
|
||||
{ 4, GL_RGBA, GL_RGBA8, 0 },
|
||||
{ PIPE_FORMAT_R8G8B8A8_UNORM, DEFAULT_RGBA_FORMATS }
|
||||
{ DEFAULT_RGBA_FORMATS }
|
||||
},
|
||||
{
|
||||
{ GL_BGRA, 0 },
|
||||
{ PIPE_FORMAT_B8G8R8A8_UNORM, DEFAULT_RGBA_FORMATS }
|
||||
{ DEFAULT_RGBA_FORMATS }
|
||||
},
|
||||
{
|
||||
{ 3, GL_RGB, GL_RGB8, 0 },
|
||||
|
@@ -260,6 +260,12 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
|
||||
else
|
||||
level = stImage->base.Level;
|
||||
|
||||
if (stObj->base.Immutable) {
|
||||
level += stObj->base.MinLevel;
|
||||
z += stObj->base.MinLayer;
|
||||
d = MIN2(d, stObj->base.NumLayers);
|
||||
}
|
||||
|
||||
z += stImage->base.Face;
|
||||
|
||||
map = pipe_transfer_map_3d(st->pipe, stImage->pt, level, usage,
|
||||
@@ -289,8 +295,13 @@ st_texture_image_unmap(struct st_context *st,
|
||||
struct st_texture_image *stImage, unsigned slice)
|
||||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct pipe_transfer **transfer =
|
||||
&stImage->transfer[slice + stImage->base.Face].transfer;
|
||||
struct st_texture_object *stObj =
|
||||
st_texture_object(stImage->base.TexObject);
|
||||
struct pipe_transfer **transfer;
|
||||
|
||||
if (stObj->base.Immutable)
|
||||
slice += stObj->base.MinLayer;
|
||||
transfer = &stImage->transfer[slice + stImage->base.Face].transfer;
|
||||
|
||||
DBG("%s\n", __FUNCTION__);
|
||||
|
||||
|
Reference in New Issue
Block a user