mesa/st: support using PIPE_TEXTURE_RECT internally
Currently Gallium internals always use PIPE_TEXTURE_2D and normalized coordinates to access textures. However, PIPE_TEXTURE_2D is not always supported for NPOT textures, and PIPE_TEXTURE_RECT requires unnormalized coordinates. Hence, this change adds support for both kinds of normalization.
This commit is contained in:
@@ -275,7 +275,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
|
||||
/**
|
||||
* Create texture to hold bitmap pattern.
|
||||
*/
|
||||
pt = st_texture_create(st, PIPE_TEXTURE_2D, st->bitmap.tex_format,
|
||||
pt = st_texture_create(st, st->internal_target, st->bitmap.tex_format,
|
||||
0, width, height, 1,
|
||||
PIPE_BIND_SAMPLER_VIEW);
|
||||
if (!pt) {
|
||||
@@ -304,7 +304,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
|
||||
}
|
||||
|
||||
static GLuint
|
||||
setup_bitmap_vertex_data(struct st_context *st,
|
||||
setup_bitmap_vertex_data(struct st_context *st, bool normalized,
|
||||
int x, int y, int width, int height,
|
||||
float z, const float color[4])
|
||||
{
|
||||
@@ -316,13 +316,19 @@ setup_bitmap_vertex_data(struct st_context *st,
|
||||
const GLfloat x1 = (GLfloat)(x + width);
|
||||
const GLfloat y0 = (GLfloat)y;
|
||||
const GLfloat y1 = (GLfloat)(y + height);
|
||||
const GLfloat sLeft = (GLfloat)0.0, sRight = (GLfloat)1.0;
|
||||
const GLfloat tTop = (GLfloat)0.0, tBot = (GLfloat)1.0 - tTop;
|
||||
GLfloat sLeft = (GLfloat)0.0, sRight = (GLfloat)1.0;
|
||||
GLfloat tTop = (GLfloat)0.0, tBot = (GLfloat)1.0 - tTop;
|
||||
const GLfloat clip_x0 = (GLfloat)(x0 / fb_width * 2.0 - 1.0);
|
||||
const GLfloat clip_y0 = (GLfloat)(y0 / fb_height * 2.0 - 1.0);
|
||||
const GLfloat clip_x1 = (GLfloat)(x1 / fb_width * 2.0 - 1.0);
|
||||
const GLfloat clip_y1 = (GLfloat)(y1 / fb_height * 2.0 - 1.0);
|
||||
|
||||
if(!normalized)
|
||||
{
|
||||
sRight = width;
|
||||
tBot = height;
|
||||
}
|
||||
|
||||
/* XXX: Need to improve buffer_write to allow NO_WAIT (as well as
|
||||
* no_flush) updates to buffers where we know there is no conflict
|
||||
* with previous data. Currently using max_slots > 1 will cause
|
||||
@@ -462,7 +468,7 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
|
||||
for (i = 0; i < st->state.num_samplers; i++) {
|
||||
samplers[i] = &st->state.samplers[i];
|
||||
}
|
||||
samplers[stfp->bitmap_sampler] = &st->bitmap.sampler;
|
||||
samplers[stfp->bitmap_sampler] = &st->bitmap.samplers[sv->texture->target != PIPE_TEXTURE_RECT];
|
||||
cso_set_samplers(cso, num, (const struct pipe_sampler_state **) samplers);
|
||||
}
|
||||
|
||||
@@ -499,7 +505,7 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
|
||||
z = z * 2.0 - 1.0;
|
||||
|
||||
/* draw textured quad */
|
||||
offset = setup_bitmap_vertex_data(st, x, y, width, height, z, color);
|
||||
offset = setup_bitmap_vertex_data(st, sv->texture->target != PIPE_TEXTURE_RECT, x, y, width, height, z, color);
|
||||
|
||||
util_draw_vertex_buffer(pipe, st->bitmap.vbuf, offset,
|
||||
PIPE_PRIM_TRIANGLE_FAN,
|
||||
@@ -789,7 +795,7 @@ st_init_bitmap_functions(struct dd_function_table *functions)
|
||||
void
|
||||
st_init_bitmap(struct st_context *st)
|
||||
{
|
||||
struct pipe_sampler_state *sampler = &st->bitmap.sampler;
|
||||
struct pipe_sampler_state *sampler = &st->bitmap.samplers[0];
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
|
||||
@@ -801,7 +807,8 @@ st_init_bitmap(struct st_context *st)
|
||||
sampler->min_img_filter = PIPE_TEX_FILTER_NEAREST;
|
||||
sampler->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
||||
sampler->mag_img_filter = PIPE_TEX_FILTER_NEAREST;
|
||||
sampler->normalized_coords = 1;
|
||||
st->bitmap.samplers[1] = *sampler;
|
||||
st->bitmap.samplers[1].normalized_coords = 1;
|
||||
|
||||
/* init baseline rasterizer state once */
|
||||
memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer));
|
||||
|
||||
@@ -304,34 +304,9 @@ alloc_texture(struct st_context *st, GLsizei width, GLsizei height,
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
struct pipe_resource *pt;
|
||||
int ptw, pth;
|
||||
|
||||
ptw = width;
|
||||
pth = height;
|
||||
|
||||
/* Need to use POT texture? */
|
||||
if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
|
||||
int l2pt, maxSize;
|
||||
|
||||
l2pt = util_logbase2(width);
|
||||
if (1 << l2pt != width) {
|
||||
ptw = 1 << (l2pt + 1);
|
||||
}
|
||||
|
||||
l2pt = util_logbase2(height);
|
||||
if (1 << l2pt != height) {
|
||||
pth = 1 << (l2pt + 1);
|
||||
}
|
||||
|
||||
/* Check against maximum texture size */
|
||||
maxSize = 1 << (pipe->screen->get_param(pipe->screen,
|
||||
PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
|
||||
assert(ptw <= maxSize);
|
||||
assert(pth <= maxSize);
|
||||
}
|
||||
|
||||
pt = st_texture_create(st, PIPE_TEXTURE_2D, texFormat, 0,
|
||||
ptw, pth, 1, PIPE_BIND_SAMPLER_VIEW);
|
||||
pt = st_texture_create(st, st->internal_target, texFormat, 0,
|
||||
width, height, 1, PIPE_BIND_SAMPLER_VIEW);
|
||||
|
||||
return pt;
|
||||
}
|
||||
@@ -536,6 +511,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
|
||||
struct cso_context *cso = st->cso_context;
|
||||
GLfloat x0, y0, x1, y1;
|
||||
GLsizei maxSize;
|
||||
boolean normalized = sv->texture->target != PIPE_TEXTURE_RECT;
|
||||
|
||||
/* limit checks */
|
||||
/* XXX if DrawPixels image is larger than max texture size, break
|
||||
@@ -579,7 +555,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
|
||||
sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
|
||||
sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
||||
sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
|
||||
sampler.normalized_coords = 1;
|
||||
sampler.normalized_coords = normalized;
|
||||
|
||||
cso_single_sampler(cso, 0, &sampler);
|
||||
if (st->pixel_xfer.pixelmap_enabled) {
|
||||
@@ -635,8 +611,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
|
||||
z = z * 2.0 - 1.0;
|
||||
|
||||
draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex,
|
||||
(GLfloat) width / sv->texture->width0,
|
||||
(GLfloat) height / sv->texture->height0);
|
||||
normalized ? ((GLfloat) width / sv->texture->width0) : (GLfloat)width,
|
||||
normalized ? ((GLfloat) height / sv->texture->height0) : (GLfloat)height);
|
||||
|
||||
/* restore state */
|
||||
cso_restore_rasterizer(cso);
|
||||
@@ -1002,7 +978,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
|
||||
|
||||
srcFormat = rbRead->texture->format;
|
||||
|
||||
if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE_2D, sample_count,
|
||||
if (screen->is_format_supported(screen, srcFormat, st->internal_target, sample_count,
|
||||
PIPE_BIND_SAMPLER_VIEW, 0)) {
|
||||
texFormat = srcFormat;
|
||||
}
|
||||
@@ -1010,13 +986,13 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
|
||||
/* srcFormat can't be used as a texture format */
|
||||
if (type == GL_DEPTH) {
|
||||
texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT,
|
||||
PIPE_TEXTURE_2D, sample_count,
|
||||
st->internal_target, sample_count,
|
||||
PIPE_BIND_DEPTH_STENCIL);
|
||||
assert(texFormat != PIPE_FORMAT_NONE);
|
||||
}
|
||||
else {
|
||||
/* default color format */
|
||||
texFormat = st_choose_format(screen, GL_RGBA, PIPE_TEXTURE_2D,
|
||||
texFormat = st_choose_format(screen, GL_RGBA, st->internal_target,
|
||||
sample_count, PIPE_BIND_SAMPLER_VIEW);
|
||||
assert(texFormat != PIPE_FORMAT_NONE);
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
|
||||
/* Setup new texture template.
|
||||
*/
|
||||
memset(&template, 0, sizeof(template));
|
||||
template.target = PIPE_TEXTURE_2D;
|
||||
template.target = st->internal_target;
|
||||
template.format = format;
|
||||
template.width0 = width;
|
||||
template.height0 = height;
|
||||
|
||||
@@ -125,6 +125,11 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )
|
||||
st_init_generate_mipmap(st);
|
||||
st_init_blit(st);
|
||||
|
||||
if(pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES))
|
||||
st->internal_target = PIPE_TEXTURE_2D;
|
||||
else
|
||||
st->internal_target = PIPE_TEXTURE_RECT;
|
||||
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
|
||||
st->state.sampler_list[i] = &st->state.samplers[i];
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ struct st_context
|
||||
/** for glBitmap */
|
||||
struct {
|
||||
struct pipe_rasterizer_state rasterizer;
|
||||
struct pipe_sampler_state sampler;
|
||||
struct pipe_sampler_state samplers[2];
|
||||
enum pipe_format tex_format;
|
||||
void *vs;
|
||||
float vertices[4][3][4]; /**< vertex pos + color + texcoord */
|
||||
@@ -182,6 +182,7 @@ struct st_context
|
||||
|
||||
void *passthrough_fs; /**< simple pass-through frag shader */
|
||||
|
||||
enum pipe_texture_target internal_target;
|
||||
struct gen_mipmap_state *gen_mipmap;
|
||||
struct blit_state *blit;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user