/**************************************************************************
*
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
-#include "main/mfeatures.h"
#include "main/bufferobj.h"
#include "main/enums.h"
#include "main/fbobject.h"
case GL_TEXTURE_2D:
case GL_PROXY_TEXTURE_2D:
case GL_TEXTURE_EXTERNAL_OES:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
return PIPE_TEXTURE_2D;
case GL_TEXTURE_RECTANGLE_NV:
case GL_PROXY_TEXTURE_RECTANGLE_NV:
return PIPE_TEXTURE_1D_ARRAY;
case GL_TEXTURE_2D_ARRAY_EXT:
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
return PIPE_TEXTURE_2D_ARRAY;
case GL_TEXTURE_BUFFER:
return PIPE_BUFFER;
struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object);
DBG("%s\n", __FUNCTION__);
- _mesa_initialize_texture_object(&obj->base, name, target);
+ _mesa_initialize_texture_object(ctx, &obj->base, name, target);
return &obj->base;
}
pipe_resource_reference(&stImage->pt, NULL);
}
- if (stImage->TexData) {
- _mesa_align_free(stImage->TexData);
- stImage->TexData = NULL;
- }
+ _mesa_align_free(stImage->TexData);
+ stImage->TexData = NULL;
}
ptWidth,
ptHeight,
ptDepth,
- ptLayers,
+ ptLayers, 0,
bindings);
stObj->lastLevel = lastLevel;
ptWidth,
ptHeight,
ptDepth,
- ptLayers,
+ ptLayers, 0,
bindings);
return stImage->pt != NULL;
}
if (stObj->surface_based) {
const GLenum target = texObj->Target;
const GLuint level = texImage->Level;
- gl_format texFormat;
+ mesa_format texFormat;
_mesa_clear_texture_object(ctx, texObj);
pipe_resource_reference(&stObj->pt, NULL);
struct pipe_transfer *transfer;
struct pipe_blit_info blit;
enum pipe_format src_format, dst_format;
- gl_format mesa_src_format;
+ mesa_format mesa_src_format;
GLenum gl_target = texImage->TexObject->Target;
unsigned bind;
GLubyte *map;
const uint bytesPerRow = width * util_format_get_blocksize(src_format);
GLuint row, slice;
- for (slice = 0; slice < depth; slice++) {
+ for (slice = 0; slice < (unsigned) depth; slice++) {
if (gl_target == GL_TEXTURE_1D_ARRAY) {
/* 1D array textures.
* We need to convert gallium coords to GL coords.
else {
ubyte *slice_map = map;
- for (row = 0; row < height; row++) {
+ for (row = 0; row < (unsigned) height; row++) {
GLvoid *src = _mesa_image_address3d(unpack, pixels,
width, height, format,
type, slice, row, 0);
struct pipe_resource *dst = NULL;
struct pipe_resource dst_templ;
enum pipe_format dst_format, src_format;
- gl_format mesa_format;
+ mesa_format mesa_format;
GLenum gl_target = texImage->TexObject->Target;
enum pipe_texture_target pipe_target;
struct pipe_blit_info blit;
goto fallback;
}
- if (!stImage->pt) {
+ if (!stImage->pt || !src) {
goto fallback;
}
struct st_renderbuffer *strb,
struct st_texture_image *stImage,
GLenum baseFormat,
- GLint destX, GLint destY, GLint destZ,
+ GLint destX, GLint destY, GLint slice,
GLint srcX, GLint srcY,
GLsizei width, GLsizei height)
{
srcY = strb->Base.Height - srcY - height;
}
- if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
- /* Move y/height to z/depth for 1D array textures. */
- destZ = destY;
- destY = 0;
- dst_depth = dst_height;
- dst_height = 1;
- }
-
map = pipe_transfer_map(pipe,
strb->texture,
- strb->rtt_level,
- strb->rtt_face + strb->rtt_slice,
+ strb->surface->u.tex.level,
+ strb->surface->u.tex.first_layer,
PIPE_TRANSFER_READ,
srcX, srcY,
width, height, &src_trans);
transfer_usage = PIPE_TRANSFER_WRITE;
texDest = st_texture_image_map(st, stImage, transfer_usage,
- destX, destY, destZ,
+ destX, destY, slice,
dst_width, dst_height, dst_depth);
if (baseFormat == GL_DEPTH_COMPONENT ||
static void
st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
struct gl_texture_image *texImage,
- GLint destX, GLint destY, GLint destZ,
+ GLint destX, GLint destY, GLint slice,
struct gl_renderbuffer *rb,
GLint srcX, GLint srcY, GLsizei width, GLsizei height)
{
enum pipe_format dst_format;
GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
unsigned bind;
- GLint srcY0, srcY1, yStep;
+ GLint srcY0, srcY1;
if (!strb || !strb->surface || !stImage->pt) {
debug_printf("%s: null strb or stImage\n", __FUNCTION__);
if (do_flip) {
srcY1 = strb->Base.Height - srcY - height;
srcY0 = srcY1 + height;
- yStep = -1;
}
else {
srcY0 = srcY;
srcY1 = srcY0 + height;
- yStep = 1;
}
/* Blit the texture.
blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level;
blit.dst.box.x = destX;
blit.dst.box.y = destY;
- blit.dst.box.z = stImage->base.Face + destZ;
+ blit.dst.box.z = stImage->base.Face + slice;
blit.dst.box.width = width;
blit.dst.box.height = height;
blit.dst.box.depth = 1;
blit.mask = st_get_blit_mask(rb->_BaseFormat, texImage->_BaseFormat);
blit.filter = PIPE_TEX_FILTER_NEAREST;
-
- /* 1D array textures need special treatment.
- * Blit rows from the source to layers in the destination. */
- if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
- int y, layer;
-
- for (y = srcY0, layer = 0; layer < height; y += yStep, layer++) {
- blit.src.box.y = y;
- blit.src.box.height = 1;
- blit.dst.box.y = 0;
- blit.dst.box.height = 1;
- blit.dst.box.z = destY + layer;
-
- pipe->blit(pipe, &blit);
- }
- }
- else {
- /* All the other texture targets. */
- pipe->blit(pipe, &blit);
- }
+ pipe->blit(pipe, &blit);
return;
fallback:
/* software fallback */
fallback_copy_texsubimage(ctx,
strb, stImage, texImage->_BaseFormat,
- destX, destY, destZ,
+ destX, destY, slice,
srcX, srcY, width, height);
}
GLuint face;
struct st_texture_image *firstImage;
enum pipe_format firstImageFormat;
- GLuint ptWidth, ptHeight, ptDepth, ptLayers;
+ GLuint ptWidth, ptHeight, ptDepth, ptLayers, ptNumSamples;
if (_mesa_is_texture_complete(tObj, &tObj->Sampler)) {
/* The texture is complete and we know exactly how many mipmap levels
if (tObj->Target == GL_TEXTURE_BUFFER) {
struct st_buffer_object *st_obj = st_buffer_object(tObj->BufferObject);
+ if (!st_obj) {
+ pipe_resource_reference(&stObj->pt, NULL);
+ pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+ return GL_TRUE;
+ }
+
if (st_obj->buffer != stObj->pt) {
pipe_resource_reference(&stObj->pt, st_obj->buffer);
pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
}
+ /* If this texture comes from a window system, there is nothing else to do. */
+ if (stObj->surface_based) {
+ return GL_TRUE;
+ }
+
/* Find gallium format for the Mesa texture */
firstImageFormat = st_mesa_format_to_pipe_format(firstImage->base.TexFormat);
/* convert GL dims to Gallium dims */
st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, depth,
&ptWidth, &ptHeight, &ptDepth, &ptLayers);
+ ptNumSamples = firstImage->base.NumSamples;
}
/* If we already have a gallium texture, check that it matches the texture
*/
if (stObj->pt) {
if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
- !st_sampler_compat_formats(stObj->pt->format, firstImageFormat) ||
+ stObj->pt->format != firstImageFormat ||
stObj->pt->last_level < stObj->lastLevel ||
stObj->pt->width0 != ptWidth ||
stObj->pt->height0 != ptHeight ||
stObj->pt->depth0 != ptDepth ||
+ stObj->pt->nr_samples != ptNumSamples ||
stObj->pt->array_size != ptLayers)
{
/* The gallium texture does not match the Mesa texture so delete the
ptWidth,
ptHeight,
ptDepth,
- ptLayers,
+ ptLayers, ptNumSamples,
bindings);
if (!stObj->pt) {
GLsizei height, GLsizei depth)
{
const GLuint numFaces = _mesa_num_tex_faces(texObj->Target);
+ struct gl_texture_image *texImage = texObj->Image[0][0];
struct st_context *st = st_context(ctx);
struct st_texture_object *stObj = st_texture_object(texObj);
+ struct pipe_screen *screen = st->pipe->screen;
GLuint ptWidth, ptHeight, ptDepth, ptLayers, bindings;
enum pipe_format fmt;
GLint level;
+ GLuint num_samples = texImage->NumSamples;
assert(levels > 0);
stObj->depth0 = depth;
stObj->lastLevel = levels - 1;
- fmt = st_mesa_format_to_pipe_format(texObj->Image[0][0]->TexFormat);
+ fmt = st_mesa_format_to_pipe_format(texImage->TexFormat);
bindings = default_bindings(st, fmt);
+ /* Raise the sample count if the requested one is unsupported. */
+ if (num_samples > 1) {
+ boolean found = FALSE;
+
+ for (; num_samples <= ctx->Const.MaxSamples; num_samples++) {
+ if (screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D,
+ num_samples,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ /* Update the sample count in gl_texture_image as well. */
+ texImage->NumSamples = num_samples;
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found) {
+ return GL_FALSE;
+ }
+ }
+
st_gl_texture_dims_to_pipe_dims(texObj->Target,
width, height, depth,
&ptWidth, &ptHeight, &ptDepth, &ptLayers);
stObj->pt = st_texture_create(st,
gl_target_to_pipe(texObj->Target),
fmt,
- levels,
+ levels - 1,
ptWidth,
ptHeight,
ptDepth,
- ptLayers,
+ ptLayers, num_samples,
bindings);
if (!stObj->pt)
return GL_FALSE;
static GLboolean
st_TestProxyTexImage(struct gl_context *ctx, GLenum target,
- GLint level, gl_format format,
+ GLint level, mesa_format format,
GLint width, GLint height,
GLint depth, GLint border)
{