/*
- Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ Copyright 2003 VMware, Inc.
Copyright (C) Intel Corp. 2006. All Rights Reserved.
- Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ Intel funded Tungsten Graphics to
develop this 3D driver.
-
+
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
-
+
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
-
+
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 NONINFRINGEMENT.
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.
-
+
**********************************************************************/
/*
* Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
+ * Keith Whitwell <keithw@vmware.com>
*/
(void) target;
switch (brw->gen) {
+ case 8:
+ samples[0] = 8;
+ samples[1] = 4;
+ samples[2] = 2;
+ return 3;
+
case 7:
samples[0] = 8;
samples[1] = 4;
}
}
+const char *const brw_vendor_string = "Intel Open Source Technology Center";
+
+const char *
+brw_get_renderer_string(unsigned deviceID)
+{
+ const char *chipset;
+ static char buffer[128];
+
+ switch (deviceID) {
+#undef CHIPSET
+#define CHIPSET(id, symbol, str) case id: chipset = str; break;
+#include "pci_ids/i965_pci_ids.h"
+ default:
+ chipset = "Unknown Intel Chipset";
+ break;
+ }
+
+ (void) driGetRendererString(buffer, chipset, 0);
+ return buffer;
+}
+
static const GLubyte *
intelGetString(struct gl_context * ctx, GLenum name)
{
const struct brw_context *const brw = brw_context(ctx);
- const char *chipset;
- static char buffer[128];
switch (name) {
case GL_VENDOR:
- return (GLubyte *) "Intel Open Source Technology Center";
- break;
+ return (GLubyte *) brw_vendor_string;
case GL_RENDERER:
- switch (brw->intelScreen->deviceID) {
-#undef CHIPSET
-#define CHIPSET(id, family, str) case id: chipset = str; break;
-#include "pci_ids/i965_pci_ids.h"
- default:
- chipset = "Unknown Intel Chipset";
- break;
- }
-
- (void) driGetRendererString(buffer, chipset, 0);
- return (GLubyte *) buffer;
+ return
+ (GLubyte *) brw_get_renderer_string(brw->intelScreen->deviceID);
default:
return NULL;
}
static void
-intel_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+intel_viewport(struct gl_context *ctx)
{
struct brw_context *brw = brw_context(ctx);
__DRIcontext *driContext = brw->driContext;
- if (brw->saved_viewport)
- brw->saved_viewport(ctx, x, y, w, h);
-
if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
dri2InvalidateDrawable(driContext->driDrawablePriv);
dri2InvalidateDrawable(driContext->driReadablePriv);
brw->NewGLState |= new_state;
}
+#define flushFront(screen) ((screen)->image.loader ? (screen)->image.loader->flushFrontBuffer : (screen)->dri2.loader->flushFrontBuffer)
+
static void
intel_flush_front(struct gl_context *ctx)
{
__DRIscreen *const screen = brw->intelScreen->driScrnPriv;
if (brw->front_buffer_dirty && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
- if (screen->dri2.loader->flushFrontBuffer != NULL &&
- driDrawable &&
+ if (flushFront(screen) && driDrawable &&
driDrawable->loaderPrivate) {
/* Resolve before flushing FAKE_FRONT_LEFT to FRONT_LEFT.
intel_resolve_for_dri2_flush(brw, driDrawable);
intel_batchbuffer_flush(brw);
- screen->dri2.loader->flushFrontBuffer(driDrawable,
- driDrawable->loaderPrivate);
+ flushFront(screen)(driDrawable, driDrawable->loaderPrivate);
/* We set the dirty bit in intel_prepare_render() if we're
* front buffer rendering once we get there.
intel_batchbuffer_flush(brw);
intel_flush_front(ctx);
- if (brw->is_front_buffer_rendering)
+ if (brw_is_front_buffer_drawing(ctx->DrawBuffer))
brw->need_throttle = true;
}
* So EGL still relies on viewport hacks to handle window resizing.
* This should go away with DRI3000.
*/
- if (!brw->driContext->driScreenPriv->dri2.useInvalidate) {
- brw->saved_viewport = functions->Viewport;
+ if (!brw->driContext->driScreenPriv->dri2.useInvalidate)
functions->Viewport = intel_viewport;
- }
functions->Flush = intel_glFlush;
functions->Finish = intelFinish;
functions->QuerySamplesForFormat = brw_query_samples_for_format;
+ functions->NewTransformFeedback = brw_new_transform_feedback;
+ functions->DeleteTransformFeedback = brw_delete_transform_feedback;
+ functions->GetTransformFeedbackVertexCount =
+ brw_get_transform_feedback_vertex_count;
if (brw->gen >= 7) {
functions->BeginTransformFeedback = gen7_begin_transform_feedback;
functions->EndTransformFeedback = gen7_end_transform_feedback;
+ functions->PauseTransformFeedback = gen7_pause_transform_feedback;
+ functions->ResumeTransformFeedback = gen7_resume_transform_feedback;
} else {
functions->BeginTransformFeedback = brw_begin_transform_feedback;
functions->EndTransformFeedback = brw_end_transform_feedback;
{
struct gl_context *ctx = &brw->ctx;
+ unsigned max_samplers =
+ brw->gen >= 8 || brw->is_haswell ? BRW_MAX_TEX_UNIT : 16;
+
ctx->Const.QueryCounterBits.Timestamp = 36;
ctx->Const.StripTextureBorder = true;
ctx->Const.MaxDualSourceDrawBuffers = 1;
ctx->Const.MaxDrawBuffers = BRW_MAX_DRAW_BUFFERS;
- ctx->Const.FragmentProgram.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = max_samplers;
ctx->Const.MaxTextureCoordUnits = 8; /* Mesa limit */
ctx->Const.MaxTextureUnits =
MIN2(ctx->Const.MaxTextureCoordUnits,
- ctx->Const.FragmentProgram.MaxTextureImageUnits);
- ctx->Const.VertexProgram.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits);
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = max_samplers;
if (brw->gen >= 7)
- ctx->Const.GeometryProgram.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = max_samplers;
else
- ctx->Const.GeometryProgram.MaxTextureImageUnits = 0;
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = 0;
+ if (getenv("INTEL_COMPUTE_SHADER")) {
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
+ ctx->Const.MaxUniformBufferBindings += 12;
+ } else {
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits = 0;
+ }
ctx->Const.MaxCombinedTextureImageUnits =
- ctx->Const.VertexProgram.MaxTextureImageUnits +
- ctx->Const.FragmentProgram.MaxTextureImageUnits +
- ctx->Const.GeometryProgram.MaxTextureImageUnits;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits +
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits +
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits +
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits;
ctx->Const.MaxTextureLevels = 14; /* 8192 */
if (ctx->Const.MaxTextureLevels > MAX_TEXTURE_LEVELS)
ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
- ctx->Const.Max3DTextureLevels = 9;
- ctx->Const.MaxCubeTextureLevels = 12;
+ ctx->Const.Max3DTextureLevels = 12; /* 2048 */
+ ctx->Const.MaxCubeTextureLevels = 14; /* 8192 */
+ ctx->Const.MaxTextureMbytes = 1536;
if (brw->gen >= 7)
ctx->Const.MaxArrayTextureLayers = 2048;
ctx->Const.MaxArrayTextureLayers = 512;
ctx->Const.MaxTextureRectSize = 1 << 12;
-
+
ctx->Const.MaxTextureMaxAnisotropy = 16.0;
ctx->Const.MaxRenderbufferSize = 8192;
ctx->Const.MaxTransformFeedbackSeparateComponents =
BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS;
- if (brw->gen == 6) {
- ctx->Const.MaxSamples = 4;
- ctx->Const.MaxColorTextureSamples = 4;
- ctx->Const.MaxDepthTextureSamples = 4;
- ctx->Const.MaxIntegerSamples = 4;
- } else if (brw->gen >= 7) {
- ctx->Const.MaxSamples = 8;
- ctx->Const.MaxColorTextureSamples = 8;
- ctx->Const.MaxDepthTextureSamples = 8;
- ctx->Const.MaxIntegerSamples = 8;
- ctx->Const.MaxProgramTextureGatherComponents = 4;
+ ctx->Const.AlwaysUseGetTransformFeedbackVertexCount = true;
+
+ int max_samples;
+ const int *msaa_modes = intel_supported_msaa_modes(brw->intelScreen);
+ const int clamp_max_samples =
+ driQueryOptioni(&brw->optionCache, "clamp_max_samples");
+
+ if (clamp_max_samples < 0) {
+ max_samples = msaa_modes[0];
+ } else {
+ /* Select the largest supported MSAA mode that does not exceed
+ * clamp_max_samples.
+ */
+ max_samples = 0;
+ for (int i = 0; msaa_modes[i] != 0; ++i) {
+ if (msaa_modes[i] <= clamp_max_samples) {
+ max_samples = msaa_modes[i];
+ break;
+ }
+ }
}
+ ctx->Const.MaxSamples = max_samples;
+ ctx->Const.MaxColorTextureSamples = max_samples;
+ ctx->Const.MaxDepthTextureSamples = max_samples;
+ ctx->Const.MaxIntegerSamples = max_samples;
+
+ if (brw->gen >= 7)
+ ctx->Const.MaxProgramTextureGatherComponents = 4;
+ else if (brw->gen == 6)
+ ctx->Const.MaxProgramTextureGatherComponents = 1;
+
ctx->Const.MinLineWidth = 1.0;
ctx->Const.MinLineWidthAA = 1.0;
ctx->Const.MaxLineWidth = 5.0;
if (brw->gen >= 5 || brw->is_g4x)
ctx->Const.MaxClipPlanes = 8;
- ctx->Const.VertexProgram.MaxNativeInstructions = 16 * 1024;
- ctx->Const.VertexProgram.MaxAluInstructions = 0;
- ctx->Const.VertexProgram.MaxTexInstructions = 0;
- ctx->Const.VertexProgram.MaxTexIndirections = 0;
- ctx->Const.VertexProgram.MaxNativeAluInstructions = 0;
- ctx->Const.VertexProgram.MaxNativeTexInstructions = 0;
- ctx->Const.VertexProgram.MaxNativeTexIndirections = 0;
- ctx->Const.VertexProgram.MaxNativeAttribs = 16;
- ctx->Const.VertexProgram.MaxNativeTemps = 256;
- ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
- ctx->Const.VertexProgram.MaxNativeParameters = 1024;
- ctx->Const.VertexProgram.MaxEnvParams =
- MIN2(ctx->Const.VertexProgram.MaxNativeParameters,
- ctx->Const.VertexProgram.MaxEnvParams);
-
- ctx->Const.FragmentProgram.MaxNativeInstructions = 1024;
- ctx->Const.FragmentProgram.MaxNativeAluInstructions = 1024;
- ctx->Const.FragmentProgram.MaxNativeTexInstructions = 1024;
- ctx->Const.FragmentProgram.MaxNativeTexIndirections = 1024;
- ctx->Const.FragmentProgram.MaxNativeAttribs = 12;
- ctx->Const.FragmentProgram.MaxNativeTemps = 256;
- ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0;
- ctx->Const.FragmentProgram.MaxNativeParameters = 1024;
- ctx->Const.FragmentProgram.MaxEnvParams =
- MIN2(ctx->Const.FragmentProgram.MaxNativeParameters,
- ctx->Const.FragmentProgram.MaxEnvParams);
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeInstructions = 16 * 1024;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxAluInstructions = 0;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxTexInstructions = 0;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxTexIndirections = 0;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeAluInstructions = 0;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeTexInstructions = 0;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeTexIndirections = 0;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeAttribs = 16;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeTemps = 256;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeAddressRegs = 1;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeParameters = 1024;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxEnvParams =
+ MIN2(ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeParameters,
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxEnvParams);
+
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeInstructions = 1024;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeAluInstructions = 1024;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeTexInstructions = 1024;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeTexIndirections = 1024;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeAttribs = 12;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeTemps = 256;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeAddressRegs = 0;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeParameters = 1024;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxEnvParams =
+ MIN2(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeParameters,
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxEnvParams);
/* Fragment shaders use real, 32-bit twos-complement integers for all
* integer types.
*/
- ctx->Const.FragmentProgram.LowInt.RangeMin = 31;
- ctx->Const.FragmentProgram.LowInt.RangeMax = 30;
- ctx->Const.FragmentProgram.LowInt.Precision = 0;
- ctx->Const.FragmentProgram.HighInt = ctx->Const.FragmentProgram.LowInt;
- ctx->Const.FragmentProgram.MediumInt = ctx->Const.FragmentProgram.LowInt;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt.RangeMin = 31;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt.RangeMax = 30;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt.Precision = 0;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].HighInt = ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MediumInt = ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt;
+
+ if (brw->gen >= 7) {
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicBuffers = BRW_MAX_ABO;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxAtomicBuffers = BRW_MAX_ABO;
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicBuffers = BRW_MAX_ABO;
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicBuffers = BRW_MAX_ABO;
+ ctx->Const.MaxCombinedAtomicBuffers = 3 * BRW_MAX_ABO;
+ }
/* Gen6 converts quads to polygon in beginning of 3D pipeline,
* but we're not sure how it's actually done for vertex order,
if (brw->gen >= 6) {
ctx->Const.MaxVarying = 32;
- ctx->Const.VertexProgram.MaxOutputComponents = 128;
- ctx->Const.GeometryProgram.MaxInputComponents = 128;
- ctx->Const.GeometryProgram.MaxOutputComponents = 128;
- ctx->Const.FragmentProgram.MaxInputComponents = 128;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 128;
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents = 64;
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = 128;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 128;
}
/* We want the GLSL compiler to emit code that uses condition codes */
- for (int i = 0; i < MESA_SHADER_TYPES; i++) {
+ for (int i = 0; i < MESA_SHADER_STAGES; i++) {
ctx->ShaderCompilerOptions[i].MaxIfDepth = brw->gen < 6 ? 16 : UINT_MAX;
ctx->ShaderCompilerOptions[i].EmitCondCodes = true;
ctx->ShaderCompilerOptions[i].EmitNoNoise = true;
ctx->ShaderCompilerOptions[i].LowerClipDistance = true;
}
- ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].PreferDP4 = true;
+ ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS = true;
+ ctx->ShaderCompilerOptions[MESA_SHADER_GEOMETRY].OptimizeForAOS = true;
+
+ /* ARB_viewport_array */
+ if (brw->gen >= 7 && ctx->API == API_OPENGL_CORE) {
+ ctx->Const.MaxViewports = GEN7_NUM_VIEWPORTS;
+ ctx->Const.ViewportSubpixelBits = 0;
+
+ /* Cast to float before negating becuase MaxViewportWidth is unsigned.
+ */
+ ctx->Const.ViewportBounds.Min = -(float)ctx->Const.MaxViewportWidth;
+ ctx->Const.ViewportBounds.Max = ctx->Const.MaxViewportWidth;
+ }
}
/**
driQueryOptionb(options, "disable_glsl_line_continuations");
}
-bool
+GLboolean
brwCreateContext(gl_api api,
const struct gl_config *mesaVis,
__DRIcontext *driContextPriv,
unsigned major_version,
unsigned minor_version,
uint32_t flags,
+ bool notify_reset,
unsigned *dri_ctx_error,
void *sharedContextPrivate)
{
struct intel_screen *screen = sPriv->driverPrivate;
const struct brw_device_info *devinfo = screen->devinfo;
struct dd_function_table functions;
- struct gl_config visual;
+
+ /* Only allow the __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS flag if the kernel
+ * provides us with context reset notifications.
+ */
+ uint32_t allowed_flags = __DRI_CTX_FLAG_DEBUG
+ | __DRI_CTX_FLAG_FORWARD_COMPATIBLE;
+
+ if (screen->has_context_reset_notification)
+ allowed_flags |= __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS;
+
+ if (flags & ~allowed_flags) {
+ *dri_ctx_error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
+ return false;
+ }
struct brw_context *brw = rzalloc(NULL, struct brw_context);
if (!brw) {
- printf("%s: failed to alloc context\n", __FUNCTION__);
+ fprintf(stderr, "%s: failed to alloc context\n", __FUNCTION__);
*dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
return false;
}
brw->must_use_separate_stencil = screen->hw_must_use_separate_stencil;
brw->has_swizzling = screen->hw_has_swizzling;
- if (brw->gen >= 7) {
+ if (brw->gen >= 8) {
+ gen8_init_vtable_surface_functions(brw);
+ gen7_init_vtable_sampler_functions(brw);
+ brw->vtbl.emit_depth_stencil_hiz = gen8_emit_depth_stencil_hiz;
+ } else if (brw->gen >= 7) {
gen7_init_vtable_surface_functions(brw);
gen7_init_vtable_sampler_functions(brw);
brw->vtbl.emit_depth_stencil_hiz = gen7_emit_depth_stencil_hiz;
brw_init_driver_functions(brw, &functions);
- struct gl_context *ctx = &brw->ctx;
+ if (notify_reset)
+ functions.GetGraphicsResetStatus = brw_get_graphics_reset_status;
- if (mesaVis == NULL) {
- memset(&visual, 0, sizeof visual);
- mesaVis = &visual;
- }
+ struct gl_context *ctx = &brw->ctx;
if (!_mesa_initialize_context(ctx, api, mesaVis, shareCtx, &functions)) {
*dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
- printf("%s: failed to init mesa context\n", __FUNCTION__);
+ fprintf(stderr, "%s: failed to init mesa context\n", __FUNCTION__);
intelDestroyContext(driContextPriv);
return false;
}
+ driContextSetFlags(ctx, flags);
+
/* Initialize the software rasterizer and helper modules.
*
* As of GL 3.1 core, the gen4+ driver doesn't need the swrast context for
brw_process_intel_debug_variable(brw);
brw_initialize_context_constants(brw);
+ ctx->Const.ResetStrategy = notify_reset
+ ? GL_LOSE_CONTEXT_ON_RESET_ARB : GL_NO_RESET_NOTIFICATION_ARB;
+
/* Reinitialize the context point state. It depends on ctx->Const values. */
_mesa_init_point(ctx);
- intelInitExtensions(ctx);
+ intel_fbo_init(brw);
intel_batchbuffer_init(brw);
- intel_fbo_init(brw);
-
if (brw->gen >= 6) {
/* Create a new hardware context. Using a hardware context means that
* our GPU state will be saved/restored on context switch, allowing us
}
}
+ brw_init_state(brw);
+
+ intelInitExtensions(ctx);
+
brw_init_surface_formats(brw);
if (brw->is_g4x || brw->gen >= 5) {
brw->prim_restart.in_progress = false;
brw->prim_restart.enable_cut_index = false;
-
- brw_init_state( brw );
+ brw->gs.enabled = false;
if (brw->gen < 6) {
brw->curbe.last_buf = calloc(1, 4096);
brw->perf_debug = true;
}
- brw_fs_alloc_reg_sets(brw);
- brw_vec4_alloc_reg_set(brw);
+ if ((flags & __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS) != 0)
+ ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB;
if (INTEL_DEBUG & DEBUG_SHADER_TIME)
brw_init_shader_time(brw);
brw_draw_destroy(brw);
drm_intel_bo_unreference(brw->curbe.curbe_bo);
- drm_intel_bo_unreference(brw->vs.base.const_bo);
- drm_intel_bo_unreference(brw->wm.base.const_bo);
free(brw->curbe.last_buf);
free(brw->curbe.next_buf);
fb->Visual.sRGBCapable = false;
for (int i = 0; i < BUFFER_COUNT; i++) {
if (fb->Attachment[i].Renderbuffer &&
- fb->Attachment[i].Renderbuffer->Format == MESA_FORMAT_SARGB8) {
- fb->Attachment[i].Renderbuffer->Format = MESA_FORMAT_ARGB8888;
+ fb->Attachment[i].Renderbuffer->Format == MESA_FORMAT_B8G8R8A8_SRGB) {
+ fb->Attachment[i].Renderbuffer->Format = MESA_FORMAT_B8G8R8A8_UNORM;
}
}
}
intel_gles3_srgb_workaround(brw, fb);
intel_gles3_srgb_workaround(brw, readFb);
- intel_prepare_render(brw);
+ /* If the context viewport hasn't been initialized, force a call out to
+ * the loader to get buffers so we have a drawable size for the initial
+ * viewport. */
+ if (!brw->ctx.ViewportInitialized)
+ intel_prepare_render(brw);
+
_mesa_make_current(ctx, fb, readFb);
} else {
_mesa_make_current(NULL, NULL, NULL);
if (rb->mt->num_samples <= 1)
intel_miptree_resolve_color(brw, rb->mt);
else
- intel_miptree_downsample(brw, rb->mt);
+ intel_renderbuffer_downsample(brw, rb);
}
}
struct intel_renderbuffer *rb,
const char *buffer_name);
-void
-intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
+static void
+intel_update_image_buffers(struct brw_context *brw, __DRIdrawable *drawable);
+
+static void
+intel_update_dri2_buffers(struct brw_context *brw, __DRIdrawable *drawable)
{
struct gl_framebuffer *fb = drawable->driverPrivate;
struct intel_renderbuffer *rb;
- struct brw_context *brw = context->driverPrivate;
__DRIbuffer *buffers = NULL;
int i, count;
const char *region_name;
intel_process_dri2_buffer(brw, drawable, &buffers[i], rb, region_name);
}
+}
+
+void
+intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
+{
+ struct brw_context *brw = context->driverPrivate;
+ __DRIscreen *screen = brw->intelScreen->driScrnPriv;
+
+ /* Set this up front, so that in case our buffers get invalidated
+ * while we're getting new buffers, we don't clobber the stamp and
+ * thus ignore the invalidate. */
+ drawable->lastStamp = drawable->dri2.stamp;
+
+ if (unlikely(INTEL_DEBUG & DEBUG_DRI))
+ fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
+
+ if (screen->image.loader)
+ intel_update_image_buffers(brw, drawable);
+ else
+ intel_update_dri2_buffers(brw, drawable);
+
driUpdateFramebufferSize(&brw->ctx, drawable);
}
void
intel_prepare_render(struct brw_context *brw)
{
+ struct gl_context *ctx = &brw->ctx;
__DRIcontext *driContext = brw->driContext;
__DRIdrawable *drawable;
* that will happen next will probably dirty the front buffer. So
* mark it as dirty here.
*/
- if (brw->is_front_buffer_rendering)
+ if (brw_is_front_buffer_drawing(ctx->DrawBuffer))
brw->front_buffer_dirty = true;
/* Wait for the swapbuffers before the one we just emitted, so we
back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
memset(attachments, 0, sizeof(attachments));
- if ((brw->is_front_buffer_rendering ||
- brw->is_front_buffer_reading ||
+ if ((brw_is_front_buffer_drawing(fb) ||
+ brw_is_front_buffer_reading(fb) ||
!back_rb) && front_rb) {
/* If a fake front buffer is in use, then querying for
* __DRI_BUFFER_FRONT_LEFT will cause the server to copy the image from
const char *buffer_name)
{
struct intel_region *region = NULL;
+ struct gl_framebuffer *fb = drawable->driverPrivate;
if (!rb)
return;
* use of a mapping of the buffer involves a bunch of page faulting which is
* moderately expensive.
*/
- if (num_samples == 0) {
- if (rb->mt &&
- rb->mt->region &&
- rb->mt->region->name == buffer->name)
- return;
- } else {
- if (rb->mt &&
- rb->mt->singlesample_mt &&
- rb->mt->singlesample_mt->region &&
- rb->mt->singlesample_mt->region->name == buffer->name)
- return;
- }
+ struct intel_mipmap_tree *last_mt;
+ if (num_samples == 0)
+ last_mt = rb->mt;
+ else
+ last_mt = rb->singlesample_mt;
+
+ if (last_mt && last_mt->region->name == buffer->name)
+ return;
if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
fprintf(stderr,
buffer->pitch,
buffer->name,
buffer_name);
- if (!region)
+ if (!region) {
+ fprintf(stderr,
+ "Failed to make region for returned DRI2 buffer "
+ "(%dx%d, named %d).\n"
+ "This is likely a bug in the X Server that will lead to a "
+ "crash soon.\n",
+ drawable->w, drawable->h, buffer->name);
return;
+ }
+
+ intel_update_winsys_renderbuffer_miptree(brw, rb, region);
+
+ if (brw_is_front_buffer_drawing(fb) &&
+ (buffer->attachment == __DRI_BUFFER_FRONT_LEFT ||
+ buffer->attachment == __DRI_BUFFER_FAKE_FRONT_LEFT) &&
+ rb->Base.Base.NumSamples > 1) {
+ intel_renderbuffer_upsample(brw, rb);
+ }
+
+ assert(rb->mt);
- rb->mt = intel_miptree_create_for_dri2_buffer(brw,
- buffer->attachment,
- intel_rb_format(rb),
- num_samples,
- region);
intel_region_release(®ion);
}
+
+/**
+ * \brief Query DRI image loader to obtain a DRIdrawable's buffers.
+ *
+ * To determine which DRI buffers to request, examine the renderbuffers
+ * attached to the drawable's framebuffer. Then request the buffers from
+ * the image loader
+ *
+ * This is called from intel_update_renderbuffers().
+ *
+ * \param drawable Drawable whose buffers are queried.
+ * \param buffers [out] List of buffers returned by DRI2 query.
+ * \param buffer_count [out] Number of buffers returned.
+ *
+ * \see intel_update_renderbuffers()
+ */
+
+static void
+intel_update_image_buffer(struct brw_context *intel,
+ __DRIdrawable *drawable,
+ struct intel_renderbuffer *rb,
+ __DRIimage *buffer,
+ enum __DRIimageBufferMask buffer_type)
+{
+ struct intel_region *region = buffer->region;
+ struct gl_framebuffer *fb = drawable->driverPrivate;
+
+ if (!rb || !region)
+ return;
+
+ unsigned num_samples = rb->Base.Base.NumSamples;
+
+ /* Check and see if we're already bound to the right
+ * buffer object
+ */
+ struct intel_mipmap_tree *last_mt;
+ if (num_samples == 0)
+ last_mt = rb->mt;
+ else
+ last_mt = rb->singlesample_mt;
+
+ if (last_mt && last_mt->region->bo == region->bo)
+ return;
+
+ intel_update_winsys_renderbuffer_miptree(intel, rb, region);
+
+ if (brw_is_front_buffer_drawing(fb) &&
+ buffer_type == __DRI_IMAGE_BUFFER_FRONT &&
+ rb->Base.Base.NumSamples > 1) {
+ intel_renderbuffer_upsample(intel, rb);
+ }
+}
+
+static void
+intel_update_image_buffers(struct brw_context *brw, __DRIdrawable *drawable)
+{
+ struct gl_framebuffer *fb = drawable->driverPrivate;
+ __DRIscreen *screen = brw->intelScreen->driScrnPriv;
+ struct intel_renderbuffer *front_rb;
+ struct intel_renderbuffer *back_rb;
+ struct __DRIimageList images;
+ unsigned int format;
+ uint32_t buffer_mask = 0;
+
+ front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+ back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
+
+ if (back_rb)
+ format = intel_rb_format(back_rb);
+ else if (front_rb)
+ format = intel_rb_format(front_rb);
+ else
+ return;
+
+ if (front_rb && (brw_is_front_buffer_drawing(fb) ||
+ brw_is_front_buffer_reading(fb) || !back_rb)) {
+ buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
+ }
+
+ if (back_rb)
+ buffer_mask |= __DRI_IMAGE_BUFFER_BACK;
+
+ (*screen->image.loader->getBuffers) (drawable,
+ driGLFormatToImageFormat(format),
+ &drawable->dri2.stamp,
+ drawable->loaderPrivate,
+ buffer_mask,
+ &images);
+
+ if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) {
+ drawable->w = images.front->width;
+ drawable->h = images.front->height;
+ intel_update_image_buffer(brw,
+ drawable,
+ front_rb,
+ images.front,
+ __DRI_IMAGE_BUFFER_FRONT);
+ }
+ if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
+ drawable->w = images.back->width;
+ drawable->h = images.back->height;
+ intel_update_image_buffer(brw,
+ drawable,
+ back_rb,
+ images.back,
+ __DRI_IMAGE_BUFFER_BACK);
+ }
+}