diff options
Diffstat (limited to 'mesalib/src/mesa/state_tracker')
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom_scissor.c | 77 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom_viewport.c | 37 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c | 133 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_bufferobjects.h | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_texturebarrier.c | 17 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_context.h | 4 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_draw_feedback.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_extensions.c | 22 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_format.c | 8 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 121 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_manager.c | 9 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_program.c | 10 |
12 files changed, 305 insertions, 137 deletions
diff --git a/mesalib/src/mesa/state_tracker/st_atom_scissor.c b/mesalib/src/mesa/state_tracker/st_atom_scissor.c index a1f72da47..a19ade1fa 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_scissor.c +++ b/mesalib/src/mesa/state_tracker/st_atom_scissor.c @@ -43,51 +43,56 @@ static void update_scissor( struct st_context *st ) { - struct pipe_scissor_state scissor; + struct pipe_scissor_state scissor[PIPE_MAX_VIEWPORTS]; const struct gl_context *ctx = st->ctx; const struct gl_framebuffer *fb = ctx->DrawBuffer; GLint miny, maxy; + int i; + bool changed = false; + for (i = 0 ; i < ctx->Const.MaxViewports; i++) { + scissor[i].minx = 0; + scissor[i].miny = 0; + scissor[i].maxx = fb->Width; + scissor[i].maxy = fb->Height; - scissor.minx = 0; - scissor.miny = 0; - scissor.maxx = fb->Width; - scissor.maxy = fb->Height; + if (ctx->Scissor.EnableFlags & (1 << i)) { + /* need to be careful here with xmax or ymax < 0 */ + GLint xmax = MAX2(0, ctx->Scissor.ScissorArray[i].X + ctx->Scissor.ScissorArray[i].Width); + GLint ymax = MAX2(0, ctx->Scissor.ScissorArray[i].Y + ctx->Scissor.ScissorArray[i].Height); - if (ctx->Scissor.EnableFlags & 1) { - /* need to be careful here with xmax or ymax < 0 */ - GLint xmax = MAX2(0, ctx->Scissor.ScissorArray[0].X + ctx->Scissor.ScissorArray[0].Width); - GLint ymax = MAX2(0, ctx->Scissor.ScissorArray[0].Y + ctx->Scissor.ScissorArray[0].Height); + if (ctx->Scissor.ScissorArray[i].X > (GLint)scissor[i].minx) + scissor[i].minx = ctx->Scissor.ScissorArray[i].X; + if (ctx->Scissor.ScissorArray[i].Y > (GLint)scissor[i].miny) + scissor[i].miny = ctx->Scissor.ScissorArray[i].Y; - if (ctx->Scissor.ScissorArray[0].X > (GLint)scissor.minx) - scissor.minx = ctx->Scissor.ScissorArray[0].X; - if (ctx->Scissor.ScissorArray[0].Y > (GLint)scissor.miny) - scissor.miny = ctx->Scissor.ScissorArray[0].Y; + if (xmax < (GLint) scissor[i].maxx) + scissor[i].maxx = xmax; + if (ymax < (GLint) scissor[i].maxy) + scissor[i].maxy = ymax; + + /* check for null space */ + if (scissor[i].minx >= scissor[i].maxx || scissor[i].miny >= scissor[i].maxy) + scissor[i].minx = scissor[i].miny = scissor[i].maxx = scissor[i].maxy = 0; + } - if (xmax < (GLint) scissor.maxx) - scissor.maxx = xmax; - if (ymax < (GLint) scissor.maxy) - scissor.maxy = ymax; + /* Now invert Y if needed. + * Gallium drivers use the convention Y=0=top for surfaces. + */ + if (st_fb_orientation(fb) == Y_0_TOP) { + miny = fb->Height - scissor[i].maxy; + maxy = fb->Height - scissor[i].miny; + scissor[i].miny = miny; + scissor[i].maxy = maxy; + } - /* check for null space */ - if (scissor.minx >= scissor.maxx || scissor.miny >= scissor.maxy) - scissor.minx = scissor.miny = scissor.maxx = scissor.maxy = 0; - } - - /* Now invert Y if needed. - * Gallium drivers use the convention Y=0=top for surfaces. - */ - if (st_fb_orientation(fb) == Y_0_TOP) { - miny = fb->Height - scissor.maxy; - maxy = fb->Height - scissor.miny; - scissor.miny = miny; - scissor.maxy = maxy; - } - - if (memcmp(&scissor, &st->state.scissor, sizeof(scissor)) != 0) { - /* state has changed */ - st->state.scissor = scissor; /* struct copy */ - st->pipe->set_scissor_states(st->pipe, 0, 1, &scissor); /* activate */ + if (memcmp(&scissor[i], &st->state.scissor[i], sizeof(scissor)) != 0) { + /* state has changed */ + st->state.scissor[i] = scissor[i]; /* struct copy */ + changed = true; + } } + if (changed) + st->pipe->set_scissor_states(st->pipe, 0, ctx->Const.MaxViewports, scissor); /* activate */ } diff --git a/mesalib/src/mesa/state_tracker/st_atom_viewport.c b/mesalib/src/mesa/state_tracker/st_atom_viewport.c index 8c6d679a0..7584f9b3d 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_viewport.c +++ b/mesalib/src/mesa/state_tracker/st_atom_viewport.c @@ -43,7 +43,7 @@ update_viewport( struct st_context *st ) { struct gl_context *ctx = st->ctx; GLfloat yScale, yBias; - + int i; /* _NEW_BUFFERS */ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { @@ -61,26 +61,29 @@ update_viewport( struct st_context *st ) /* _NEW_VIEWPORT */ + for (i = 0; i < ctx->Const.MaxViewports; i++) { - GLfloat x = ctx->ViewportArray[0].X; - GLfloat y = ctx->ViewportArray[0].Y; - GLfloat z = ctx->ViewportArray[0].Near; - GLfloat half_width = ctx->ViewportArray[0].Width * 0.5f; - GLfloat half_height = ctx->ViewportArray[0].Height * 0.5f; - GLfloat half_depth = (GLfloat)(ctx->ViewportArray[0].Far - ctx->ViewportArray[0].Near) * 0.5f; + GLfloat x = ctx->ViewportArray[i].X; + GLfloat y = ctx->ViewportArray[i].Y; + GLfloat z = ctx->ViewportArray[i].Near; + GLfloat half_width = ctx->ViewportArray[i].Width * 0.5f; + GLfloat half_height = ctx->ViewportArray[i].Height * 0.5f; + GLfloat half_depth = (GLfloat)(ctx->ViewportArray[i].Far - ctx->ViewportArray[i].Near) * 0.5f; - st->state.viewport.scale[0] = half_width; - st->state.viewport.scale[1] = half_height * yScale; - st->state.viewport.scale[2] = half_depth; - st->state.viewport.scale[3] = 1.0; - - st->state.viewport.translate[0] = half_width + x; - st->state.viewport.translate[1] = (half_height + y) * yScale + yBias; - st->state.viewport.translate[2] = half_depth + z; - st->state.viewport.translate[3] = 0.0; + st->state.viewport[i].scale[0] = half_width; + st->state.viewport[i].scale[1] = half_height * yScale; + st->state.viewport[i].scale[2] = half_depth; + st->state.viewport[i].scale[3] = 1.0; - cso_set_viewport(st->cso_context, &st->state.viewport); + st->state.viewport[i].translate[0] = half_width + x; + st->state.viewport[i].translate[1] = (half_height + y) * yScale + yBias; + st->state.viewport[i].translate[2] = half_depth + z; + st->state.viewport[i].translate[3] = 0.0; } + + cso_set_viewport(st->cso_context, &st->state.viewport[0]); + if (ctx->Const.MaxViewports > 1) + st->pipe->set_viewport_states(st->pipe, 1, ctx->Const.MaxViewports - 1, &st->state.viewport[1]); } diff --git a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c index c8f088dc8..49c4b903e 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -76,7 +76,7 @@ st_bufferobj_free(struct gl_context *ctx, struct gl_buffer_object *obj) struct st_buffer_object *st_obj = st_buffer_object(obj); assert(obj->RefCount == 0); - assert(st_obj->transfer == NULL); + _mesa_buffer_unmap_all_mappings(ctx, obj); if (st_obj->buffer) pipe_resource_reference(&st_obj->buffer, NULL); @@ -176,15 +176,18 @@ st_bufferobj_data(struct gl_context *ctx, GLsizeiptrARB size, const GLvoid * data, GLenum usage, + GLbitfield storageFlags, struct gl_buffer_object *obj) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; struct st_buffer_object *st_obj = st_buffer_object(obj); - unsigned bind, pipe_usage; + unsigned bind, pipe_usage, pipe_flags = 0; if (size && data && st_obj->buffer && - st_obj->Base.Size == size && st_obj->Base.Usage == usage) { + st_obj->Base.Size == size && + st_obj->Base.Usage == usage && + st_obj->Base.StorageFlags == storageFlags) { /* Just discard the old contents and write new data. * This should be the same as creating a new buffer, but we avoid * a lot of validation in Mesa. @@ -200,6 +203,7 @@ st_bufferobj_data(struct gl_context *ctx, st_obj->Base.Size = size; st_obj->Base.Usage = usage; + st_obj->Base.StorageFlags = storageFlags; switch (target) { case GL_PIXEL_PACK_BUFFER_ARB: @@ -225,24 +229,41 @@ st_bufferobj_data(struct gl_context *ctx, bind = 0; } - switch (usage) { - case GL_STATIC_DRAW: - case GL_STATIC_READ: - case GL_STATIC_COPY: - default: - pipe_usage = PIPE_USAGE_DEFAULT; - break; - case GL_DYNAMIC_DRAW: - case GL_DYNAMIC_READ: - case GL_DYNAMIC_COPY: - pipe_usage = PIPE_USAGE_DYNAMIC; - break; - case GL_STREAM_DRAW: - case GL_STREAM_READ: - case GL_STREAM_COPY: - pipe_usage = PIPE_USAGE_STREAM; - break; + /* Set usage. */ + if (st_obj->Base.Immutable) { + /* BufferStorage */ + if (storageFlags & GL_CLIENT_STORAGE_BIT) + pipe_usage = PIPE_USAGE_STAGING; + else + pipe_usage = PIPE_USAGE_DEFAULT; } + else { + /* BufferData */ + switch (usage) { + case GL_STATIC_DRAW: + case GL_STATIC_READ: + case GL_STATIC_COPY: + default: + pipe_usage = PIPE_USAGE_DEFAULT; + break; + case GL_DYNAMIC_DRAW: + case GL_DYNAMIC_READ: + case GL_DYNAMIC_COPY: + pipe_usage = PIPE_USAGE_DYNAMIC; + break; + case GL_STREAM_DRAW: + case GL_STREAM_READ: + case GL_STREAM_COPY: + pipe_usage = PIPE_USAGE_STREAM; + break; + } + } + + /* Set flags. */ + if (storageFlags & GL_MAP_PERSISTENT_BIT) + pipe_flags |= PIPE_RESOURCE_FLAG_MAP_PERSISTENT; + if (storageFlags & GL_MAP_COHERENT_BIT) + pipe_flags |= PIPE_RESOURCE_FLAG_MAP_COHERENT; pipe_resource_reference( &st_obj->buffer, NULL ); @@ -251,8 +272,20 @@ st_bufferobj_data(struct gl_context *ctx, } if (size != 0) { - st_obj->buffer = pipe_buffer_create(pipe->screen, bind, - pipe_usage, size); + struct pipe_resource buffer; + + memset(&buffer, 0, sizeof buffer); + buffer.target = PIPE_BUFFER; + buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */ + buffer.bind = bind; + buffer.usage = pipe_usage; + buffer.flags = pipe_flags; + buffer.width0 = size; + buffer.height0 = 1; + buffer.depth0 = 1; + buffer.array_size = 1; + + st_obj->buffer = pipe->screen->resource_create(pipe->screen, &buffer); if (!st_obj->buffer) { /* out of memory */ @@ -277,7 +310,8 @@ st_bufferobj_data(struct gl_context *ctx, static void * st_bufferobj_map_range(struct gl_context *ctx, GLintptr offset, GLsizeiptr length, GLbitfield access, - struct gl_buffer_object *obj) + struct gl_buffer_object *obj, + gl_map_buffer_index index) { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_buffer_object *st_obj = st_buffer_object(obj); @@ -305,6 +339,12 @@ st_bufferobj_map_range(struct gl_context *ctx, if (access & GL_MAP_UNSYNCHRONIZED_BIT) flags |= PIPE_TRANSFER_UNSYNCHRONIZED; + if (access & GL_MAP_PERSISTENT_BIT) + flags |= PIPE_TRANSFER_PERSISTENT; + + if (access & GL_MAP_COHERENT_BIT) + flags |= PIPE_TRANSFER_COHERENT; + /* ... other flags ... */ @@ -316,28 +356,29 @@ st_bufferobj_map_range(struct gl_context *ctx, assert(offset < obj->Size); assert(offset + length <= obj->Size); - obj->Pointer = pipe_buffer_map_range(pipe, + obj->Mappings[index].Pointer = pipe_buffer_map_range(pipe, st_obj->buffer, offset, length, flags, - &st_obj->transfer); - if (obj->Pointer) { - obj->Offset = offset; - obj->Length = length; - obj->AccessFlags = access; + &st_obj->transfer[index]); + if (obj->Mappings[index].Pointer) { + obj->Mappings[index].Offset = offset; + obj->Mappings[index].Length = length; + obj->Mappings[index].AccessFlags = access; } else { - st_obj->transfer = NULL; + st_obj->transfer[index] = NULL; } - return obj->Pointer; + return obj->Mappings[index].Pointer; } static void st_bufferobj_flush_mapped_range(struct gl_context *ctx, GLintptr offset, GLsizeiptr length, - struct gl_buffer_object *obj) + struct gl_buffer_object *obj, + gl_map_buffer_index index) { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_buffer_object *st_obj = st_buffer_object(obj); @@ -345,14 +386,15 @@ st_bufferobj_flush_mapped_range(struct gl_context *ctx, /* Subrange is relative to mapped range */ assert(offset >= 0); assert(length >= 0); - assert(offset + length <= obj->Length); - assert(obj->Pointer); + assert(offset + length <= obj->Mappings[index].Length); + assert(obj->Mappings[index].Pointer); if (!length) return; - pipe_buffer_flush_mapped_range(pipe, st_obj->transfer, - obj->Offset + offset, length); + pipe_buffer_flush_mapped_range(pipe, st_obj->transfer[index], + obj->Mappings[index].Offset + offset, + length); } @@ -360,18 +402,19 @@ st_bufferobj_flush_mapped_range(struct gl_context *ctx, * Called via glUnmapBufferARB(). */ static GLboolean -st_bufferobj_unmap(struct gl_context *ctx, struct gl_buffer_object *obj) +st_bufferobj_unmap(struct gl_context *ctx, struct gl_buffer_object *obj, + gl_map_buffer_index index) { struct pipe_context *pipe = st_context(ctx)->pipe; struct st_buffer_object *st_obj = st_buffer_object(obj); - if (obj->Length) - pipe_buffer_unmap(pipe, st_obj->transfer); + if (obj->Mappings[index].Length) + pipe_buffer_unmap(pipe, st_obj->transfer[index]); - st_obj->transfer = NULL; - obj->Pointer = NULL; - obj->Offset = 0; - obj->Length = 0; + st_obj->transfer[index] = NULL; + obj->Mappings[index].Pointer = NULL; + obj->Mappings[index].Offset = 0; + obj->Mappings[index].Length = 0; return GL_TRUE; } @@ -395,8 +438,8 @@ st_copy_buffer_subdata(struct gl_context *ctx, return; /* buffer should not already be mapped */ - assert(!src->Pointer); - assert(!dst->Pointer); + assert(!_mesa_check_disallowed_mapping(src)); + assert(!_mesa_check_disallowed_mapping(dst)); u_box_1d(readOffset, size, &box); diff --git a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.h b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.h index a039c0a50..a5ab12219 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.h +++ b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.h @@ -43,7 +43,7 @@ struct st_buffer_object { struct gl_buffer_object Base; struct pipe_resource *buffer; /* GPU storage */ - struct pipe_transfer *transfer; /* In-progress map information */ + struct pipe_transfer *transfer[MAP_COUNT]; }; diff --git a/mesalib/src/mesa/state_tracker/st_cb_texturebarrier.c b/mesalib/src/mesa/state_tracker/st_cb_texturebarrier.c index 2f1a22b58..dd4dde74c 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texturebarrier.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texturebarrier.c @@ -54,7 +54,24 @@ st_TextureBarrier(struct gl_context *ctx) } +/** + * Called via ctx->Driver.MemoryBarrier() + */ +static void +st_MemoryBarrier(struct gl_context *ctx, GLbitfield barriers) +{ + struct pipe_context *pipe = st_context(ctx)->pipe; + unsigned flags = 0; + + if (barriers & GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT) + flags |= PIPE_BARRIER_MAPPED_BUFFER; + + if (flags && pipe->memory_barrier) + pipe->memory_barrier(pipe, flags); +} + void st_init_texture_barrier_functions(struct dd_function_table *functions) { functions->TextureBarrier = st_TextureBarrier; + functions->MemoryBarrier = st_MemoryBarrier; } diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index 996e0c6bc..9c699a015 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -115,8 +115,8 @@ struct st_context unsigned size; } constants[PIPE_SHADER_TYPES]; struct pipe_framebuffer_state framebuffer; - struct pipe_scissor_state scissor; - struct pipe_viewport_state viewport; + struct pipe_scissor_state scissor[PIPE_MAX_VIEWPORTS]; + struct pipe_viewport_state viewport[PIPE_MAX_VIEWPORTS]; unsigned sample_mask; GLuint poly_stipple[32]; /**< In OpenGL's bottom-to-top order */ diff --git a/mesalib/src/mesa/state_tracker/st_draw_feedback.c b/mesalib/src/mesa/state_tracker/st_draw_feedback.c index 09cd9511d..177f6b5ae 100644 --- a/mesalib/src/mesa/state_tracker/st_draw_feedback.c +++ b/mesalib/src/mesa/state_tracker/st_draw_feedback.c @@ -156,7 +156,7 @@ st_feedback_draw_vbo(struct gl_context *ctx, * code sends state updates to the pipe, not to our private draw module. */ assert(draw); - draw_set_viewport_states(draw, 0, 1, &st->state.viewport); + draw_set_viewport_states(draw, 0, 1, &st->state.viewport[0]); draw_set_clip_state(draw, &st->state.clip); draw_set_rasterizer_state(draw, &st->state.rasterizer, NULL); draw_bind_vertex_shader(draw, st->vp_variant->draw_shader); diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index 9829eb596..18ddd4e47 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -39,6 +39,12 @@ #include "st_extensions.h" #include "st_format.h" + +/* + * Note: we use these function rather than the MIN2, MAX2, CLAMP macros to + * avoid evaluating arguments (which are often function calls) more than once. + */ + static unsigned _min(unsigned a, unsigned b) { return (a < b) ? a : b; @@ -262,10 +268,13 @@ void st_init_limits(struct st_context *st) c->Program[MESA_SHADER_VERTEX].MaxOutputComponents = c->MaxVarying * 4; c->Program[MESA_SHADER_GEOMETRY].MaxInputComponents = c->MaxVarying * 4; c->Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = c->MaxVarying * 4; + c->MaxGeometryOutputVertices = screen->get_param(screen, PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES); + c->MaxGeometryTotalOutputComponents = screen->get_param(screen, PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS); c->MinProgramTexelOffset = screen->get_param(screen, PIPE_CAP_MIN_TEXEL_OFFSET); c->MaxProgramTexelOffset = screen->get_param(screen, PIPE_CAP_MAX_TEXEL_OFFSET); + c->MaxProgramTextureGatherComponents = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS); c->UniformBooleanTrue = ~0; c->MaxTransformFeedbackBuffers = @@ -373,6 +382,7 @@ void st_init_extensions(struct st_context *st) static const struct st_extension_cap_mapping cap_mapping[] = { { o(ARB_base_instance), PIPE_CAP_START_INSTANCE }, + { o(ARB_buffer_storage), PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT }, { o(ARB_depth_clamp), PIPE_CAP_DEPTH_CLIP_DISABLE }, { o(ARB_depth_texture), PIPE_CAP_TEXTURE_SHADOW_MAP }, { o(ARB_draw_buffers_blend), PIPE_CAP_INDEP_BLEND_FUNC }, @@ -526,7 +536,6 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE; ctx->Extensions.ARB_fragment_program = GL_TRUE; ctx->Extensions.ARB_fragment_shader = GL_TRUE; - ctx->Extensions.ARB_half_float_pixel = GL_TRUE; ctx->Extensions.ARB_half_float_vertex = GL_TRUE; ctx->Extensions.ARB_internalformat_query = GL_TRUE; ctx->Extensions.ARB_map_buffer_range = GL_TRUE; @@ -777,4 +786,15 @@ void st_init_extensions(struct st_context *st) if (!ctx->Extensions.EXT_transform_feedback) ctx->Const.DisableVaryingPacking = GL_TRUE; } + + if (ctx->API == API_OPENGL_CORE) { + ctx->Const.MaxViewports = screen->get_param(screen, PIPE_CAP_MAX_VIEWPORTS); + if (ctx->Const.MaxViewports >= 16) { + ctx->Const.ViewportBounds.Min = -16384.0; + ctx->Const.ViewportBounds.Max = 16384.0; + ctx->Extensions.ARB_viewport_array = GL_TRUE; + } + } + if (ctx->Const.MaxProgramTextureGatherComponents > 0) + ctx->Extensions.ARB_texture_gather = GL_TRUE; } diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c index 90e9f2f78..5f951eb02 100644 --- a/mesalib/src/mesa/state_tracker/st_format.c +++ b/mesalib/src/mesa/state_tracker/st_format.c @@ -107,11 +107,11 @@ st_mesa_format_to_pipe_format(mesa_format mesaFormat) return PIPE_FORMAT_Z32_UNORM; case MESA_FORMAT_S8_UINT_Z24_UNORM: return PIPE_FORMAT_S8_UINT_Z24_UNORM; - case MESA_FORMAT_Z24_UNORM_X8_UINT: + case MESA_FORMAT_Z24_UNORM_S8_UINT: return PIPE_FORMAT_Z24_UNORM_S8_UINT; case MESA_FORMAT_X8Z24_UNORM: return PIPE_FORMAT_X8Z24_UNORM; - case MESA_FORMAT_Z24_UNORM_S8_UINT: + case MESA_FORMAT_Z24_UNORM_X8_UINT: return PIPE_FORMAT_Z24X8_UNORM; case MESA_FORMAT_S_UINT8: return PIPE_FORMAT_S8_UINT; @@ -465,9 +465,9 @@ st_pipe_format_to_mesa_format(enum pipe_format format) case PIPE_FORMAT_X8Z24_UNORM: return MESA_FORMAT_X8Z24_UNORM; case PIPE_FORMAT_Z24X8_UNORM: - return MESA_FORMAT_Z24_UNORM_S8_UINT; - case PIPE_FORMAT_Z24_UNORM_S8_UINT: return MESA_FORMAT_Z24_UNORM_X8_UINT; + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + return MESA_FORMAT_Z24_UNORM_S8_UINT; case PIPE_FORMAT_Z32_FLOAT: return MESA_FORMAT_Z_FLOAT32; case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 610fc68a8..a9e75d8a6 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -87,7 +87,7 @@ extern "C" { */ #define MAX_ARRAYS 256 -/* will be 4 for GLSL 4.00 */ +/* if we support a native gallium TG4 with the ability to take 4 texoffsets then bump this */ #define MAX_GLSL_TEXTURE_OFFSET 1 class st_src_reg; @@ -249,7 +249,8 @@ public: int sampler; /**< sampler index */ int tex_target; /**< One of TEXTURE_*_INDEX */ GLboolean tex_shadow; - struct tgsi_texture_offset tex_offsets[MAX_GLSL_TEXTURE_OFFSET]; + + st_src_reg tex_offsets[MAX_GLSL_TEXTURE_OFFSET]; unsigned tex_offset_num_offset; int dead_mask; /**< Used in dead code elimination */ @@ -983,6 +984,7 @@ type_size(const struct glsl_type *type) } return size; case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: /* Samplers take up one slot in UNIFORMS[], but they're baked in * at link time. */ @@ -2685,7 +2687,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir) void glsl_to_tgsi_visitor::visit(ir_texture *ir) { - st_src_reg result_src, coord, cube_sc, lod_info, projector, dx, dy, offset, sample_index; + st_src_reg result_src, coord, cube_sc, lod_info, projector, dx, dy, offset, sample_index, component; st_dst_reg result_dst, coord_dst, cube_sc_dst; glsl_to_tgsi_instruction *inst = NULL; unsigned opcode = TGSI_OPCODE_NOP; @@ -2779,12 +2781,20 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) ir->lod_info.sample_index->accept(this); sample_index = this->result; break; + case ir_tg4: + opcode = TGSI_OPCODE_TG4; + ir->lod_info.component->accept(this); + component = this->result; + if (ir->offset) { + ir->offset->accept(this); + /* this should have been lowered */ + assert(ir->offset->type->base_type != GLSL_TYPE_ARRAY); + offset = this->result; + } + break; case ir_lod: assert(!"Unexpected ir_lod opcode"); break; - case ir_tg4: - assert(!"Unexpected ir_tg4 opcode"); - break; case ir_query_levels: assert(!"Unexpected ir_query_levels opcode"); break; @@ -2892,7 +2902,13 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) inst = emit(ir, opcode, result_dst, coord, lod_info); } else if (opcode == TGSI_OPCODE_TEX2) { inst = emit(ir, opcode, result_dst, coord, cube_sc); - } else + } else if (opcode == TGSI_OPCODE_TG4) { + if (is_cube_array && ir->shadow_comparitor) { + inst = emit(ir, opcode, result_dst, coord, cube_sc); + } else { + inst = emit(ir, opcode, result_dst, coord, component); + } + } else inst = emit(ir, opcode, result_dst, coord); if (ir->shadow_comparitor) @@ -2903,12 +2919,8 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) this->prog); if (ir->offset) { - inst->tex_offset_num_offset = 1; - inst->tex_offsets[0].Index = offset.index; - inst->tex_offsets[0].File = offset.file; - inst->tex_offsets[0].SwizzleX = GET_SWZ(offset.swizzle, 0); - inst->tex_offsets[0].SwizzleY = GET_SWZ(offset.swizzle, 1); - inst->tex_offsets[0].SwizzleZ = GET_SWZ(offset.swizzle, 2); + inst->tex_offset_num_offset = 1; + inst->tex_offsets[0] = offset; } switch (sampler_type->sampler_dimensionality) { @@ -3266,6 +3278,13 @@ glsl_to_tgsi_visitor::rename_temp_register(int index, int new_index) inst->src[j].index = new_index; } } + + for (j=0; j < inst->tex_offset_num_offset; j++) { + if (inst->tex_offsets[j].file == PROGRAM_TEMPORARY && + inst->tex_offsets[j].index == index) { + inst->tex_offsets[j].index = new_index; + } + } if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) { inst->dst.index = new_index; @@ -3289,6 +3308,12 @@ glsl_to_tgsi_visitor::get_first_temp_read(int index) return (depth == 0) ? i : loop_start; } } + for (j=0; j < inst->tex_offset_num_offset; j++) { + if (inst->tex_offsets[j].file == PROGRAM_TEMPORARY && + inst->tex_offsets[j].index == index) { + return (depth == 0) ? i : loop_start; + } + } if (inst->op == TGSI_OPCODE_BGNLOOP) { if(depth++ == 0) @@ -3350,6 +3375,11 @@ glsl_to_tgsi_visitor::get_last_temp_read(int index) last = (depth == 0) ? i : -2; } } + for (j=0; j < inst->tex_offset_num_offset; j++) { + if (inst->tex_offsets[j].file == PROGRAM_TEMPORARY && + inst->tex_offsets[j].index == index) + last = (depth == 0) ? i : -2; + } if (inst->op == TGSI_OPCODE_BGNLOOP) depth++; @@ -3726,6 +3756,26 @@ glsl_to_tgsi_visitor::eliminate_dead_code_advanced(void) } } } + for (unsigned i = 0; i < inst->tex_offset_num_offset; i++) { + if (inst->tex_offsets[i].file == PROGRAM_TEMPORARY && inst->tex_offsets[i].reladdr){ + /* Any temporary might be read, so no dead code elimination + * across this instruction. + */ + memset(writes, 0, sizeof(*writes) * this->next_temp * 4); + } else if (inst->tex_offsets[i].file == PROGRAM_TEMPORARY) { + /* Clear where it's used as src. */ + int src_chans = 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 0); + src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 1); + src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 2); + src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 3); + + for (int c = 0; c < 4; c++) { + if (src_chans & (1 << c)) { + writes[4 * inst->tex_offsets[i].index + c] = NULL; + } + } + } + } break; } @@ -4079,7 +4129,7 @@ struct st_translate { struct ureg_dst address[2]; struct ureg_src samplers[PIPE_MAX_SAMPLERS]; struct ureg_src systemValues[SYSTEM_VALUE_MAX]; - + struct tgsi_texture_offset tex_offsets[MAX_GLSL_TEXTURE_OFFSET]; unsigned array_sizes[MAX_ARRAYS]; const GLuint *inputMapping; @@ -4379,22 +4429,34 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg) static struct tgsi_texture_offset translate_tex_offset(struct st_translate *t, - const struct tgsi_texture_offset *in_offset) + const st_src_reg *in_offset, int idx) { struct tgsi_texture_offset offset; struct ureg_src imm_src; - assert(in_offset->File == PROGRAM_IMMEDIATE); - imm_src = t->immediates[in_offset->Index]; - - offset.File = imm_src.File; - offset.Index = imm_src.Index; - offset.SwizzleX = imm_src.SwizzleX; - offset.SwizzleY = imm_src.SwizzleY; - offset.SwizzleZ = imm_src.SwizzleZ; - offset.File = TGSI_FILE_IMMEDIATE; - offset.Padding = 0; - + switch (in_offset->file) { + case PROGRAM_IMMEDIATE: + imm_src = t->immediates[in_offset->index]; + + offset.File = imm_src.File; + offset.Index = imm_src.Index; + offset.SwizzleX = imm_src.SwizzleX; + offset.SwizzleY = imm_src.SwizzleY; + offset.SwizzleZ = imm_src.SwizzleZ; + offset.Padding = 0; + break; + case PROGRAM_TEMPORARY: + imm_src = ureg_src(t->temps[in_offset->index]); + offset.File = imm_src.File; + offset.Index = imm_src.Index; + offset.SwizzleX = GET_SWZ(in_offset->swizzle, 0); + offset.SwizzleY = GET_SWZ(in_offset->swizzle, 1); + offset.SwizzleZ = GET_SWZ(in_offset->swizzle, 2); + offset.Padding = 0; + break; + default: + break; + } return offset; } @@ -4450,9 +4512,10 @@ compile_tgsi_instruction(struct st_translate *t, case TGSI_OPCODE_TEX2: case TGSI_OPCODE_TXB2: case TGSI_OPCODE_TXL2: + case TGSI_OPCODE_TG4: src[num_src++] = t->samplers[inst->sampler]; for (i = 0; i < inst->tex_offset_num_offset; i++) { - texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i]); + texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i], i); } tex_target = st_translate_texture_target(inst->tex_target, inst->tex_shadow); @@ -5140,7 +5203,7 @@ get_mesa_program(struct gl_context *ctx, printf("GLSL IR for linked %s program %d:\n", _mesa_shader_stage_to_string(shader->Stage), shader_program->Name); - _mesa_print_ir(shader->ir, NULL); + _mesa_print_ir(stdout, shader->ir, NULL); printf("\n"); printf("\n"); fflush(stdout); @@ -5182,6 +5245,7 @@ get_mesa_program(struct gl_context *ctx, stgp->Base.InputType = shader_program->Geom.InputType; stgp->Base.OutputType = shader_program->Geom.OutputType; stgp->Base.VerticesOut = shader_program->Geom.VerticesOut; + stgp->Base.Invocations = shader_program->Geom.Invocations; break; default: assert(!"should not be reached"); @@ -5268,6 +5332,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) lower_packing_builtins(ir, lower_inst); } + lower_offset_arrays(ir); do_mat_op_to_vec(ir); lower_instructions(ir, MOD_TO_FRACT | diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c index 215b27634..6a776a8a2 100644 --- a/mesalib/src/mesa/state_tracker/st_manager.c +++ b/mesalib/src/mesa/state_tracker/st_manager.c @@ -30,6 +30,7 @@ #include "main/texobj.h" #include "main/teximage.h" #include "main/texstate.h" +#include "main/errors.h" #include "main/framebuffer.h" #include "main/fbobject.h" #include "main/renderbuffer.h" @@ -626,10 +627,14 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, return NULL; } - st->ctx->Debug.DebugOutput = GL_FALSE; if (attribs->flags & ST_CONTEXT_FLAG_DEBUG){ + struct gl_debug_state *debug = _mesa_get_debug_state(st->ctx); + if (!debug) { + *error = ST_CONTEXT_ERROR_NO_MEMORY; + return NULL; + } st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT; - st->ctx->Debug.DebugOutput = GL_TRUE; + debug->DebugOutput = GL_TRUE; } if (attribs->flags & ST_CONTEXT_FLAG_FORWARD_COMPATIBLE) diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c index cadbe1705..e9074ac97 100644 --- a/mesalib/src/mesa/state_tracker/st_program.c +++ b/mesalib/src/mesa/state_tracker/st_program.c @@ -572,6 +572,11 @@ st_translate_fragment_program(struct st_context *st, input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_CONSTANT; break; + case VARYING_SLOT_VIEWPORT: + input_semantic_name[slot] = TGSI_SEMANTIC_VIEWPORT_INDEX; + input_semantic_index[slot] = 0; + interpMode[slot] = TGSI_INTERPOLATE_CONSTANT; + break; case VARYING_SLOT_CLIP_DIST0: input_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST; input_semantic_index[slot] = 0; @@ -1027,6 +1032,10 @@ st_translate_geometry_program(struct st_context *st, gs_output_semantic_name[slot] = TGSI_SEMANTIC_PRIMID; gs_output_semantic_index[slot] = 0; break; + case VARYING_SLOT_VIEWPORT: + gs_output_semantic_name[slot] = TGSI_SEMANTIC_VIEWPORT_INDEX; + gs_output_semantic_index[slot] = 0; + break; case VARYING_SLOT_TEX0: case VARYING_SLOT_TEX1: case VARYING_SLOT_TEX2: @@ -1087,6 +1096,7 @@ st_translate_geometry_program(struct st_context *st, ureg_property_gs_input_prim(ureg, stgp->Base.InputType); ureg_property_gs_output_prim(ureg, stgp->Base.OutputType); ureg_property_gs_max_vertices(ureg, stgp->Base.VerticesOut); + ureg_property_gs_invocations(ureg, stgp->Base.Invocations); if (stgp->glsl_to_tgsi) st_translate_program(st->ctx, |