#include "st_sampler_view.h"
#include "st_texture.h"
#include "st_format.h"
+#include "st_cb_bufferobjects.h"
#include "st_cb_texture.h"
*/
static unsigned
compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode,
- enum pipe_format actualFormat,
- unsigned glsl_version)
+ bool glsl130_or_later)
{
switch (baseFormat) {
case GL_RGBA:
return SWIZZLE_XYZW;
case GL_RGB:
- if (util_format_has_alpha(actualFormat))
- return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
- else
- return SWIZZLE_XYZW;
+ return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
case GL_RG:
- if (util_format_get_nr_components(actualFormat) > 2)
- return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
- else
- return SWIZZLE_XYZW;
+ return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
case GL_RED:
- if (util_format_get_nr_components(actualFormat) > 1)
- return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
- SWIZZLE_ZERO, SWIZZLE_ONE);
- else
- return SWIZZLE_XYZW;
+ return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
+ SWIZZLE_ZERO, SWIZZLE_ONE);
case GL_ALPHA:
- if (util_format_get_nr_components(actualFormat) > 1)
- return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
- SWIZZLE_ZERO, SWIZZLE_W);
- else
- return SWIZZLE_XYZW;
+ return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
+ SWIZZLE_ZERO, SWIZZLE_W);
case GL_LUMINANCE:
- if (util_format_get_nr_components(actualFormat) > 1)
- return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
- else
- return SWIZZLE_XYZW;
+ return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
case GL_LUMINANCE_ALPHA:
- if (util_format_get_nr_components(actualFormat) > 2)
- return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_W);
- else
- return SWIZZLE_XYZW;
+ return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_W);
case GL_INTENSITY:
- if (util_format_get_nr_components(actualFormat) > 1)
- return SWIZZLE_XXXX;
- else
- return SWIZZLE_XYZW;
+ return SWIZZLE_XXXX;
case GL_STENCIL_INDEX:
case GL_DEPTH_STENCIL:
case GL_DEPTH_COMPONENT:
* BTW, it's required that sampler views are updated when
* shaders change (check_sampler_swizzle takes care of that).
*/
- if (glsl_version && glsl_version >= 130)
+ if (glsl130_or_later)
return SWIZZLE_XXXX;
else
return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
static unsigned
get_texture_format_swizzle(const struct st_context *st,
const struct st_texture_object *stObj,
- unsigned glsl_version)
+ bool glsl130_or_later)
{
- GLenum baseFormat = _mesa_texture_base_format(&stObj->base);
+ GLenum baseFormat = _mesa_base_tex_image(&stObj->base)->_BaseFormat;
unsigned tex_swizzle;
-
- if (baseFormat != GL_NONE) {
- GLenum depth_mode = stObj->base.DepthMode;
- /* In ES 3.0, DEPTH_TEXTURE_MODE is expected to be GL_RED for textures
- * with depth component data specified with a sized internal format.
- */
- if (_mesa_is_gles3(st->ctx) &&
- util_format_is_depth_or_stencil(stObj->pt->format)) {
- const struct gl_texture_image *firstImage =
- _mesa_base_tex_image(&stObj->base);
- if (firstImage->InternalFormat != GL_DEPTH_COMPONENT &&
- firstImage->InternalFormat != GL_DEPTH_STENCIL &&
- firstImage->InternalFormat != GL_STENCIL_INDEX)
- depth_mode = GL_RED;
- }
- tex_swizzle = compute_texture_format_swizzle(baseFormat,
- depth_mode,
- stObj->pt->format,
- glsl_version);
- }
- else {
- tex_swizzle = SWIZZLE_XYZW;
+ GLenum depth_mode = stObj->base.DepthMode;
+
+ /* In ES 3.0, DEPTH_TEXTURE_MODE is expected to be GL_RED for textures
+ * with depth component data specified with a sized internal format.
+ */
+ if (_mesa_is_gles3(st->ctx) &&
+ (baseFormat == GL_DEPTH_COMPONENT ||
+ baseFormat == GL_DEPTH_STENCIL ||
+ baseFormat == GL_STENCIL_INDEX)) {
+ const struct gl_texture_image *firstImage =
+ _mesa_base_tex_image(&stObj->base);
+ if (firstImage->InternalFormat != GL_DEPTH_COMPONENT &&
+ firstImage->InternalFormat != GL_DEPTH_STENCIL &&
+ firstImage->InternalFormat != GL_STENCIL_INDEX)
+ depth_mode = GL_RED;
}
+ tex_swizzle = compute_texture_format_swizzle(baseFormat,
+ depth_mode,
+ glsl130_or_later);
/* Combine the texture format swizzle with user's swizzle */
return swizzle_swizzle(stObj->base._Swizzle, tex_swizzle);
MAYBE_UNUSED static boolean
check_sampler_swizzle(const struct st_context *st,
const struct st_texture_object *stObj,
- const struct pipe_sampler_view *sv, unsigned glsl_version)
+ const struct pipe_sampler_view *sv,
+ bool glsl130_or_later)
{
- unsigned swizzle = get_texture_format_swizzle(st, stObj, glsl_version);
+ unsigned swizzle = get_texture_format_swizzle(st, stObj, glsl130_or_later);
return ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
(sv->swizzle_g != GET_SWZ(swizzle, 1)) ||
{
enum pipe_format format;
- if (stObj->base.Target == GL_TEXTURE_BUFFER) {
- format =
- st_mesa_format_to_pipe_format(st, stObj->base._BufferObjectFormat);
- }
- else {
- format =
- stObj->surface_based ? stObj->surface_format : stObj->pt->format;
+ GLenum baseFormat = _mesa_base_tex_image(&stObj->base)->_BaseFormat;
+ format = stObj->surface_based ? stObj->surface_format : stObj->pt->format;
- if (util_format_is_depth_and_stencil(format)) {
- if (stObj->base.StencilSampling) {
- format = util_format_stencil_only(format);
- }
- else {
- GLenum baseFormat = _mesa_texture_base_format(&stObj->base);
- if (baseFormat == GL_STENCIL_INDEX) {
- format = util_format_stencil_only(format);
- }
- }
- }
- else {
- /* If sRGB decoding is off, use the linear format */
- if (samp->sRGBDecode == GL_SKIP_DECODE_EXT) {
- format = util_format_linear(format);
- }
+ if (baseFormat == GL_DEPTH_COMPONENT ||
+ baseFormat == GL_DEPTH_STENCIL ||
+ baseFormat == GL_STENCIL_INDEX) {
+ if (stObj->base.StencilSampling || baseFormat == GL_STENCIL_INDEX)
+ format = util_format_stencil_only(format);
- /* Use R8_UNORM for video formats */
- switch (format) {
- case PIPE_FORMAT_NV12:
- case PIPE_FORMAT_IYUV:
- format = PIPE_FORMAT_R8_UNORM;
- break;
- default:
- break;
- }
- }
+ return format;
}
+ /* If sRGB decoding is off, use the linear format */
+ if (samp->sRGBDecode == GL_SKIP_DECODE_EXT)
+ format = util_format_linear(format);
+
+ /* Use R8_UNORM for video formats */
+ switch (format) {
+ case PIPE_FORMAT_NV12:
+ case PIPE_FORMAT_IYUV:
+ format = PIPE_FORMAT_R8_UNORM;
+ break;
+ default:
+ break;
+ }
return format;
}
st_create_texture_sampler_view_from_stobj(struct st_context *st,
struct st_texture_object *stObj,
enum pipe_format format,
- unsigned glsl_version)
+ bool glsl130_or_later)
{
+ /* There is no need to clear this structure (consider CPU overhead). */
struct pipe_sampler_view templ;
- unsigned swizzle = get_texture_format_swizzle(st, stObj, glsl_version);
+ unsigned swizzle = get_texture_format_swizzle(st, stObj, glsl130_or_later);
- u_sampler_view_default_template(&templ, stObj->pt, format);
+ templ.format = format;
- if (stObj->pt->target == PIPE_BUFFER) {
- unsigned base, size;
-
- base = stObj->base.BufferOffset;
- if (base >= stObj->pt->width0)
- return NULL;
- size = MIN2(stObj->pt->width0 - base, (unsigned)stObj->base.BufferSize);
- if (!size)
- return NULL;
-
- templ.u.buf.offset = base;
- templ.u.buf.size = size;
+ 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);
+ if (stObj->layer_override) {
+ templ.u.tex.first_layer = templ.u.tex.last_layer = stObj->layer_override;
} else {
- 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);
- if (stObj->layer_override) {
- templ.u.tex.first_layer = templ.u.tex.last_layer = stObj->layer_override;
- } else {
- 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);
+ 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);
templ.swizzle_r = GET_SWZ(swizzle, 0);
templ.swizzle_g = GET_SWZ(swizzle, 1);
st_get_texture_sampler_view_from_stobj(struct st_context *st,
struct st_texture_object *stObj,
const struct gl_sampler_object *samp,
- unsigned glsl_version)
+ bool glsl130_or_later)
{
struct pipe_sampler_view **sv;
- if (!stObj || !stObj->pt) {
- return NULL;
- }
-
sv = st_texture_get_sampler_view(st, stObj);
if (*sv) {
* what they're supposed to be.
*/
MAYBE_UNUSED struct pipe_sampler_view *view = *sv;
- assert(!check_sampler_swizzle(st, stObj, view, glsl_version));
+ assert(stObj->pt == view->texture);
+ assert(!check_sampler_swizzle(st, stObj, view, glsl130_or_later));
assert(get_sampler_view_format(st, stObj, samp) == view->format);
assert(gl_target_to_pipe(stObj->base.Target) == view->target);
- if (stObj->base.Target == GL_TEXTURE_BUFFER) {
- unsigned base = stObj->base.BufferOffset;
- MAYBE_UNUSED unsigned size = MIN2(stObj->pt->width0 - base,
- (unsigned) stObj->base.BufferSize);
- assert(view->u.buf.offset == base);
- assert(view->u.buf.size == size);
- }
- else {
- assert(stObj->base.MinLevel + stObj->base.BaseLevel ==
- view->u.tex.first_level);
- assert(last_level(stObj) == view->u.tex.last_level);
- assert(stObj->layer_override || stObj->base.MinLayer == view->u.tex.first_layer);
- assert(stObj->layer_override || last_layer(stObj) == view->u.tex.last_layer);
- assert(!stObj->layer_override ||
- (stObj->layer_override == view->u.tex.first_layer &&
- stObj->layer_override == view->u.tex.last_layer));
- }
+ assert(stObj->base.MinLevel + stObj->base.BaseLevel ==
+ view->u.tex.first_level);
+ assert(last_level(stObj) == view->u.tex.last_level);
+ assert(stObj->layer_override || stObj->base.MinLayer == view->u.tex.first_layer);
+ assert(stObj->layer_override || last_layer(stObj) == view->u.tex.last_layer);
+ assert(!stObj->layer_override ||
+ (stObj->layer_override == view->u.tex.first_layer &&
+ stObj->layer_override == view->u.tex.last_layer));
}
else {
/* create new sampler view */
enum pipe_format format = get_sampler_view_format(st, stObj, samp);
*sv = st_create_texture_sampler_view_from_stobj(st, stObj,
- format, glsl_version);
+ format, glsl130_or_later);
}
return *sv;
}
+
+
+struct pipe_sampler_view *
+st_get_buffer_sampler_view_from_stobj(struct st_context *st,
+ struct st_texture_object *stObj)
+{
+ struct pipe_sampler_view **sv;
+ struct st_buffer_object *stBuf =
+ st_buffer_object(stObj->base.BufferObject);
+
+ if (!stBuf || !stBuf->buffer)
+ return NULL;
+
+ sv = st_texture_get_sampler_view(st, stObj);
+
+ struct pipe_resource *buf = stBuf->buffer;
+ struct pipe_sampler_view *view = *sv;
+
+ if (view && view->texture == buf) {
+ /* Debug check: make sure that the sampler view's parameters are
+ * what they're supposed to be.
+ */
+ assert(st_mesa_format_to_pipe_format(st, stObj->base._BufferObjectFormat)
+ == view->format);
+ assert(view->target == PIPE_BUFFER);
+ unsigned base = stObj->base.BufferOffset;
+ MAYBE_UNUSED unsigned size = MIN2(buf->width0 - base,
+ (unsigned) stObj->base.BufferSize);
+ assert(view->u.buf.offset == base);
+ assert(view->u.buf.size == size);
+ } else {
+ unsigned base = stObj->base.BufferOffset;
+
+ if (base >= buf->width0)
+ return NULL;
+
+ unsigned size = buf->width0 - base;
+ size = MIN2(size, (unsigned)stObj->base.BufferSize);
+ if (!size)
+ return NULL;
+
+ /* Create a new sampler view. There is no need to clear the entire
+ * structure (consider CPU overhead).
+ */
+ struct pipe_sampler_view templ;
+
+ templ.format =
+ st_mesa_format_to_pipe_format(st, stObj->base._BufferObjectFormat);
+ templ.target = PIPE_BUFFER;
+ templ.swizzle_r = PIPE_SWIZZLE_X;
+ templ.swizzle_g = PIPE_SWIZZLE_Y;
+ templ.swizzle_b = PIPE_SWIZZLE_Z;
+ templ.swizzle_a = PIPE_SWIZZLE_W;
+ templ.u.buf.offset = base;
+ templ.u.buf.size = size;
+
+ pipe_sampler_view_reference(sv, NULL);
+ *sv = st->pipe->create_sampler_view(st->pipe, buf, &templ);
+ }
+ return *sv;
+}