/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2011 Intel Corporation
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors:
+ * Chad Versace <chad@chad-versace.us>
+ *
**************************************************************************/
+#include <stdbool.h>
+#include <stdint.h>
#include "main/glheader.h"
#include "main/macros.h"
#include "main/mtypes.h"
#include "main/colormac.h"
+#include "main/renderbuffer.h"
#include "intel_buffers.h"
#include "intel_fbo.h"
#define LOCAL_VARS \
struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
- const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \
- const GLint yBias = ctx->DrawBuffer->Name ? 0 : irb->Base.Height - 1;\
int minx = 0, miny = 0; \
- int maxx = ctx->DrawBuffer->Width; \
- int maxy = ctx->DrawBuffer->Height; \
- int pitch = irb->region->pitch * irb->region->cpp; \
- void *buf = irb->region->buffer->virtual; \
+ int maxx = rb->Width; \
+ int maxy = rb->Height; \
+ int pitch = rb->RowStride * irb->region->cpp; \
+ void *buf = rb->Data; \
GLuint p; \
- (void) p; \
- (void)buf; (void)pitch; /* unused for non-gttmap. */ \
+ (void) p;
#define HW_CLIPLOOP()
#define HW_ENDCLIPLOOP()
-#define Y_FLIP(_y) ((_y) * yScale + yBias)
+#define Y_FLIP(_y) (_y)
#define HW_LOCK()
#define HW_UNLOCK()
-/* Convenience macros to avoid typing the address argument over and over */
-#define NO_TILE(_X, _Y) (((_Y) * irb->region->pitch + (_X)) * irb->region->cpp)
-
/* r5g6b5 color span and pixel functions */
#define SPANTMP_PIXEL_FMT GL_RGB
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
#define TAG2(x,y) intel_##x##y##_xRGB8888
#include "spantmp2.h"
-#define LOCAL_DEPTH_VARS \
- struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
- const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \
- const GLint yBias = ctx->DrawBuffer->Name ? 0 : irb->Base.Height - 1;\
- int minx = 0, miny = 0; \
- int maxx = ctx->DrawBuffer->Width; \
- int maxy = ctx->DrawBuffer->Height; \
- int pitch = irb->region->pitch * irb->region->cpp; \
- void *buf = irb->region->buffer->virtual; \
- (void)buf; (void)pitch; /* unused for non-gttmap. */ \
-
-#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
-
-/* z16 depthbuffer functions. */
-#define VALUE_TYPE GLushort
-#define WRITE_DEPTH(_x, _y, d) \
- (*(uint16_t *)(irb->region->buffer->virtual + NO_TILE(_x, _y)) = d)
-#define READ_DEPTH(d, _x, _y) \
- d = *(uint16_t *)(irb->region->buffer->virtual + NO_TILE(_x, _y))
-#define TAG(x) intel_##x##_z16
-#include "depthtmp.h"
-
-/* z24_s8 and z24_x8 depthbuffer functions. */
-#define VALUE_TYPE GLuint
-#define WRITE_DEPTH(_x, _y, d) \
- (*(uint32_t *)(irb->region->buffer->virtual + NO_TILE(_x, _y)) = d)
-#define READ_DEPTH(d, _x, _y) \
- d = *(uint32_t *)(irb->region->buffer->virtual + NO_TILE(_x, _y))
-#define TAG(x) intel_##x##_z24_x8
-#include "depthtmp.h"
+/* a8 color span and pixel functions */
+#define SPANTMP_PIXEL_FMT GL_ALPHA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_BYTE
+#define TAG(x) intel_##x##_A8
+#define TAG2(x,y) intel_##x##y##_A8
+#include "spantmp2.h"
+
+/* ------------------------------------------------------------------------- */
+/* s8 stencil span and pixel functions */
+/* ------------------------------------------------------------------------- */
+
+/*
+ * HAVE_HW_STENCIL_SPANS determines if stencil buffer read/writes are done with
+ * memcpy or for loops. Since the stencil buffer is interleaved, memcpy won't
+ * work.
+ */
+#define HAVE_HW_STENCIL_SPANS 0
+
+#define LOCAL_STENCIL_VARS \
+ (void) ctx; \
+ int minx = 0; \
+ int miny = 0; \
+ int maxx = rb->Width; \
+ int maxy = rb->Height; \
+ int stride = rb->RowStride; \
+ uint8_t *buf = rb->Data; \
+
+/* Don't flip y. */
+#undef Y_FLIP
+#define Y_FLIP(y) y
+
+/**
+ * \brief Get pointer offset into stencil buffer.
+ *
+ * The stencil buffer interleaves two rows into one. Yay for crazy hardware.
+ * The table below demonstrates how the pointer arithmetic behaves for a buffer
+ * with positive stride (s=stride).
+ *
+ * x | y | byte offset
+ * --------------------------
+ * 0 | 0 | 0
+ * 0 | 0 | 1
+ * 1 | 0 | 2
+ * 1 | 1 | 3
+ * ... | ... | ...
+ * 0 | 2 | s
+ * 0 | 3 | s + 1
+ * 1 | 2 | s + 2
+ * 1 | 3 | s + 3
+ *
+ *
+ */
+static inline intptr_t
+intel_offset_S8(int stride, GLint x, GLint y)
+{
+ return 2 * ((y / 2) * stride + x) + y % 2;
+}
+
+#define WRITE_STENCIL(x, y, src) buf[intel_offset_S8(stride, x, y)] = src;
+#define READ_STENCIL(dest, x, y) dest = buf[intel_offset_S8(stride, x, y)]
+#define TAG(x) intel_##x##_S8
+#include "stenciltmp.h"
+
+/* ------------------------------------------------------------------------- */
void
intel_renderbuffer_map(struct intel_context *intel, struct gl_renderbuffer *rb)
drm_intel_gem_bo_map_gtt(irb->region->buffer);
+ rb->Data = irb->region->buffer->virtual;
+ rb->RowStride = irb->region->pitch;
+
+ if (!rb->Name) {
+ /* Flip orientation of the window system buffer */
+ rb->Data += rb->RowStride * (irb->region->height - 1) * irb->region->cpp;
+ rb->RowStride = -rb->RowStride;
+ } else {
+ /* Adjust the base pointer of a texture image drawbuffer to the image
+ * within the miptree region (all else has draw_x/y = 0).
+ */
+ rb->Data += irb->draw_x * irb->region->cpp;
+ rb->Data += irb->draw_y * rb->RowStride * irb->region->cpp;
+ }
+
intel_set_span_functions(intel, rb);
}
rb->GetRow = NULL;
rb->PutRow = NULL;
+ rb->Data = NULL;
+ rb->RowStride = 0;
}
-/**
- * Map or unmap all the renderbuffers which we may need during
- * software rendering.
- * XXX in the future, we could probably convey extra information to
- * reduce the number of mappings needed. I.e. if doing a glReadPixels
- * from the depth buffer, we really only need one mapping.
- *
- * XXX Rewrite this function someday.
- * We can probably just loop over all the renderbuffer attachments,
- * map/unmap all of them, and not worry about the _ColorDrawBuffers
- * _ColorReadBuffer, _DepthBuffer or _StencilBuffer fields.
- */
static void
-intel_map_unmap_framebuffer(struct intel_context *intel,
- struct gl_framebuffer *fb,
- GLboolean map)
+intel_framebuffer_map(struct intel_context *intel, struct gl_framebuffer *fb)
{
- GLuint i;
-
- /* color draw buffers */
- for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
- if (map)
- intel_renderbuffer_map(intel, fb->_ColorDrawBuffers[i]);
- else
- intel_renderbuffer_unmap(intel, fb->_ColorDrawBuffers[i]);
- }
-
- /* color read buffer */
- if (map)
- intel_renderbuffer_map(intel, fb->_ColorReadBuffer);
- else
- intel_renderbuffer_unmap(intel, fb->_ColorReadBuffer);
+ int i;
- /* check for render to textures */
for (i = 0; i < BUFFER_COUNT; i++) {
- struct gl_renderbuffer_attachment *att =
- fb->Attachment + i;
- struct gl_texture_object *tex = att->Texture;
- if (tex) {
- /* render to texture */
- ASSERT(att->Renderbuffer);
- if (map)
- intel_tex_map_images(intel, intel_texture_object(tex));
- else
- intel_tex_unmap_images(intel, intel_texture_object(tex));
- }
+ intel_renderbuffer_map(intel, fb->Attachment[i].Renderbuffer);
}
- /* depth buffer (Note wrapper!) */
- if (fb->_DepthBuffer) {
- if (map)
- intel_renderbuffer_map(intel, fb->_DepthBuffer->Wrapped);
- else
- intel_renderbuffer_unmap(intel, fb->_DepthBuffer->Wrapped);
- }
+ intel_check_front_buffer_rendering(intel);
+}
- /* stencil buffer (Note wrapper!) */
- if (fb->_StencilBuffer) {
- if (map)
- intel_renderbuffer_map(intel, fb->_StencilBuffer->Wrapped);
- else
- intel_renderbuffer_unmap(intel, fb->_StencilBuffer->Wrapped);
- }
+static void
+intel_framebuffer_unmap(struct intel_context *intel, struct gl_framebuffer *fb)
+{
+ int i;
- intel_check_front_buffer_rendering(intel);
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ intel_renderbuffer_unmap(intel, fb->Attachment[i].Renderbuffer);
+ }
}
/**
* Old note: Moved locking out to get reasonable span performance.
*/
void
-intelSpanRenderStart(GLcontext * ctx)
+intelSpanRenderStart(struct gl_context * ctx)
{
struct intel_context *intel = intel_context(ctx);
GLuint i;
- intelFlush(&intel->ctx);
+ intel_flush(&intel->ctx);
intel_prepare_render(intel);
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
if (ctx->Texture.Unit[i]._ReallyEnabled) {
struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
+
+ intel_finalize_mipmap_tree(intel, i);
intel_tex_map_images(intel, intel_texture_object(texObj));
}
}
- intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_TRUE);
- if (ctx->ReadBuffer != ctx->DrawBuffer)
- intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_TRUE);
+ intel_framebuffer_map(intel, ctx->DrawBuffer);
+ if (ctx->ReadBuffer != ctx->DrawBuffer) {
+ intel_framebuffer_map(intel, ctx->ReadBuffer);
+ }
}
/**
* the above function.
*/
void
-intelSpanRenderFinish(GLcontext * ctx)
+intelSpanRenderFinish(struct gl_context * ctx)
{
struct intel_context *intel = intel_context(ctx);
GLuint i;
}
}
- intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_FALSE);
- if (ctx->ReadBuffer != ctx->DrawBuffer)
- intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_FALSE);
+ intel_framebuffer_unmap(intel, ctx->DrawBuffer);
+ if (ctx->ReadBuffer != ctx->DrawBuffer) {
+ intel_framebuffer_unmap(intel, ctx->ReadBuffer);
+ }
}
void
-intelInitSpanFuncs(GLcontext * ctx)
+intelInitSpanFuncs(struct gl_context * ctx)
{
struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
swdd->SpanRenderStart = intelSpanRenderStart;
}
void
-intel_map_vertex_shader_textures(GLcontext *ctx)
+intel_map_vertex_shader_textures(struct gl_context *ctx)
{
struct intel_context *intel = intel_context(ctx);
int i;
}
void
-intel_unmap_vertex_shader_textures(GLcontext *ctx)
+intel_unmap_vertex_shader_textures(struct gl_context *ctx)
{
struct intel_context *intel = intel_context(ctx);
int i;
}
}
+typedef void (*span_init_func)(struct gl_renderbuffer *rb);
+
+static span_init_func intel_span_init_funcs[MESA_FORMAT_COUNT] =
+{
+ [MESA_FORMAT_A8] = intel_InitPointers_A8,
+ [MESA_FORMAT_RGB565] = intel_InitPointers_RGB565,
+ [MESA_FORMAT_ARGB4444] = intel_InitPointers_ARGB4444,
+ [MESA_FORMAT_ARGB1555] = intel_InitPointers_ARGB1555,
+ [MESA_FORMAT_XRGB8888] = intel_InitPointers_xRGB8888,
+ [MESA_FORMAT_ARGB8888] = intel_InitPointers_ARGB8888,
+ [MESA_FORMAT_SARGB8] = intel_InitPointers_ARGB8888,
+ [MESA_FORMAT_Z16] = _mesa_set_renderbuffer_accessors,
+ [MESA_FORMAT_X8_Z24] = _mesa_set_renderbuffer_accessors,
+ [MESA_FORMAT_S8_Z24] = _mesa_set_renderbuffer_accessors,
+ [MESA_FORMAT_S8] = intel_InitStencilPointers_S8,
+ [MESA_FORMAT_R8] = _mesa_set_renderbuffer_accessors,
+ [MESA_FORMAT_RG88] = _mesa_set_renderbuffer_accessors,
+ [MESA_FORMAT_R16] = _mesa_set_renderbuffer_accessors,
+ [MESA_FORMAT_RG1616] = _mesa_set_renderbuffer_accessors,
+ [MESA_FORMAT_RGBA_FLOAT32] = _mesa_set_renderbuffer_accessors,
+ [MESA_FORMAT_RG_FLOAT32] = _mesa_set_renderbuffer_accessors,
+ [MESA_FORMAT_R_FLOAT32] = _mesa_set_renderbuffer_accessors,
+ [MESA_FORMAT_INTENSITY_FLOAT32] = _mesa_set_renderbuffer_accessors,
+ [MESA_FORMAT_LUMINANCE_FLOAT32] = _mesa_set_renderbuffer_accessors,
+};
+
+bool
+intel_span_supports_format(gl_format format)
+{
+ return intel_span_init_funcs[format] != NULL;
+}
+
/**
* Plug in appropriate span read/write functions for the given renderbuffer.
* These are used for the software fallbacks.
{
struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb;
- switch (irb->Base.Format) {
- case MESA_FORMAT_RGB565:
- intel_InitPointers_RGB565(rb);
- break;
- case MESA_FORMAT_ARGB4444:
- intel_InitPointers_ARGB4444(rb);
- break;
- case MESA_FORMAT_ARGB1555:
- intel_InitPointers_ARGB1555(rb);
- break;
- case MESA_FORMAT_XRGB8888:
- intel_InitPointers_xRGB8888(rb);
- break;
- case MESA_FORMAT_ARGB8888:
- intel_InitPointers_ARGB8888(rb);
- break;
- case MESA_FORMAT_Z16:
- intel_InitDepthPointers_z16(rb);
- break;
- case MESA_FORMAT_X8_Z24:
- case MESA_FORMAT_S8_Z24:
- intel_InitDepthPointers_z24_x8(rb);
- break;
- default:
- _mesa_problem(NULL,
- "Unexpected MesaFormat %d in intelSetSpanFunctions",
- irb->Base.Format);
- break;
- }
+ assert(intel_span_init_funcs[irb->Base.Format]);
+ intel_span_init_funcs[irb->Base.Format](rb);
}